wulf-pulse/.planning/phases/02-mobile-shell-more-drawer/02-02-SUMMARY.md
lorentz 9658640c04 fix(04-01): restore phase 2/3 work lost by worktree soft-reset
The soft reset to 77073ba inadvertently staged deletions of all phase 2
and 3 artifacts. This commit restores them from their source commits so
subsequent task commits build on the complete prior-phase foundation:
- components/mobile/{BottomNav,HeaderBar,KpiCardMobile,MoreDrawer,NeedsAttentionStrip,WorkerStatusRow}
- app/mobile/layout.tsx, dashboard/page.tsx, analyzer/page.tsx
- app/api/mobile/dashboard/route.ts
- All .planning/** files from phases 01-04
- CLAUDE.md, app/layout.tsx, app/styles/brand.css, public/manifest.json
2026-05-03 18:01:14 -04:00

7.2 KiB
Raw Blame History


phase: 02-mobile-shell-more-drawer plan: 02 subsystem: mobile-shell tags: [mobile, navigation, shell, drawer, layout, react-state]

dependency_graph: requires: - phase: 02-01 provides: HeaderBar, BottomNav, MoreDrawer components in components/mobile/ provides: - app/mobile/layout.tsx (new shell wiring all three components with shared drawer state) - DRAWER-06 fulfilled — app/mobile/nav/page.tsx deleted, /mobile/nav returns 404 affects: - All /mobile/* pages — they automatically land inside the new shell (header + bottom nav visible) - Phases 3-7 — page authors must NOT add their own header or bottom nav

tech-stack: added: [] patterns: - Single useState(drawerOpen) in layout.tsx shared between two triggers (avatar + More button) - pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))] for bottom-nav-aware main padding - 'use client' layout with controlled Sheet drawer via child component props

key-files: created: [] modified: - app/mobile/layout.tsx deleted: - app/mobile/nav/page.tsx

key-decisions:

  • "Single useState in layout.tsx — no Zustand, no Context — per CLAUDE.md no new state libraries"
  • "pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))] Tailwind 4 arbitrary value worked without fallback to inline style"
  • "No redirect for /mobile/nav deletion — per DRAWER-06 spec, 404 is the desired behavior"
  • "Cleared .next cache before type-check to resolve stale validator.ts reference to deleted page"

patterns-established:

  • "Mobile layout owns all chrome (header, bottom nav, drawer) — mobile pages render content only"
  • "Drawer state lifted to layout — single Sheet instance shared between multiple triggers"

requirements-completed: [SHELL-01, SHELL-05, DRAWER-06]

duration: 8min completed: "2026-05-03"

Phase 02 Plan 02: Mobile Shell Wiring Summary

app/mobile/layout.tsx rewritten to wire HeaderBar + BottomNav + MoreDrawer with single shared useState, completing the Phase 2 mobile shell redesign

Performance

  • Duration: ~8 min
  • Started: 2026-05-03T20:03:00Z
  • Completed: 2026-05-03T20:11:18Z
  • Tasks: 3 auto + 1 visual checkpoint (auto-approved)
  • Files modified: 2 (1 rewrite, 1 deletion)

Accomplishments

  • app/mobile/layout.tsx fully rewritten — sticky HeaderBar, scrollable main with bottom-nav-aware padding, fixed BottomNav, MoreDrawer with shared open state
  • Single useState(drawerOpen) wires both the header avatar and the bottom-nav More button to the same drawer instance — no Zustand, no Context, no prop-drilling
  • app/mobile/nav/page.tsx deleted; visiting /mobile/nav now returns Next.js 404 per DRAWER-06 spec
  • TypeScript clean (npx tsc --noEmit exits 0) and full build clean (272 routes, /mobile/nav absent from route table)
  • Combined with Plan 01, all 15 phase requirements (SHELL-01..06, NAV-01..03, DRAWER-01..06) are now satisfied

Requirements Addressed

Requirement Description Status
SHELL-01 /mobile/layout.tsx replaced in-place with new shell Closed
SHELL-05 Scrollable main with bottom-nav-aware padding (pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))]) Closed
DRAWER-06 /mobile/nav/page.tsx deleted; no redirect; 404 on visit Closed

Combined with Plan 01, all 15 phase requirements are now closed:

Plan Requirements closed
02-01 SHELL-02, SHELL-03, SHELL-04, SHELL-06, NAV-01, NAV-02, NAV-03, DRAWER-01, DRAWER-02, DRAWER-03, DRAWER-04, DRAWER-05
02-02 SHELL-01, SHELL-05, DRAWER-06

Task Commits

  1. Task 1: Rewrite app/mobile/layout.tsx - 7a095fb (feat)
  2. Task 2: Delete app/mobile/nav/page.tsx - 2af7395 (feat)
  3. Task 3: Type-check + build gate - no commit (gate-only task; Tasks 1-2 already committed)
  4. Task 4: Visual checkpoint - auto-approved (auto mode active)

Files Created/Modified

  • app/mobile/layout.tsx — Rewritten; now imports HeaderBar/BottomNav/MoreDrawer, owns single useState for drawer, pads main content to clear bottom nav + safe-area inset
  • app/mobile/nav/page.tsx — Deleted; 91 lines removed; standalone nav page replaced by MoreDrawer Sheet

Decisions Made

  • Single useState in layout.tsx — No new state libs per CLAUDE.md constraint. Both onAvatarClick and onMoreClick call () => setDrawerOpen(true); the Radix Sheet's onOpenChange propagates close events back through setDrawerOpen.
  • Tailwind 4 arbitrary value workedpb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))] was accepted by the Tailwind 4 build without needing the inline-style fallback documented in the plan.
  • No redirect on /mobile/nav deletion — Per CONTEXT.md DRAWER-06: "URL was never bookmarked-worthy." Standard 404 is correct behavior.

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] Cleared .next cache before type-check

  • Found during: Task 3 (type-check gate)
  • Issue: .next/types/validator.ts contained a stale generated reference to ../../app/mobile/nav/page.js from a previous build. Running npx tsc --noEmit immediately after deleting the file produced TS2307 on this generated file.
  • Fix: rm -rf .next before re-running npx tsc --noEmit. The generated validator regenerates on build and does not include the deleted route.
  • Files modified: None (cache directory, not source)
  • Verification: Type-check exits 0 after cache clear; subsequent npm run build also exits 0
  • Committed in: Not committed (cache directory is gitignored)

Total deviations: 1 auto-fixed (1 blocking — stale build cache) Impact on plan: Necessary to unblock the type-check gate. No source file changes required.

Issues Encountered

None beyond the stale .next cache (documented above as a deviation).

User Setup Required

None — no external service configuration required.

Notes for Phases 37

Every /mobile/* page now automatically renders inside the new shell. Page authors must NOT add their own header or bottom nav. The layout provides:

  • Sticky <HeaderBar> at the top (brand + Bell placeholder + avatar → drawer)
  • Scrollable <main> with bottom padding pre-applied (clears the 64px bottom nav + safe-area inset)
  • Fixed <BottomNav> at the bottom (4 tabs + More → drawer)
  • <MoreDrawer> (Sheet side="right") with three sections (Mobile sections / Full site / Account + Sign out)

Pages should render their own <h1> and content — the chrome is fully handled by the layout.

Known Stubs

None introduced by this plan. (Existing stubs from Plan 01 carry forward: analyzer placeholder card and Bell empty onClick — both intentional and documented in 02-01-SUMMARY.md.)

Threat Flags

None — no new network endpoints, no new auth paths, no new DB access. Layout is purely client-side React state + UI composition.

Self-Check: PASSED

Files verified:

  • app/mobile/layout.tsx — exists, imports all three components, contains useState + drawerOpen + safe-area-inset-bottom
  • app/mobile/nav/page.tsx — does not exist (deleted)
  • /mobile/nav absent from npm run build route table

Commits verified:

  • 7a095fb — feat(02-02): rewrite mobile layout
  • 2af7395 — feat(02-02): delete app/mobile/nav/page.tsx