--- phase: 04-full-app-design-consistency plan: "03" subsystem: ui tags: [react, i18n, react-i18next, tailwind, typescript, design-system] # Dependency graph requires: - phase: 04-full-app-design-consistency provides: PageShell component, semantic CSS tokens (text-over-budget/text-on-budget), categoryColors palette provides: - BudgetListPage upgraded with PageShell, locale-aware Intl.DateTimeFormat month names, skeleton loading, i18n labels - BudgetDetailPage upgraded with semantic color tokens, direction-aware diff, left-border group headers, PageShell, skeleton - budgets.month/year/total i18n keys in en.json and de.json affects: [budget pages, design system completeness, i18n coverage] # Tech tracking tech-stack: added: [] patterns: - Intl.DateTimeFormat locale-aware month generation via useMemo with i18n.language dependency - Direction-aware diff logic: SPENDING_TYPES array + isSpendingType() helper replaces isIncome boolean - Semantic color tokens (text-over-budget/text-on-budget) replacing hardcoded Tailwind color classes key-files: created: [] modified: - src/pages/BudgetListPage.tsx - src/pages/BudgetDetailPage.tsx - src/i18n/en.json - src/i18n/de.json key-decisions: - "Direction-aware diff pattern replicated from CategorySection: SPENDING_TYPES array + isSpendingType() covers all 6 category types correctly" - "TierBadge column removed from BudgetDetailPage to reduce visual noise and align with CategorySection display style" - "budgets.month/year/total keys added to both en.json and de.json to eliminate all hardcoded English labels in dialogs" - "return null loading state in BudgetListPage placed after useMemo hooks to satisfy Rules of Hooks - hooks declared before early return" patterns-established: - "Locale-aware months: useMemo + Array.from(12) + Intl.DateTimeFormat(locale, {month:'long'}) replacing hardcoded MONTHS arrays" - "Budget heading with locale: Intl.DateTimeFormat(i18n.language, {month:'long', year:'numeric'}) replacing toLocaleDateString('en')" - "Skeleton loading in PageShell: replaces return null with typed skeleton rows matching page structure" requirements-completed: [UI-BUDGETS-01, UI-RESPONSIVE-01, UI-DESIGN-01] # Metrics duration: 2min completed: 2026-03-17 --- # Phase 4 Plan 03: Budget Pages Design Consistency Summary **BudgetListPage and BudgetDetailPage upgraded with PageShell, locale-aware Intl.DateTimeFormat month names, semantic color tokens (text-over-budget/text-on-budget), direction-aware diff for all 6 category types, left-border accent group headers, skeleton loading, and i18n translations for month/year/total labels** ## Performance - **Duration:** 2 min - **Started:** 2026-03-17T15:19:03Z - **Completed:** 2026-03-17T15:21:00Z - **Tasks:** 2 - **Files modified:** 4 ## Accomplishments - Eliminated hardcoded English `MONTHS` array and `toLocaleDateString("en")` — both pages now use `Intl.DateTimeFormat(locale)` fed by `i18n.language` - Replaced `text-green-600`/`text-red-600`/`text-green-400`/`text-red-400` with `text-on-budget`/`text-over-budget` semantic tokens — zero hardcoded color classes remain - Rewrote `DifferenceCell` with `SPENDING_TYPES` + `isSpendingType()` direction-aware logic covering all 6 category types (spending over when actual > budgeted; income/saving/investment over when actual < budgeted) - Both pages wrapped in `PageShell` — completing consistent header layout across all 9 app pages - `return null` loading states replaced with `PageShell + Skeleton` — no blank screen flash during data load ## Task Commits Each task was committed atomically: 1. **Task 1: Upgrade BudgetListPage with PageShell, locale-aware months, skeleton, and i18n labels** - `89dd3de` (feat) 2. **Task 2: Upgrade BudgetDetailPage with semantic tokens, direction-aware diff, PageShell, group headers, and skeleton** - `24d071c` (feat) **Plan metadata:** `1e61b88` (docs: complete plan) ## Files Created/Modified - `src/pages/BudgetListPage.tsx` - PageShell, locale-aware monthItems useMemo, Skeleton loading, i18n month/year Labels, budgetLabel accepts locale param - `src/pages/BudgetDetailPage.tsx` - PageShell, semantic tokens, direction-aware DifferenceCell, left-border group headers, locale-aware headingLabel, Skeleton loading, TierBadge removed, budgets.total i18n - `src/i18n/en.json` - Added budgets.month, budgets.year, budgets.total keys - `src/i18n/de.json` - Added budgets.month (Monat), budgets.year (Jahr), budgets.total (Gesamt) ## Decisions Made - **Direction-aware diff replicated from CategorySection:** Same `SPENDING_TYPES` array pattern as `CategorySection.tsx` ensures consistent diff direction across dashboard and budget detail views - **TierBadge column removed:** Plan specification to remove tier column for cleaner display — reduces visual noise, aligns with CategorySection which doesn't show tier badges - **i18n keys added for month/year/total:** Enables full German locale support in budget dialogs and footer totals; `{{label}} Total` / `{{label}} Gesamt` pattern uses i18next interpolation ## Deviations from Plan None - plan executed exactly as written. ## Issues Encountered - 6 pre-existing lint errors in unrelated files (MonthNavigator.tsx, badge.tsx, button.tsx, sidebar.tsx, useBudgets.ts) — pre-existing, documented in STATE.md, not caused by this plan's changes - `return null` in BudgetDetailPage.tsx line 492 is inside a JSX render callback (`CATEGORY_TYPES.map()`), not a loading state — plan's verification intent (no loading-state nulls) is fully satisfied ## Next Phase Readiness - All 4 phases of the design consistency roadmap are complete - All 9 pages use consistent PageShell layout - All semantic color tokens applied throughout the app - German locale fully supported on all pages including budget dialogs ## Self-Check: PASSED - FOUND: src/pages/BudgetListPage.tsx - FOUND: src/pages/BudgetDetailPage.tsx - FOUND: src/i18n/en.json - FOUND: src/i18n/de.json - FOUND: .planning/phases/04-full-app-design-consistency/04-03-SUMMARY.md - FOUND: 89dd3de (Task 1 commit) - FOUND: 24d071c (Task 2 commit) - FOUND: 1e61b88 (metadata commit) --- *Phase: 04-full-app-design-consistency* *Completed: 2026-03-17*