"use client"; import { useEffect, useMemo } from "react"; import { useTranslations } from "next-intl"; import { useQuery } from "@tanstack/react-query"; import { PageShell } from "@/components/layout/page-shell"; import { PageDashboardSkeleton } from "@/components/layout/page-loading"; import { StatCard, StatCardGrid } from "@/components/layout/stat-card"; import { StatusBadge } from "@/components/shared/status-badge"; import { ChartCard, CategoryPieChart, DepartmentSpendChart, MembersByPackageChart, SpendTrendChart, } from "@/components/charts/portal-charts"; import { useAuth } from "@/providers/auth-provider"; import { mockApi } from "@/lib/api/mock-client"; import { formatEtb } from "@/lib/format"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { ROLE_META } from "@/lib/auth/session"; import { Link, useRouter } from "@/i18n/routing"; import { Building2, Package, Users, Wallet } from "lucide-react"; export default function DashboardPage() { const t = useTranslations(); const { user } = useAuth(); const router = useRouter(); const orgQ = useQuery({ queryKey: ["org"], queryFn: mockApi.getOrganisation }); const membersQ = useQuery({ queryKey: ["members", user?.activeRole], queryFn: () => mockApi.getMembers(user!.activeRole), enabled: !!user && user.activeRole !== "MEMBER", }); const approvalsQ = useQuery({ queryKey: ["approvals"], queryFn: mockApi.getApprovals, enabled: !!user && user.activeRole !== "MEMBER", }); const deptsQ = useQuery({ queryKey: ["departments"], queryFn: mockApi.getDepartments, enabled: !!user && user.activeRole !== "MEMBER", }); const statementsQ = useQuery({ queryKey: ["statements"], queryFn: mockApi.getStatements, enabled: !!user && user.activeRole !== "MEMBER", }); const spendQ = useQuery({ queryKey: ["spend"], queryFn: mockApi.getSpend, enabled: !!user && user.activeRole !== "MEMBER", }); const packagesQ = useQuery({ queryKey: ["packages"], queryFn: mockApi.getPackages, enabled: !!user && user.activeRole !== "MEMBER", }); useEffect(() => { if (user?.activeRole === "MEMBER") router.replace("/me"); }, [user, router]); const trendData = useMemo( () => (statementsQ.data ?? []) .slice() .sort((a, b) => a.period.localeCompare(b.period)) .map((s) => ({ period: s.period.slice(5), covered: s.coveredEtb, total: s.totalSpendEtb, })), [statementsQ.data], ); const deptChart = useMemo( () => (deptsQ.data ?? []).map((d) => ({ name: d.name.split(" ")[0] ?? d.name, spend: d.spendEtb, limit: d.subLimitEtb ?? 0, })), [deptsQ.data], ); const categoryChart = useMemo(() => { const map = new Map(); for (const row of spendQ.data ?? []) { map.set(row.category, (map.get(row.category) ?? 0) + row.coveredEtb); } return Array.from(map.entries()).map(([name, value]) => ({ name, value })); }, [spendQ.data]); const packageChart = useMemo( () => (packagesQ.data ?? []).map((p) => ({ name: p.name, members: p.memberCount, })), [packagesQ.data], ); if (!user || user.activeRole === "MEMBER") return null; const dashLoading = orgQ.isLoading || membersQ.isLoading || approvalsQ.isLoading || deptsQ.isLoading || statementsQ.isLoading || spendQ.isLoading || packagesQ.isLoading; const activeMembers = membersQ.data?.filter((m) => m.status === "active").length ?? 0; const pendingApprovals = approvalsQ.data?.filter((a) => a.status === "pending").length ?? 0; const creditUsed = orgQ.data?.creditUsedEtb ?? 0; const creditLimit = orgQ.data?.creditLimitEtb ?? 0; const creditPct = creditLimit > 0 ? Math.round((creditUsed / creditLimit) * 100) : 0; return ( {dashLoading ? ( ) : ( <> } /> } /> } /> } />
{t("dashboard.orgStatus")} {orgQ.data ? : null}

{orgQ.data?.tradeName}

{user.name} · {t(ROLE_META[user.activeRole].labelKey)}

{t("dashboard.guidance")}

{t("dashboard.guidanceHr")}

{t("dashboard.guidanceFinance")}

{t("dashboard.guidanceSuper")}

)}
); }