"use client"; import SubmitToast from "@/app/components/ui/SubmitToast"; import { useMemo, useState } from "react"; type FeedbackJson = { sections: { satisfaction: { title: string; eventRating: { label: string; left: string; right: string; min: number; max: number }; venueSatisfaction: { label: string; left: string; right: string; min: number; max: number }; }; content: { title: string; session: { label: string; placeholder: string; options: { value: string; label: string }[] }; speakerRating: { label: string; left: string; right: string; min: number; max: number }; }; qualitative: { title: string; improve2027: { label: string; placeholder: string }; comments: { label: string; placeholder: string }; }; industry: { title: string; ipv6Readiness: { label: string; hint: string; left: string; right: string; min: number; max: number }; challenge: { label: string; hint: string; placeholder: string; options: { value: string; label: string }[]; }; }; networking: { title: string; introductions: { label: string; hint: string; placeholder: string }; collaboration: { label: string; hint: string; options: { value: string; label: string }[] }; }; logistics: { title: string; venueRating: { label: string; hint: string; left: string; right: string; min: number; max: number }; }; }; submit: { label: string; disclaimer: string }; }; function RadioScale({ name, label, left, right, min, max, value, onChange, }: { name: string; label: string; left: string; right: string; min: number; max: number; value: string; onChange: (v: string) => void; }) { const values = useMemo(() => { const out: number[] = []; for (let i = min; i <= max; i++) out.push(i); return out; }, [min, max]); return (
{label}
{left}
{values.map((n) => ( ))}
{right}
); } const emptyFeedback = { eventRating: "", venueSatisfaction: "", session: "", speakerRating: "", improve2027: "", comments: "", ipv6Readiness: "", challenge: "", introductions: "", collaboration: [] as string[], venueRating: "", }; export default function FeedbackForm({ data }: { data: FeedbackJson }) { const [form, setForm] = useState({ ...emptyFeedback, collaboration: [] as string[] }); const [submitState, setSubmitState] = useState<"idle" | "sending" | "ok" | "error">("idle"); const toggleCollaboration = (value: string) => { setForm((s) => ({ ...s, collaboration: s.collaboration.includes(value) ? s.collaboration.filter((x) => x !== value) : [...s.collaboration, value], })); }; return (
{ e.preventDefault(); setSubmitState("sending"); const sessionLabel = data.sections.content.session.options.find((o) => o.value === form.session)?.label ?? ""; const challengeLabel = data.sections.industry.challenge.options.find((o) => o.value === form.challenge)?.label ?? ""; const collaborationLabels = form.collaboration .map( (v) => data.sections.networking.collaboration.options.find((o) => o.value === v)?.label ?? v, ) .filter(Boolean); try { const res = await fetch("/api/submissions", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type: "feedback", ...form, sessionLabel, challengeLabel, collaborationLabels, }), }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(typeof err?.error === "string" ? err.error : res.statusText); } setSubmitState("ok"); } catch { setSubmitState("error"); } }} > {/* 1 */}

{data.sections.satisfaction.title}

setForm((s) => ({ ...s, eventRating: v }))} />
setForm((s) => ({ ...s, venueSatisfaction: v }))} />
{/* 2 */}

{data.sections.content.title}

expand_more
setForm((s) => ({ ...s, speakerRating: v }))} />
{/* 3 */}

{data.sections.qualitative.title}