From 0c860d9fe506f447860769d13431d3daffc9a0b9 Mon Sep 17 00:00:00 2001 From: Hyko Date: Wed, 22 Apr 2026 15:51:01 -0400 Subject: [PATCH] feat(admin): replace single page name with dynamic breadcrumb navigation in AdminTop --- src/features/admin/components/AdminTop.js | 66 ++++++++++++++++------- src/features/admin/pages/index.client.js | 4 +- src/features/admin/registry.js | 4 +- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/features/admin/components/AdminTop.js b/src/features/admin/components/AdminTop.js index 095ef27..ee1404a 100644 --- a/src/features/admin/components/AdminTop.js +++ b/src/features/admin/components/AdminTop.js @@ -5,6 +5,7 @@ import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/r import { ChevronDownIcon, User03Icon } from '@zen/core/shared/icons'; import { UserAvatar } from '@zen/core/shared/components'; import { useRouter, usePathname } from 'next/navigation'; +import { getPages } from '../registry.js'; import { useTheme, getThemeIcon } from '@zen/core/themes'; const AdminTop = ({ isMobileMenuOpen, setIsMobileMenuOpen, user, onLogout, appName = 'ZEN', navigationSections = [] }) => { @@ -34,19 +35,34 @@ const AdminTop = ({ isMobileMenuOpen, setIsMobileMenuOpen, user, onLogout, appNa const ThemeIcon = getThemeIcon(theme, systemIsDark); const themeLabel = theme === 'light' ? 'Mode clair' : theme === 'dark' ? 'Mode sombre' : 'Thème système'; - const currentPageName = (() => { - for (const section of navigationSections) { - for (const item of section.items) { - if (pathname === item.href || pathname.startsWith(item.href + '/')) { - return item.name; - } - } - if (section.items.length === 1 && (pathname === section.items[0].href || pathname.startsWith(section.items[0].href + '/'))) { - return section.title; - } + const buildBreadcrumbs = () => { + const crumbs = [{ label: appName, href: '/admin/' }]; + const after = pathname.replace(/^\/admin\/?/, ''); + if (!after) return crumbs; + + const segments = after.split('/').filter(Boolean); + if (!segments.length) return crumbs; + + const [first, second] = segments; + const allItems = navigationSections.flatMap(s => s.items); + const navItem = allItems.find(item => item.href.replace('/admin/', '').split('/')[0] === first); + const hasSubPage = segments.length > 1; + + if (navItem) { + crumbs.push({ label: navItem.name, href: hasSubPage ? navItem.href : undefined }); } - return null; - })(); + + if (second === 'new') { + crumbs.push({ label: 'Nouveau' }); + } else if (second === 'edit') { + const page = getPages().find(p => p.slug === `${first}:edit`); + crumbs.push({ label: page?.breadcrumbLabel || page?.title || 'Modifier' }); + } + + return crumbs; + }; + + const breadcrumbs = buildBreadcrumbs(); const quickLinks = []; @@ -68,13 +84,27 @@ const AdminTop = ({ isMobileMenuOpen, setIsMobileMenuOpen, user, onLogout, appNa {/* Desktop breadcrumb */} - {currentPageName && ( + {breadcrumbs.length > 1 && (
- {appName} - - - - {currentPageName} + {breadcrumbs.map((crumb, i) => ( + + {i > 0 && ( + + + + )} + {crumb.href ? ( + + ) : ( + {crumb.label} + )} + + ))}
)} diff --git a/src/features/admin/pages/index.client.js b/src/features/admin/pages/index.client.js index 9ecc750..5355c80 100644 --- a/src/features/admin/pages/index.client.js +++ b/src/features/admin/pages/index.client.js @@ -15,5 +15,5 @@ registerPage({ slug: 'dashboard', Component: DashboardPage, title: 'Tableau de registerPage({ slug: 'users', Component: UsersPage, title: 'Utilisateurs' }); registerPage({ slug: 'roles', Component: RolesPage, title: 'Rôles' }); registerPage({ slug: 'profile', Component: ProfilePage, title: 'Profil' }); -registerPage({ slug: 'users:edit', Component: UserEditPage, title: 'Modifier utilisateur' }); -registerPage({ slug: 'roles:edit', Component: RoleEditPage, title: 'Modifier rôle' }); +registerPage({ slug: 'users:edit', Component: UserEditPage, title: 'Modifier utilisateur', breadcrumbLabel: 'Modifier' }); +registerPage({ slug: 'roles:edit', Component: RoleEditPage, title: 'Modifier rôle', breadcrumbLabel: 'Modifier' }); diff --git a/src/features/admin/registry.js b/src/features/admin/registry.js index 53ed6f4..8f648bf 100644 --- a/src/features/admin/registry.js +++ b/src/features/admin/registry.js @@ -71,8 +71,8 @@ export function getNavItems() { // ---- Pages ----------------------------------------------------------------- -export function registerPage({ slug, Component, title }) { - pages.set(slug, { slug, Component, title }); +export function registerPage({ slug, Component, title, breadcrumbLabel }) { + pages.set(slug, { slug, Component, title, breadcrumbLabel }); } export function getPage(slug) {