InvitedForm.tsx 4.8 KB

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