docs(01-02): complete Portal Shell plan with SUMMARY, state updates
- SUMMARY.md documenting design tokens, i18n, layout components - STATE.md advanced to plan 2/3, decisions recorded - ROADMAP.md updated to 2/3 plans complete - REQUIREMENTS.md: PRTAL-01, PRTAL-04, UI-01, UI-02, UI-03 marked complete
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
---
|
||||
phase: 01-foundation-portal-shell
|
||||
plan: 02
|
||||
subsystem: ui
|
||||
tags: [next-intl, next-themes, zustand, tailwindcss, oklch, i18n, theming, responsive-layout, portal-shell]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 01-01
|
||||
provides: "Monorepo scaffold, Next.js app, Tailwind CSS v4, build tooling"
|
||||
provides:
|
||||
- OKLCH design token system with yellow #ffed00 primary and dark gray-blue dark mode
|
||||
- i18n framework with DE/EN translations via next-intl cookie-based locale
|
||||
- Theme switching (light/dark/system) via next-themes with persistence
|
||||
- Sticky header with logo, breadcrumb, theme toggle, locale switcher, user avatar placeholder
|
||||
- Collapsible sidebar (240px to 64px) with Dashboard/Marketplace nav and accordion categories
|
||||
- Mobile responsive layout with hamburger menu and overlay sidebar
|
||||
- Empty dashboard state with "Keine Widgets aktiv" placeholder and add widget button
|
||||
- AppShell layout composition component for all future pages
|
||||
- Zustand sidebar store with localStorage persistence
|
||||
affects: [01-03-portal-shell, phase-2-auth, phase-3-modules, phase-4-marketplace, phase-5-dashboard]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: [next-intl@4.13, next-themes@0.4.6, zustand@5.0.14]
|
||||
patterns: [design-tokens-oklch, cookie-based-locale, zustand-persist-store, provider-wrapped-layout, responsive-sidebar-overlay]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- apps/web/src/app/globals.css
|
||||
- apps/web/src/i18n/request.ts
|
||||
- apps/web/src/messages/de.json
|
||||
- apps/web/src/messages/en.json
|
||||
- apps/web/src/lib/stores/sidebar-store.ts
|
||||
- apps/web/src/components/layout/app-shell.tsx
|
||||
- apps/web/src/components/layout/header.tsx
|
||||
- apps/web/src/components/layout/sidebar.tsx
|
||||
- apps/web/src/components/layout/sidebar-footer.tsx
|
||||
- apps/web/src/components/theme-toggle.tsx
|
||||
- apps/web/src/components/locale-switcher.tsx
|
||||
modified:
|
||||
- apps/web/package.json
|
||||
- apps/web/next.config.ts
|
||||
- apps/web/src/app/layout.tsx
|
||||
- apps/web/src/app/page.tsx
|
||||
|
||||
key-decisions:
|
||||
- "Used OKLCH color space for all design tokens per Tailwind v4 best practice"
|
||||
- "Dark mode uses oklch(0.17 0.01 260) dark gray-blue for comfortable contrast with yellow primary"
|
||||
- "Cookie-based locale (NEXT_LOCALE) instead of URL routing since portal is a logged-in app"
|
||||
- "Zustand with persist middleware for sidebar state to survive page refreshes"
|
||||
- "CSS custom property --current-sidebar-width for responsive main content margin"
|
||||
- "Added Inter font-family as --font-sans variable for clean modern style"
|
||||
|
||||
patterns-established:
|
||||
- "Design tokens: All colors as CSS custom properties at :root, theme variants via .dark selector"
|
||||
- "i18n: Every user-visible string through useTranslations() hook, German as default locale"
|
||||
- "State management: Zustand stores in src/lib/stores/ with persist middleware"
|
||||
- "Layout composition: AppShell wraps Header + Sidebar + main content area"
|
||||
- "Component organization: layout/ for structural components, root for reusable UI"
|
||||
- "Responsive: md breakpoint (768px) separates mobile overlay from desktop sidebar"
|
||||
|
||||
requirements-completed: [PRTAL-01, PRTAL-04, UI-01, UI-02, UI-03]
|
||||
|
||||
# Metrics
|
||||
duration: 7min
|
||||
completed: 2026-06-18
|
||||
---
|
||||
|
||||
# Phase 1 Plan 02: Portal Shell Summary
|
||||
|
||||
**Responsive portal shell with OKLCH design tokens (yellow #ffed00 primary), collapsible sidebar, sticky header, DE/EN i18n via next-intl cookies, and light/dark/system theme switching via next-themes**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 7 min
|
||||
- **Started:** 2026-06-18T08:21:15Z
|
||||
- **Completed:** 2026-06-18T08:28:41Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 15
|
||||
|
||||
## Accomplishments
|
||||
- Full design token system with OKLCH colors, sidebar/header layout tokens, and light/dark theme variants
|
||||
- Bilingual interface (DE/EN) with 24 translation keys and cookie-based locale persistence
|
||||
- Complete portal layout: sticky header with branding/actions, collapsible sidebar with nav and categories, responsive main area
|
||||
- Theme toggle cycling light/dark/system with localStorage persistence and SSR-safe mounted guard
|
||||
- Empty dashboard state showing "Keine Widgets aktiv" with add widget button per D-16
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: Design token system + i18n framework + theme provider setup** - `f3791c6` (feat)
|
||||
2. **Task 2: Portal layout components -- header, sidebar, app shell, interactions** - `6039387` (feat)
|
||||
|
||||
## Files Created/Modified
|
||||
- `apps/web/src/app/globals.css` - OKLCH design tokens with @theme inline block, light/dark variants, sidebar tokens, layout dimensions
|
||||
- `apps/web/next.config.ts` - Wrapped with createNextIntlPlugin for i18n support
|
||||
- `apps/web/src/app/layout.tsx` - Async root layout with ThemeProvider and NextIntlClientProvider wrappers
|
||||
- `apps/web/src/i18n/request.ts` - Locale resolution from NEXT_LOCALE cookie, dynamic message import
|
||||
- `apps/web/src/messages/de.json` - German translations (24 keys across 6 namespaces)
|
||||
- `apps/web/src/messages/en.json` - English translations (matching 24 keys)
|
||||
- `apps/web/src/lib/stores/sidebar-store.ts` - Zustand store with isCollapsed, isMobileOpen, persist to localStorage
|
||||
- `apps/web/src/components/layout/header.tsx` - Sticky header: logo left, breadcrumb center, theme/locale/user right, mobile hamburger
|
||||
- `apps/web/src/components/layout/sidebar.tsx` - Collapsible sidebar: Dashboard (active), Marketplace, accordion categories, collapse toggle, mobile overlay
|
||||
- `apps/web/src/components/layout/sidebar-footer.tsx` - Settings icon and user info placeholder
|
||||
- `apps/web/src/components/layout/app-shell.tsx` - Layout composition with responsive main content margin
|
||||
- `apps/web/src/components/theme-toggle.tsx` - Three-state theme cycle with SVG icons and hydration guard
|
||||
- `apps/web/src/components/locale-switcher.tsx` - Cookie-based DE/EN toggle with router.refresh
|
||||
- `apps/web/src/app/page.tsx` - Dashboard page with empty state: grid icon, translated text, add widget button
|
||||
- `apps/web/package.json` - Added next-intl, next-themes, zustand dependencies
|
||||
|
||||
## Decisions Made
|
||||
- **OKLCH color space**: Used OKLCH for all design tokens (Tailwind v4 native support) rather than hex/hsl -- provides perceptually uniform color manipulation
|
||||
- **Dark gray-blue dark mode**: Used oklch(0.17 0.01 260) -- comfortable with yellow primary, avoids harsh true-black per user recommendation in D-14
|
||||
- **Cookie-based locale**: NEXT_LOCALE cookie with 1-year max-age, read server-side by next-intl -- avoids URL routing complexity for portal app
|
||||
- **CSS custom property for main margin**: Used --current-sidebar-width CSS variable with @media query rather than inline style -- cleanly handles responsive breakpoint
|
||||
- **Inter font-family**: Selected Inter as primary font per discretion recommendation for clean modern style
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 2 - Missing Critical] Added i18n for hardcoded strings in mobile sidebar and sidebar footer**
|
||||
- **Found during:** Task 2 (Portal layout components)
|
||||
- **Issue:** Mobile sidebar header had hardcoded "Tessera" text and sidebar footer had hardcoded "User" placeholder -- violated UI-03 requirement
|
||||
- **Fix:** Added tCommon('appName') in sidebar mobile header, t('userPlaceholder') in sidebar footer, common.menu key for hamburger aria-label
|
||||
- **Files modified:** sidebar.tsx, sidebar-footer.tsx, de.json, en.json
|
||||
- **Verification:** grep for hardcoded strings returns no results
|
||||
- **Committed in:** 6039387 (Task 2 commit)
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 1 auto-fixed (1 missing critical -- i18n compliance)
|
||||
**Impact on plan:** Essential fix for UI-03 requirement compliance. No scope creep.
|
||||
|
||||
## Issues Encountered
|
||||
None - both tasks executed cleanly with type-check and build verification passing.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required.
|
||||
|
||||
## Known Stubs
|
||||
|
||||
- `apps/web/src/components/layout/header.tsx` line 67 - User avatar is a placeholder div (will be wired to auth in Phase 2)
|
||||
- `apps/web/src/components/layout/sidebar-footer.tsx` line 52 - User name shows translation placeholder (will be wired to auth in Phase 2)
|
||||
- `apps/web/src/app/page.tsx` line 40 - Add widget button is non-functional (dashboard implementation in Phase 5)
|
||||
|
||||
## Next Phase Readiness
|
||||
- Portal shell is fully functional with theme, i18n, and responsive layout
|
||||
- AppShell component ready to wrap all future page routes
|
||||
- Sidebar navigation entries ready for dynamic population from module registry (Phase 3-4)
|
||||
- Design token system provides consistent theming foundation for all future components
|
||||
- Message file structure supports additional namespaces for future modules
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
All 15 key files verified present. Both commit hashes (f3791c6, 6039387) verified in git log.
|
||||
|
||||
---
|
||||
*Phase: 01-foundation-portal-shell*
|
||||
*Completed: 2026-06-18*
|
||||
Reference in New Issue
Block a user