BasicInfoSettings.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import React from 'react';
  2. import { useTranslation, i18n } from 'next-i18next';
  3. import { i18n as i18nConfig } from '^/config/next-i18next.config';
  4. import { toastSuccess, toastError } from '~/client/util/toastr';
  5. import { useRegistrationWhitelist } from '~/stores/context';
  6. import { usePersonalSettings } from '~/stores/personal-settings';
  7. export const BasicInfoSettings = (): JSX.Element => {
  8. const { t } = useTranslation();
  9. const { data: registrationWhitelist } = useRegistrationWhitelist();
  10. const {
  11. data: personalSettingsInfo, mutate: mutatePersonalSettings, sync, updateBasicInfo, error,
  12. } = usePersonalSettings();
  13. const submitHandler = async() => {
  14. try {
  15. await updateBasicInfo();
  16. sync();
  17. toastSuccess(t('toaster.update_successed', { target: t('Basic Info'), ns: 'commons' }));
  18. }
  19. catch (errs) {
  20. const err = errs[0];
  21. const message = err.message;
  22. const code = err.code;
  23. if (code === 'email-is-already-in-use') {
  24. toastError(t('alert.email_is_already_in_use', { ns: 'commons' }));
  25. }
  26. else {
  27. toastError(message);
  28. }
  29. }
  30. };
  31. const changePersonalSettingsHandler = (updateData) => {
  32. if (personalSettingsInfo == null) {
  33. return;
  34. }
  35. mutatePersonalSettings({ ...personalSettingsInfo, ...updateData });
  36. };
  37. return (
  38. <>
  39. <div className="row mt-3 mt-md-4">
  40. <label htmlFor="userForm[name]" className="text-start text-md-end col-md-3 col-form-label">{t('Name')}</label>
  41. <div className="col-md-6">
  42. <input
  43. className="form-control"
  44. type="text"
  45. name="userForm[name]"
  46. defaultValue={personalSettingsInfo?.name || ''}
  47. onChange={e => changePersonalSettingsHandler({ name: e.target.value })}
  48. />
  49. </div>
  50. </div>
  51. <div className="row mt-3">
  52. <label htmlFor="userForm[email]" className="text-start text-md-end col-md-3 col-form-label">{t('Email')}</label>
  53. <div className="col-md-6">
  54. <input
  55. className="form-control"
  56. type="text"
  57. name="userForm[email]"
  58. defaultValue={personalSettingsInfo?.email || ''}
  59. onChange={e => changePersonalSettingsHandler({ email: e.target.value })}
  60. />
  61. {registrationWhitelist != null && registrationWhitelist.length !== 0 && (
  62. <div className="form-text text-muted">
  63. {t('page_register.form_help.email')}
  64. <ul>
  65. {registrationWhitelist.map(data => <li key={data}><code>{data}</code></li>)}
  66. </ul>
  67. </div>
  68. )}
  69. </div>
  70. </div>
  71. <div className="row mt-3">
  72. <label className="text-start text-md-end col-md-3 col-form-label">{t('Disclose E-mail')}</label>
  73. <div className="col-md-6 my-auto">
  74. <div className="form-check form-check-inline me-4">
  75. <input
  76. type="radio"
  77. id="radioEmailShow"
  78. className="form-check-input"
  79. name="userForm[isEmailPublished]"
  80. checked={personalSettingsInfo?.isEmailPublished === true}
  81. onChange={() => changePersonalSettingsHandler({ isEmailPublished: true })}
  82. />
  83. <label className="form-label form-check-label mb-0" htmlFor="radioEmailShow">{t('Show')}</label>
  84. </div>
  85. <div className="form-check form-check-inline">
  86. <input
  87. type="radio"
  88. id="radioEmailHide"
  89. className="form-check-input"
  90. name="userForm[isEmailPublished]"
  91. checked={personalSettingsInfo?.isEmailPublished === false}
  92. onChange={() => changePersonalSettingsHandler({ isEmailPublished: false })}
  93. />
  94. <label className="form-label form-check-label mb-0" htmlFor="radioEmailHide">{t('Hide')}</label>
  95. </div>
  96. </div>
  97. </div>
  98. <div className="row mt-3">
  99. <label className="text-start text-md-end col-md-3 col-form-label">{t('Language')}</label>
  100. <div className="col-md-6 my-auto">
  101. {
  102. i18nConfig.locales.map((locale) => {
  103. if (i18n == null) { return }
  104. const fixedT = i18n.getFixedT(locale);
  105. return (
  106. <div key={locale} className="form-check form-check-inline me-4">
  107. <input
  108. type="radio"
  109. id={`radioLang${locale}`}
  110. className="form-check-input"
  111. name="userForm[lang]"
  112. checked={personalSettingsInfo?.lang === locale}
  113. onChange={() => changePersonalSettingsHandler({ lang: locale })}
  114. />
  115. <label className="form-label form-check-label mb-0" htmlFor={`radioLang${locale}`}>{fixedT('meta.display_name') as string}</label>
  116. </div>
  117. );
  118. })
  119. }
  120. </div>
  121. </div>
  122. <div className="row mt-3">
  123. <label htmlFor="userForm[slackMemberId]" className="text-start text-md-end col-md-3 col-form-label">{t('Slack Member ID')}</label>
  124. <div className="col-md-6">
  125. <input
  126. className="form-control"
  127. type="text"
  128. key="slackMemberId"
  129. name="userForm[slackMemberId]"
  130. defaultValue={personalSettingsInfo?.slackMemberId || ''}
  131. onChange={e => changePersonalSettingsHandler({ slackMemberId: e.target.value })}
  132. />
  133. </div>
  134. </div>
  135. <div className="row mt-4">
  136. <div className="offset-4 col-5">
  137. <button
  138. data-testid="grw-besic-info-settings-update-button"
  139. type="button"
  140. className="btn btn-primary"
  141. onClick={submitHandler}
  142. disabled={error != null}
  143. >
  144. {t('Update')}
  145. </button>
  146. </div>
  147. </div>
  148. </>
  149. );
  150. };