199 lines
5.3 KiB
TypeScript
199 lines
5.3 KiB
TypeScript
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>
|
||
);
|
||
}
|