mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 11:33:12 +00:00
Add the Completion Docs page under Data Management: a searchable template table, a read-only detail panel, add and edit with a live document preview, and delete behind a confirmation that counts the open work orders still using the template and links to them. Add, edit and delete are hidden for users whose role lacks the matching template permission. The preview shares the work-order completion document's page frame, header, safety bullets and procedure heading so the two stay identical.
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
import type { LucideIcon } from "lucide-react";
|
|
import {
|
|
// BarChart2,
|
|
BadgeDollarSign,
|
|
BriefcaseBusiness,
|
|
Building2,
|
|
ClipboardList,
|
|
FileText,
|
|
LayoutDashboard,
|
|
MapPin,
|
|
Bell,
|
|
BarChart3,
|
|
Star,
|
|
Users,
|
|
Wrench,
|
|
} from "lucide-react";
|
|
|
|
export type NavItemDef = {
|
|
label: string;
|
|
icon: LucideIcon;
|
|
path: string;
|
|
badge?: number;
|
|
};
|
|
|
|
export type NavGroup = {
|
|
title: string;
|
|
items: NavItemDef[];
|
|
};
|
|
|
|
export const SIDEBAR_WIDTH = 244;
|
|
|
|
export const SIDEBAR_COLLAPSED_WIDTH = 76;
|
|
|
|
export function getSidebarWidth(collapsed: boolean): number {
|
|
return collapsed ? SIDEBAR_COLLAPSED_WIDTH : SIDEBAR_WIDTH;
|
|
}
|
|
|
|
export const navGroups: NavGroup[] = [
|
|
{
|
|
title: "",
|
|
items: [
|
|
{ label: "Work Orders", icon: ClipboardList, path: "/workorders", badge: 11 },
|
|
{ label: "Dashboard", icon: LayoutDashboard, path: "/" },
|
|
{ label: "Notifications", icon: Bell, path: "/notifications" },
|
|
// { label: "Reports", icon: BarChart2, path: "/reports" },
|
|
],
|
|
},
|
|
{
|
|
title: "VENDORS",
|
|
items: [
|
|
{ label: "Vendors", icon: Building2, path: "/vendors" },
|
|
{ label: "Vendor POs", icon: FileText, path: "/vendor-pos" },
|
|
{ label: "Vendor Insights", icon: BarChart3, path: "/vendors/insights" },
|
|
{ label: "Site Preferences", icon: Star, path: "/vendors/preferences" },
|
|
],
|
|
},
|
|
{
|
|
title: "CUSTOMERS & SITES",
|
|
items: [
|
|
{ label: "Accounts", icon: BriefcaseBusiness, path: "/accounts" },
|
|
{ label: "Sites", icon: MapPin, path: "/locations" },
|
|
],
|
|
},
|
|
{
|
|
title: "DATA MANAGEMENT",
|
|
items: [
|
|
{ label: "Services", icon: Wrench, path: "/settings/services" },
|
|
{ label: "Completion Docs", icon: FileText, path: "/completion-docs" },
|
|
],
|
|
},
|
|
{
|
|
title: "TEAM",
|
|
items: [{ label: "Team Members", icon: Users, path: "/team-members" }],
|
|
},
|
|
// {
|
|
// title: "INTERNAL",
|
|
// items: [{ label: "Documents", icon: FileText, path: "/documents" }],
|
|
// },
|
|
];
|
|
|
|
// Approvals navigation is gated on the same server-derived authority the
|
|
// uplift approve/reject API enforces (UpliftService.CanApprove tier roles,
|
|
// exposed via GET uplifts/can-approve), so the sidebar never shows the queue
|
|
// to a user the backend would refuse.
|
|
const approvalsNavGroup: NavGroup = {
|
|
title: "APPROVALS",
|
|
items: [{ label: "Uplift Approvals", icon: BadgeDollarSign, path: "/uplifts" }],
|
|
};
|
|
|
|
export function getNavGroups({ canReviewUplifts }: { canReviewUplifts: boolean }): NavGroup[] {
|
|
return canReviewUplifts ? [...navGroups, approvalsNavGroup] : navGroups;
|
|
}
|
|
|
|
export function getActiveNavPath(pathname: string): string | undefined {
|
|
return [...navGroups, approvalsNavGroup]
|
|
.flatMap((group) => group.items)
|
|
.map((item) => item.path)
|
|
.filter((path) =>
|
|
path === "/" ? pathname === path : pathname === path || pathname.startsWith(`${path}/`),
|
|
)
|
|
.sort((firstPath, secondPath) => secondPath.length - firstPath.length)[0];
|
|
}
|