From cc8a584f3f6cc5fe6df1185be548ff513f5a388f Mon Sep 17 00:00:00 2001 From: lorentz Date: Sun, 3 May 2026 16:12:25 -0400 Subject: [PATCH] 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 --- .planning/REQUIREMENTS.md | 12 +- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 18 +- .../02-02-SUMMARY.md | 155 ++++++++++++++++++ 4 files changed, 174 insertions(+), 15 deletions(-) create mode 100644 .planning/phases/02-mobile-shell-more-drawer/02-02-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 905c3b8..58f4de0 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -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**: `
` content area is scrollable with bottom padding equal to bottom-nav height + safe-area inset +- [x] **SHELL-05**: `
` 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 | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index dda8edf..9ce85a7 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -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 diff --git a/.planning/STATE.md b/.planning/STATE.md index ef53676..5881c07 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -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 3–7; Phases 3–7 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 diff --git a/.planning/phases/02-mobile-shell-more-drawer/02-02-SUMMARY.md b/.planning/phases/02-mobile-shell-more-drawer/02-02-SUMMARY.md new file mode 100644 index 0000000..85b8b78 --- /dev/null +++ b/.planning/phases/02-mobile-shell-more-drawer/02-02-SUMMARY.md @@ -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 3–7 + +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 `` at the top (brand + Bell placeholder + avatar → drawer) +- Scrollable `
` with bottom padding pre-applied (clears the 64px bottom nav + safe-area inset) +- Fixed `` at the bottom (4 tabs + More → drawer) +- `` (Sheet side="right") with three sections (Mobile sections / Full site / Account + Sign out) + +Pages should render their own `

` 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