front-hub/src/pages/auth/RecoverPassword.tsx
2024-05-27 18:43:38 +03:00

199 lines
5.3 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 {
Box,
Dialog,
IconButton,
Link,
Typography,
useMediaQuery,
useTheme,
Button,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
import { useLocation, useNavigate } from "react-router-dom";
import { useFormik } from "formik";
import InputTextfield from "@components/InputTextfield";
import PenaLogo from "@components/PenaLogo";
import { enqueueSnackbar } from "notistack";
import { object, string } from "yup";
import { useEffect, useState } from "react";
import { useUserStore } from "@root/stores/user";
import { cardShadow } from "@root/utils/theme";
import { patchUser } from "@api/user";
import { setAuthToken } from "@frontend/kitui";
interface Values {
password: string;
}
const initialValues: Values = {
password: "",
};
const validationSchema = object({
password: string()
.min(8, "Минимум 8 символов")
.matches(
/^[.,:;\-_+!&()*<>\[\]\{\}`@"#$\%\^\=?\d\w]+$/,
"Некорректные символы"
)
.required("Поле обязательно"),
});
export default function RecoverPassword() {
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(true);
const [tokenUser, setTokenUser] = useState<string | null>("");
const user = useUserStore((state) => state.user);
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const navigate = useNavigate();
const location = useLocation();
const formik = useFormik<Values>({
initialValues,
validationSchema,
onSubmit: async (values, formikHelpers) => {
if (tokenUser) {
setAuthToken(tokenUser || "");
const [, patchUserError] = await patchUser({
password: values.password,
});
if (!patchUserError) {
setIsDialogOpen(false);
navigate("/");
enqueueSnackbar("Пароль успешно сменён");
} else {
setAuthToken("");
enqueueSnackbar(
"Извините, произошла ошибка, попробуйте повторить позже"
);
}
} else {
enqueueSnackbar("Неверный url-адрес");
}
},
});
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const authToken = params.get("auth");
setTokenUser(authToken);
history.pushState(null, document.title, "/changepwd");
return () => {
setAuthToken("");
};
}, []);
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: cardShadow,
"& .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>
<PenaLogo width={upMd ? 233 : 196} color="black" />
</Box>
<Typography
sx={{
color: theme.palette.gray.dark,
mt: "5px",
mb: upMd ? "10px" : "33px",
}}
>
Введите новый пароль
</Typography>
<InputTextfield
TextfieldProps={{
value: formik.values.password,
placeholder: "введите пароль",
onBlur: formik.handleBlur,
error: formik.touched.password && Boolean(formik.errors.password),
helperText: formik.touched.password && formik.errors.password,
}}
onChange={formik.handleChange}
color="#F2F3F7"
id="password"
label="Новый пароль"
gap={upMd ? "10px" : "10px"}
/>
<Button
variant="pena-contained-dark"
fullWidth
type="submit"
disabled={formik.isSubmitting}
sx={{
py: "12px",
"&:hover": {
backgroundColor: theme.palette.purple.dark,
},
"&:active": {
color: "white",
backgroundColor: "black",
},
}}
>
Восстановить
</Button>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "10px",
mt: "auto",
}}
></Box>
</Box>
</Dialog>
);
}