InvitedForm.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import React, { useCallback, useState } from 'react';
  2. import { LoadingSpinner } from '@growi/ui/dist/components';
  3. import { useTranslation } from 'next-i18next';
  4. import { useRouter } from 'next/router';
  5. import { apiv3Post } from '~/client/util/apiv3-client';
  6. import { useCurrentUser } from '../stores/context';
  7. export type InvitedFormProps = {
  8. invitedFormUsername: string,
  9. invitedFormName: string,
  10. }
  11. export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
  12. const { t } = useTranslation();
  13. const router = useRouter();
  14. const { data: user } = useCurrentUser();
  15. const [loginErrors, setLoginErrors] = useState<Error[]>([]);
  16. const [isLoading, setIsLoading] = useState(false);
  17. const { invitedFormUsername, invitedFormName } = props;
  18. const submitHandler = useCallback(async(e) => {
  19. e.preventDefault();
  20. setIsLoading(true);
  21. const formData = e.target.elements;
  22. const {
  23. 'invitedForm[name]': { value: name },
  24. 'invitedForm[password]': { value: password },
  25. 'invitedForm[username]': { value: username },
  26. } = formData;
  27. const invitedForm = {
  28. name,
  29. password,
  30. username,
  31. };
  32. try {
  33. const res = await apiv3Post('/invited', { invitedForm });
  34. const { redirectTo } = res.data;
  35. router.push(redirectTo ?? '/');
  36. }
  37. catch (err) {
  38. setLoginErrors(err);
  39. setIsLoading(false);
  40. }
  41. }, [router]);
  42. const formNotification = useCallback(() => {
  43. return (
  44. <>
  45. { loginErrors != null && loginErrors.length > 0 ? (
  46. <p className="alert alert-danger">
  47. { loginErrors.map((err) => {
  48. return <span>{ t(err.message) }<br /></span>;
  49. }) }
  50. </p>
  51. ) : (
  52. <p className="alert alert-success">
  53. <strong>{ t('invited.discription_heading') }</strong><br></br>
  54. <small>{ t('invited.discription') }</small>
  55. </p>
  56. ) }
  57. </>
  58. );
  59. }, [loginErrors, t]);
  60. if (user == null) {
  61. return <></>;
  62. }
  63. return (
  64. <div className="nologin-dialog px-3 pb-3 mx-auto" id="nologin-dialog">
  65. { formNotification() }
  66. <form role="form" onSubmit={submitHandler} id="invited-form">
  67. {/* Email Form */}
  68. <div className="input-group">
  69. <span className="input-group-text">
  70. <span className="material-symbols-outlined">mail</span>
  71. </span>
  72. <input
  73. type="text"
  74. className="form-control"
  75. disabled
  76. placeholder={t('Email')}
  77. name="invitedForm[email]"
  78. defaultValue={user.email}
  79. required
  80. />
  81. </div>
  82. {/* UserID Form */}
  83. <div className="input-group" id="input-group-username">
  84. <span className="input-group-text">
  85. <span className="material-symbols-outlined">person</span>
  86. </span>
  87. <input
  88. type="text"
  89. className="form-control"
  90. placeholder={t('User ID')}
  91. name="invitedForm[username]"
  92. value={invitedFormUsername}
  93. required
  94. />
  95. </div>
  96. {/* Name Form */}
  97. <div className="input-group">
  98. <span className="input-group-text">
  99. <span className="material-symbols-outlined">sell</span>
  100. </span>
  101. <input
  102. type="text"
  103. className="form-control"
  104. placeholder={t('Name')}
  105. name="invitedForm[name]"
  106. value={invitedFormName}
  107. required
  108. />
  109. </div>
  110. {/* Password Form */}
  111. <div className="input-group">
  112. <span className="input-group-text">
  113. <span className="material-symbols-outlined">lock</span>
  114. </span>
  115. <input
  116. type="password"
  117. className="form-control"
  118. placeholder={t('Password')}
  119. name="invitedForm[password]"
  120. required
  121. minLength={6}
  122. />
  123. </div>
  124. {/* Create Button */}
  125. <div className="input-group justify-content-center d-flex mt-4">
  126. <button type="submit" className="btn btn-fill" id="register" disabled={isLoading}>
  127. <span className="btn-label">
  128. {isLoading ? (
  129. <LoadingSpinner />
  130. ) : (
  131. <span className="material-symbols-outlined">person_add</span>
  132. )}
  133. </span>
  134. <span className="btn-label-text">{t('Create')}</span>
  135. </button>
  136. </div>
  137. </form>
  138. <div className="input-group mt-4 d-flex justify-content-center">
  139. <a href="https://growi.org" className="link-growi-org">
  140. <span className="growi">GROWI</span><span className="org">.ORG</span>
  141. </a>
  142. </div>
  143. </div>
  144. );
  145. };