upd
This commit is contained in:
@@ -18,6 +18,7 @@ import IError from "../types/IError";
|
||||
import Schedule from "../components/Schedule";
|
||||
import IScheduledSession from "../types/IScheduledSession";
|
||||
import toast, { Toaster } from "react-hot-toast";
|
||||
import Calendar from "../components/Calendar";
|
||||
|
||||
function DashboardPage() {
|
||||
const { user } = useAuthStore();
|
||||
@@ -228,7 +229,7 @@ function DashboardPage() {
|
||||
</button>
|
||||
</div>
|
||||
<div className="overflow-x-hidden overflow-y-auto">
|
||||
{/* <Calendar /> */}
|
||||
<Calendar />
|
||||
{/* <Schedules /> */}
|
||||
<Managers />
|
||||
</div>
|
||||
|
||||
@@ -70,11 +70,6 @@ function LoginPage() {
|
||||
handleChange={(value) => setPassword(value)}
|
||||
/>
|
||||
</div>
|
||||
{/* <ReCAPTCHA
|
||||
ref={recaptchaRef}
|
||||
sitekey="6LdKPH4oAAAAAM8cyMoCkmNvbnBbe2UIrwRwQ425"
|
||||
className="mt-3"
|
||||
/> */}
|
||||
<Button
|
||||
type="submit"
|
||||
size="medium"
|
||||
@@ -89,6 +84,9 @@ function LoginPage() {
|
||||
<Link to="/registration" className="text-xs text-[#49A1F5]">
|
||||
Нет аккаунта?
|
||||
</Link>
|
||||
<Link to="/reset" className="text-xs text-[#49A1F5]">
|
||||
Забыли пароль?
|
||||
</Link>
|
||||
{/* <Link to="" className="text-xs text-[#49A1F5]">
|
||||
Забыли пароль?
|
||||
</Link> */}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useEffect, useState } from "react";
|
||||
import Form from "../components/Form";
|
||||
import Label from "../components/Label";
|
||||
import Input from "../components/Input";
|
||||
import Button from "../components/Button";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import toast, { Toaster } from "react-hot-toast";
|
||||
import IError from "../types/IError";
|
||||
import api from "../utils/api";
|
||||
|
||||
function ResetPasswordConfirmPage() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const [password, setPassword] = useState<string>("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
async function resetPasswordConfirm() {
|
||||
try {
|
||||
const result: any | IError = await api
|
||||
.post("resetConfirm", {
|
||||
credentials: "include",
|
||||
json: { resetCode: searchParams.get("code"), password },
|
||||
})
|
||||
.json();
|
||||
|
||||
if ("error" in result) {
|
||||
toast.error(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success("Пароль успешно изменен");
|
||||
|
||||
setTimeout(() => {
|
||||
navigate("/login");
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
toast.error((error as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmitResetPassword() {
|
||||
setLoading(true);
|
||||
await resetPasswordConfirm();
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log("searchParams [code]:", searchParams.get("code"));
|
||||
}, [searchParams]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center flex-1 min-h-screen p-8">
|
||||
<div className="overflow-hidden bg-white rounded-lg shadow-md max-w-[528px]">
|
||||
<div className="flex flex-col gap-6 p-12">
|
||||
<p className="text-2xl font-semibold">Изменение пароля</p>
|
||||
<Form handleSubmit={handleSubmitResetPassword} className="space-y-12">
|
||||
<div className="space-y-6">
|
||||
<p className="text-[#77828C] text-sm">Введите новый пароль</p>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Label value="Новый пароль" />
|
||||
<Input
|
||||
type="password"
|
||||
placeholder=""
|
||||
autoFocus
|
||||
required
|
||||
value={password}
|
||||
handleChange={(value) => setPassword(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-6">
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="medium"
|
||||
widthFull
|
||||
onClick={() => navigate("/login")}
|
||||
>
|
||||
На главную
|
||||
</Button>
|
||||
<Button type="submit" size="medium" loading={loading} widthFull>
|
||||
Продолжить
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toaster />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ResetPasswordConfirmPage;
|
||||
@@ -0,0 +1,118 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useState } from "react";
|
||||
import Form from "../components/Form";
|
||||
import Label from "../components/Label";
|
||||
import Input from "../components/Input";
|
||||
import Button from "../components/Button";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import toast, { Toaster } from "react-hot-toast";
|
||||
import IError from "../types/IError";
|
||||
import api from "../utils/api";
|
||||
|
||||
function ResetPasswordPage() {
|
||||
const [step, setStep] = useState<number>(1);
|
||||
const [username, setUsername] = useState<string>();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
async function resetPassword() {
|
||||
try {
|
||||
const result: any | IError = await api
|
||||
.post("reset", {
|
||||
credentials: "include",
|
||||
json: { username },
|
||||
})
|
||||
.json();
|
||||
|
||||
if ("error" in result) {
|
||||
toast.error(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
setStep(2);
|
||||
} catch (error) {
|
||||
toast.error((error as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmitResetPassword() {
|
||||
setLoading(true);
|
||||
await resetPassword();
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center flex-1 min-h-screen p-8">
|
||||
<div className="overflow-hidden bg-white rounded-lg shadow-md max-w-[528px]">
|
||||
<div className="flex flex-col gap-6 p-12">
|
||||
<p className="text-2xl font-semibold">Сброс пароля</p>
|
||||
{step === 1 && (
|
||||
<Form
|
||||
handleSubmit={handleSubmitResetPassword}
|
||||
className="space-y-12"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<p className="text-[#77828C] text-sm">
|
||||
На указанный почтовый адрес будет отправлена информация для
|
||||
восстановления пароля
|
||||
</p>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Label value="Email" />
|
||||
<Input
|
||||
type="email"
|
||||
placeholder="mail@example.com"
|
||||
autoFocus
|
||||
required
|
||||
handleChange={(value) => setUsername(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-6">
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="medium"
|
||||
widthFull
|
||||
onClick={() => navigate("/login")}
|
||||
>
|
||||
Назад
|
||||
</Button>
|
||||
<Button type="submit" size="medium" loading={loading} widthFull>
|
||||
Продолжить
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
{step === 2 && (
|
||||
<div className="space-y-10">
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<p className="">
|
||||
Мы отправили вам письмо на адрес <b>{username}</b> с
|
||||
инструкциями для восстановления пароля.
|
||||
</p>
|
||||
<p className="">
|
||||
Если вы не получите его в ближайшее время, проверьте папку
|
||||
«Спам».
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-[#77828C] text-sm">
|
||||
Если же письма нигде не будет, пожалуйста, свяжитесь с нами по
|
||||
адресу support@graff.tech
|
||||
</p>
|
||||
</div>
|
||||
<Button size="medium" onClick={() => navigate("/login")}>
|
||||
На главную
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toaster />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ResetPasswordPage;
|
||||
Reference in New Issue
Block a user