import { useEffect, useId, useRef, useState } from "react"; import { CheckIcon, ChevronRightIcon } from "@/components/icons"; interface Props { focusOnMount?: boolean; showHelper?: boolean; compact?: boolean; } export function EmailSubscription({ focusOnMount = false, showHelper = true, compact = false }: Props) { const id = useId(); const pending = useRef(false); const inputRef = useRef(null); useEffect(() => { if (focusOnMount) inputRef.current?.focus({ preventScroll: true }); }, [focusOnMount]); const [state, setState] = useState<"idle" | "pending" | "success" | "error">("idle"); const [message, setMessage] = useState(""); const [hasEmail, setHasEmail] = useState(false); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (pending.current) return; const form = event.currentTarget; const email = new FormData(form).get("email"); pending.current = true; setState("pending"); setMessage(""); try { const response = await fetch("/api/subscribe", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email }), }); const data = await response.json(); if (!response.ok) throw new Error(data.message || "Couldn't subscribe. Please try again."); setState("success"); setMessage(data.message || "You’re subscribed."); form.reset(); } catch (error) { setState("error"); setMessage(error instanceof Error ? error.message : "Couldn't subscribe. Please try again."); } finally { pending.current = false; } } let buttonLabel = "Subscribe"; if (state === "pending") buttonLabel = "Subscribing…"; if (state === "success") buttonLabel = "Subscribed"; return (
setHasEmail(false)} className="newsletter-form" data-compact={compact || undefined} data-has-email={hasEmail || undefined} aria-busy={state === "pending"} >
setHasEmail(event.currentTarget.value.length > 0)} />

{message || (showHelper ? "Essays by email. Unsubscribe anytime." : "")}

); }