diff --git a/apps/edr-freight-web/backoffice/src/App.tsx b/apps/edr-freight-web/backoffice/src/App.tsx
index 92784cd38..f7b26af00 100644
--- a/apps/edr-freight-web/backoffice/src/App.tsx
+++ b/apps/edr-freight-web/backoffice/src/App.tsx
@@ -23,6 +23,7 @@ import {
Users,
Wallet,
} from "lucide-react";
+import { useEffect } from "react";
import {
Navigate,
Outlet,
@@ -135,17 +136,17 @@ const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [
icon: ,
},
{
- label: "User Management",
+ label: "Staff",
href: "/um",
icon: ,
},
{
- label: "Booking requests",
+ label: "Bookings",
href: "/dashboard/booking-requests",
icon: ,
},
{
- label: "Contract requests",
+ label: "Contracts",
href: "/dashboard/contract-requests",
icon: ,
permission: FREIGHT_PERMS.contracts.view,
@@ -174,7 +175,7 @@ const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [
title: "Operations",
items: [
{
- label: "Document Clearance",
+ label: "Clearance",
href: "/dashboard/contracts/clearance",
icon: ,
permission: [
@@ -312,7 +313,7 @@ const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [
title: "Port & Terminal",
items: [
{
- label: "Import Operations",
+ label: "Imports",
href: "/dashboard/import-warehouse",
icon: ,
children: [
@@ -344,7 +345,7 @@ const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [
],
},
{
- label: "Export Operations",
+ label: "Exports",
href: "/dashboard/export-warehouse",
icon: ,
children: [
@@ -516,6 +517,38 @@ const filterSidebarByPermission = (
.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();
@@ -541,6 +574,14 @@ const DashboardShell = () => {
: 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 ;
}