pediatric-ai-scribe-v3/public/components/notes.html
Daniel 67b7667e04 feat: ED encounters + notes model selector; remove AI corrections; fix notes framing
Four changes batched:

1. ED Encounters tab (new) — multi-stage emergency note with don't-miss
   tooltips and 2023 E/M MDM finalize. New route /api/ed-encounters
   (generate per-stage + finalize MDM), new ed-encounters.js owning all
   client logic, new ed-encounter.html component, new template_ed memory
   category. Persists draft to localStorage every keystroke and to
   saved_encounters on stage advance. encounters.js touched only to
   register the new tab in sessionStorage restore + tabMap (save and
   idempotency code untouched).

2. Notes model selector — /notes/from-voice now accepts a client-supplied
   model (validated by the existing callAI allow-list); falls back to the
   admin default. Added <select class="tab-model-select"> to notes.html
   so the existing app.js populator handles options + default.

3. Remove AI-learning-from-corrections — deleted correctionTracker.js,
   POST /memories/correction, the corrections branch in
   /memories/context, the settings UI section, the FAQ entry, and all
   dead trackAIOutput/saveCorrection guards in callers. Legacy
   correction_* DB rows are filtered (NOT LIKE) rather than dropped, so
   no destructive migration.

4. Fix notes AI framing — /notes/from-voice prompt no longer assumes
   "physician dictation". Plain notes (shopping lists, reminders,
   ideas) now match the dictation tone instead of being forced into
   clinical structure.

All 46 tests pass.
2026-04-28 03:09:38 +02:00

122 lines
6.4 KiB
HTML

<div class="module-header">
<h2><i class="fas fa-note-sticky" style="color:#f59e0b;"></i> Notes</h2>
</div>
<!-- data-view controls which pane is visible on mobile (<900px):
"list" — sidebar only, "reader" — read pane only,
"editor" — edit pane only. On desktop the sidebar is always
visible and the right pane flips between reader/editor. -->
<div class="notes-layout" id="notes-layout" data-view="list">
<!-- Left pane: list + new-note button + search + trash toggle -->
<aside class="notes-sidebar">
<div class="notes-sidebar-head">
<button id="btn-notes-new" class="btn-primary notes-new-btn" type="button">
<i class="fas fa-plus"></i> New note
</button>
<div class="notes-search">
<i class="fas fa-search"></i>
<input type="text" id="notes-search" placeholder="Search" autocomplete="off">
</div>
<div class="notes-tabs">
<button id="btn-notes-tab-active" class="notes-tab-btn active" type="button" data-view="active">
Notes
</button>
<button id="btn-notes-tab-trash" class="notes-tab-btn" type="button" data-view="trash">
<i class="fas fa-trash"></i> Trash <span class="notes-trash-count" id="notes-trash-count"></span>
</button>
</div>
</div>
<div id="notes-list" class="notes-list">
<div class="notes-empty">Loading…</div>
</div>
<div id="notes-trash-foot" class="notes-trash-foot hidden">
<button id="btn-notes-trash-empty" class="btn-sm" type="button"
style="background:var(--red-light);color:var(--red);border:1px solid var(--red);">
<i class="fas fa-fire"></i> Empty trash
</button>
</div>
</aside>
<!-- Reader pane — shown by default after opening any saved note -->
<section id="notes-reader" class="notes-reader hidden">
<div class="notes-reader-head">
<button type="button" class="btn-sm btn-ghost notes-back" id="btn-notes-reader-back" title="Back to list">
<i class="fas fa-arrow-left"></i>
</button>
<h2 id="notes-reader-title" class="notes-reader-title">Note title</h2>
<div class="notes-reader-actions">
<button id="btn-note-edit" class="btn-sm btn-primary" type="button">
<i class="fas fa-pen"></i> Edit
</button>
<button id="btn-note-delete-read" class="btn-sm" type="button"
style="background:var(--red-light);color:var(--red);border:1px solid var(--red);">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<div id="notes-reader-body" class="notes-reader-body"></div>
<div class="notes-reader-foot">
<span id="notes-reader-meta" class="notes-meta"></span>
</div>
</section>
<!-- Editor pane — shown when creating a new note or editing an existing one -->
<section id="notes-editor" class="notes-editor hidden">
<div class="notes-editor-head">
<button type="button" class="btn-sm btn-ghost notes-back" id="btn-notes-editor-back" title="Back">
<i class="fas fa-arrow-left"></i>
</button>
<input type="text" id="note-title"
class="notes-title-input"
placeholder="Title"
maxlength="200"
autocomplete="off">
<div class="notes-editor-actions">
<!-- Voice → AI note: transcribes via the admin-configured
STT provider, then asks the AI to produce a clean note.
Pause/Resume available natively through MediaRecorder. -->
<div class="notes-voice-bar" id="notes-voice-bar">
<select id="notes-model-select" class="tab-model-select" title="AI model for voice → note conversion" style="font-size:11px;padding:2px 6px;max-width:160px;"></select>
<button id="btn-note-rec-start" class="btn-sm btn-ghost" type="button" title="Record voice → AI note">
<i class="fas fa-microphone" style="color:var(--red);"></i> Dictate
</button>
<button id="btn-note-rec-pause" class="btn-sm btn-ghost hidden" type="button">
<i class="fas fa-pause"></i> Pause
</button>
<button id="btn-note-rec-stop" class="btn-sm hidden" type="button" style="background:var(--red);color:white;border:none;">
<i class="fas fa-stop"></i> Stop
</button>
<span id="notes-rec-indicator" class="notes-rec-indicator hidden">
<span class="pulse-dot"></span>
<span id="notes-rec-state">Recording</span>
<span class="notes-rec-timer" id="notes-rec-timer">00:00</span>
</span>
</div>
<span id="notes-status" class="notes-status"></span>
<button id="btn-note-save" class="btn-sm btn-primary" type="button">
<i class="fas fa-floppy-disk"></i> Save
</button>
<button id="btn-note-delete" class="btn-sm" type="button"
style="background:var(--red-light);color:var(--red);border:1px solid var(--red);">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<div id="note-body-editor" class="notes-body-editor"></div>
<div class="notes-editor-foot">
<span id="note-meta" class="notes-meta"></span>
</div>
</section>
<!-- Empty placeholder — shown on desktop when nothing's picked -->
<section id="notes-empty-state" class="notes-empty-state">
<div class="notes-empty-card">
<div class="notes-empty-icon"><i class="fas fa-note-sticky"></i></div>
<button id="btn-notes-new-empty" type="button" class="btn-primary notes-empty-cta">
<i class="fas fa-plus"></i> New note
</button>
</div>
</section>
</div>