CustomizeScriptSetting.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import React, { useCallback, useEffect, type JSX } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import { useForm } from 'react-hook-form';
  4. import { PrismAsyncLight } from 'react-syntax-highlighter';
  5. import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
  6. import { Card, CardBody } from 'reactstrap';
  7. import AdminCustomizeContainer from '~/client/services/AdminCustomizeContainer';
  8. import { toastSuccess, toastError } from '~/client/util/toastr';
  9. import { withUnstatedContainers } from '../../UnstatedUtils';
  10. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  11. type Props = {
  12. adminCustomizeContainer: AdminCustomizeContainer
  13. }
  14. const CustomizeScriptSetting = (props: Props): JSX.Element => {
  15. const { adminCustomizeContainer } = props;
  16. const { t } = useTranslation();
  17. const {
  18. register,
  19. handleSubmit,
  20. reset,
  21. } = useForm();
  22. // Sync form with container state
  23. useEffect(() => {
  24. reset({
  25. customizeScript: adminCustomizeContainer.state.currentCustomizeScript || '',
  26. });
  27. }, [adminCustomizeContainer.state.currentCustomizeScript, reset]);
  28. const onSubmit = useCallback(async(data) => {
  29. try {
  30. // Update container state before API call
  31. await adminCustomizeContainer.changeCustomizeScript(data.customizeScript);
  32. await adminCustomizeContainer.updateCustomizeScript();
  33. toastSuccess(t('toaster.update_successed', { target: t('admin:customize_settings.custom_script'), ns: 'commons' }));
  34. }
  35. catch (err) {
  36. toastError(err);
  37. }
  38. }, [t, adminCustomizeContainer]);
  39. return (
  40. <React.Fragment>
  41. <div className="row">
  42. <div className="col-12">
  43. <h2 className="admin-setting-header">{t('admin:customize_settings.custom_script')}</h2>
  44. <Card className="card custom-card bg-body-tertiary mb-3">
  45. <CardBody className="px-0 py-2">
  46. {t('admin:customize_settings.write_java')}<br />
  47. {t('admin:customize_settings.reflect_change')}
  48. </CardBody>
  49. </Card>
  50. <form onSubmit={handleSubmit(onSubmit)}>
  51. <div>
  52. <textarea
  53. className="form-control mb-2"
  54. rows={8}
  55. {...register('customizeScript')}
  56. />
  57. </div>
  58. <a
  59. className="text-muted"
  60. data-bs-toggle="collapse"
  61. href="#collapseExampleScript"
  62. role="button"
  63. aria-expanded="false"
  64. aria-controls="collapseExampleScript"
  65. >
  66. <span className="material-symbols-outlined me-1" aria-hidden="true">navigate_next</span>
  67. Example for Google Tag Manager
  68. </a>
  69. <div className="collapse" id="collapseExampleScript">
  70. <PrismAsyncLight
  71. style={oneDark}
  72. language="javascript"
  73. >
  74. {`(function(w,d,s,l,i){
  75. w[l]=w[l]||[];
  76. w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});
  77. var f=d.getElementsByTagName(s)[0],
  78. j=d.createElement(s),
  79. dl=l!='dataLayer'?'&l='+l:'';
  80. j.async=true;
  81. j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
  82. })(window,document,'script','dataLayer','GTM-XXXXXX');`}
  83. </PrismAsyncLight>
  84. </div>
  85. <AdminUpdateButtonRow type="submit" disabled={adminCustomizeContainer.state.retrieveError != null} />
  86. </form>
  87. </div>
  88. </div>
  89. </React.Fragment>
  90. );
  91. };
  92. const CustomizeScriptSettingWrapper = withUnstatedContainers(CustomizeScriptSetting, [AdminCustomizeContainer]);
  93. export default CustomizeScriptSettingWrapper;