import { useState } from "react"; import { canViewAllDispatchersOnDashboard } from "@/lib/auth/user-utils"; import { useAuthContext } from "@/providers/auth-context"; import { DEFAULT_DASHBOARD_RANGE, type DashboardRangeKey, } from "@/domain/dashboard/types/dashboard-range"; import { DASHBOARD_SCOPE_ALL, scopeDispatcherId, type DashboardScope } from "./dashboard-scope"; export interface DashboardScopeState { canViewAll: boolean; currentUserId: string | number | undefined; range: DashboardRangeKey; scope: DashboardScope; /** The `dispatcherId` query param for the scoped endpoints (null = company-wide). */ dispatcherId: string | null; workloadPage: number; performancePage: number; showReset: boolean; setWorkloadPage: (page: number) => void; setPerformancePage: (page: number) => void; changeRange: (next: DashboardRangeKey) => void; changeScope: (next: DashboardScope) => void; resetFilters: () => void; } /** * SH-336 dashboard scope/paging state. A Dispatcher (no * `viewAllDispatchersOnDashboard`) is locked to their own work orders and sends * no dispatcherId; Scheduler/Admin drive an explicit scope through the picker. */ export function useDashboardScope(): DashboardScopeState { const { user } = useAuthContext(); const canViewAll = canViewAllDispatchersOnDashboard(user?.userRoles); const [range, setRange] = useState(DEFAULT_DASHBOARD_RANGE); const [scope, setScope] = useState(DASHBOARD_SCOPE_ALL); const [workloadPage, setWorkloadPage] = useState(1); const [performancePage, setPerformancePage] = useState(1); const dispatcherId = canViewAll ? scopeDispatcherId(scope, user?.id) : null; // why: A range or scope change re-scopes both dispatcher tables, so their page must reset — otherwise a // switch while on page 3 lands on an out-of-range empty page that reads as a false "no // dispatchers" state. const resetPages = () => { setWorkloadPage(1); setPerformancePage(1); }; const changeRange = (next: DashboardRangeKey) => { setRange(next); resetPages(); }; const changeScope = (next: DashboardScope) => { setScope(next); resetPages(); }; const resetFilters = () => { setRange(DEFAULT_DASHBOARD_RANGE); setScope(DASHBOARD_SCOPE_ALL); resetPages(); }; // why: A Dispatcher's forced own-WOs scope never triggers the reset affordance (only an active date // range can, for that role); a Scheduler/Admin's non-All scope does. const scopeIsFiltered = canViewAll && scope.mode !== "all"; const showReset = range !== DEFAULT_DASHBOARD_RANGE || scopeIsFiltered; return { canViewAll, currentUserId: user?.id, range, scope, dispatcherId, workloadPage, performancePage, showReset, setWorkloadPage, setPerformancePage, changeRange, changeScope, resetFilters, }; }