Add send appeal form
This commit is contained in:
1 parent
9dda476c16
commit
9c3657190a
7 files changed
+141
-23
No files matched your search
@@ -1,8 +1,58 @@
|
||||
"use client";
|
||||
import { apiInstance } from "@/shared/config/apiConfig";
|
||||
import { Container, Title } from "@/shared/ui";
|
||||
|
||||
// import ContactForm from "@/widgets/forms/ContactForm";
|
||||
import Loader from "@/shared/ui/Loader/Loader";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { AxiosError } from "axios";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "react-toastify";
|
||||
import { z } from "zod";
|
||||
|
||||
export default function Contacts() {
|
||||
const t = useTranslations("contacts");
|
||||
const [error, setError] = useState<string>("");
|
||||
const [loader, setLoader] = useState<boolean>(false);
|
||||
|
||||
const appealFormScheme = z.object({
|
||||
first_name: z.string(),
|
||||
last_name: z.string(),
|
||||
email: z.string(),
|
||||
phone_number: z.string(),
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
type FormFields = z.infer<typeof appealFormScheme>;
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm<FormFields>({
|
||||
resolver: zodResolver(appealFormScheme),
|
||||
});
|
||||
|
||||
const onSubmit = async (data: FormFields) => {
|
||||
try {
|
||||
setError("");
|
||||
setLoader(true);
|
||||
|
||||
const response = await apiInstance.post("/appeal_response/", data);
|
||||
console.log(response);
|
||||
toast.success(t("successMessage"));
|
||||
} catch (error) {
|
||||
if (error instanceof AxiosError) {
|
||||
if (
|
||||
[500, 501, 502, 503, 504].includes(error.response?.status as number)
|
||||
) {
|
||||
toast.error(t("serverError"));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setLoader(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<section className="bg-[#FAFCFF]">
|
||||
<Container className="py-[100px] ">
|
||||
@@ -12,13 +62,11 @@ export default function Contacts() {
|
||||
></iframe>
|
||||
<section className="flex items-center justify-between mb-[152px] mt-[64px]">
|
||||
<div className="max-w-[384px] max-h-[106px] flex flex-col items-center px-7">
|
||||
<Title text="Адрес" className="font-extrabold mb-2" />
|
||||
<p className="text-grey-text">
|
||||
г. Бишкек, ул. Турусбекова 109/1, офис 108
|
||||
</p>
|
||||
<Title text={t("addressTitle")} className="font-extrabold mb-2" />
|
||||
<p className="text-grey-text">{t("address")}</p>
|
||||
</div>
|
||||
<div className="max-w-[384px] max-h-[106px] flex flex-col items-center px-7">
|
||||
<Title text="Телефон" className="font-extrabold mb-2" />
|
||||
<Title text={t("phoneTitle")} className="font-extrabold mb-2" />
|
||||
<p className="text-grey-text">(0312) 39 40 38</p>
|
||||
</div>
|
||||
<div className="max-w-[384px] max-h-[106px] flex flex-col items-center px-7">
|
||||
@@ -26,36 +74,38 @@ export default function Contacts() {
|
||||
<p className="text-grey-text">kyrgyzstan@transparency.org</p>
|
||||
</div>
|
||||
</section>
|
||||
{/* <ContactForm /> */}
|
||||
<form className="w-[480px] my-0 mx-auto">
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
className="w-[480px] my-0 mx-auto"
|
||||
>
|
||||
<div className="flex items-center flex-col mt-[96px] mb-[96px]">
|
||||
<h1 className="text-gray-900 text-[36px]">Мы на связи</h1>
|
||||
<h1 className="text-gray-900 text-[36px]">{t("title")}</h1>
|
||||
<div className="flex flex-col items-center gap-6 mt-[64px]">
|
||||
<div className="flex gap-8 w-full">
|
||||
<div className="w-[224px] flex flex-col">
|
||||
<label htmlFor="firstName" className="mb-[6px]">
|
||||
Имя
|
||||
{t("name")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="firstName"
|
||||
className="w-full h-[48px] bg-white py-3 px-4 rounded-md shadow-sm border border-gray"
|
||||
placeholder="Имя"
|
||||
placeholder={t("name")}
|
||||
id="firstName"
|
||||
required
|
||||
{...register("first_name", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-[224px] flex flex-col">
|
||||
<label htmlFor="lastName" className="mb-[6px]">
|
||||
Фамилия
|
||||
{t("surname")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="lastName"
|
||||
className="w-full h-[48px] bg-white py-3 px-4 rounded-md shadow-sm border border-gray"
|
||||
placeholder="Фамилия"
|
||||
placeholder={t("surname")}
|
||||
id="lastName"
|
||||
required
|
||||
{...register("last_name", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,36 +115,36 @@ export default function Contacts() {
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="email"
|
||||
placeholder="user@gmail.com"
|
||||
className="w-full h-[48px] bg-white py-3 px-4 rounded-md shadow-sm border border-gray"
|
||||
id="email"
|
||||
{...register("email", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<label htmlFor="phoneNumber" className="mb-[6px]">
|
||||
Номер телефона
|
||||
{t("phone")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="phoneNumber"
|
||||
className="w-full h-[48px] bg-white py-3 px-4 rounded-md shadow-sm border border-gray"
|
||||
placeholder="+996"
|
||||
id="phoneNumber"
|
||||
required
|
||||
{...register("phone_number", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<label htmlFor="message" className="mb-[6px]">
|
||||
Сообщение
|
||||
{t("message")}
|
||||
</label>
|
||||
<textarea
|
||||
className="h-[120px] resize-none w-full bg-white py-3 px-4 rounded-md shadow-sm border border-gray"
|
||||
id="message"
|
||||
name="message"
|
||||
required
|
||||
{...register("message", { required: true })}
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
@@ -110,16 +160,24 @@ export default function Contacts() {
|
||||
htmlFor="consentCheckbox"
|
||||
className="text-[#667085] ml-[10px]"
|
||||
>
|
||||
Я согласен (-на) на обработку моих личных данных
|
||||
{t("checkbox")}
|
||||
</label>
|
||||
</div>
|
||||
{errors.root && (
|
||||
<p className="text-sm leading-5 text-red-500">
|
||||
{errors.root.message}
|
||||
</p>
|
||||
)}
|
||||
{error ? (
|
||||
<p className="text-red-500 leading-5 text-sm">{error}</p>
|
||||
) : null}
|
||||
|
||||
<div className="w-full">
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-blue text-white w-full h-[48px] rounded-md "
|
||||
>
|
||||
Отправить сообщение
|
||||
{loader ? <Loader /> : t("send")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,8 @@ import { NextIntlClientProvider, useMessages } from "next-intl";
|
||||
import Footer from "../../widgets/Footer/Footer";
|
||||
import Navbar from "@/widgets/Navbar/Navbar";
|
||||
import { Providers } from "./Providers";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
@@ -29,6 +31,7 @@ export default function RootLayout({
|
||||
<Providers>
|
||||
<Navbar />
|
||||
<div>{children}</div>
|
||||
<ToastContainer />
|
||||
<Footer />
|
||||
</Providers>
|
||||
</NextIntlClientProvider>
|
||||
|
||||
Reference in new issue
Block a user