docs(02-02): complete mobile shell wiring plan

- SUMMARY.md: layout rewrite + nav/page.tsx deletion, all 15 phase requirements closed
- STATE.md: decisions, metrics, session recorded
- ROADMAP.md: Phase 02 marked Complete (2/2 plans done)
- REQUIREMENTS.md: SHELL-01, SHELL-05, DRAWER-06 marked complete
This commit is contained in:
lorentz 2026-05-03 16:12:25 -04:00
parent 2af73955ae
commit cc8a584f3f
4 changed files with 174 additions and 15 deletions

View file

@ -17,11 +17,11 @@ Requirements for this milestone. Each maps to a spec section and a roadmap phase
### Shell — `/mobile` layout (spec §5)
- [ ] **SHELL-01**: New `app/mobile/layout.tsx` replaces the current layout (rebuild in place — no parallel `/mobile-v2`)
- [x] **SHELL-01**: New `app/mobile/layout.tsx` replaces the current layout (rebuild in place — no parallel `/mobile-v2`)
- [ ] **SHELL-02**: Sticky top header: `bg-background/95 backdrop-blur` + bottom border; left = Wulf mark + "Pulse" wordmark linked to `/mobile/dashboard`; no page title in header
- [ ] **SHELL-03**: Header right slot — `Bell` icon button (placeholder, no menu/badge, `aria-label="Notifications"`, empty `onClick`, keyboard-accessible)
- [ ] **SHELL-04**: Header right slot — compact user avatar (`h-7 w-7`); tapping opens the More drawer
- [ ] **SHELL-05**: `<main>` content area is scrollable with bottom padding equal to bottom-nav height + safe-area inset
- [x] **SHELL-05**: `<main>` content area is scrollable with bottom padding equal to bottom-nav height + safe-area inset
- [ ] **SHELL-06**: Fixed bottom nav: `border-t bg-background`, `max-w-lg mx-auto` wrapper, 5 cells (4 tabs + More)
### NAV — Bottom tab bar (spec §3.1)
@ -37,7 +37,7 @@ Requirements for this milestone. Each maps to a spec section and a roadmap phase
- [ ] **DRAWER-03**: Drawer top section "Mobile sections" lists Engagement (`/mobile/engagement`)
- [ ] **DRAWER-04**: Drawer middle section "Full site" lists desktop-only pages (Quotes, Configuration Items, Backup Status, Ticket Digest, Admin / Sync) each with `ExternalLink` icon
- [ ] **DRAWER-05**: Drawer bottom section "Account" shows current user (avatar + email, read-only) and a Sign out action that calls `signOut()` then `router.push('/auth/sign-in')`
- [ ] **DRAWER-06**: `app/mobile/nav/page.tsx` is deleted in the same change that ships the drawer
- [x] **DRAWER-06**: `app/mobile/nav/page.tsx` is deleted in the same change that ships the drawer
### DASH — Mobile Dashboard (spec §6.1)
@ -132,11 +132,11 @@ Updated during roadmap creation.
| PWA-02 | Phase 1 | Pending |
| PWA-03 | Phase 1 | Pending |
| PWA-04 | Phase 1 | Pending |
| SHELL-01 | Phase 2 | Pending |
| SHELL-01 | Phase 2 | Complete |
| SHELL-02 | Phase 2 | Pending |
| SHELL-03 | Phase 2 | Pending |
| SHELL-04 | Phase 2 | Pending |
| SHELL-05 | Phase 2 | Pending |
| SHELL-05 | Phase 2 | Complete |
| SHELL-06 | Phase 2 | Pending |
| NAV-01 | Phase 2 | Pending |
| NAV-02 | Phase 2 | Pending |
@ -146,7 +146,7 @@ Updated during roadmap creation.
| DRAWER-03 | Phase 2 | Pending |
| DRAWER-04 | Phase 2 | Pending |
| DRAWER-05 | Phase 2 | Pending |
| DRAWER-06 | Phase 2 | Pending |
| DRAWER-06 | Phase 2 | Complete |
| DASH-01 | Phase 3 | Pending |
| DASH-02 | Phase 3 | Pending |
| DASH-03 | Phase 3 | Pending |

View file

@ -58,8 +58,8 @@ Decimal phases appear between their surrounding integers in numeric order.
5. `app/mobile/nav/page.tsx` no longer exists; visiting `/mobile/nav` does not render the old standalone nav page
6. Page content scrolls under the sticky header and is not hidden behind the bottom nav (bottom padding accounts for nav height + safe-area inset)
**Plans**: 2 plans
- [ ] 02-01-PLAN.md — Build mobile shell components (HeaderBar, BottomNav, MoreDrawer) + analyzer placeholder (SHELL-02..04, SHELL-06, NAV-01..03, DRAWER-01..05)
- [ ] 02-02-PLAN.md — Wire new components into app/mobile/layout.tsx, delete app/mobile/nav/page.tsx (SHELL-01, SHELL-05, DRAWER-06)
- [x] 02-01-PLAN.md — Build mobile shell components (HeaderBar, BottomNav, MoreDrawer) + analyzer placeholder (SHELL-02..04, SHELL-06, NAV-01..03, DRAWER-01..05)
- [x] 02-02-PLAN.md — Wire new components into app/mobile/layout.tsx, delete app/mobile/nav/page.tsx (SHELL-01, SHELL-05, DRAWER-06)
**UI hint**: yes
### Phase 3: Dashboard Restyle

View file

@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
status: executing
stopped_at: Roadmap created — ready to plan Phase 1
last_updated: "2026-05-03T18:05:22.540Z"
stopped_at: Completed 02-mobile-shell-more-drawer/02-02-PLAN.md
last_updated: "2026-05-03T20:12:16.875Z"
last_activity: 2026-05-03
progress:
total_phases: 8
completed_phases: 1
total_plans: 2
completed_plans: 2
completed_phases: 2
total_plans: 4
completed_plans: 4
percent: 100
---
@ -52,6 +52,7 @@ Progress: [░░░░░░░░░░] 0%
- Trend: —
*Updated after each plan completion*
| Phase 02-mobile-shell-more-drawer P02 | 8 | 4 tasks | 2 files |
## Accumulated Context
@ -63,6 +64,9 @@ Recent decisions affecting current work:
- Roadmap: Phases mirror the spec's 8-step build order so each step ships independently to `master` (spec §8)
- Phase 2 unblocks Phases 37; Phases 37 are mutually independent and can be parallelized; Phase 8 depends on Phase 7
- All work happens in place under `/mobile/*` — no `/mobile-v2`, no parallel routes (spec §2)
- [Phase 02-mobile-shell-more-drawer]: Single useState in mobile layout.tsx for drawer open state — no Zustand/Context per CLAUDE.md constraint
- [Phase 02-mobile-shell-more-drawer]: Tailwind 4 pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))] arbitrary value works without inline-style fallback
- [Phase 02-mobile-shell-more-drawer]: No redirect on /mobile/nav deletion — standard 404 per DRAWER-06 spec
### Pending Todos
@ -74,6 +78,6 @@ None yet.
## Session Continuity
Last session: 2026-05-03
Stopped at: Roadmap created — ready to plan Phase 1
Last session: 2026-05-03T20:12:16.872Z
Stopped at: Completed 02-mobile-shell-more-drawer/02-02-PLAN.md
Resume file: None

View file

@ -0,0 +1,155 @@
---
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 worked**`pb-[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