frontPanel/src/pages/auth/Signin.tsx

214 lines
6.1 KiB
TypeScript
Raw Normal View History

2023-11-08 12:51:40 +00:00
import { login } from "@api/auth";
import CloseIcon from "@mui/icons-material/Close";
2023-12-16 13:02:27 +00:00
import { Box, Button, Dialog, IconButton, Link, Typography, useMediaQuery, useTheme } from "@mui/material";
2023-11-08 12:51:40 +00:00
import { setUserId, useUserStore } from "@root/user";
import InputTextfield from "@ui_kit/InputTextfield";
2023-12-16 13:02:27 +00:00
import Logotip from "../../pages/Landing/images/icons/QuizLogo";
2023-11-08 12:51:40 +00:00
import PasswordInput from "@ui_kit/passwordInput";
import { useFormik } from "formik";
import { enqueueSnackbar } from "notistack";
import { useEffect, useState } from "react";
import { Link as RouterLink, useNavigate, useLocation } from "react-router-dom";
2023-11-08 12:51:40 +00:00
import { object, string } from "yup";
interface Values {
email: string;
password: string;
}
const initialValues: Values = {
email: "",
password: "",
};
const validationSchema = object({
2023-12-16 13:02:27 +00:00
email: string().required("Поле обязательно").email("Введите корректный email"),
2023-11-08 12:51:40 +00:00
password: string().required("Поле обязательно").min(8, "Минимум 8 символов"),
});
export default function SigninDialog() {
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(true);
const user = useUserStore((state) => state.user);
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const navigate = useNavigate();
const location = useLocation();
2023-11-08 12:51:40 +00:00
const formik = useFormik<Values>({
initialValues,
validationSchema,
onSubmit: async (values, formikHelpers) => {
2023-12-16 13:02:27 +00:00
const [loginResponse, loginError] = await login(values.email.trim(), values.password.trim());
2023-11-08 12:51:40 +00:00
formikHelpers.setSubmitting(false);
if (loginError) {
return enqueueSnackbar(loginError);
}
if (loginResponse) {
setUserId(loginResponse._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%)",
2023-12-16 13:02:27 +00:00
"& .MuiFormHelperText-root.Mui-error, & .MuiFormHelperText-root.Mui-error.MuiFormHelperText-filled": {
position: "absolute",
top: "46px",
margin: "0",
},
2023-11-08 12:51:40 +00:00
}}
>
<IconButton
onClick={handleClose}
sx={{
position: "absolute",
right: "7px",
top: "7px",
}}
>
<CloseIcon sx={{ transform: "scale(1.5)" }} />
</IconButton>
<Box>
2023-12-16 13:02:27 +00:00
<Logotip width={upMd ? 233 : 196} />
2023-11-08 12:51:40 +00:00
</Box>
<Typography
sx={{
color: "#4D4D4D",
mt: "5px",
mb: upMd ? "10px" : "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,
2023-11-27 23:07:24 +00:00
"data-cy": "username",
2023-11-08 12:51:40 +00:00
}}
onChange={formik.handleChange}
color="#F2F3F7"
id="email"
label="Email"
gap={upMd ? "10px" : "10px"}
/>
2023-11-08 12:51:40 +00:00
<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,
type: "password",
2023-11-27 23:07:24 +00:00
"data-cy": "password",
2023-11-08 12:51:40 +00:00
}}
onChange={formik.handleChange}
color="#F2F3F7"
id="password"
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",
},
}}
2023-11-27 23:07:24 +00:00
data-cy="signin"
2023-11-08 12:51:40 +00:00
>
Войти
</Button>
{/* <Link
component={RouterLink}
to="/"
href="#"
sx={{
color: "#4D4D4D",
mb: "15px",
}}
>
Забыли пароль?
</Link> */}
2023-11-08 12:51:40 +00:00
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "10px",
mt: "auto",
}}
>
2023-12-16 13:02:27 +00:00
<Typography sx={{ color: "#7E2AEA", textAlign: "center" }}>Вы еще не присоединились?</Typography>
<Box sx={{ display: "flex", alignItems: "center", gap: "4px" }}>
<Link component={RouterLink} to="/signup" sx={{ color: "#7E2AEA" }}>
Регистрация
</Link>
<Link component={RouterLink} to="/restore" sx={{ color: "#7E2AEA" }}>
Забыли пароль
</Link>
</Box>
2023-11-08 12:51:40 +00:00
</Box>
</Box>
</Dialog>
);
}