RegisterForm.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { useState, useEffect, useContext } from "react";
  2. import { connect } from "react-redux";
  3. // import { actionRegister } from 'actions';
  4. import { MdVisibility, MdVisibilityOff } from "react-icons/md";
  5. import { Box, Button, IconButton, TextField, Typography } from "@mui/material";
  6. import { useFormik } from "formik";
  7. import * as Yup from "yup";
  8. import { actionRegister } from "../../../actions/actionRegister";
  9. import { UIContext } from "../../UIContext";
  10. const signUpSchema = Yup.object().shape({
  11. username: Yup.string().min(3, "Too Short!").max(15, "Too Long!").required("Required"),
  12. password: Yup.string().min(3, "Too Short!").max(15, "Too Long!").required("Required"),
  13. repeatPassword: Yup.string()
  14. .min(3, "Too Short!")
  15. .max(15, "Too Long!")
  16. .required("Required")
  17. .oneOf([Yup.ref("password")], "Your passwords do not match."),
  18. });
  19. export const RegisterForm = ({ serverErrors, promiseStatus, onRegister, onLoginButtonClick }) => {
  20. const [showPassword, setShowPassword] = useState(false);
  21. const { setAlert } = useContext(UIContext);
  22. const [promiseTimeOut, setPromiseTimeOut] = useState(null);
  23. const formik = useFormik({
  24. initialValues: {
  25. username: "",
  26. password: "",
  27. repeatPassword: "",
  28. },
  29. validationSchema: signUpSchema,
  30. validateOnChange: true,
  31. onSubmit: () => {
  32. onRegister(formik.values.username, formik.values.password);
  33. setPromiseTimeOut(setTimeout(() => formik.setSubmitting(false), 3000));
  34. },
  35. });
  36. useEffect(() => {
  37. return () => {
  38. promiseTimeOut && clearTimeout(promiseTimeOut);
  39. setPromiseTimeOut(null);
  40. };
  41. }, []);
  42. useEffect(() => {
  43. if (promiseStatus === "FULFILLED") {
  44. formik.setSubmitting(false);
  45. promiseTimeOut && clearTimeout(promiseTimeOut);
  46. setPromiseTimeOut(null);
  47. setAlert({
  48. show: true,
  49. severity: "success",
  50. message: "Готово",
  51. });
  52. }
  53. if (promiseStatus === "REJECTED") {
  54. const errorMessage = (serverErrors ? [].concat(serverErrors) : []).reduce((prev, curr) => prev + "\n" + curr.message, "");
  55. formik.setSubmitting(false);
  56. promiseTimeOut && clearTimeout(promiseTimeOut);
  57. setPromiseTimeOut(null);
  58. setAlert({
  59. show: true,
  60. severity: "error",
  61. message: errorMessage,
  62. });
  63. }
  64. }, [promiseStatus]);
  65. return (
  66. <Box
  67. className="RegisterForm"
  68. display="flex"
  69. flexDirection="column"
  70. alignItems="center"
  71. component="form"
  72. onSubmit={formik.handleSubmit}
  73. >
  74. <TextField
  75. id="username"
  76. name="username"
  77. variant="standard"
  78. label="Username"
  79. error={formik.touched.username && Boolean(formik.errors.username)}
  80. value={formik.values.username}
  81. onBlur={formik.handleBlur}
  82. onChange={formik.handleChange}
  83. helperText={formik.touched.username && formik.errors.username}
  84. fullWidth
  85. sx={{ mt: 2 }}
  86. />
  87. <TextField
  88. id="password"
  89. name="password"
  90. variant="standard"
  91. label="Password"
  92. type={showPassword ? "text" : "password"}
  93. error={formik.touched.password && Boolean(formik.errors.password)}
  94. value={formik.values.password}
  95. onBlur={formik.handleBlur}
  96. onChange={formik.handleChange}
  97. helperText={formik.touched.password && formik.errors.password}
  98. InputProps={{
  99. endAdornment: (
  100. <IconButton onClick={() => setShowPassword((prev) => !prev)} edge="end">
  101. {showPassword ? <MdVisibilityOff /> : <MdVisibility />}
  102. </IconButton>
  103. ),
  104. }}
  105. fullWidth
  106. sx={{ mt: 2 }}
  107. />
  108. <TextField
  109. id="repeatPassword"
  110. name="repeatPassword"
  111. variant="standard"
  112. label="Repeat password"
  113. type={showPassword ? "text" : "password"}
  114. error={formik.touched.repeatPassword && Boolean(formik.errors.repeatPassword)}
  115. value={formik.values.repeatPassword}
  116. onBlur={formik.handleBlur}
  117. onChange={formik.handleChange}
  118. helperText={formik.touched.repeatPassword && formik.errors.repeatPassword}
  119. InputProps={{
  120. endAdornment: (
  121. <IconButton onClick={() => setShowPassword((prev) => !prev)} edge="end">
  122. {showPassword ? <MdVisibilityOff /> : <MdVisibility />}
  123. </IconButton>
  124. ),
  125. }}
  126. fullWidth
  127. sx={{ mt: 2 }}
  128. />
  129. <Button
  130. variant="contained"
  131. color="primary"
  132. type="submit"
  133. disabled={formik.isSubmitting || !formik.isValid}
  134. fullWidth
  135. sx={{ mt: 2 }}
  136. >
  137. Зареєструватися
  138. </Button>
  139. <Button variant="text" onClick={onLoginButtonClick}>
  140. <Typography>Увійти</Typography>
  141. </Button>
  142. </Box>
  143. );
  144. };
  145. export const CRegisterForm = connect(
  146. (state) => ({ promiseStatus: state.promise?.register?.status || null, serverErrors: state.promise?.register?.error || [] }),
  147. {
  148. onRegister: (login, password) => actionRegister(login, password),
  149. }
  150. )(RegisterForm);