frontPanel/src/pages/auth/Signup.tsx

237 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { register } from "@api/auth";
import CloseIcon from "@mui/icons-material/Close";
import {
Box,
Button,
Dialog,
IconButton,
Link,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import { setUserId, useUserStore } from "@root/user";
import InputTextfield from "@ui_kit/InputTextfield";
import PenaLogo2 from "@ui_kit/PenaLogo2";
import PasswordInput from "@ui_kit/passwordInput";
import { useFormik } from "formik";
import { enqueueSnackbar } from "notistack";
import { useEffect, useState } from "react";
import {Link as RouterLink, useLocation, useNavigate} from "react-router-dom";
import { object, ref, string } from "yup";
interface Values {
email: string;
password: string;
repeatPassword: string;
}
const initialValues: Values = {
email: "",
password: "",
repeatPassword: "",
};
const validationSchema = object({
email: string()
.required("Поле обязательно")
.email("Введите корректный email"),
password: string()
.min(8, "Минимум 8 символов")
.matches(/^[.,:;-_+\d\w]+$/, "Некорректные символы")
.required("Поле обязательно"),
repeatPassword: string()
.oneOf([ref("password"), undefined], "Пароли не совпадают")
.required("Повторите пароль"),
});
export default function SignupDialog() {
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(true);
const user = useUserStore((state) => state.user);
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const location = useLocation()
const navigate = useNavigate();
const formik = useFormik<Values>({
initialValues,
validationSchema,
onSubmit: async (values, formikHelpers) => {
const [registerResponse, registerError] = await register(
values.email.trim(),
values.password.trim(),
"+7"
);
formikHelpers.setSubmitting(false);
if (registerError) {
return enqueueSnackbar(registerError);
}
if (registerResponse) {
setUserId(registerResponse._id);
}
},
});
useEffect(
function redirectIfSignedIn() {
if (user) navigate("/list", { replace: true });
},
[navigate, user]
);
function handleClose() {
setIsDialogOpen(false);
setTimeout(() => navigate("/"), theme.transitions.duration.leavingScreen);
}
return (
<Dialog
open={isDialogOpen}
onClose={handleClose}
PaperProps={{
sx: {
width: "600px",
maxWidth: "600px",
},
}}
slotProps={{
backdrop: {
style: {
backgroundColor: "rgb(0 0 0 / 0.7)",
},
},
}}
>
<Box
component="form"
onSubmit={formik.handleSubmit}
noValidate
sx={{
position: "relative",
backgroundColor: "white",
display: "flex",
alignItems: "center",
flexDirection: "column",
p: upMd ? "50px" : "18px",
pb: upMd ? "40px" : "30px",
gap: "15px",
borderRadius: "12px",
boxShadow: "0px 15px 80px rgb(210 208 225 / 70%)",
"& .MuiFormHelperText-root.Mui-error, & .MuiFormHelperText-root.Mui-error.MuiFormHelperText-filled":
{
position: "absolute",
top: "46px",
margin: "0",
},
}}
>
<IconButton
onClick={handleClose}
sx={{
position: "absolute",
right: "7px",
top: "7px",
}}
>
<CloseIcon sx={{ transform: "scale(1.5)" }} />
</IconButton>
<Box sx={{ mt: upMd ? undefined : "62px" }}>
<PenaLogo2 width={upMd ? 233 : 196} color="black" />
</Box>
<Typography
sx={{
color: "#4D4D4D",
mt: "5px",
mb: upMd ? "35px" : "33px",
}}
>
Регистрация
</Typography>
<InputTextfield
TextfieldProps={{
value: formik.values.email,
placeholder: "username",
onBlur: formik.handleBlur,
error: formik.touched.email && Boolean(formik.errors.email),
helperText: formik.touched.email && formik.errors.email,
"data-cy": "username",
}}
onChange={formik.handleChange}
color="#F2F3F7"
id="email"
label="Email"
gap={upMd ? "10px" : "10px"}
/>
<PasswordInput
TextfieldProps={{
value: formik.values.password,
placeholder: "Не менее 8 символов",
onBlur: formik.handleBlur,
error: formik.touched.password && Boolean(formik.errors.password),
helperText: formik.touched.password && formik.errors.password,
autoComplete: "new-password",
"data-cy": "password",
}}
onChange={formik.handleChange}
color="#F2F3F7"
id="password"
label="Пароль"
gap={upMd ? "10px" : "10px"}
/>
<PasswordInput
TextfieldProps={{
value: formik.values.repeatPassword,
placeholder: "Не менее 8 символов",
onBlur: formik.handleBlur,
error:
formik.touched.repeatPassword &&
Boolean(formik.errors.repeatPassword),
helperText:
formik.touched.repeatPassword && formik.errors.repeatPassword,
autoComplete: "new-password",
"data-cy": "repeat-password",
}}
onChange={formik.handleChange}
color="#F2F3F7"
id="repeatPassword"
label="Повторить пароль"
gap={upMd ? "10px" : "10px"}
/>
<Button
variant="contained"
fullWidth
type="submit"
disabled={formik.isSubmitting}
sx={{
py: "12px",
"&:hover": {
backgroundColor: "#581CA7",
},
"&:active": {
color: "white",
backgroundColor: "black",
},
}}
data-cy="signup"
>
Зарегистрироваться
</Button>
<Link
component={RouterLink}
to="/signin"
state={{ backgroundLocation: location.state.backgroundLocation }}
sx={{
color: "#7E2AEA",
mt: "auto",
}}
>
Вход в личный кабинет
</Link>
</Box>
</Dialog>
);
}