import { useState } from "react"; import { useTheme } from "next-themes"; import HCaptcha from "@hcaptcha/react-hcaptcha"; import { CheckOcticon, XOcticon } from "../icons/octicons"; import { SendIcon } from "../icons"; import styles from "./ContactForm.module.scss"; const ContactForm = () => { const { resolvedTheme } = useTheme(); // status/feedback: const [status, setStatus] = useState({ success: false, message: "" }); // keep track of fetch: const [sending, setSending] = useState(false); const onSubmit = (e) => { // immediately prevent browser from actually navigating to a new page e.preventDefault(); // begin the process setSending(true); // extract data from form fields const formData = { name: e.target.elements.name?.value, email: e.target.elements.email?.value, message: e.target.elements.message?.value, "h-captcha-response": e.target.elements["h-captcha-response"]?.value, }; // some client-side validation to save requests (these are also checked on the server to be safe) if (!(formData.name && formData.email && formData.message && formData["h-captcha-response"])) { setSending(false); setStatus({ success: false, message: "Please make sure that all fields are filled in." }); return; } // if we've gotten here then all data is (or should be) valid and ready to post to API fetch("/api/contact/", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify(formData), }) .then((response) => response.json()) .then((data) => { setSending(false); if (data.success === true) { // handle successful submission // disable submissions, hide the send button, and let user know we were successful setStatus({ success: true, message: "Thanks! You should hear from me soon." }); } else { // pass on any error sent by the server throw new Error(data.message); } }) .catch((error) => { const message = error instanceof Error ? error.message : "UNKNOWN_EXCEPTION"; setSending(false); // give user feedback based on the error message returned if (message === "USER_INVALID_CAPTCHA") { setStatus({ success: false, message: "Did you complete the CAPTCHA? (If you're human, that is...)", }); } else if (message === "USER_MISSING_DATA") { setStatus({ success: false, message: "Please make sure that all fields are filled in.", }); } else { // something else went wrong, and it's probably my fault... setStatus({ success: false, message: "Internal server error. Try again later?" }); } }); }; return (
); }; export default ContactForm;