"use client" import { createContext, useContext, useState, useEffect } from "react" import { usePathname } from "next/navigation" import { useAgentOptional } from "@/components/agent/chat-provider" import { MessageCircle } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Textarea } from "@/components/ui/textarea" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" const FeedbackContext = createContext<{ open: () => void }>({ open: () => {} }) export function useFeedback() { return useContext(FeedbackContext) } export function openFeedbackDialog() { window.dispatchEvent(new CustomEvent("open-feedback-dialog")) } export function FeedbackCallout() { const { open } = useFeedback() return (

Have feedback?{" "} {" "}— we'd love to hear from you.

) } export function FeedbackWidget({ children }: { children?: React.ReactNode }) { const [dialogOpen, setDialogOpen] = useState(false) const [submitting, setSubmitting] = useState(false) const [type, setType] = useState("") const [message, setMessage] = useState("") const [name, setName] = useState("") const [email, setEmail] = useState("") const pathname = usePathname() const agentContext = useAgentOptional() const chatOpen = agentContext?.isOpen ?? false function resetForm() { setType("") setMessage("") setName("") setEmail("") } async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!type || !message.trim()) return setSubmitting(true) try { const res = await fetch("/api/feedback", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type, message, name: name || undefined, email: email || undefined, pageUrl: pathname, userAgent: navigator.userAgent, viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, }), }) if (res.ok) { toast.success("Feedback submitted, thank you!") resetForm() setDialogOpen(false) } else { const data = await res.json() as { error?: string } toast.error(data.error || "Something went wrong") } } catch { toast.error("Failed to submit feedback") } finally { setSubmitting(false) } } useEffect(() => { const handleOpenFeedback = () => setDialogOpen(true) window.addEventListener("open-feedback-dialog", handleOpenFeedback) return () => window.removeEventListener("open-feedback-dialog", handleOpenFeedback) }, []) return ( setDialogOpen(true) }}> {children} Send Feedback Report a bug, request a feature, or ask a question. Feedback is sent directly to developers for review.