// ============================================================ // DICTATION — voice dictation → HPI via /api/generate-hpi-dictation // // Minimum-viable port: demographics + transcript textarea + generate. // The vanilla version also has MediaRecorder-based audio capture, // transcription upload, save/load popover, refine, shorten, and // Nextcloud export. Those each land in follow-up commits — this // first pass proves the generate-HPI wire protocol works from React. // ============================================================ import { useState } from 'react'; import { useMutation } from '@tanstack/react-query'; import { api, ApiError } from '@/lib/api'; import type { HpiOk } from '@/shared/types'; import { HpiEncounterRequestSchema, type HpiEncounterRequest } from '@/shared/schemas'; type Setting = 'outpatient' | 'inpatient'; export default function Dictation() { const [patientAge, setPatientAge] = useState(''); const [patientGender, setPatientGender] = useState(''); const [setting, setSetting] = useState('outpatient'); const [transcript, setTranscript] = useState(''); const [result, setResult] = useState(null); const [validationError, setValidationError] = useState(null); const generate = useMutation({ mutationFn: (body) => api.post('/api/generate-hpi-dictation', body), onSuccess: (data) => setResult(data.hpi), onError: () => setResult(null), }); function submit(e: React.FormEvent) { e.preventDefault(); setValidationError(null); const body: HpiEncounterRequest = { transcript, patientAge, patientGender, setting }; const parsed = HpiEncounterRequestSchema.safeParse(body); if (!parsed.success) { setValidationError(parsed.error.issues.map((i: { message: string }) => i.message).join(', ')); return; } setResult(null); generate.mutate(parsed.data); } function clear() { setTranscript(''); setResult(null); setValidationError(null); } const input = 'w-full rounded-md border border-input bg-background px-3 py-2 text-sm'; return (

Voice Dictation → HPI

Dictate your narrative → AI restructures into polished HPI. Audio-capture UI is a follow-up; this minimal form supports typed/pasted transcripts.