import { Boxes, Building2, Container, FileSignature, FileText, LayoutDashboard, LayoutGrid, MapPin, Network, Package, PackageCheck, PackageOpen, Paperclip, Receipt, ScrollText, Send, Settings, ShieldCheck, Ship, SlidersHorizontal, Train, Truck, Users, Wallet, } from "lucide-react"; import { useEffect } from "react"; import { Navigate, Outlet, Route, Routes, useLocation, useNavigate, useParams, } from "react-router-dom"; import { FreightDashboardLayout, type SidebarItem, type SidebarSection, } from "@/components/layout"; import { useAuth } from "./auth/useAuth"; import LoadingScreen from "./components/LoadingScreen"; import LoginPage from "./pages/auth/LoginPage"; import BookingContractPage from "./pages/bookings/BookingContractPage"; import BookingRequestDetailPage from "./pages/bookings/BookingRequestDetailPage"; import BookingRequestsPage from "./pages/bookings/BookingRequestsPage"; import NewBookingPage from "./pages/bookings/NewBookingPage"; import ContractRequestsPage from "./pages/contracts/ContractRequestsPage"; import ContractRequestDetailPage from "./pages/contracts/ContractRequestDetailPage"; import ContractViewPage from "./pages/contracts/ContractViewPage"; import ContractClearanceListPage from "./pages/contracts/ContractClearanceListPage"; import ContractClearanceDetailPage from "./pages/contracts/ContractClearanceDetailPage"; import GlDjiboutiClearanceListPage from "./pages/contracts/GlDjiboutiClearanceListPage"; import GlClearanceDetailPage from "./pages/contracts/GlClearanceDetailPage"; import ShipmentRequestsPage from "./pages/contracts/ShipmentRequestsPage"; import ShipmentRequestDetailPage from "./pages/contracts/ShipmentRequestDetailPage"; import GlCreateBookingForm from "./components/contracts/GlCreateBookingForm"; import DocumentClearanceDetailPage from "./pages/bookings/DocumentClearanceDetailPage"; import DocumentClearanceListPage from "./pages/bookings/DocumentClearanceListPage"; import CustomerDetailPage from "./pages/customers/CustomerDetailPage"; import CustomersPage from "./pages/customers/CustomersPage"; import InvoiceDetailPage from "./pages/invoices/InvoiceDetailPage"; import InvoicesPage from "./pages/invoices/InvoicesPage"; import DemoUser1Page from "./pages/dashboard/demo/DemoUser1Page"; import DemoUser2Page from "./pages/dashboard/demo/DemoUser2Page"; import MyProfilePage from "./pages/dashboard/MyProfilePage"; import OverviewPage from "./pages/dashboard/OverviewPage"; import UserManagementHostPage from "./pages/dashboard/user-management/UserManagementHostPage"; import PaymentsPage from "./pages/payments/PaymentsPage"; //import EmployeesPage from "./pages/dashboard/user-management/EmployeesPage"; import { RequirePermission } from "./components/auth/RequirePermission"; import { FREIGHT_PERMS, hasPermission as hasFreightPermission, isDjiboutiGl, isEthiopianGl, isSuperAdmin, } from "./lib/permissions"; import PermissionsPage from "./pages/dashboard/user-management/PermissionsPage"; import PositionTypesPage from "./pages/dashboard/user-management/PositionTypesPage"; import RolesPage from "./pages/dashboard/user-management/RolesPage"; import UserManagementPage from "./pages/dashboard/user-management/UserManagementPage"; import UsersPage from "./pages/dashboard/user-management/UsersPage"; import FileUploadSettingsPage from "./pages/documents/FileUploadSettingsPage"; import DropdownSettingsPage from "./pages/dropdown_settings/DropdownSettingsPage"; import ContractTemplatesPage from "./pages/contract_templates/ContractTemplatesPage"; import ContractTemplateEditorPage from "./pages/contract_templates/ContractTemplateEditorPage"; import FleetResourcePage from "./pages/fleet/FleetResourcePage"; import VehicleDetailPage from "./pages/fleet/VehicleDetailPage"; import DriverDetailPage from "./pages/fleet/DriverDetailPage"; import RoutesPage from "./pages/fleet/RoutesPage"; import FuelPurchasePage from "./pages/fleet/FuelPurchasePage"; import FuelStatsPage from "./pages/fleet/FuelStatsPage"; import { MaintenancePage } from "./pages/fleet/MaintenancePage"; import { FinancialReportsPage } from "./pages/fleet/FinancialReportsPage"; import { FleetDashboard } from "./pages/fleet/FleetDashboard"; import { TrackingPage } from "./pages/fleet/TrackingPage"; import CompliancePage from "./pages/fleet/CompliancePage"; import IncidentsPage from "./pages/fleet/IncidentsPage"; import WorkOrdersPage from "./pages/fleet/WorkOrdersPage"; import ProcurementPage from "./pages/fleet/ProcurementPage"; import { getCategorySidebarChildren } from "./pages/ruleEngine/config/resources"; import RuleEngineLegacyRedirect from "./pages/ruleEngine/RuleEngineLegacyRedirect"; import RuleEngineResourcePage from "./pages/ruleEngine/RuleEngineResourcePage"; import CargoTypesPage from "./pages/ruleEngine/CargoTypesPage"; import TrainScheduleV2ListPage from "./pages/trainScheduling/TrainScheduleV2ListPage"; import BatchBoardPage from "./pages/trainScheduling/BatchBoardPage"; import BatchScheduleDetailPage from "./pages/trainScheduling/BatchScheduleDetailPage"; import TrainScheduleV2DetailPage from "./pages/trainScheduling/TrainScheduleV2DetailPage"; import TrainScheduleTrackPage from "./pages/trainScheduling/TrainScheduleTrackPage"; import TrainSchedulingGlobalRulesPage from "./pages/trainScheduling/TrainSchedulingGlobalRulesPage"; import ContractValidityPeriodsPage from "./pages/configuration/ContractValidityPeriodsPage"; import FirstMilePage from "./pages/operations/FirstMilePage"; import LastMilePage from "./pages/operations/LastMilePage"; import TrainDetailPage from "./pages/trains/TrainDetailPage"; import ArrivalQueuePage from "./pages/warehouses/ArrivalQueuePage"; import DispatchQueuePage from "./pages/warehouses/DispatchQueuePage"; import ExportDjiboutiUnloadingQueuePage from "./pages/warehouses/ExportDjiboutiUnloadingQueuePage"; import ExportWarehouseFlowPage from "./pages/warehouses/ExportWarehouseFlowPage"; import ImportWarehouseFlowPage from "./pages/warehouses/ImportWarehouseFlowPage"; import InterchangeDocumentsPage from "./pages/warehouses/InterchangeDocumentsPage"; import InventoryInquiryPage from "./pages/warehouses/InventoryInquiryPage"; import LoadedInventoryPage from "./pages/warehouses/LoadedInventoryPage"; import LoadingQueuePage from "./pages/warehouses/LoadingQueuePage"; import WarehouseDashboardPage from "./pages/warehouses/WarehouseDashboardPage"; import WarehouseDetailPage from "./pages/warehouses/WarehouseDetailPage"; import WarehouseInventoryPage from "./pages/warehouses/WarehouseInventoryPage"; import WarehouseInvoicesPage from "./pages/warehouses/WarehouseInvoicesPage"; import WarehouseListPage from "./pages/warehouses/WarehouseListPage"; import WarehouseRulesPage from "./pages/warehouses/WarehouseRulesPage"; import { HealthCheck } from "./features/health/HealthCheck"; import FaydaCallbackPage from "./pages/FaydaCallbackPage"; const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [ { title: "Main menu", items: [ { label: "Overview", href: "/dashboard/overview", icon: , }, { label: "Staff", href: "/um", icon: , }, { label: "Bookings", href: "/dashboard/booking-requests", icon: , }, { label: "Contracts", href: "/dashboard/contract-requests", icon: , permission: FREIGHT_PERMS.contracts.view, }, { label: "Customers", href: "/dashboard/customers", icon: , }, { label: "Payments", href: "/dashboard/payments", icon: , permission: FREIGHT_PERMS.bookings.view, }, { label: "Invoices", href: "/dashboard/invoices", icon: , permission: FREIGHT_PERMS.bookings.view, }, ...demoItems, ], }, { title: "Operations", items: [ { label: "Clearance", href: "/dashboard/contracts/clearance", icon: , permission: [ FREIGHT_PERMS.contracts.clearanceReview, FREIGHT_PERMS.contracts.clearanceEtActions, ], }, { label: "Shipment Requests", href: "/dashboard/shipment-requests", icon: , permission: FREIGHT_PERMS.contracts.createBooking, }, { label: "Self-Clearance Review", href: "/dashboard/contracts/ops-clearance", icon: , permission: FREIGHT_PERMS.contracts.opsClearanceReview, }, { label: "GL Djibouti Clearance", href: "/dashboard/gl-djibouti/clearance", icon: , permission: FREIGHT_PERMS.contracts.clearanceDjActions, }, { label: "Train Schedules", href: "/dashboard/operations/train-scheduling-v2", icon: , permission: FREIGHT_PERMS.trainScheduling.view, }, { label: "Batch Board", href: "/dashboard/operations/batch-board", icon: , permission: FREIGHT_PERMS.trainScheduling.view, }, { label: "First Mile", href: "/dashboard/operations/first-mile", icon: , permission: FREIGHT_PERMS.firstMile.view, }, { label: "Last Mile", href: "/dashboard/operations/last-mile", icon: , permission: FREIGHT_PERMS.lastMile.view, }, ], }, { title: "Fleet Management", items: [ { label: "Fleet Dashboard", href: "/dashboard/fleet-dashboard", icon: , permission: FREIGHT_PERMS.fleetDashboard.view, }, { label: "Routes", href: "/dashboard/routes", icon: , permission: FREIGHT_PERMS.fleet.view, }, { label: "Locomotives", href: "/dashboard/locomotives", icon: , permission: FREIGHT_PERMS.fleet.view, }, // { // label: "Wagon types", // href: "/dashboard/wagon-types", // icon: , // }, { label: "Wagons", href: "/dashboard/wagons", icon: , permission: FREIGHT_PERMS.fleet.view, }, { label: "Vehicles", href: "/dashboard/vehicles", icon: , permission: FREIGHT_PERMS.vehicles.view, }, { label: "Drivers", href: "/dashboard/drivers", icon: , permission: FREIGHT_PERMS.drivers.view, }, { label: "Track Vehicles", href: "/dashboard/tracking", icon: , permission: FREIGHT_PERMS.tracking.view, }, { label: "Fuel Purchases", href: "/dashboard/fuel-purchases", icon: , permission: FREIGHT_PERMS.fuel.view, }, { label: "Fuel Analytics", href: "/dashboard/fuel-stats", icon: , permission: FREIGHT_PERMS.fuel.view, }, { label: "Maintenance", href: "/dashboard/maintenance", icon: , permission: FREIGHT_PERMS.maintenance.view, }, { label: "Work Orders", href: "/dashboard/work-orders", icon: , permission: FREIGHT_PERMS.maintenance.view, }, { label: "Compliance & Alerts", href: "/dashboard/compliance", icon: , permission: FREIGHT_PERMS.fleet.view, }, { label: "Incidents", href: "/dashboard/incidents", icon: , permission: FREIGHT_PERMS.fleet.view, }, { label: "Procurement", href: "/dashboard/procurement", icon: , permission: FREIGHT_PERMS.fleet.view, }, { label: "Financial Reports", href: "/dashboard/financial-reports", icon: , permission: FREIGHT_PERMS.fleetReports.view, }, // { // label: "Containers", // href: "/dashboard/containers", // icon: , // }, // { // label: "Cargoes", // href: "/dashboard/cargoes", // icon: , // }, ], }, { title: "Port & Terminal", items: [ { label: "Imports", href: "/dashboard/import-warehouse", icon: , children: [ { label: "Import Overview", href: "/dashboard/import-warehouse", icon: , }, { label: "Arrival Queue", href: "/dashboard/arrival-queue", icon: , }, { label: "Dispatch Queue", href: "/dashboard/dispatch-queue", icon: , }, { label: "Terminal Inventory", href: "/dashboard/warehouse-inventory?direction=IMPORT", icon: , }, { label: "Inventory Inquiry", href: "/dashboard/inventory-inquiry", icon: , }, ], }, { label: "Exports", href: "/dashboard/export-warehouse", icon: , children: [ { label: "Export Overview", href: "/dashboard/export-warehouse", icon: , }, { label: "Loading Queue", href: "/dashboard/loading-queue", icon: , }, { label: "Loaded Inventory", href: "/dashboard/loaded-inventory", icon: , }, { label: "Dispatch Queue", href: "/dashboard/dispatch-queue", icon: , }, { label: "Djibouti Unloading", href: "/dashboard/export-djibouti-unloading", icon: , }, { label: "Interchange Documents", href: "/dashboard/interchange-documents", icon: , }, { label: "Terminal Inventory", href: "/dashboard/warehouse-inventory?direction=EXPORT", icon: , }, ], }, ], }, { title: "Warehouse Management", items: [ { label: "Warehouse Dashboard", href: "/dashboard/warehouse-dashboard", icon: , }, { label: "Warehouses", href: "/dashboard/warehouses", icon: , }, { label: "Allocation & Fees", href: "/dashboard/warehouse-rules", icon: , }, { label: "Fee Invoices", href: "/dashboard/warehouse-fee-invoices", icon: , }, ], }, { title: "Administration", items: [ { label: "File settings", href: "/dashboard/file-settings", icon: , permission: FREIGHT_PERMS.admin, }, { label: "Dropdown settings", href: "/dashboard/dropdown-settings", icon: , permission: FREIGHT_PERMS.admin, }, { label: "Contract templates", href: "/dashboard/contract-templates", icon: , permission: FREIGHT_PERMS.admin, }, ], }, { title: "Freight configuration", mutedTitle: true, items: [ { label: "Configuration", href: "/dashboard/configuration", icon: , children: [ ...getCategorySidebarChildren("configuration"), { label: "Contract validity", href: "/dashboard/configuration/contract-validity-periods", }, { label: "Train scheduling rules", href: "/dashboard/configuration/train-scheduling-rules", }, ], }, { label: "Rules", href: "/dashboard/rules", icon: , children: getCategorySidebarChildren("rules"), }, ], }, ]; /** Hrefs of the two document-clearance menu items (stable identifiers). */ const ET_CLEARANCE_HREF = "/dashboard/contracts/clearance"; const DJ_CLEARANCE_HREF = "/dashboard/gl-djibouti/clearance"; const isEtClearanceItem = (item: SidebarItem): boolean => item.href === ET_CLEARANCE_HREF; const isDjClearanceItem = (item: SidebarItem): boolean => item.href === DJ_CLEARANCE_HREF; const isClearanceItem = (item: SidebarItem): boolean => isEtClearanceItem(item) || isDjClearanceItem(item); /** * Keep only items the user is permitted to see; drop now-empty sections. * * Position-scoped visibility (super_admin sees everything): * - Super Admin → sees all items (all permissions pass, all tabs visible) * - Ethiopian GL → sees ONLY the ET document-clearance page. * - Djibouti GL → sees ONLY the DJ clearance page. * - Everyone else → sees everything they have permission for, EXCEPT the two * clearance pages (those are GL-only). */ const filterSidebarByPermission = ( sections: SidebarSection[], user: ReturnType["user"], ): SidebarSection[] => { // Superadmin sees every section and item — no permission filtering. if (isSuperAdmin(user)) return sections; const etGl = isEthiopianGl(user); const djGl = isDjiboutiGl(user); const permissionAllowed = (item: SidebarItem): boolean => { if (!item.permission) return true; const keys = Array.isArray(item.permission) ? item.permission : [item.permission]; return keys.some((key) => hasFreightPermission(user, key)); }; const itemAllowed = (item: SidebarItem): boolean => { // GL positions are locked to their single clearance page. if (etGl) return isEtClearanceItem(item); if (djGl) return isDjClearanceItem(item); // Everyone else: hide the GL-only clearance pages entirely. if (isClearanceItem(item)) return false; return permissionAllowed(item); }; return sections .map((section) => ({ ...section, items: section.items.filter(itemAllowed), })) .filter((section) => section.items.length > 0); }; const APP_TITLE = "EDR Freight Backoffice"; /** Flatten sidebar sections (incl. nested children) into {href, label} pairs. */ const flattenSidebarItems = ( sections: SidebarSection[], ): { href: string; label: string }[] => sections.flatMap((section) => section.items.flatMap((item) => [ ...(item.href ? [{ href: item.href, label: item.label }] : []), ...(item.children ?? []) .filter((child): child is SidebarItem & { href: string } => Boolean(child.href), ) .map((child) => ({ href: child.href, label: child.label })), ]), ); /** Find the sidebar label whose href matches (exactly or as a prefix of) the current path. */ const findActiveSidebarLabel = ( pathname: string, sections: SidebarSection[], ): string | undefined => { const path = pathname.toLowerCase(); const candidates = flattenSidebarItems(sections) .map(({ href, label }) => ({ label, href: href.split("?")[0].toLowerCase() })) .sort((a, b) => b.href.length - a.href.length); return candidates.find( ({ href }) => path === href || path.startsWith(`${href}/`), )?.label; }; const DashboardShell = () => { const navigate = useNavigate(); const location = useLocation(); const { user, logout } = useAuth(); const demoItems: SidebarItem[] = []; const sidebarSections = filterSidebarByPermission( buildSidebarSections(demoItems), user, ); const displayName = user?.name?.en || user?.username || user?.email || "User"; // GL positions are locked to their single clearance page: if they navigate // (or deep-link) anywhere else, send them back to their clearance hub. // Super admin is exempt. Allow the clearance path + its detail sub-routes. const superAdmin = isSuperAdmin(user); const glClearanceHome = !superAdmin ? isEthiopianGl(user) ? ET_CLEARANCE_HREF : isDjiboutiGl(user) ? DJ_CLEARANCE_HREF : null : null; useEffect(() => { const activeLabel = findActiveSidebarLabel( location.pathname, sidebarSections, ); document.title = activeLabel ? `${activeLabel} | ${APP_TITLE}` : APP_TITLE; }, [location.pathname, sidebarSections]); if (glClearanceHome && !location.pathname.startsWith(glClearanceHome)) { return ; } return ( ); }; const App = () => { const { user, loading } = useAuth(); if (loading) { return ; } if (!user) { return ( } /> } /> } /> } /> ); } return ( } /> } /> } /> } /> } /> }> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Legacy booking-based clearance URLs → the contract clearance hub. */} } /> } /> {/* Contracts (Path A/B) */} } /> } /> } /> } /> } /> } /> {/* GL (Path B) contract clearance review hub */} } /> } /> } /> } /> } /> } /> {/* Path A — Operations reviews per-booking self-clearance documents (GENERAL contracts without customs). */} } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Legacy embedded user management routes */} } /> } /> } /> {/* } /> */} } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); }; /** Redirect removed milestones page to document clearance. */ function BookingMilestonesRedirect() { const { id } = useParams(); return ; } /** Redirect legacy GL Ethiopia clearance URLs to the unified document clearance hub. */ function LegacyGlEthiopiaClearanceRedirect() { const { id } = useParams(); if (id) { return ; } return ; } export default App;