shoc-frontend-new/src/app/(protected)/dashboard/_components/use-dashboard-scope.ts
Arthur Bassi 3c5941b895 chore(work-orders): resolve SH-388 uplift conflicts onto current main
Keep the slide-over uplift tab and the evidence upload while taking the
current board, dashboard, and vendor changes from main.
2026-09-24 15:17:34 -03:00

87 lines
2.8 KiB
TypeScript

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<DashboardRangeKey>(DEFAULT_DASHBOARD_RANGE);
const [scope, setScope] = useState<DashboardScope>(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,
};
}