43 lines
2.4 KiB
TypeScript
43 lines
2.4 KiB
TypeScript
|
|
import type { UserAccess } from "./auth-policy";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* What each access level may reach inside the Plant Clock app (/clock and /api/clock).
|
||
|
|
*
|
||
|
|
* full everything in the main app, and Employees / Fuel / Job cards in the clock app (not Slips)
|
||
|
|
* clock clock-in user: Employees, Fuel, Job cards
|
||
|
|
* mechanic Fuel and Job cards only — no clock in/out
|
||
|
|
* office Slips only (photo of a cash-card slip) — and ONLY office sees Slips
|
||
|
|
*
|
||
|
|
* Pure and dependency-free so the proxy, the bottom nav and the tests share one rule.
|
||
|
|
*/
|
||
|
|
export type ClockTab = { href: string; label: string };
|
||
|
|
|
||
|
|
export const CLOCK_TABS: Record<UserAccess, ClockTab[]> = {
|
||
|
|
full: [{ href: "/clock", label: "Employees" }, { href: "/clock/stock", label: "Fuel" }, { href: "/clock/job-cards", label: "Job cards" }],
|
||
|
|
clock: [{ href: "/clock", label: "Employees" }, { href: "/clock/stock", label: "Fuel" }, { href: "/clock/job-cards", label: "Job cards" }],
|
||
|
|
mechanic: [{ href: "/clock/stock", label: "Fuel" }, { href: "/clock/job-cards", label: "Job cards" }],
|
||
|
|
office: [{ href: "/clock/slips", label: "Slips" }],
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Where a user lands when they open the clock app. */
|
||
|
|
export const clockHome = (access: UserAccess): string => (access === "mechanic" ? "/clock/job-cards" : access === "office" ? "/clock/slips" : "/clock");
|
||
|
|
|
||
|
|
const under = (path: string, base: string) => path === base || path.startsWith(`${base}/`);
|
||
|
|
|
||
|
|
// Pages and APIs a restricted role may use, besides the sign-in / password screens.
|
||
|
|
const ALLOWED: Partial<Record<UserAccess, string[]>> = {
|
||
|
|
mechanic: ["/clock/stock", "/clock/job-cards", "/api/clock/stock-out", "/api/clock/oil-out", "/api/clock/job-start", "/api/clock/job-finish"],
|
||
|
|
office: ["/clock/slips", "/api/clock/slip", "/api/clock/cash-float"],
|
||
|
|
};
|
||
|
|
// The slip scanner belongs to the Office role alone. (The cash-float opening-balance call is also
|
||
|
|
// open to full users, because the main Cash Floats page makes it.)
|
||
|
|
const SLIPS = ["/clock/slips", "/api/clock/slip"];
|
||
|
|
const ALWAYS = ["/clock/login", "/clock/change-password"];
|
||
|
|
|
||
|
|
export function clockPathAllowed(access: UserAccess, path: string): boolean {
|
||
|
|
if (ALWAYS.some((p) => under(path, p))) return true;
|
||
|
|
if (access === "full") return !SLIPS.some((p) => under(path, p));
|
||
|
|
if (access === "clock") return ![...SLIPS, "/api/clock/cash-float"].some((p) => under(path, p));
|
||
|
|
return (ALLOWED[access] ?? []).some((p) => under(path, p));
|
||
|
|
}
|