All Q1-Q5 answered A: - Topbar removed; LanguageSwitcher + UserMenu move to sidebar footer - Mobile: slide-over overlay with hamburger button - Theme toggle in sidebar footer - No-flash init via inline script in index.html - Role-filtered sidebar items client-side Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2.5 KiB
2.5 KiB
Business Rules — Unit 3: Layout & Navigation
Navigation Visibility Rules (BR-U3-01 – BR-U3-06)
| Route / Item | Owner | Administrator | User | Rule ID |
|---|---|---|---|---|
Dashboard (/dashboard) |
✅ visible | ✅ visible | ✅ visible | BR-U3-01 |
User Management (/users) |
✅ visible | ✅ visible | ❌ hidden | BR-U3-02 |
System Settings (/settings) |
✅ visible | ❌ hidden | ❌ hidden | BR-U3-03 |
CMS Management (/cms) |
✅ visible | ❌ hidden | ❌ hidden | BR-U3-04 |
Profile (/profile) |
✅ visible | ✅ visible | ✅ visible | BR-U3-05 |
| Logout | ✅ visible | ✅ visible | ✅ visible | BR-U3-06 |
Sidebar items are filtered client-side based on user.role from AuthContext. The backend is the authoritative enforcement point; sidebar filtering is defence-in-depth UX only.
Active Route Highlighting (BR-U3-07)
The sidebar highlights the nav item whose to path matches the current route via TanStack Router activeProps. Exact match for leaf routes; prefix match for section roots.
Responsive Behaviour (BR-U3-08)
- ≥ 768px (md): sidebar always visible at fixed width (
w-64), no top bar. - < 768px: sidebar hidden by default. A slim mobile bar (hamburger + app name) is shown. Tapping the hamburger opens the sidebar as a slide-over overlay.
- The overlay closes when: the user taps the backdrop, taps the close button in the sidebar, or navigates to a new route.
Topbar Removal (BR-U3-09)
The Topbar component is removed entirely. No top bar exists on desktop. A slim mobile-only bar replaces it solely for the hamburger button. All functionality previously in the Topbar (LanguageSwitcher, UserMenu) moves to the sidebar footer.
Theme Toggle (BR-U3-10 – BR-U3-13)
| Rule | Description |
|---|---|
| BR-U3-10 | Toggle switches between light and dark class on <html> immediately |
| BR-U3-11 | Chosen theme persisted in localStorage under key cms-theme |
| BR-U3-12 | On app load, persisted preference applied before first React render via inline script in index.html (no flash) |
| BR-U3-13 | If no preference is stored, OS preference (prefers-color-scheme) is used as default |
Only cms-theme is stored in localStorage — no auth data.
Sidebar Footer (BR-U3-14)
The sidebar footer contains three controls in a fixed bottom section:
LanguageSwitcher(moved from Topbar)ThemeToggle(new)UserMenu(moved from Topbar) — shows name, email, logout action