Files
stream.graff.tech-client/src/components/FeedbackForm.tsx
T
2023-08-07 15:05:18 +05:00

188 lines
7.5 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.
import ky from "ky";
import { ChangeEvent, FormEvent, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import InputMask from "react-input-mask";
import AsteriskIcon from "./icons/AsteriskIcon";
import SendIcon from "./icons/SendIcon";
import CheckGradientIcon from "./icons/CheckGradientIcon";
import LoaderIcon from "./icons/LoaderIcon";
function FeedbackForm() {
const { t } = useTranslation();
const [name, setName] = useState<string>("");
const [phone, setPhone] = useState<string>("");
const [email, setEmail] = useState<string>("");
const [description, setDescription] = useState<string>("");
const [isSend, setIsSend] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
async function sendMail(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
setIsLoading(true);
try {
await ky
.post(`https://estate.graff.tech/api/mail`, {
json: {
fullname: name,
phone,
email,
request: description,
},
})
.json();
setIsSend(true);
setIsLoading(false);
} catch (error) {
setIsLoading(false);
if (error instanceof Error) {
alert(error.message);
}
}
}
return (
<form
className="grid lg:grid-cols-3 sm:grid-cols-2 relative"
onSubmit={(e) => void sendMail(e)}
>
<div className="relative col-span-1">
<input
required
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
className="feedback-field bg-transparent border border-[#3D425C] rounded-none lg:p-6 lg:pt-14 p-4 pt-12 outline-none outline-1 -outline-offset-1 focus:outline-[#D375FF] transition-all w-full"
/>
<p className="feedback-placeholder lg:text-base text-sm absolute lg:top-4 top-5 left-0 w-full lg:p-6 p-4 opacity-50 transition-all pointer-events-none flex justify-between">
<span>
<Trans i18nKey={"feedback.form.field1"}>Имя</Trans>
</span>
<AsteriskIcon />
</p>
</div>
<div className="relative">
<InputMask
required
type="tel"
mask={"+999999999999999"}
maskChar={null}
value={phone}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setPhone(e.target.value)
}
className={[
"feedback-field bg-transparent border rounded-none sm:border-l-0 sm:border-t border-t-0 border-l border-[#3D425C] lg:p-6 lg:pt-14 p-4 pt-12 outline-none outline-1 -outline-offset-1 focus:outline-[#D375FF] transition-all w-full",
].join(" ")}
/>
<p className="feedback-placeholder lg:text-base text-sm absolute lg:top-4 top-5 left-0 w-full lg:p-6 p-4 opacity-50 transition-all pointer-events-none flex justify-between">
<span>
<Trans i18nKey={"feedback.form.field2"}>Телефон</Trans>
</span>
<AsteriskIcon />
</p>
</div>
<div className="relative lg:col-span-1 sm:col-span-2 col-span-1">
<input
required
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="feedback-field bg-transparent border rounded-none lg:border-l-0 lg:border-t border-t-0 border-[#3D425C] lg:p-6 lg:pt-14 p-4 pt-12 outline-none outline-1 -outline-offset-1 focus:outline-[#D375FF] transition-all w-full"
/>
<p className="feedback-placeholder lg:text-base text-sm absolute lg:top-4 top-5 left-0 w-full lg:p-6 p-4 opacity-50 transition-all pointer-events-none flex justify-between">
<span>Email</span>
<AsteriskIcon />
</p>
</div>
<div className="relative lg:col-span-3 sm:col-span-2 h-[194px]">
<textarea
placeholder={t("feedback.form.field3").toString()}
value={description}
onChange={(e) => setDescription(e.target.value)}
className="feedback-field bg-transparent resize-none border rounded-none border-t-0 border-[#3D425C] lg:p-6 p-4 h-full outline-none outline-1 -outline-offset-1 focus:outline-[#D375FF] transition-all w-full"
></textarea>
</div>
<div className="2xl:pt-6 2xl:pr-6 pt-4 sm:pr-4 lg:order-none order-last flex items-center">
<button
disabled={isLoading}
className="group relative px-6 py-4 2xl:text-base text-sm bg-gradient rounded-full font-medium flex justify-between items-center w-full transition-opacity disabled:opacity-75"
>
<div className="absolute top-0 left-0 w-full h-full rounded-full bg-black opacity-0 group-hover:opacity-10 transition-all"></div>
<span className="relative">
<Trans i18nKey={"feedback.form.button"}>Отправить</Trans>
</span>
{!isLoading ? (
<SendIcon className="relative 2xl:w-8 2xl:h-8 w-6 h-6" />
) : (
<LoaderIcon className="relative 2xl:w-8 2xl:h-8 w-6 h-6 animate-spin" />
)}
</button>
</div>
<div className="border sm:border-t-0 border-t border-[#3D425C] 2xl:p-6 p-4 sm:mt-0 mt-6 flex items-center">
<div className="text-xs leading-tight">
<Trans i18nKey={"feedback.form.desc1.text1"}>
Нажимая кнопку отправить, вы принимаете
</Trans>{" "}
<a className="text-[#798FFF] cursor-pointer opacity-95 hover:opacity-100 transition-all">
<Trans i18nKey={"feedback.form.desc1.link1"}>
условия использования
</Trans>
</a>{" "}
<Trans i18nKey={"feedback.form.desc1.text2"}>и</Trans>{" "}
<a className="text-[#798FFF] cursor-pointer opacity-95 hover:opacity-100 transition-all">
<Trans i18nKey={"feedback.form.desc1.link2"}>
политику конфиденциальности
</Trans>
</a>
</div>
</div>
<div className="border border-t-0 sm:border-l-0 border-[#3D425C] 2xl:p-6 p-4 text-xs flex items-center gap-2">
<div className="flex gap-2">
<div className="">
<AsteriskIcon />
</div>
<p></p>
<p className="leading-tight">
<Trans i18nKey={"feedback.form.desc2"}>
Звездочкой отмечены обязательные
<br />
для заполнения поля
</Trans>
</p>
</div>
</div>
{isSend && (
<div className="absolute top-0 left-0 w-full h-full bg-[#14161F] border border-[#3D425C] p-6 flex flex-col justify-between">
<p className="text-gradient text-xl font-gilroy leading-tight font-semibold flex items-center gap-2">
<span>Заявка отправлена</span>
<CheckGradientIcon className="lg:w-8 lg:h-8 w-6 h-6" />
</p>
<div className="flex flex-col gap-2">
<p className="font-gilroy leading-snug lg:text-2xl text-xl font-semibold">
Спасибо за подачу заявки!
</p>
<p className="lg:w-1/2 sm:w-2/3 lg:text-base text-sm">
Мы ценим ваш интерес к нашей компании и в ближайшее время свяжемся
с вами для уточнения деталей проекта.
</p>
</div>
</div>
)}
</form>
);
}
export default FeedbackForm;