import { AnimatePresence, motion } from "motion/react"; import { useRef, useState, type KeyboardEvent } from "react"; type Props = { title?: string; description?: string; placeholder?: string; buttonLabel?: string; }; function LoaderIcon({ className = "", size = 14 }: { className?: string; size?: number }) { return ( ); } export default function NewsletterInput({ title = "Get updates", description = "Fresh UI skills and design engineering notes.", placeholder = "Enter your email", buttonLabel = "Subscribe", }: Props) { const [email, setEmail] = useState(""); const [status, setStatus] = useState<"idle" | "subscribing" | "subscribed">("idle"); const [botField, setBotField] = useState(""); const [error, setError] = useState(""); const startedAtRef = useRef(Date.now()); const submit = async () => { if (!email.trim() || status !== "idle") return; setError(""); setStatus("subscribing"); try { const response = await fetch("https://api.interfaceoffice.com/subscribe", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email, source: "ui-skills", honeypot: botField, startedAt: startedAtRef.current, }), }); if (!response.ok) { throw new Error("Failed to subscribe"); } setStatus("subscribed"); setEmail(""); window.setTimeout(() => { setError(""); setStatus("idle"); }, 1600); } catch { setError("Couldn't subscribe right now. Please try again."); setStatus("idle"); } }; return (

{title}

{description}

setBotField(event.target.value)} className="pointer-events-none absolute inset-0 -z-10 h-0 w-0 opacity-0" /> { setEmail(event.target.value); if (error) setError(""); }} disabled={status !== "idle"} aria-invalid={error ? "true" : "false"} onKeyDown={(event: KeyboardEvent) => { if (event.key === "Enter") { event.preventDefault(); void submit(); } }} className="text-parchment-900 placeholder:text-parchment-400 focus:border-parchment-300 relative z-0 h-12 w-full rounded-[12px] bg-white px-4 pr-36 text-sm shadow-2xs ring-1 ring-black/10 transition-colors outline-none" />
{error ? (

{error}

) : null}
{/*
*/}
); }