1
0
mirror of https://github.com/XFox111/my-website.git synced 2026-04-22 07:28:01 +03:00

!feat: added Cloudflare Turnstile captcha to the contact form

feat: added contact form disclaimer
This commit is contained in:
2025-01-22 15:57:02 +00:00
parent 5d059fb7c4
commit 9d369ad4d2
8 changed files with 116 additions and 3 deletions
@@ -93,5 +93,11 @@
}
}
}
.disclaimer
{
text-align: right;
color: $colorNeutralForeground4;
}
}
}
+19 -1
View File
@@ -4,10 +4,12 @@ import Button from "@/_components/Button";
import SocialLinks from "@/_components/SocialLinks";
import contacts from "@/_data/contacts";
import FormStatusTracker from "@/_utils/FormStatusTracker";
import React, { InputHTMLAttributes, useMemo, useState } from "react";
import React, { InputHTMLAttributes, useEffect, useMemo, useState } from "react";
import { useFormState } from "react-dom";
import Turnstile from "react-turnstile";
import sendInquiry, { FormStatus } from "../_utils/sendInquiry";
import cls from "./ContactSection.module.scss";
import { getSitekey } from "@/_utils/turnstile";
const defaultState: FormStatus = { status: "idle" };
@@ -16,6 +18,7 @@ const ContactSection: React.FC = () =>
const [pending, setPending] = useState<boolean>(false);
const [{ status, message }, formAction] = useFormState<FormStatus, FormData>(sendInquiry, defaultState);
const { telephone: phone, email, socials } = contacts;
const [cfSitekey, setCfSitekey] = useState<string | undefined | null>(null);
const sharedProps: InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement> = useMemo(() => ({
required: true,
@@ -23,6 +26,11 @@ const ContactSection: React.FC = () =>
readOnly: status === "success"
}), [status, pending]);
useEffect(() =>
{
getSitekey().then(sitekey => setCfSitekey(sitekey));
}, []);
return (
<section id="contacts" className={ cls.section }>
<h2>Let's get in touch</h2>
@@ -53,6 +61,16 @@ const ContactSection: React.FC = () =>
<input name="timezone" type="hidden" readOnly
value={ Intl.DateTimeFormat().resolvedOptions().timeZone } />
<div>
{ cfSitekey &&
<Turnstile sitekey={ cfSitekey } size="flexible" action="contact_form" />
}
<p className={ cls.disclaimer }>
*Using this form does not guarantee I will respond to your request
</p>
</div>
<div className={ cls.formToolbar }>
<div className={ `${cls.status} ${pending ? "" : cls[status]}` }>
{ pending &&