docs(unit-3): Revert to open questions in functional design plan

Functional design documents were written based on self-answered questions
instead of asking the user. Removed pre-written docs and restored the plan
with open questions for the user to answer.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 11:47:33 +02:00
co-authored by Claude Haiku 4.5
parent 31cc45d79b
commit 037332e52f
5 changed files with 59 additions and 332 deletions
@@ -1,152 +0,0 @@
# Frontend Components — Unit 3: Layout & Navigation
## Modified Components
### `AppLayout.tsx` (modify existing)
**Path**: `frontend/src/components/layout/AppLayout.tsx`
Remove `Topbar` import and render. Add `MobileBar`. Layout becomes:
```tsx
<div className="flex min-h-svh">
<Sidebar /> {/* desktop only */}
<MobileBar onMenuOpen={...} /> {/* mobile only */}
<main className="flex-1 p-6" data-testid="app-main">
<Outlet />
</main>
</div>
```
Mobile open/close state lives here (or in `MobileBar`).
---
### `Sidebar.tsx` (modify existing)
**Path**: `frontend/src/components/layout/Sidebar.tsx`
Changes:
- Add `roles?: Role[]` to `NavItem` interface
- Filter `NAV_ITEMS` by `user.role` before rendering
- Add `SidebarFooter` section at bottom with `LanguageSwitcher`, `ThemeToggle`, `UserMenu`
- Accept optional `onClose?: () => void` prop for mobile overlay close button
- `data-testid="app-sidebar"` retained
Nav items:
| Label key | Route | Roles | Icon |
|---|---|---|---|
| `nav.dashboard` | `/dashboard` | all | `LayoutDashboard` |
| `nav.users` | `/users` | Owner, Administrator | `Users` |
| `nav.settings` | `/settings` | Owner | `Settings` |
| `nav.cms` | `/cms` | Owner | `FileText` |
| `nav.profile` | `/profile` | all | `User` |
---
## New Components
### `MobileBar.tsx`
**Path**: `frontend/src/components/layout/MobileBar.tsx`
Slim bar, visible only on `< md`. Contains hamburger button (`Menu` icon) and app name.
```tsx
<header className="flex h-14 items-center gap-3 border-b border-border bg-card px-4 md:hidden"
data-testid="app-mobile-bar">
<button onClick={onMenuOpen} aria-label="Open navigation" data-testid="mobile-menu-button">
<Menu />
</button>
<span className="font-semibold">{t('common.appName')}</span>
</header>
```
Props: `onMenuOpen: () => void`
---
### `SidebarOverlay.tsx`
**Path**: `frontend/src/components/layout/SidebarOverlay.tsx`
Wraps `<Sidebar onClose={...} />` in a backdrop overlay for mobile:
```tsx
<div className="fixed inset-0 z-40 md:hidden">
<div className="absolute inset-0 bg-black/50" onClick={onClose} data-testid="sidebar-backdrop" />
<div className="absolute left-0 top-0 h-full w-64 shadow-xl">
<Sidebar onClose={onClose} />
</div>
</div>
```
Only rendered when mobile menu is open.
---
### `ThemeToggle.tsx`
**Path**: `frontend/src/components/layout/ThemeToggle.tsx`
Button that reads/writes `cms-theme` in localStorage and toggles `dark` class on `<html>`.
```tsx
<button
onClick={toggleTheme}
aria-label={isDark ? t('theme.switchToLight') : t('theme.switchToDark')}
data-testid="theme-toggle"
>
{isDark ? <Sun /> : <Moon />}
</button>
```
Uses `useTheme()` hook (see below).
---
### `useTheme.ts`
**Path**: `frontend/src/hooks/useTheme.ts`
```ts
function useTheme(): { theme: Theme; toggleTheme: () => void }
```
- Reads initial value from `localStorage['cms-theme']` or `prefers-color-scheme`
- On toggle: flips theme, writes to localStorage, applies class to `document.documentElement`
---
## Removed Components
### `Topbar.tsx`
Deleted. Functionality moved to Sidebar footer (`LanguageSwitcher`, `UserMenu`).
`data-testid="app-topbar"` removed from the DOM.
---
## i18n Keys (additions to `translation.json`)
```json
{
"nav": {
"settings": "Instellingen"
},
"theme": {
"switchToLight": "Overschakelen naar licht thema",
"switchToDark": "Overschakelen naar donker thema"
}
}
```
(English equivalents added to `en/translation.json`)
---
## Test IDs Summary
| Element | `data-testid` |
|---|---|
| Sidebar (desktop) | `app-sidebar` |
| Mobile bar | `app-mobile-bar` |
| Hamburger button | `mobile-menu-button` |
| Sidebar backdrop | `sidebar-backdrop` |
| Theme toggle button | `theme-toggle` |
| Nav: dashboard | `nav-dashboard` |
| Nav: users | `nav-users` |
| Nav: settings | `nav-settings` |
| Nav: cms | `nav-cms` |
| Nav: profile | `nav-profile` |
| Main content area | `app-main` |