---
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
