"use client"; /** * /feedback — single-page form for bug reports, feature requests, and * general comments. Submissions persist to the BFF and trigger an * admin notification email. No follow-up UI beyond a success toast * and a redirect back to /. * * Authed visitors don't see the contact-email field — the BFF reads * their account email from the session cookie. Anonymous visitors get * the field and must fill it in so we have a reply path. */ import { useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { ArrowLeft, MessageSquare, Send } from "lucide-react"; import { toast } from "sonner"; import { feedback as feedbackAPI, SocialError } from "@/lib/social"; import { useAuth } from "@/components/auth/auth-provider"; type Category = "bug" | "feature" | "general" | "other"; const CATEGORIES: { value: Category; label: string; description: string }[] = [ { value: "general", label: "General feedback", description: "Thoughts, impressions, suggestions — anything else." }, { value: "bug", label: "Bug report", description: "Something is broken or behaving unexpectedly." }, { value: "feature", label: "Feature request", description: "An idea for something new on the site." }, { value: "other", label: "Other", description: "Doesn't fit the above? Use this." }, ]; export default function FeedbackPage() { const router = useRouter(); const { user, loading } = useAuth(); const authed = !loading && !!user; const [category, setCategory] = useState("general"); const [message, setMessage] = useState(""); const [contactEmail, setContactEmail] = useState(""); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); async function submit(e: React.FormEvent) { e.preventDefault(); setError(null); const trimmed = message.trim(); if (!trimmed) { setError("Message is required."); return; } if (!authed && !contactEmail.trim()) { setError("Email is required so we can reply."); return; } setSubmitting(true); try { await feedbackAPI.submit({ category, message: trimmed, contact_email: authed ? undefined : contactEmail.trim(), }); toast.success("Thanks for the feedback!", { description: "We've forwarded it to the team.", duration: 5000, }); setMessage(""); setContactEmail(""); router.push("/"); } catch (err) { setError(err instanceof SocialError ? err.message : "Could not send feedback."); } finally { setSubmitting(false); } } const selected = CATEGORIES.find((c) => c.value === category); return (
Back to home

Send feedback

Tell us what's working, what's broken, or what you'd like to see next. We read every message.

{selected?.description}