"use client"; import { env } from "../../lib/env"; import { useActionState, useState } from "react"; import TextareaAutosize from "react-textarea-autosize"; import Turnstile from "react-turnstile"; import clsx from "clsx"; import { CheckIcon, XIcon } from "lucide-react"; import Link from "../../components/Link"; import { send, type ContactState, type ContactInput } from "./action"; import styles from "./form.module.css"; const ContactForm = () => { const [formState, formAction, pending] = useActionState(send, { success: false, message: "", }); // keep track of input so we can repopulate the fields if the form fails const [formFields, setFormFields] = useState>({ name: "", email: "", message: "", }); return (
{ setFormFields({ ...formFields, name: e.target.value }); }} disabled={pending || formState.success} className={clsx(styles.input, !pending && formState.errors?.name && styles.invalid)} /> {!pending && formState.errors?.name && {formState.errors.name[0]}} { setFormFields({ ...formFields, email: e.target.value }); }} disabled={pending || formState.success} className={clsx(styles.input, !pending && formState.errors?.email && styles.invalid)} /> {!pending && formState.errors?.email && {formState.errors.email[0]}} { setFormFields({ ...formFields, message: e.target.value }); }} disabled={pending || formState.success} className={clsx(styles.input, styles.textarea, !pending && formState.errors?.message && styles.invalid)} /> {!pending && formState.errors?.message && ( {formState.errors.message[0]} )}
{" "} Basic{" "} Markdown syntax {" "} is allowed here, e.g.: **bold**, _italics_, [ links ](https://jarv.is), and `code`.
{!pending && formState.errors?.["cf-turnstile-response"] && ( {formState.errors["cf-turnstile-response"][0]} )}
{!formState.success && ( )} {!pending && formState.message && (
{formState.success ? ( ) : ( )}{" "} {formState.message}
)}
); }; export default ContactForm;