wulf-pulse/.planning/phases/02-mobile-shell-more-drawer/02-01-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

6.2 KiB

phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
02-mobile-shell-more-drawer 01 mobile-shell
mobile
navigation
shell
drawer
components
requires provides affects
components/mobile/HeaderBar.tsx
components/mobile/BottomNav.tsx
components/mobile/MoreDrawer.tsx
app/mobile/analyzer/page.tsx
app/mobile/layout.tsx (Plan 02 will wire these in)
added patterns
shadcn Sheet (side="right") for drawer
Controlled open/onOpenChange props for shared drawer state
pathname.startsWith(href) for active tab detection
initials-circle pattern from UserMenu (no shadcn avatar primitive)
pt-safe / pb-safe from Phase 1 brand.css utilities
created modified
components/mobile/HeaderBar.tsx
components/mobile/BottomNav.tsx
components/mobile/MoreDrawer.tsx
app/mobile/analyzer/page.tsx
Sheet side="right" (locked per DRAWER-02 in CONTEXT.md)
No shadcn avatar primitive — initials-circle pattern matches existing UserMenu
Bell onClick intentionally empty (SHELL-03 placeholder, Phase 7+ wires real notifications)
No page title in HeaderBar — pages render their own H1
analyzer/page.tsx is a deliberate "coming soon" placeholder — Phase 6 owns the real feed
duration_minutes completed_date tasks_completed tasks_total files_created files_modified
5 2026-05-03 5 5 4 0

Phase 02 Plan 01: Mobile Shell Components Summary

Three new reusable shell components and an analyzer route placeholder — the building blocks Plan 02 will wire into app/mobile/layout.tsx to complete the mobile shell redesign.

What Was Built

MoreDrawer (components/mobile/MoreDrawer.tsx) — shadcn Sheet (side="right") with controlled open/onOpenChange props so both the header avatar and the bottom-nav More button share one drawer instance. Three sections:

  • Mobile sections: Engagement (in-shell, no ExternalLink)
  • Full site: Quotes, Configuration Items, Backup Status, Ticket Digest, Admin/Sync (each with ExternalLink icon)
  • Account: user initials + name/email (read-only) + Sign out (calls signOut() then navigates to /auth/sign-in)

HeaderBar (components/mobile/HeaderBar.tsx) — sticky header with bg-background/95 backdrop-blur border-b pt-safe. Left: WulfMark + "Pulse" wordmark linked to /mobile/dashboard. Right: Bell placeholder (aria-label="Notifications", empty onClick) + compact avatar circle (h-7 w-7) calling onAvatarClick prop. No page title in the header.

BottomNav (components/mobile/BottomNav.tsx) — fixed bottom bar (border-t bg-background pb-safe, max-w-lg mx-auto, h-16). Four tabs: Dashboard (LayoutDashboard), Tickets (Ticket), Finance (DollarSign), Analyzer (Sparkles) — all with pathname.startsWith(href) active detection (text-primary when active, text-muted-foreground otherwise). Fifth cell: More button calling onMoreClick prop.

Analyzer placeholder (app/mobile/analyzer/page.tsx) — minimal server component with "coming soon" card. Resolves the /mobile/analyzer route so the new Analyzer tab doesn't 404 before Phase 6 (ANL-01..06) ships the real feed.

Requirements Addressed

Requirement Status
SHELL-02 Sticky header, brand mark+wordmark, /mobile/dashboard link, backdrop blur, border-b
SHELL-03 Bell placeholder with aria-label, empty onClick
SHELL-04 Avatar circle h-7 w-7, triggers drawer via onAvatarClick
SHELL-06 Fixed bottom nav, max-w-lg mx-auto, border-t, pb-safe
NAV-01 4 tab icons: LayoutDashboard, Ticket, DollarSign, Sparkles + Menu for More
NAV-02 4 routes: /mobile/dashboard, /mobile/tickets, /mobile/finance, /mobile/analyzer
NAV-03 pathname.startsWith(href) active detection, text-primary/text-muted-foreground
DRAWER-01 More button in BottomNav triggers shared drawer via onMoreClick prop
DRAWER-02 Sheet side="right" (locked decision)
DRAWER-03 Mobile sections: Engagement /mobile/engagement (no ExternalLink)
DRAWER-04 Full site: Quotes, Config Items, Backup Status, Ticket Digest, Admin/Sync with ExternalLink
DRAWER-05 Account: user display (read-only) + Sign out via signOut() + router.push('/auth/sign-in')

Locked Decisions Honored

  • side="right" — locked in CONTEXT.md DRAWER-02
  • No shadcn avatar primitive — uses existing initials-circle pattern from UserMenu
  • Bell onClick is empty — SHELL-03 explicitly says "placeholder only this iteration"
  • No <h1> in HeaderBar — SHELL-02 explicit: "pages render their own H1"
  • MoreDrawer uses controlled state (props, not internal) — both triggers share one drawer

Notes for Plan 02

Plan 02 rewrites app/mobile/layout.tsx and deletes app/mobile/nav/page.tsx. When wiring the new components:

// In layout.tsx (Plan 02):
const [drawerOpen, setDrawerOpen] = useState(false);

<HeaderBar onAvatarClick={() => setDrawerOpen(true)} />
<MoreDrawer open={drawerOpen} onOpenChange={setDrawerOpen} />
<BottomNav onMoreClick={() => setDrawerOpen(true)} />

Deviations from Plan

None — plan executed exactly as written.

Known Stubs

File Stub Reason
app/mobile/analyzer/page.tsx "coming soon" card, no data Intentional — Phase 6 (ANL-01..06) owns the real mobile analyzer feed. This file exists only to prevent a 404 on the new BottomNav Analyzer tab.
components/mobile/HeaderBar.tsx Bell onClick is empty Intentional — SHELL-03 explicitly defers real notifications to Phase 7+.

Threat Flags

None — no new network endpoints, no new auth paths, no new DB access. All trust boundaries match the plan's threat model exactly.

Self-Check: PASSED

Files verified:

  • components/mobile/HeaderBar.tsx — exists
  • components/mobile/BottomNav.tsx — exists
  • components/mobile/MoreDrawer.tsx — exists
  • app/mobile/analyzer/page.tsx — exists

Commits verified:

  • 6630589 — feat(02-01): create MoreDrawer component
  • 14375f1 — feat(02-01): create HeaderBar component
  • a42c0a8 — feat(02-01): create BottomNav component
  • 3fc0ee3 — feat(02-01): add /mobile/analyzer placeholder

Build: npx tsc --noEmit --pretty exits 0, npm run build exits 0 (273 routes generated, /mobile/analyzer in route table).