"use client"; import { useState } from "react"; import Link from "next/link"; import { toast } from "sonner"; import { ExternalLink } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; type TicketStatus = "open" | "triaged" | "closed"; type Ticket = { id: string; userEmail: string; username: string | null; type: string; title: string; description: string; status: TicketStatus; giteaIssueUrl: string | null; giteaError: string | null; createdAt: string; }; function formatDateTime(iso: string) { return new Date(iso).toLocaleString(undefined, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", }); } const statusVariant: Record = { open: "default", triaged: "secondary", closed: "outline", }; export function AdminSupportManager({ initialTickets }: { initialTickets: Ticket[] }) { const [tickets, setTickets] = useState(initialTickets); const [retrying, setRetrying] = useState(null); async function handleStatusChange(id: string, status: TicketStatus) { try { const res = await fetch(`/api/v1/admin/support/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), }); if (!res.ok) throw new Error(); setTickets((prev) => prev.map((t) => (t.id === id ? { ...t, status } : t))); } catch { toast.error("Failed to update status"); } } async function handleRetryGitea(id: string) { setRetrying(id); try { const res = await fetch(`/api/v1/admin/support/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ retryGitea: true }), }); if (!res.ok) throw new Error(); // Re-fetch the single ticket's fields isn't wired up server-side, so // reload the list to pick up the new giteaIssueUrl/giteaError. const listRes = await fetch("/api/v1/admin/support"); if (listRes.ok) { const data = (await listRes.json()) as Ticket[]; setTickets(data); } toast.success("Retried Gitea issue creation"); } catch { toast.error("Retry failed"); } finally { setRetrying(null); } } if (tickets.length === 0) { return

No support tickets yet.

; } return (
{tickets.map((ticket) => (

{ticket.title}

{ticket.username ? `@${ticket.username}` : ticket.userEmail} · {formatDateTime(ticket.createdAt)}

{ticket.description}

{ticket.type} {ticket.status} {ticket.giteaIssueUrl ? ( View Gitea issue ) : ( <> {ticket.giteaError && ( Gitea issue failed )} )}
))}
); }