spb/tools-spboucher-ai
Public
1"use client";2import { useState } from "react";3export function ReportForm({ slug }: { slug: string }) {4 const [state, setState] = useState<"idle" | "sending" | "done" | "error">("idle"); const [msg, setMsg] = useState("");5 return (6 <form className="card max-w-xl p-4" onSubmit={async (e) => { e.preventDefault(); setState("sending"); const fd = new FormData(e.currentTarget);7 const r = await fetch("/api/report", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ slug, message: fd.get("message"), contact: fd.get("contact"), website: fd.get("website") }) });8 setState(r.ok ? "done" : "error"); if (!r.ok) setMsg((await r.json().catch(() => ({}))).error ?? "Could not send"); }}>9 <p className="text-sm text-fg-2">Broken link, outdated license, wrong category, or a tool that no longer exists? Tell us; reports are reviewed by the editor.</p>10 <label className="label mt-3" htmlFor={`msg-${slug}`}>What is wrong?</label>11 <textarea id={`msg-${slug}`} name="message" required minLength={10} maxLength={2000} rows={3} className="input" placeholder="The pricing model changed to… / The docs link now redirects to…" />12 <label className="label mt-3" htmlFor={`contact-${slug}`}>Contact (optional)</label>13 <input id={`contact-${slug}`} name="contact" type="email" maxLength={200} className="input" placeholder="you@example.org" autoComplete="email" />14 <input type="text" name="website" tabIndex={-1} autoComplete="off" className="hidden" aria-hidden />15 <div className="mt-3 flex items-center gap-3"><button className="btn-primary" disabled={state === "sending" || state === "done"}>{state === "done" ? "Thank you" : state === "sending" ? "Sending…" : "Send report"}</button>{state === "error" && <span className="text-sm text-bad" role="alert">{msg}</span>}{state === "done" && <span className="text-sm text-ok" role="status">Report received.</span>}</div>16 </form>17 );18}19