Three new pages behind the /app/* React router:
client/src/components/Layout.tsx
Sidebar + main content shell. NavLink-based nav with a single
NAV data structure mirroring the vanilla app's sidebar groups
(Encounters / Notes / Clinical Tools / Account). Items with
`available: false` render as greyed-out 'pending' stubs so the
future tab list is visible during migration without breaking
clicks. Vanilla-app fallback link is pinned at the top so anyone
needing a feature not yet ported can jump back to /.
client/src/pages/Faq.tsx
8 sections, 27 questions ported verbatim from
public/components/faq.html. Collapsible accordion pattern via
local useState — no Radix dependency yet. Content lives in
client/src/data/faq.ts (extracted from the HTML via a one-off
python parse, so re-extraction is reproducible if the vanilla
FAQ ever grows).
client/src/pages/Dictation.tsx
Minimum-viable port of Voice Dictation → HPI. Demographics
(age / gender / setting), transcript textarea, Zod-validated
submit to POST /api/generate-hpi-dictation, result pane with
copy-to-clipboard. Not yet ported from the vanilla tab:
MediaRecorder audio capture + /api/transcribe upload, save/load
popover, refine + shorten buttons, Nextcloud export. Each of
those is its own follow-up.
client/src/App.tsx
All routes now render inside <Layout />. New routes wired:
/, /extensions, /dictation, /faq. A catch-all Navigate redirects
any unknown /app/* path back to home.
Build check:
client: npx tsc -b → EXIT 0
client: npx vite build → 350 kB / 108 kB gzipped
Public bundle at public/app/index-BmpHzFRb.js replaces the previous
one; committed so the next prod rebuild ships it atomically.
Nothing on the backend changed. /api/generate-hpi-dictation and
/api/extensions already exist; the React pages just call them.