# Business Logic Model — Unit 3: Layout & Navigation ## Component Hierarchy ``` AppLayout ├── Sidebar (desktop: always visible) │ ├── Logo / AppName │ ├── NavList (role-filtered NavItems) │ │ └── NavItem (Link with activeProps) │ └── SidebarFooter │ ├── LanguageSwitcher │ ├── ThemeToggle │ └── UserMenu (name, email, logout) ├── MobileBar (mobile only — hamburger + app name) │ └── opens → SidebarOverlay (Sidebar rendered in overlay) └──
└── ``` ## Theme Initialisation (no flash) Theme is applied in a blocking inline script in `index.html` — before React hydrates — to prevent a flash of the wrong theme: ```html ``` React's `useTheme` hook reads from `localStorage` on mount and keeps the toggle in sync. ## NavItem Filtering Logic ```ts const visibleItems = NAV_ITEMS.filter(item => !item.roles || item.roles.includes(user.role) ); ``` `item.roles` being `undefined` means "visible to everyone". This is evaluated at render time whenever `user.role` changes. ## Mobile Sidebar State Local `useState` in `AppLayout` (or `MobileBar`). The sidebar overlay uses a `` or a Tailwind-animated `translate-x` panel. Closes on: - Backdrop click (`onBackdropClick`) - Close button click - TanStack Router navigation (via `useEffect` watching `location.pathname`) ## Logout Flow (unchanged from Unit 1/2) `UserMenu` in sidebar footer calls `useAuth().logout()` then `navigate({ to: '/login' })`.