procurement-frontend2/src/widgets/forms/SignUpForm.tsx

174 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { AxiosError } from "axios";
import Loader from "@/shared/ui/Loader/Loader";
import { apiInstance } from "@/shared/config/apiConfig";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "next/navigation";
import React from "react";
import alert from "./icons/alert-circle.svg";
import Image from "next/image";
import eye_off from "./icons/eye-off.svg";
import eye_on from "./icons/eye-on.svg";
const SignUpForm = () => {
const [resError, setResError] = React.useState<string>("");
const [loader, setLoader] = React.useState<boolean>(false);
const [showPassword, setShowPassword] = React.useState(false);
const [showPasswordTwo, setShowPasswordTwo] = React.useState(false);
const router = useRouter();
const signUpFormScheme = z
.object({
email: z.string().email("Неверный формат email"),
password: z.string().min(8, "Пароль должен содержать минимум 8 символов"),
password_repeat: z
.string()
.min(8, "Пароль должен содержать минимум 8 символов"),
})
.refine((data) => data.password === data.password_repeat, {
message: "Пароли не совпадают",
path: ["password_repeat"],
});
type FormFields = z.infer<typeof signUpFormScheme>;
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<FormFields>({
resolver: zodResolver(signUpFormScheme),
});
const onSubmit = async (data: FormFields) => {
try {
const res = await apiInstance.post("/auth/register/", data);
const encodedEmail = encodeURIComponent(data.email);
console.log(encodedEmail);
if ([200, 201].includes(res.status)) {
router.push(`sign-up/confirm-email?email=${encodedEmail}`);
}
} catch (error: unknown) {
if (error instanceof AxiosError) {
if ([401, 400].includes(error.response?.status as number)) {
setResError("Такой пользователь уже существует");
} else if (error.response?.status.toString().slice(0, 1) === "5") {
setResError("Ошибка на стороне сервера");
}
} else {
setResError("Непредвиденная ошибка");
}
} finally {
setLoader(false);
}
};
return (
<form
className="mb-2 w-[360px] flex flex-col"
onSubmit={handleSubmit(onSubmit)}
>
<div className="flex flex-col gap-5">
<div>
<label className="text-[14px] leading-5 text-gray-700">Email</label>
<div
className={`flex items-center${
errors.email?.message && "border border-red-400"
}`}
>
<input
placeholder="Email"
className="w-full text-[16px] leading-6 text-gray-900 px-[10px] py-[14px] border border-gray-300 rounded-lg shadow-sm bg-white"
type="text"
{...register("email", { required: true })}
/>
</div>
{errors?.email?.message && (
<p className="flex items-center justify-between text-[14px] font-normal leading-5 text-red-500">
{errors.email.message} <Image src={alert} alt="Alert Icon" />
</p>
)}
</div>
<div>
<label className="text-[14px] leading-5 text-gray-700">Пароль</label>
<div
className={`flex items-center border border-gray-300 rounded-lg shadow-sm bg-white${
errors?.password?.message && "border border-red-400"
}`}
>
<input
placeholder="Пароль"
className="w-full text-[16px] leading-6 text-gray-900 px-[10px] py-[14px]"
type={showPassword ? "text" : "password"}
{...register("password", { required: true })}
/>
<button
onClick={() => setShowPassword((prev) => !prev)}
type="button"
className="pr-2"
>
<Image src={showPassword ? eye_on : eye_off} alt="Eye Icon" />
</button>
</div>
{errors?.password?.message && (
<p className="flex items-center justify-between text-[14px] font-normal leading-5 text-red-500">
{errors.password.message} <Image src={alert} alt="Alert Icon" />
</p>
)}
</div>
<div>
<label className="text-[14px] leading-5 text-gray-700">
Пароль потверждения
</label>
<div
className={`flex items-center border border-gray-300 rounded-lg shadow-sm bg-white${
errors?.password_repeat?.message && "border border-red-400"
}`}
>
<input
placeholder="Пароль потверждения"
className="w-full text-[16px] leading-6 text-gray-900 px-[10px] py-[14px] "
type={showPasswordTwo ? "text" : "password"}
{...register("password_repeat", { required: true })}
/>
<button
onClick={() => setShowPasswordTwo((prev) => !prev)}
type="button"
className="pr-2"
>
<Image src={showPasswordTwo ? eye_on : eye_off} alt="Eye Icon" />
</button>
</div>
{errors?.password_repeat?.message && (
<p className="flex items-center justify-between text-[14px] font-normal leading-5 text-red-500">
{errors.password_repeat.message}{" "}
<Image src={alert} alt="Alert Icon" />
</p>
)}
</div>
</div>
{errors.root && (
<p className="text-sm leading-5 text-red-500">{errors.root.message}</p>
)}
{resError && <p className="text-sm leading-5 text-red-500">{resError}</p>}
<div className="flex flex-col mt-[36px] gap-4">
<button
className="p-4 h-[50px] w-full font-bold leading-6 text-white bg-light-blue rounded-md"
type="submit"
>
{loader ? <Loader /> : "Зарегистрироваться"}
</button>
</div>
</form>
);
};
export default SignUpForm;