CustomizeTitle.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import type { FC } from 'react';
  2. import React, { useCallback, useEffect } from 'react';
  3. import { useTranslation } from 'next-i18next';
  4. import { useForm } from 'react-hook-form';
  5. import { Card, CardBody } from 'reactstrap';
  6. import { apiv3Put } from '~/client/util/apiv3-client';
  7. import { toastError, toastSuccess } from '~/client/util/toastr';
  8. import { useCustomTitleTemplate } from '~/states/global';
  9. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  10. export const CustomizeTitle: FC = () => {
  11. const { t } = useTranslation('admin');
  12. const customTitleTemplate = useCustomTitleTemplate();
  13. const { register, handleSubmit, reset } = useForm();
  14. // Sync form with store data
  15. useEffect(() => {
  16. reset({
  17. customizeTitle: customTitleTemplate ?? '',
  18. });
  19. }, [customTitleTemplate, reset]);
  20. const onSubmit = useCallback(
  21. async (data) => {
  22. try {
  23. await apiv3Put('/customize-setting/customize-title', {
  24. customizeTitle: data.customizeTitle,
  25. });
  26. toastSuccess(
  27. t('toaster.update_successed', {
  28. target: t('admin:customize_settings.custom_title'),
  29. ns: 'commons',
  30. }),
  31. );
  32. } catch (err) {
  33. toastError(err);
  34. }
  35. },
  36. [t],
  37. );
  38. return (
  39. <React.Fragment>
  40. <div className="row">
  41. <div className="col-12">
  42. <h2 className="admin-setting-header">
  43. {t('admin:customize_settings.custom_title')}
  44. </h2>
  45. </div>
  46. <div className="col-12">
  47. <Card className="card custom-card bg-body-tertiary mb-3">
  48. <CardBody className="px-0 py-2">
  49. {/* eslint-disable react/no-danger */}
  50. <p
  51. // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
  52. dangerouslySetInnerHTML={{
  53. __html: t('admin:customize_settings.custom_title_detail'),
  54. }}
  55. />
  56. <ul>
  57. <li>
  58. <span
  59. // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
  60. dangerouslySetInnerHTML={{
  61. __html: t(
  62. 'admin:customize_settings.custom_title_detail_placeholder1',
  63. ),
  64. }}
  65. />
  66. </li>
  67. <li>
  68. <span
  69. // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
  70. dangerouslySetInnerHTML={{
  71. __html: t(
  72. 'admin:customize_settings.custom_title_detail_placeholder2',
  73. ),
  74. }}
  75. />
  76. </li>
  77. <li>
  78. <span
  79. // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
  80. dangerouslySetInnerHTML={{
  81. __html: t(
  82. 'admin:customize_settings.custom_title_detail_placeholder3',
  83. ),
  84. }}
  85. />
  86. </li>
  87. </ul>
  88. {/* eslint-enable react/no-danger */}
  89. </CardBody>
  90. </Card>
  91. </div>
  92. {/* TODO i18n */}
  93. <div className="form-text text-muted col-12 mb-3">
  94. Default Value:{' '}
  95. <code>
  96. &#123;&#123;pagename&#125;&#125; - &#123;&#123;sitename&#125;&#125;
  97. </code>
  98. <br />
  99. Default Output Example:{' '}
  100. <code className="xml">
  101. &lt;title&gt;Page name - My GROWI&lt;&#047;title&gt;
  102. </code>
  103. </div>
  104. <form onSubmit={handleSubmit(onSubmit)}>
  105. <div className="col-12">
  106. <input className="form-control" {...register('customizeTitle')} />
  107. </div>
  108. <div className="col-12">
  109. <AdminUpdateButtonRow type="submit" disabled={false} />
  110. </div>
  111. </form>
  112. </div>
  113. </React.Fragment>
  114. );
  115. };