"use client"; import { useState } from "react"; import Link from "next/link"; import { useTranslations } from "next-intl"; import { toast } from "sonner"; import { ExternalLink } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; type TicketType = "bug" | "suggestion" | "question"; type TicketStatus = "open" | "triaged" | "closed"; type Ticket = { id: string; type: TicketType; title: string; description: string; status: TicketStatus; giteaIssueUrl: string | null; createdAt: string; }; function formatDate(iso: string) { return new Date(iso).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric", }); } export function SupportManager({ initialTickets }: { initialTickets: Ticket[] }) { const t = useTranslations("support"); const [tickets, setTickets] = useState(initialTickets); const [type, setType] = useState("bug"); const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const [submitting, setSubmitting] = useState(false); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (title.trim().length < 3 || description.trim().length < 10) return; setSubmitting(true); try { const res = await fetch("/api/v1/support", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type, title: title.trim(), description: description.trim() }), }); if (!res.ok) { const data = (await res.json()) as { error?: string }; throw new Error(data.error ?? t("submitFailed")); } const ticket = (await res.json()) as Ticket; setTickets((prev) => [ticket, ...prev]); setTitle(""); setDescription(""); setType("bug"); toast.success(t("submitSuccess")); } catch (err) { toast.error(err instanceof Error ? err.message : t("submitFailed")); } finally { setSubmitting(false); } } const statusVariant: Record = { open: "default", triaged: "secondary", closed: "outline", }; return (
setTitle(e.target.value)} placeholder={t("titlePlaceholder")} maxLength={200} required />