110 lines
3.2 KiB
TypeScript
110 lines
3.2 KiB
TypeScript
/* 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 { Link, useNavigate } from "react-router-dom";
|
||
import useAuthStore from "../stores/useAuthStore";
|
||
import toast from "react-hot-toast";
|
||
import IError from "../types/IError";
|
||
import IUser from "../types/IUser";
|
||
import api from "../utils/api";
|
||
|
||
function LoginPage() {
|
||
const [username, setUsername] = useState<string>();
|
||
const [password, setPassword] = useState<string>();
|
||
const [loading, setLoading] = useState(false);
|
||
const { setUser } = useAuthStore();
|
||
const navigate = useNavigate();
|
||
|
||
async function login() {
|
||
setLoading(true);
|
||
|
||
try {
|
||
const result: IUser | IError = await api
|
||
.post("login", {
|
||
credentials: "include",
|
||
json: { username, password },
|
||
})
|
||
.json();
|
||
|
||
if ("error" in result) {
|
||
setLoading(false);
|
||
toast.error(`Error: ${result.error}`);
|
||
return;
|
||
}
|
||
|
||
setUser({
|
||
id: result.id,
|
||
username: "username",
|
||
accessToken: result.accessToken,
|
||
companyId: result.companyId,
|
||
name: result.name,
|
||
role: result.role,
|
||
buildIds: result.buildIds,
|
||
});
|
||
|
||
navigate("/dashboard");
|
||
} catch (error) {
|
||
setLoading(false);
|
||
toast.error((error as Error).message);
|
||
}
|
||
}
|
||
|
||
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 ">
|
||
<div className="flex flex-col gap-6 p-12">
|
||
<p className="text-2xl font-semibold">Вход</p>
|
||
<Form handleSubmit={login}>
|
||
<div className="flex flex-col gap-1">
|
||
<Label value="Email" />
|
||
<Input
|
||
type="email"
|
||
placeholder="example@gmail.com"
|
||
autoFocus
|
||
required
|
||
handleChange={(value) => setUsername(value)}
|
||
/>
|
||
</div>
|
||
<div className="flex flex-col gap-1">
|
||
<Label value="Пароль" />
|
||
<Input
|
||
type="password"
|
||
placeholder="********"
|
||
required
|
||
handleChange={(value) => setPassword(value)}
|
||
/>
|
||
</div>
|
||
{/* <ReCAPTCHA
|
||
ref={recaptchaRef}
|
||
sitekey="6LdKPH4oAAAAAM8cyMoCkmNvbnBbe2UIrwRwQ425"
|
||
className="mt-3"
|
||
/> */}
|
||
<Button
|
||
type="submit"
|
||
size="medium"
|
||
className="mt-10"
|
||
loading={loading}
|
||
>
|
||
Войти
|
||
</Button>
|
||
</Form>
|
||
<div className="flex self-center gap-6">
|
||
<Link to="/registration" className="text-xs text-[#49A1F5]">
|
||
Нет аккаунта?
|
||
</Link>
|
||
{/* <Link to="" className="text-xs text-[#49A1F5]">
|
||
Забыли пароль?
|
||
</Link> */}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default LoginPage;
|