import { Link } from "react-router-dom"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Users, GraduationCap, Building2, UserCog, BarChart3, School, Building, Ticket, BookOpen, DollarSign } from "lucide-react"; import { useQuery } from "@tanstack/react-query"; import { api } from "@/lib/api-client"; import { useStudents, useTeachers } from "@/hooks/queries"; import { useEntities } from "@/hooks/queries/useEntities"; import AiInsightsPanel from "@/components/ai/AiInsightsPanel"; interface PlatformStats { total_students?: number; total_teachers?: number; total_entities?: number; total_courses?: number; active_courses?: number; total_batches?: number; active_batches?: number; total_classrooms?: number; total_tickets?: number; open_tickets?: number; total_exams?: number; total_assignments?: number; total_revenue?: number; total_payments?: number; total_subjects?: number; total_resources?: number; total_exam_sessions?: number; } export default function AdminDashboard() { const { data: stats } = useQuery({ queryKey: ["platform", "stats"], queryFn: async (): Promise => { const res = await api.get<{ data: PlatformStats } | PlatformStats>("/stats"); const wrapped = res as { data?: PlatformStats }; return wrapped.data ?? (res as PlatformStats); }, staleTime: 30_000, }); const { data: studentsData, isLoading: ls } = useStudents({ size: 5 }); const { data: teachersData, isLoading: lt } = useTeachers({ size: 5 }); const { data: entitiesData, isLoading: le } = useEntities({ size: 50 }); const students = studentsData?.items ?? []; const teachers = teachersData?.items ?? []; const entities = entitiesData?.items ?? []; const loading = ls || lt || le; const statCards = [ { label: "Students", count: stats?.total_students ?? 0, icon: GraduationCap, color: "bg-primary/10 text-primary" }, { label: "Teachers", count: stats?.total_teachers ?? 0, icon: UserCog, color: "bg-info/10 text-info" }, { label: "Entities", count: stats?.total_entities ?? 0, icon: Building2, color: "bg-warning/10 text-warning" }, { label: "Active Courses", count: stats?.active_courses ?? 0, icon: BookOpen, color: "bg-success/10 text-success" }, ]; const shortcuts = [ { label: "Exams", count: stats?.total_exams ?? 0, url: "/admin/exams", icon: BarChart3 }, { label: "Classrooms", count: stats?.total_classrooms ?? 0, url: "/admin/classrooms", icon: School }, { label: "Entities", count: stats?.total_entities ?? 0, url: "/admin/entities", icon: Building2 }, { label: "Tickets", count: `${stats?.open_tickets ?? 0} open`, url: "/admin/tickets", icon: Ticket }, ]; if (loading) { return (
); } return (

Platform Dashboard

Overview of platform activity and user statistics.

{statCards.map((s) => (

{s.count.toLocaleString()}

{s.label}

))}
{shortcuts.map((s) => (
{s.label}
{s.count}
))}
{[ { label: "Batches", value: `${stats?.active_batches ?? 0} / ${stats?.total_batches ?? 0}` }, { label: "Subjects", value: stats?.total_subjects ?? 0 }, { label: "Resources", value: stats?.total_resources ?? 0 }, { label: "Revenue", value: `$${(stats?.total_revenue ?? 0).toLocaleString()}` }, ].map(s => (

{s.value}

{s.label}

))}
Recent Students {students.length === 0 &&

No students found.

} {students.map((s) => (
{(s.name || "?").split(" ").map(n => n[0]).join("").slice(0, 2).toUpperCase()}

{s.name}

{s.email || "—"}

{s.status || "active"}
))}
Recent Teachers {teachers.length === 0 &&

No teachers found.

} {teachers.map((t) => (
{(t.name || "?").split(" ").map(n => n[0]).join("").slice(0, 2).toUpperCase()}

{t.name}

{t.email || "—"}

{t.department_name || "—"}
))}
Entities {entities.length === 0 &&

No entities found.

} {entities.map((e) => (

{e.name}

{e.entity_type || e.type || "—"}
))}
Platform Summary {[ { label: "Exam Sessions", value: stats?.total_exam_sessions ?? 0 }, { label: "Assignments", value: stats?.total_assignments ?? 0 }, { label: "Total Tickets", value: stats?.total_tickets ?? 0 }, { label: "Completed Payments", value: stats?.total_payments ?? 0 }, ].map(item => (

{item.label}

{item.value}

))}
); }