"use client"; import { useEffect, useMemo, useState } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import { apiFetch, ApiError } from "@/lib/api"; import { useTransactionFeed } from "@/lib/pollingFeed"; import { AuthUser, Branch, DashboardSummary, ReconciliationRow, StockLevel } from "@/lib/types"; import { useToast } from "@/components/ui/Toast"; import { SkeletonCardGrid, SkeletonTable } from "@/components/ui/Skeleton"; import EmptyState from "@/components/ui/EmptyState"; import GlobalSwitcher from "@/components/admin/GlobalSwitcher"; import FinancialOverviewCards from "@/components/admin/FinancialOverviewCards"; import PaymentSplitDonut from "@/components/admin/PaymentSplitDonut"; import LiveStatsRow from "@/components/admin/LiveStatsRow"; import BranchRankingList from "@/components/admin/BranchRankingList"; import ActivityFeedMatrix from "@/components/admin/ActivityFeedMatrix"; import ReconciliationGrid from "@/components/admin/ReconciliationGrid"; import StockSummaryCard from "@/components/admin/StockSummaryCard"; export default function AdminDashboardPage() { const router = useRouter(); const { show } = useToast(); const [me, setMe] = useState(null); const [authChecked, setAuthChecked] = useState(false); const [branches, setBranches] = useState([]); const [branchesLoaded, setBranchesLoaded] = useState(false); const [selectedBranchId, setSelectedBranchId] = useState("ALL"); const [summary, setSummary] = useState(null); const [reconciliation, setReconciliation] = useState([]); const [stock, setStock] = useState([]); const [loading, setLoading] = useState(true); const { events: feedTransactions, connected } = useTransactionFeed(selectedBranchId, 50); useEffect(() => { (async () => { try { const result = await apiFetch<{ user: AuthUser }>("/api/auth/me"); if (result.user.role === "DELIVERY") { router.replace("/terminal"); return; } setMe(result.user); if (result.user.role !== "SUPER_ADMIN" && result.user.branchId) { setSelectedBranchId(result.user.branchId); } } catch { router.replace("/login"); return; } setAuthChecked(true); })(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { if (!authChecked) return; (async () => { try { const result = await apiFetch<{ branches: Branch[] }>("/api/branches"); setBranches(result.branches); } catch { // handled by the empty-branches nudge below on a best-effort basis } setBranchesLoaded(true); })(); }, [authChecked]); useEffect(() => { if (!authChecked) return; loadDashboardData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [authChecked, selectedBranchId]); async function loadDashboardData() { setLoading(true); try { const branchParam = selectedBranchId === "ALL" ? "" : "?branchId=" + selectedBranchId; const [summaryRes, reconRes, stockRes] = await Promise.all([ apiFetch("/api/dashboard/summary" + branchParam), apiFetch<{ rows: ReconciliationRow[] }>("/api/dashboard/reconciliation" + branchParam), apiFetch<{ levels: StockLevel[] }>("/api/stock" + branchParam), ]); setSummary(summaryRes); setReconciliation(reconRes.rows); setStock(stockRes.levels); } catch (err) { show(err instanceof ApiError ? err.message : "Could not load dashboard data", "error"); } setLoading(false); } const branchNames = useMemo(() => { const map: Record = {}; branches.forEach((b) => (map[b._id] = b.branchName)); return map; }, [branches]); if (!authChecked || !me) { return (
); } const scope: "global" | "branch" = selectedBranchId === "ALL" ? "global" : "branch"; const showNoBranchesNudge = me.role === "SUPER_ADMIN" && branchesLoaded && branches.length === 0; return (

{me.businessName ?? "Vessel"}

{me.role === "SUPER_ADMIN" ? "Global Control Center" : me.branchName ? `${me.branchName} Dashboard` : "Branch Dashboard"}

{me.isPlatformAdmin && ( Platform )} Stock Products Staff Purchases Expenses Reports
{showNoBranchesNudge && (
)} {loading || !summary ? ( <> ) : ( <>
{scope === "global" && }
)}
); }