"use client"; import { useState, useEffect } from "react"; import styles from "./components.module.css"; import Script from "next/script"; export default function Contact() { const [loading, setLoading] = useState(false); const [status, setStatus] = useState(null); const [captchaToken, setCaptchaToken] = useState(null); const [pendingForm, setPendingForm] = useState(null); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (!captchaToken) { setPendingForm(e.currentTarget); // @ts-ignore window.grecaptcha.execute(); return; } await sendForm(e.currentTarget); } async function sendForm(form: HTMLFormElement) { setLoading(true); setStatus(null); const data = { name: "Website Contact", email: (form.elements.namedItem("from") as HTMLInputElement).value, subject: (form.elements.namedItem("subject") as HTMLInputElement).value, message: (form.elements.namedItem("message") as HTMLTextAreaElement).value, token: captchaToken, }; try { const res = await fetch("/api/contact", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); if (!res.ok) throw new Error(); setStatus(true); form.reset(); } catch { setStatus(false); } finally { setLoading(false); setCaptchaToken(null); // @ts-ignore window.grecaptcha.reset(); } } useEffect(() => { if (captchaToken && pendingForm) { sendForm(pendingForm); setPendingForm(null); } }, [captchaToken]); useEffect(() => { if (status === true) { const timer = setTimeout(() => { setStatus(null); }, 3_000); return () => clearTimeout(timer); } }, [status]); useEffect(() => { (window as any).onRecaptchaSuccess = (token: string) => { setCaptchaToken(token); }; }, []); const icon = status === null ? "/img/icons/send.png" : status === true ? "/img/icons/check.png" : "/img/icons/error.png"; return (