InvitedForm.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import React, { useCallback, useState } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import { useRouter } from 'next/router';
  4. import { apiv3Post } from '~/client/util/apiv3-client';
  5. import { useCurrentUser } from '../stores/context';
  6. export type InvitedFormProps = {
  7. invitedFormUsername: string,
  8. invitedFormName: string,
  9. }
  10. export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
  11. const { t } = useTranslation();
  12. const router = useRouter();
  13. const { data: user } = useCurrentUser();
  14. const [isConnectSuccess, setIsConnectSuccess] = useState<boolean>(false);
  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. setIsConnectSuccess(true);
  35. const { redirectTo } = res.data;
  36. router.push(redirectTo ?? '/');
  37. }
  38. catch (err) {
  39. setLoginErrors(err);
  40. setIsLoading(false);
  41. }
  42. }, [router]);
  43. const formNotification = useCallback(() => {
  44. if (isConnectSuccess) {
  45. return (
  46. <p className="alert alert-success">
  47. <strong>{ t('message.successfully_connected') }</strong><br></br>
  48. </p>
  49. );
  50. }
  51. return (
  52. <>
  53. { loginErrors != null && loginErrors.length > 0 ? (
  54. <p className="alert alert-danger">
  55. { loginErrors.map((err, index) => {
  56. return <span key={index}>{ t(err.message) }<br/></span>;
  57. }) }
  58. </p>
  59. ) : (
  60. <p className="alert alert-success">
  61. <strong>{ t('invited.discription_heading') }</strong><br></br>
  62. <small>{ t('invited.discription') }</small>
  63. </p>
  64. ) }
  65. </>
  66. );
  67. }, [isConnectSuccess, loginErrors, t]);
  68. if (user == null) {
  69. return <></>;
  70. }
  71. return (
  72. <div className="nologin-dialog px-3 pb-3 mx-auto" id="nologin-dialog">
  73. { formNotification() }
  74. <form role="form" onSubmit={submitHandler} id="invited-form">
  75. {/* Email Form */}
  76. <div className="input-group">
  77. <div className="input-group-prepend">
  78. <span className="input-group-text">
  79. <i className="icon-envelope"></i>
  80. </span>
  81. </div>
  82. <input
  83. type="text"
  84. className="form-control"
  85. disabled
  86. placeholder={t('Email')}
  87. name="invitedForm[email]"
  88. defaultValue={user.email}
  89. required
  90. />
  91. </div>
  92. {/* UserID Form */}
  93. <div className="input-group" id="input-group-username">
  94. <div className="input-group-prepend">
  95. <span className="input-group-text">
  96. <i className="icon-user"></i>
  97. </span>
  98. </div>
  99. <input
  100. type="text"
  101. className="form-control"
  102. placeholder={t('User ID')}
  103. name="invitedForm[username]"
  104. value={invitedFormUsername}
  105. required
  106. />
  107. </div>
  108. {/* Name Form */}
  109. <div className="input-group">
  110. <div className="input-group-prepend">
  111. <span className="input-group-text">
  112. <i className="icon-tag"></i>
  113. </span>
  114. </div>
  115. <input
  116. type="text"
  117. className="form-control"
  118. placeholder={t('Name')}
  119. name="invitedForm[name]"
  120. value={invitedFormName}
  121. required
  122. />
  123. </div>
  124. {/* Password Form */}
  125. <div className="input-group">
  126. <div className="input-group-prepend">
  127. <span className="input-group-text">
  128. <i className="icon-lock"></i>
  129. </span>
  130. </div>
  131. <input
  132. type="password"
  133. className="form-control"
  134. placeholder={t('Password')}
  135. name="invitedForm[password]"
  136. required
  137. minLength={6}
  138. />
  139. </div>
  140. {/* Create Button */}
  141. <div className="input-group justify-content-center d-flex mt-4">
  142. <button type="submit" className="btn btn-fill" id="register" disabled={isLoading}>
  143. <div className="eff"></div>
  144. <span className="btn-label"><i className={isLoading ? 'fa fa-spinner fa-pulse mr-1' : 'icon-user-follow'} /></span>
  145. <span className="btn-label-text">{t('Create')}</span>
  146. </button>
  147. </div>
  148. </form>
  149. <div className="input-group mt-4 d-flex justify-content-center">
  150. <a href="https://growi.org" className="link-growi-org">
  151. <span className="growi">GROWI</span>.<span className="org">ORG</span>
  152. </a>
  153. </div>
  154. </div>
  155. );
  156. };