import { useState, type ReactElement } from "react"; import { AlertCircle } from "lucide-react"; import { Alert, Button, Skeleton, Stack } from "@mantine/core"; import { useQueryClient } from "@tanstack/react-query"; import { useAuth } from "@/auth/useAuth"; import { PageContainer } from "@/components/page"; import { ClearanceOverview } from "@/components/overview/layouts/ClearanceOverview"; import { ExecutiveOverview } from "@/components/overview/layouts/ExecutiveOverview"; import { FinanceOverview } from "@/components/overview/layouts/FinanceOverview"; import { MarketingOverview } from "@/components/overview/layouts/MarketingOverview"; import { OccOverview } from "@/components/overview/layouts/OccOverview"; import { OperationsOverview } from "@/components/overview/layouts/OperationsOverview"; import type { RoleOverviewProps } from "@/components/overview/layouts/layout-kit"; import { OVERVIEW_LAYOUT_LABEL, resolveOverviewLayout, type OverviewLayoutKey, } from "@/components/overview/role-dashboards.config"; import { OverviewHero } from "@/components/overview/summary/OverviewHero"; import { OverviewHeroKpis } from "@/components/overview/summary/OverviewHeroKpis"; import { QUERY_KEYS } from "@/constants/QUERY_KEYS"; import { useOverview } from "@/hooks/useOverview"; import type { OverviewRange } from "@/types/overview"; import "@/components/overview/summary/overview-summary.css"; const RANGE_LABEL: Record = { "7d": "7d", "30d": "30d", "90d": "90d" }; /** Which composition each role sees below the hero. */ const LAYOUTS: Record ReactElement> = { executive: ExecutiveOverview, operations: OperationsOverview, occ: OccOverview, marketing: MarketingOverview, finance: FinanceOverview, clearance: ClearanceOverview, }; function OverviewSkeleton() { return ( ); } const OverviewPage = () => { const [range, setRange] = useState("30d"); const queryClient = useQueryClient(); const { user } = useAuth(); const { data, isLoading, isError, error, refetch, isFetching } = useOverview(range); // Hero, range control and headline KPIs are role-neutral; everything below // them is chosen by role key. const layoutKey = resolveOverviewLayout(user); const RoleLayout = LAYOUTS[layoutKey]; const accessDenied = (error as { response?: { status?: number } } | null)?.response?.status === 403; const handleRefresh = () => { void refetch(); void queryClient.invalidateQueries({ queryKey: QUERY_KEYS.OVERVIEW.ROOT }); }; return ( {/* Gradient greeting hero; the KPI strip overlaps its bottom edge. */}
{data ? (
) : null}
{isError && !accessDenied && ( } color="red" title="Unable to load dashboard summary" variant="light" mt="lg" > Check your connection and try again. )} {accessDenied && ( Your role has no access to the overview. )} {isLoading && !data ? ( ) : data ? ( ) : null}
); }; export default OverviewPage;