--- phase: quick-260610-jlp plan: 01 subsystem: pwa/notifications tags: [bug-fix, refactor, uat, push-notifications] dependency_graph: requires: [] provides: [InstructionSheet shared component, SettingsSheet how-to-enable wired] affects: [PermissionDeniedBanner, SettingsSheet] tech_stack: added: [] patterns: [shared component extraction, local state for sheet overlay] key_files: created: - apps/pwa/src/components/InstructionSheet.tsx - apps/pwa/src/components/InstructionSheet.test.tsx modified: - apps/pwa/src/components/PermissionDeniedBanner.tsx - apps/pwa/src/components/SettingsSheet.tsx decisions: - "Extracted InstructionSheet verbatim from PermissionDeniedBanner; zero markup/copy/style changes (behaviour-preserving extraction)" - "SettingsSheet uses local instructionsOpen state to gate rendering InstructionSheet, not onClose" metrics: duration: ~8 minutes completed: "2026-06-10" requirements: [UAT-05-T4] --- # Phase quick-260610-jlp Plan 01: Fix Broken "How to Enable" Link in SettingsSheet **One-liner:** Extracted shared InstructionSheet bottom-sheet from PermissionDeniedBanner and wired SettingsSheet's "How to enable" button to open it via local state (was: `onClick={onClose}` — dead link). ## Tasks Completed | Task | Name | Commit | Files | |------|------|--------|-------| | 1 | Extract InstructionSheet into shared component + rewire PermissionDeniedBanner | 74b5d44 | InstructionSheet.tsx (new), PermissionDeniedBanner.tsx | | 2 | Wire SettingsSheet "How to enable" + write test | 874c030 | SettingsSheet.tsx, InstructionSheet.test.tsx (new) | | 3 | Full typecheck + build + test gate | (no code change) | — | ## Quality Gate Results - `pnpm --filter @familysync/pwa typecheck`: exit 0 (no output) - `pnpm --filter @familysync/pwa build`: SUCCESS — 1851 modules transformed, dist/assets/index-CaPAI7hF.js 655.55 kB gzip 191.46 kB, dist/sw.js 17.09 kB - `pnpm --filter @familysync/pwa test`: **15 test files passed, 187 tests passed (0 failed)** ## Deviations from Plan None — plan executed exactly as written. ## Known Stubs None — all wiring is functional; InstructionSheet renders real steps. ## Threat Flags None — no new network endpoints, auth paths, or trust boundary changes. The InstructionSheet is a local display component. ## Self-Check: PASSED - `apps/pwa/src/components/InstructionSheet.tsx` — exists, named export confirmed - `apps/pwa/src/components/InstructionSheet.test.tsx` — exists, 2 new tests pass - `apps/pwa/src/components/PermissionDeniedBanner.tsx` — imports from InstructionSheet.js, no local definition - `apps/pwa/src/components/SettingsSheet.tsx` — `setInstructionsOpen(true)` on "How to enable", `instructionsOpen &&` render - Commits 74b5d44 and 874c030 both exist in git log