"use client"; import { useQuery, useMutation } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; import { Users, Wifi, FileText, DollarSign, Ticket, TrendingUp, Database, RefreshCw, AlertCircle } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card"; import { Button } from "@/components/ui/Button"; import { Badge } from "@/components/ui/Badge"; import { formatCurrency, formatDateTime } from "@/lib/utils"; import { useAuthStore } from "@/lib/auth-store"; import { toast } from "sonner"; import api from "@/lib/api"; import type { DashboardSummary, PaginatedResponse, Ticket as TicketType } from "@/types"; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, } from "recharts"; interface KpiCardProps { title: string; value: string | number; icon: React.ComponentType<{ className?: string }>; color: string; subtitle?: string; href?: string; } function KpiCard({ title, value, icon: Icon, color, subtitle, href }: KpiCardProps) { const router = useRouter(); return ( router.push(href) : undefined} >

{title}

{value}

{subtitle &&

{subtitle}

}
{href &&
}
); } function KpiSkeleton() { return (
); } function ErrorState({ message, onRetry }: { message: string; onRetry: () => void }) { return (

{message}

); } const priorityVariant: Record = { URGENT: "danger", urgent: "danger", HIGH: "warning", high: "warning", NORMAL: "default", normal: "default", MEDIUM: "default", medium: "default", LOW: "muted", low: "muted", }; function buildChartData(stats: DashboardSummary | undefined) { if (!stats) return []; const now = new Date(); const thisMonth = now.toLocaleString("default", { month: "short" }); const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1).toLocaleString("default", { month: "short" }); return [ { month: lastMonth, revenue: stats.revenue.lastMonth }, { month: thisMonth, revenue: stats.revenue.thisMonth }, ]; } export default function DashboardPage() { const router = useRouter(); const user = useAuthStore((s) => s.user); const isAdmin = user?.roles?.some(r => r.toLowerCase() === "admin" || r.toLowerCase() === "super_admin"); const { data: stats, isLoading: statsLoading, isError: statsError, refetch: refetchStats, } = useQuery({ queryKey: ["dashboard-summary"], queryFn: async () => { const res = await api.get("/api/v1/dashboard/summary"); return res.data; }, }); const { data: ticketsData, isLoading: ticketsLoading, refetch: refetchTickets, } = useQuery>({ queryKey: ["recent-tickets"], queryFn: async () => { const res = await api.get>("/api/v1/tickets?page=1&limit=5"); return res.data; }, }); const seedMutation = useMutation({ mutationFn: () => api.post<{ message: string }>("/api/v1/_seed", {}), onSuccess: (res) => { toast.success(res.data?.message || "Demo data seeded!"); refetchStats(); refetchTickets(); }, onError: (err: any) => { toast.error(err?.response?.data?.message || "Seed failed"); }, }); const recentTickets = ticketsData?.data ?? []; const chartData = buildChartData(stats); const hasChartData = chartData.some((d) => d.revenue > 0); return (
{/* Header */}

Dashboard

Overview of your ISP operations

{isAdmin && ( )}
{/* KPI Cards */} {statsLoading ? (
{[1,2,3,4].map(i => )}
) : statsError ? ( ) : (
{isAdmin && ( 0 ? "+" : ""}${stats.revenue.growth.toFixed(1)}% vs last month` : "vs last month"} href="/payments" /> )}
)} {/* Secondary stats */}
router.push("/tickets")}>

Open Tickets

{stats?.support.openTickets ?? 0}

router.push("/tickets")}>

In-Progress Tickets

{stats?.support.inProgressTickets ?? 0}

{/* Revenue Chart — admin only */} {isAdmin && !statsLoading && ( Revenue Overview {hasChartData ? ( `₱${(v/1000).toFixed(0)}k`} /> formatCurrency(Number(v))} /> ) : (

Revenue data will appear once payments are recorded.

)}
)} {/* Recent Tickets */} Recent Tickets {ticketsLoading ? (
{[1,2,3].map(i => (
))}
) : recentTickets.length === 0 ? (
No tickets yet
) : (
{recentTickets.map((ticket) => (
router.push("/tickets")}>

{ticket.subject}

{ticket.client ? `${ticket.client.firstName} ${ticket.client.lastName}` : "No client"} {" • "}{formatDateTime(ticket.createdAt)}

{ticket.priority} {ticket.status}
))}
)}
); }