SignUp.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { useIntl } from "react-intl";
  2. import {
  3. ProForm,
  4. ProFormDependency,
  5. ProFormInstance,
  6. ProFormText,
  7. } from "@ant-design/pro-components";
  8. import { Button, message, Modal, Result } from "antd";
  9. import { useNavigate } from "react-router-dom";
  10. import { EyeInvisibleOutlined, EyeTwoTone } from "@ant-design/icons";
  11. import { get, post } from "../../../request";
  12. import { IInviteResponse } from "../../../pages/studio/invite/list";
  13. import LangSelect from "../../general/LangSelect";
  14. import { useRef, useState } from "react";
  15. interface IFormData {
  16. email: string;
  17. username: string;
  18. nickname: string;
  19. password: string;
  20. password2: string;
  21. lang: string;
  22. }
  23. interface ISignInResponse {
  24. ok: boolean;
  25. message: string;
  26. data: string;
  27. }
  28. interface ISignUpRequest {
  29. token: string;
  30. username: string;
  31. nickname: string;
  32. email: string;
  33. password: string;
  34. lang: string;
  35. }
  36. interface IWidget {
  37. token?: string;
  38. }
  39. const SignUpWidget = ({ token }: IWidget) => {
  40. const intl = useIntl();
  41. const navigate = useNavigate();
  42. const [success, setSuccess] = useState(false);
  43. const [nickname, setNickname] = useState<string>();
  44. const formRef = useRef<ProFormInstance>();
  45. return success ? (
  46. <Result
  47. status="success"
  48. title="注册成功"
  49. subTitle={
  50. <Button
  51. type="primary"
  52. onClick={() => navigate("/anonymous/users/sign-in")}
  53. >
  54. 登录
  55. </Button>
  56. }
  57. />
  58. ) : (
  59. <ProForm<IFormData>
  60. formRef={formRef}
  61. onFinish={async (values: IFormData) => {
  62. if (typeof token === "undefined") {
  63. return;
  64. }
  65. if (values.password !== values.password2) {
  66. Modal.error({ title: "两次密码不同" });
  67. return;
  68. }
  69. const user = {
  70. token: token,
  71. username: values.username,
  72. nickname: values.nickname ? values.nickname : values.username,
  73. email: values.email,
  74. password: values.password,
  75. lang: values.lang,
  76. };
  77. const signUp = await post<ISignUpRequest, ISignInResponse>(
  78. "/v2/sign-up",
  79. user
  80. );
  81. if (signUp.ok) {
  82. setSuccess(true);
  83. } else {
  84. message.error(signUp.message);
  85. }
  86. }}
  87. request={async () => {
  88. const res = await get<IInviteResponse>(`/v2/invite/${token}`);
  89. console.log(res.data);
  90. return {
  91. id: res.data.id,
  92. username: "",
  93. nickname: "",
  94. password: "",
  95. password2: "",
  96. email: res.data.email,
  97. lang: "zh-Hans",
  98. };
  99. }}
  100. >
  101. <ProForm.Group>
  102. <ProFormText
  103. width="md"
  104. name="email"
  105. required
  106. label={intl.formatMessage({
  107. id: "forms.fields.email.label",
  108. })}
  109. rules={[{ required: true, max: 255, min: 4 }]}
  110. disabled
  111. />
  112. </ProForm.Group>
  113. <ProForm.Group>
  114. <ProFormText
  115. width="md"
  116. name="username"
  117. required
  118. fieldProps={{
  119. onChange: (event) => {
  120. setNickname(event.target.value);
  121. },
  122. }}
  123. label={intl.formatMessage({
  124. id: "forms.fields.username.label",
  125. })}
  126. rules={[
  127. { required: true, max: 32, min: 6 },
  128. {
  129. pattern: new RegExp("^[0-9a-zA-Z_]{1,}", "g"),
  130. message: "只允许数字,字母,下划线",
  131. },
  132. ]}
  133. />
  134. </ProForm.Group>
  135. <ProForm.Group>
  136. <ProFormText.Password
  137. width="md"
  138. name="password"
  139. fieldProps={{
  140. type: "password",
  141. iconRender: (visible) =>
  142. visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />,
  143. }}
  144. required
  145. label={intl.formatMessage({
  146. id: "forms.fields.password.label",
  147. })}
  148. rules={[{ required: true, max: 32, min: 6 }]}
  149. />
  150. </ProForm.Group>
  151. <ProForm.Group>
  152. <ProFormText.Password
  153. width="md"
  154. name="password2"
  155. fieldProps={{
  156. type: "password",
  157. iconRender: (visible) =>
  158. visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />,
  159. }}
  160. required
  161. label={intl.formatMessage({
  162. id: "forms.fields.confirm-password.label",
  163. })}
  164. rules={[{ required: true, max: 32, min: 6 }]}
  165. />
  166. </ProForm.Group>
  167. <ProForm.Group>
  168. <ProFormDependency name={["username"]}>
  169. {({ username }) => {
  170. return (
  171. <ProFormText
  172. width="md"
  173. fieldProps={{
  174. placeholder: username,
  175. value: nickname ? nickname : username,
  176. onChange: (event) => {
  177. setNickname(event.target.value);
  178. },
  179. }}
  180. name="nickname"
  181. required
  182. label={intl.formatMessage({
  183. id: "forms.fields.nickname.label",
  184. })}
  185. rules={[{ required: false, max: 32, min: 4 }]}
  186. />
  187. );
  188. }}
  189. </ProFormDependency>
  190. </ProForm.Group>
  191. <ProForm.Group>
  192. <LangSelect label="常用的译文语言" />
  193. </ProForm.Group>
  194. </ProForm>
  195. );
  196. };
  197. export default SignUpWidget;