запросы для восстановления пароля(не закончено)

This commit is contained in:
Tamara 2024-01-20 03:37:41 +03:00
parent 8496c5d273
commit 8d1192c8bc
8 changed files with 344 additions and 12 deletions

@ -15,7 +15,7 @@
"dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@frontend/kitui": "1.0.58",
"@frontend/kitui": "1.0.60",
"@mui/icons-material": "^5.10.14",
"@mui/material": "^5.10.14",
"@popperjs/core": "^2.11.8",

@ -10,7 +10,7 @@ import type {
} from "@frontend/kitui";
const apiUrl = process.env.REACT_APP_DOMAIN + "/auth";
console.log("переменная", apiUrl);
export async function register(
login: string,
password: string,
@ -61,8 +61,9 @@ export async function recover(
try {
const formData = new FormData();
formData.append("email", email);
formData.append("RedirectionURL", process.env.REACT_APP_DOMAIN + "/changepwd")
const recoverResponse = await makeRequest<unknown, unknown>({
url: process.env.REACT_APP_DOMAIN + "/recover",
url: process.env.REACT_APP_DOMAIN + "/codeword/recover",
body: formData,
useToken: false,
withCredentials: true,

@ -30,6 +30,8 @@ import PPofData from "@root/docs/PPofData"
import Docs from "@root/docs/docs"
import Oferta from "@root/docs/content/oferta"
import PrivacyPolicy from "@root/docs/content/PrivacyPolicy"
import RecoverPassword from "@root/pages/auth/RecoverPassword"
import OutdatedLink from "@root/pages/auth/OutdatedLink"
pdfjs.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.min.js", import.meta.url).toString()
@ -78,6 +80,9 @@ const App = () => {
<Route path="/signin" element={<SigninDialog />} />
<Route path="/signup" element={<SignupDialog />} />
<Route path="/recover" element={<RecoverDialog />} />
<Route path="/chengepwd" element={<RecoverPassword />} />
<Route path="/changepwd/expired" element={<OutdatedLink />} />
</Routes>
)}
<Routes location={location.state?.backgroundLocation || location}>
@ -85,6 +90,8 @@ const App = () => {
<Route path="/signin" element={<Navigate to="/" replace state={{ redirectTo: "/signin" }} />} />
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />
<Route path="/recover" element={<Navigate to="/" replace state={{ redirectTo: "/recover" }} />} />
<Route path="/chengepwd" element={<Navigate to="/" replace state={{ redirectTo: "/chengepwd" }} />} />
<Route path="/changepwd/expired" element={<Navigate to="/" replace state={{ redirectTo: "/changepwd/expired" }} />} />
<Route element={<PrivateRoute />}>
<Route element={<ProtectedLayout />}>
<Route path="/tariffs" element={<Tariffs />} />

@ -7,7 +7,7 @@ interface Props {
icon: ReactNode;
headerText: string;
discount?: string;
text: string | string[];
text?: any;
sx?: SxProps<Theme>;
buttonProps?: {
sx?: SxProps<Theme>;
@ -78,7 +78,7 @@ export default function TariffCard({ icon, headerText, text, sx, price, buttonPr
</Box>
)}
</Box>
{/* <Tooltip title={<Typography>{headerText}</Typography>} placement="top">
<Tooltip title={<Typography>{headerText}</Typography>} placement="top">
<Typography
variant="h5"
sx={{
@ -92,8 +92,8 @@ export default function TariffCard({ icon, headerText, text, sx, price, buttonPr
>
{headerText}
</Typography>
</Tooltip> */}
{/* <Tooltip
</Tooltip>
<Tooltip
title={text.map((line, index) => (
<Typography key={index}>{line}</Typography>
))}
@ -111,7 +111,7 @@ export default function TariffCard({ icon, headerText, text, sx, price, buttonPr
</Typography>
))}
</Box>
</Tooltip> */}
</Tooltip>
{buttonProps && (
<Button
onClick={buttonProps.onClick}

@ -0,0 +1,138 @@
import {
Box,
Dialog,
IconButton,
Typography,
useMediaQuery,
useTheme,
Button,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
import { useLocation, useNavigate } from "react-router-dom";
import PenaLogo from "@components/PenaLogo";
import { useEffect, useState } from "react";
import { useUserStore } from "@root/stores/user";
import { cardShadow } from "@root/utils/theme";
export default function OutdatedLink() {
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();
useEffect(
function redirectIfSignedIn() {
if (user) navigate("/tariffs", { 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"
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>
<Typography
sx={{
color: theme.palette.gray.dark,
mt: "5px",
mb: upMd ? "10px" : "33px",
}}
>
Срок действия ссылки истёк, пожалуйста повторите попытку восстановления пароля
</Typography>
<Button
variant="pena-contained-dark"
fullWidth
onClick={()=> navigate("/")}
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>
);
}

@ -56,6 +56,8 @@ export default function RecoverDialog() {
if (recoverError) {
return enqueueSnackbar(recoverError);
}
navigate("/")
enqueueSnackbar("Письмо прийдёт Вам на почту")
},
});

@ -0,0 +1,184 @@
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 { Link as RouterLink } from "react-router-dom";
import { object, string } from "yup";
import { useEffect, useState } from "react";
import { useUserStore } from "@root/stores/user";
import { cardShadow } from "@root/utils/theme";
import { recover } from "@root/api/auth";
import axios, {AxiosResponse} from "axios"
import {getAuthToken, 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 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) => {
const params = new URLSearchParams(window.location.search)
const authToken = params.get("auth")
if (authToken) {
try {
const response = await axios<unknown, unknown>({
url: process.env.REACT_APP_DOMAIN + "/user",
method: "PATCH",
headers: {"Authorization": "Bearer " + authToken},
data: {password: values.password},
});
} catch (error) { enqueueSnackbar("Извините, произошла ошибка, попробуйте повторить позже")}
} else {
enqueueSnackbar("Неверный url-адрес")
}
},
});
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>
);
}

@ -1420,10 +1420,10 @@
resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz"
integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
"@frontend/kitui@1.0.58":
version "1.0.58"
resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.58.tgz"
integrity sha1-b/p7hJXG35suzyplPXAIBcBJ6s4=
"@frontend/kitui@1.0.60":
version "1.0.60"
resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.60.tgz#159980acd53fdf47ab3c4328f5a88850f2675a36"
integrity sha1-FZmArNU/30erPEMo9aiIUPJnWjY=
dependencies:
immer "^10.0.2"
reconnecting-eventsource "^1.6.2"