forked from Transparency/kgroad-frontend2
181 lines
5.4 KiB
TypeScript
181 lines
5.4 KiB
TypeScript
"use client";
|
||
|
||
import "./SignUpForm.scss";
|
||
import { useState } from "react";
|
||
import AuthInput from "@/features/AuthInput/AuthInput";
|
||
import Loader from "@/shared/ui/components/Loader/Loader";
|
||
import GoogleButton from "@/features/GoogleButton/GoogleButton";
|
||
import { apiInstance } from "@/shared/config/apiConfig";
|
||
import { AxiosError } from "axios";
|
||
import { Link, useRouter } from "@/shared/config/navigation";
|
||
import check from "./icons/check.svg";
|
||
import Image from "next/image";
|
||
|
||
const SignUpForm = () => {
|
||
const [checkbox, setCheckbox] = useState<boolean>(false);
|
||
const [emailWarning, setEmailWarning] = useState<string>("");
|
||
const [passwordWarning, setPasswordWarning] = useState<string>("");
|
||
const [passwordConfirmWarning, setPasswordConfirmWarning] =
|
||
useState<string>("");
|
||
const [error, setError] = useState<string>("");
|
||
const [loader, setLoader] = useState<boolean>(false);
|
||
|
||
const router = useRouter();
|
||
|
||
const handleSubmit: React.MouseEventHandler<
|
||
HTMLFormElement
|
||
> = async (e) => {
|
||
e.preventDefault();
|
||
const formData = new FormData(e.currentTarget);
|
||
const regex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/;
|
||
|
||
if (!formData.get("email")?.toString()) {
|
||
setError("");
|
||
setPasswordWarning("");
|
||
setPasswordConfirmWarning("");
|
||
setEmailWarning("Заполните поле Email");
|
||
return;
|
||
}
|
||
|
||
if (!formData.get("password")?.toString()) {
|
||
setError("");
|
||
setEmailWarning("");
|
||
setPasswordConfirmWarning("");
|
||
setPasswordWarning("Заполните поле Пароль");
|
||
return;
|
||
}
|
||
|
||
if ((formData.get("password")?.toString().length as number) < 8) {
|
||
setError("");
|
||
setEmailWarning("");
|
||
setPasswordConfirmWarning("");
|
||
setPasswordWarning(
|
||
"Пароль должен содержать минимум 8 символов"
|
||
);
|
||
return;
|
||
}
|
||
|
||
if (!regex.test(formData.get("password")?.toString() as string)) {
|
||
setError("");
|
||
setEmailWarning("");
|
||
setPasswordConfirmWarning("");
|
||
setPasswordWarning(
|
||
"Пароль должен содержать по меньшей мере 1 прописную букву, одну заглавную букву и одну цифру"
|
||
);
|
||
return;
|
||
}
|
||
|
||
if (!formData.get("password2")?.toString()) {
|
||
setError("");
|
||
setEmailWarning("");
|
||
setPasswordWarning("");
|
||
setPasswordConfirmWarning("Заполните поле потверждения");
|
||
return;
|
||
}
|
||
|
||
if (
|
||
formData.get("password")?.toString() !==
|
||
formData.get("password2")?.toString()
|
||
) {
|
||
setError("");
|
||
setEmailWarning("");
|
||
setPasswordWarning("");
|
||
setPasswordConfirmWarning("Пароли не совпадают");
|
||
return;
|
||
}
|
||
|
||
if (!checkbox) {
|
||
setEmailWarning("");
|
||
setPasswordWarning("");
|
||
setPasswordConfirmWarning("");
|
||
setError("Необходимо принять политику конфиденциальности");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
setError("");
|
||
setEmailWarning("");
|
||
setPasswordWarning("");
|
||
setPasswordConfirmWarning("");
|
||
setLoader(true);
|
||
|
||
const res = await apiInstance.post(
|
||
"/users/register/",
|
||
formData
|
||
);
|
||
|
||
if ([200, 201].includes(res.status)) {
|
||
router.push(
|
||
`/sign-up/confirm-email/?email=${formData.get("email")}`
|
||
);
|
||
}
|
||
} catch (error: unknown) {
|
||
if (error instanceof AxiosError) {
|
||
if ([401, 400].includes(error.response?.status as number)) {
|
||
setError("Такой пользователь уже существует");
|
||
} else if (
|
||
error.response?.status.toString().slice(0, 1) === "5"
|
||
) {
|
||
setError("Ошибка на стороне сервера");
|
||
}
|
||
} else {
|
||
setError("Непредвиденная ошибка");
|
||
}
|
||
} finally {
|
||
setLoader(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<form className="sign-up-form" onSubmit={handleSubmit}>
|
||
<div className="sign-up-form__inputs">
|
||
<AuthInput
|
||
type="email"
|
||
label="Email"
|
||
placeholder="Введите email"
|
||
error={emailWarning}
|
||
name="email"
|
||
/>
|
||
<AuthInput
|
||
isPassword
|
||
label="Пароль"
|
||
placeholder="Введите пароль"
|
||
error={passwordWarning}
|
||
name="password"
|
||
/>
|
||
<AuthInput
|
||
isPassword
|
||
label="Пароль потверждения"
|
||
placeholder="Повторите пароль"
|
||
error={passwordConfirmWarning}
|
||
name="password2"
|
||
/>
|
||
</div>
|
||
{error ? <p className="sign-up-form__error">{error}</p> : null}
|
||
<div className="sign-up-form__policy">
|
||
<button
|
||
onClick={() => setCheckbox((prev) => !prev)}
|
||
type="button"
|
||
className="sign-up-form__checkbox"
|
||
>
|
||
{checkbox ? <Image src={check} alt="Check Icon" /> : null}
|
||
</button>
|
||
<p>
|
||
Я ознакомлен(-а) с{" "}
|
||
<Link href="#">Политикой конфиденциальности</Link>
|
||
</p>
|
||
</div>
|
||
|
||
<div className="sign-up-form__btns">
|
||
<button className="sign-up-form__btns_first" type="submit">
|
||
{loader ? <Loader /> : "Зарегистрироваться"}
|
||
</button>
|
||
|
||
<GoogleButton />
|
||
</div>
|
||
</form>
|
||
);
|
||
};
|
||
|
||
export default SignUpForm;
|