pediatric-ai-scribe-v3/client/src/pages/Faq.tsx
Daniel 552ead0901 feat(client): port FAQ + Dictation to React, add sidebar Layout
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.
2026-04-23 22:16:52 +02:00

57 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================================
// FAQ — ported from public/components/faq.html. Same content,
// same sectioned layout, collapsible questions. Content lives in
// data/faq.ts so adding an entry is a one-line data change.
// ============================================================
import { useState } from 'react';
import { FAQ_DATA } from '@/data/faq';
function FaqItem({ q, a }: { q: string; a: string }) {
const [open, setOpen] = useState(false);
return (
<div className="border-b border-border last:border-0">
<button
onClick={() => setOpen(!open)}
className="w-full text-left py-3 px-4 flex items-center justify-between hover:bg-muted/40 transition-colors"
aria-expanded={open}
>
<span className="font-medium text-sm">{q}</span>
<span className="text-muted-foreground text-sm">{open ? '' : '+'}</span>
</button>
{open && (
<div className="px-4 pb-4 text-sm text-muted-foreground leading-relaxed whitespace-pre-line">
{a}
</div>
)}
</div>
);
}
export default function Faq() {
return (
<div className="max-w-4xl mx-auto p-6 space-y-6">
<header>
<h1 className="text-2xl font-semibold">Frequently Asked Questions</h1>
<p className="text-sm text-muted-foreground">
Learn how Pediatric AI Scribe works and get the most out of it.
</p>
</header>
{FAQ_DATA.map((section) => (
<section
key={section.section}
className="rounded-lg border border-border overflow-hidden"
>
<h2 className="bg-muted/40 px-4 py-2 text-sm font-semibold">
{section.section}
</h2>
<div className="bg-card">
{section.items.map((item) => (
<FaqItem key={item.q} q={item.q} a={item.a} />
))}
</div>
</section>
))}
</div>
);
}