import { AlertCircle, CheckCircle2, Clock, Loader2, Ticket, } from "lucide-react"; import Link from "next/link"; import { redirect } from "next/navigation"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; import { prisma } from "@/lib/prisma"; const STATUS_CONFIG = { open: { label: "Open", icon: AlertCircle, class: "bg-[var(--admin-info-subtle)] text-[var(--admin-info)]", }, in_progress: { label: "In Progress", icon: Loader2, class: "bg-[var(--admin-warning-subtle)] text-[var(--admin-warning)]", }, waiting: { label: "Waiting", icon: Clock, class: "bg-[var(--admin-warning-subtle)] text-[var(--admin-warning)]", }, closed: { label: "Closed", icon: CheckCircle2, class: "bg-muted text-muted-foreground", }, } as const; const PRIORITY_COLORS = { low: "", normal: "text-[var(--admin-info)]", high: "text-[var(--admin-warning)]", urgent: "text-[var(--admin-error)] font-bold", }; interface PageProps { searchParams: Promise<{ status?: string; page?: string }>; } export default async function AdminTicketsPage({ searchParams }: PageProps) { const { session, permissions } = await getAdminContext(); if (!canAccess(permissions, PERMS.TICKETS_VIEW, session.user.rank)) { redirect("/admin"); } const sp = await searchParams; const statusFilter = sp.status || "active"; const page = Math.max(1, Number(sp.page) || 1); const perPage = 20; const where = statusFilter === "active" ? { status: { not: "closed" } } : statusFilter === "all" ? {} : { status: statusFilter }; const [tickets, total, stats] = await Promise.all([ prisma.websiteTicket.findMany({ where, orderBy: [{ createdAt: "desc" }], skip: (page - 1) * perPage, take: perPage, include: { creator: { select: { id: true, username: true } }, assignee: { select: { id: true, username: true } }, _count: { select: { messages: true } }, }, }), prisma.websiteTicket.count({ where }), Promise.all([ prisma.websiteTicket.count({ where: { status: "open" } }), prisma.websiteTicket.count({ where: { status: "in_progress" } }), prisma.websiteTicket.count({ where: { status: "waiting" } }), prisma.websiteTicket.count({ where: { status: "closed" } }), ]), ]); const [openCount, inProgressCount, waitingCount, closedCount] = stats; const totalPages = Math.ceil(total / perPage); return (
Manage user support requests