"use client"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Spinner } from "@/components/ui/spinner"; import { Form, FormField, FormItem, FormControl, clearFormDraft, } from "@/components/ui/form"; import type { FeedbackEntry } from "../types"; const PERSIST_KEY = "feedback-draft"; const HISTORY_KEY = "feedback-history"; const MAX_HISTORY = 20; interface FeedbackFormValues { message: string; } function readHistory(): FeedbackEntry[] { try { const stored = localStorage.getItem(HISTORY_KEY); return stored ? (JSON.parse(stored) as FeedbackEntry[]) : []; } catch { return []; } } function writeHistory({ entries }: { entries: FeedbackEntry[] }): void { try { localStorage.setItem(HISTORY_KEY, JSON.stringify(entries)); } catch { // localStorage may be full or unavailable } } function useFeedback() { const [entries, setEntries] = useState(readHistory); const [isSubmitting, setIsSubmitting] = useState(false); async function submit({ values, onSuccess, }: { values: FeedbackFormValues; onSuccess: () => void; }) { if (isSubmitting) return; setIsSubmitting(true); try { const res = await fetch("/api/feedback", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(values), }); if (!res.ok) { const data = await res.json().catch(() => null); throw new Error(data?.error ?? "Failed to submit"); } const { entry } = await res.json(); const next = [entry, ...entries].slice(0, MAX_HISTORY); setEntries(next); writeHistory({ entries: next }); onSuccess(); toast.success("Feedback sent"); } catch (error) { toast.error( error instanceof Error ? error.message : "Failed to send feedback", ); } finally { setIsSubmitting(false); } } return { entries, isSubmitting, submit }; } export function FeedbackPopover() { const [open, setOpen] = useState(false); return ( setOpen(false)} /> ); } function FeedbackPopoverContent({ onClose }: { onClose: () => void }) { const { entries, isSubmitting, submit } = useFeedback(); const form = useForm({ defaultValues: { message: "" }, }); async function handleSubmit(values: FeedbackFormValues) { await submit({ values, onSuccess: () => { form.reset({ message: "" }); clearFormDraft({ key: PERSIST_KEY }); onClose(); }, }); } return (
(