This commit is contained in:
2024-11-02 18:01:37 +05:00
parent 2435aa2814
commit c02176d4a7
22 changed files with 563 additions and 32 deletions
+2 -1
View File
@@ -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>
+3 -5
View File
@@ -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;
+118
View File
@@ -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;