QuestionnaireSettings.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import {
  2. useState, useCallback, useEffect,
  3. } from 'react';
  4. import { LoadingSpinner } from '@growi/ui/dist/components';
  5. import { useTranslation } from 'next-i18next';
  6. import { apiv3Put } from '~/client/util/apiv3-client';
  7. import { toastSuccess, toastError } from '~/client/util/toastr';
  8. import { useSWRxAppSettings } from '~/stores/admin/app-settings';
  9. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  10. const QuestionnaireSettings = (): JSX.Element => {
  11. const { t } = useTranslation(['admin', 'commons']);
  12. const { data, error, mutate } = useSWRxAppSettings();
  13. const [isQuestionnaireEnabled, setIsQuestionnaireEnabled] = useState(data?.isQuestionnaireEnabled);
  14. const onChangeIsQuestionnaireEnabledHandler = useCallback(() => {
  15. setIsQuestionnaireEnabled(prev => !prev);
  16. }, []);
  17. const [isAppSiteUrlHashed, setIsAppSiteUrlHashed] = useState(data?.isAppSiteUrlHashed);
  18. const onChangeisAppSiteUrlHashedHandler = useCallback(() => {
  19. setIsAppSiteUrlHashed(prev => !prev);
  20. }, []);
  21. const onSubmitHandler = useCallback(async() => {
  22. try {
  23. await apiv3Put('/app-settings/questionnaire-settings', {
  24. isQuestionnaireEnabled,
  25. isAppSiteUrlHashed,
  26. });
  27. toastSuccess(t('commons:toaster.update_successed', { target: t('app_setting.questionnaire_settings') }));
  28. }
  29. catch (err) {
  30. toastError(err);
  31. }
  32. mutate();
  33. }, [isAppSiteUrlHashed, isQuestionnaireEnabled, mutate, t]);
  34. // Sync SWR value and state
  35. useEffect(() => {
  36. setIsQuestionnaireEnabled(data?.isQuestionnaireEnabled);
  37. setIsAppSiteUrlHashed(data?.isAppSiteUrlHashed);
  38. }, [data, data?.isAppSiteUrlHashed, data?.isQuestionnaireEnabled]);
  39. const isLoading = data === undefined && error === undefined;
  40. return (
  41. <div id="questionnaire-settings" className="mb-5">
  42. <p className="card custom-card">
  43. <div className="mb-4">{t('app_setting.questionnaire_settings_explanation')}</div>
  44. <span>
  45. <div className="mb-2">
  46. <span className="text-info me-2"><span className="material-symbols-outlined">info</span>{t('app_setting.about_data_sent')}</span>
  47. <a href={t('app_setting.docs_link')} rel="noreferrer" target="_blank" className="d-inline">
  48. {t('app_setting.learn_more')} <span className="material-symbols-outlined">share</span>
  49. </a>
  50. </div>
  51. {t('app_setting.other_info_will_be_sent')}<br />
  52. {t('app_setting.we_will_use_the_data_to_improve_growi')}
  53. </span>
  54. </p>
  55. {isLoading && (
  56. <div className="text-muted text-center mb-5">
  57. <LoadingSpinner className="me-1 fs-3" />
  58. </div>
  59. )}
  60. {!isLoading && (
  61. <>
  62. <div className="row my-3">
  63. <div className="form-check form-switch form-check-info col-md-5 offset-md-5">
  64. <input
  65. type="checkbox"
  66. className="form-check-input"
  67. id="isQuestionnaireEnabled"
  68. checked={isQuestionnaireEnabled}
  69. onChange={onChangeIsQuestionnaireEnabledHandler}
  70. />
  71. <label className="form-label form-check-label" htmlFor="isQuestionnaireEnabled">
  72. {t('app_setting.enable_questionnaire')}
  73. </label>
  74. </div>
  75. </div>
  76. <div className="row my-4">
  77. <div className="form-check form-check-info col-md-5 offset-md-5">
  78. <input
  79. type="checkbox"
  80. className="form-check-input"
  81. id="isAppSiteUrlHashed"
  82. checked={isAppSiteUrlHashed}
  83. onChange={onChangeisAppSiteUrlHashedHandler}
  84. disabled={!isQuestionnaireEnabled}
  85. />
  86. <label className="form-label form-check-label" htmlFor="isAppSiteUrlHashed">
  87. {t('app_setting.anonymize_app_site_url')}
  88. </label>
  89. <p className="form-text text-muted small">
  90. {t('app_setting.url_anonymization_explanation')}
  91. </p>
  92. </div>
  93. </div>
  94. <AdminUpdateButtonRow onClick={onSubmitHandler} />
  95. </>
  96. )}
  97. </div>
  98. );
  99. };
  100. export default QuestionnaireSettings;