From 552ead0901e810f3b7616956fc4be28a229c801a Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 23 Apr 2026 22:16:47 +0200 Subject: [PATCH] feat(client): port FAQ + Dictation to React, add sidebar Layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 . 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. --- client/src/App.tsx | 22 ++++- client/src/components/Layout.tsx | 115 +++++++++++++++++++++++ client/src/pages/Dictation.tsx | 134 +++++++++++++++++++++++++++ client/src/pages/Faq.tsx | 57 ++++++++++++ public/app/assets/index-B2vc_21R.css | 2 + public/app/assets/index-B9E7ZEZn.js | 49 ---------- public/app/assets/index-BmpHzFRb.js | 49 ++++++++++ public/app/assets/index-He39n9ae.css | 2 - public/app/index.html | 4 +- 9 files changed, 376 insertions(+), 58 deletions(-) create mode 100644 client/src/components/Layout.tsx create mode 100644 client/src/pages/Dictation.tsx create mode 100644 client/src/pages/Faq.tsx create mode 100644 public/app/assets/index-B2vc_21R.css delete mode 100644 public/app/assets/index-B9E7ZEZn.js create mode 100644 public/app/assets/index-BmpHzFRb.js delete mode 100644 public/app/assets/index-He39n9ae.css diff --git a/client/src/App.tsx b/client/src/App.tsx index 9a4ba0f..4502774 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,6 +1,9 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'; +import { BrowserRouter, Routes, Route, Navigate, Link } from 'react-router-dom'; +import Layout from '@/components/Layout'; import Extensions from '@/pages/Extensions'; +import Faq from '@/pages/Faq'; +import Dictation from '@/pages/Dictation'; const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 30_000, retry: 1 } }, @@ -14,8 +17,11 @@ function Home() { This is the new React tree. The legacy vanilla-JS app still lives at{' '} /.

-