pdf-parse (was v2, broken API): - Downgraded to v1.1.1 — default export is a function again - pdfParse is not a function error fixed WebDAV file selection (style.display bug, same cascade issue): - lh-ai-webdav-selected had inline style="display:flex" always visible - selectWebdavFile() / deselectWebdavFile() now use element.style.display - On select: browser div hides, selected indicator shows with file name + X - On deselect (X): indicator hides, browser shows again Topic context for Upload and Nextcloud tabs: - Both tabs now have optional "Topic / context" field - Sent to backend as 'topic' param to help AI focus the generated content Inline refine bar (replaces window.prompt): - Refine Body button shows/hides an amber inline input bar below generate buttons - Enter instructions, press Apply — no browser dialog, works in all contexts CSP: remove unsafe-inline from scriptSrc (security issue #2): - Converted all 26 onclick= handlers in component HTML files to data-action / data-target / data-label attributes - Added delegated click handler in app.js for copy/speak/nc-export actions - script-src now 'self' only; script-src-attr 'none' WebDAV path endpoint (security issue #5): - New POST /api/user/webdav-path (authMiddleware only, not moderator) - nextcloud.js updated to use new endpoint nodemailer: already at 6.10.1 (vulnerability fixed).
306 lines
19 KiB
HTML
306 lines
19 KiB
HTML
<div class="module-header">
|
|
<h2><i class="fas fa-calendar-check"></i> Well Visit / Preventive Care</h2>
|
|
<p>AAP 2025 Bright Futures periodicity — vaccines, screenings, billing codes, and catch-up schedule</p>
|
|
</div>
|
|
|
|
<!-- Sub-tab navigation -->
|
|
<div class="wv-subtab-bar">
|
|
<button class="wv-subtab-btn active" data-subtab="byvisit">
|
|
<i class="fas fa-child"></i> By Visit Age
|
|
</button>
|
|
<button class="wv-subtab-btn" data-subtab="milestones">
|
|
<i class="fas fa-baby"></i> Milestones
|
|
</button>
|
|
<button class="wv-subtab-btn" data-subtab="shadess" style="display:none;">
|
|
<i class="fas fa-brain"></i> SSHADESS (12+)
|
|
</button>
|
|
<button class="wv-subtab-btn" data-subtab="note">
|
|
<i class="fas fa-file-medical"></i> Visit Note
|
|
</button>
|
|
</div>
|
|
|
|
<!-- By Visit sub-panel -->
|
|
<div id="wv-panel-byvisit" class="wv-subpanel">
|
|
<div class="wv-visit-selector-row">
|
|
<label for="wv-visit-select"><i class="fas fa-calendar-day"></i> Select Visit Age:</label>
|
|
<select id="wv-visit-select" class="wv-visit-select"></select>
|
|
</div>
|
|
<div id="wv-visit-detail" class="wv-visit-detail">
|
|
<p class="wv-empty">Select a visit age above to see recommendations.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Milestones sub-panel -->
|
|
<div id="wv-panel-milestones" class="wv-subpanel hidden">
|
|
|
|
<div class="demographics-bar">
|
|
<div class="demo-field"><label>Patient Age</label><input type="text" id="ms-age" placeholder="e.g., 9 months"></div>
|
|
<div class="demo-field"><label>Gender</label><select id="ms-gender"><option value="">Select</option><option>Male</option><option>Female</option></select></div>
|
|
<div class="demo-field">
|
|
<label>Age Group</label>
|
|
<select id="ms-age-group">
|
|
<option value="">-- Select --</option>
|
|
<option value="Newborn / 1 month">Newborn / 1 Month</option>
|
|
<option value="2 months">2 Months</option>
|
|
<option value="4 months">4 Months</option>
|
|
<option value="6 months">6 Months</option>
|
|
<option value="9 months">9 Months</option>
|
|
<option value="12 months">12 Months</option>
|
|
<option value="15 months">15 Months</option>
|
|
<option value="18 months">18 Months</option>
|
|
<option value="24 months">2 Years</option>
|
|
<option value="30 months">2.5 Years</option>
|
|
<option value="36 months">3 Years</option>
|
|
<option value="48 months">4 Years</option>
|
|
<option value="60 months">5 Years</option>
|
|
<option value="6 years">6 Years</option>
|
|
<option value="7 years">7 Years</option>
|
|
<option value="8 years">8 Years</option>
|
|
<option value="9 years">9 Years</option>
|
|
<option value="10 years">10 Years</option>
|
|
<option value="11 years">11 Years</option>
|
|
</select>
|
|
</div>
|
|
<div class="demo-field">
|
|
<label>Output Format</label>
|
|
<select id="ms-format">
|
|
<option value="narrative">Narrative (paragraphs)</option>
|
|
<option value="list">Structured List</option>
|
|
</select>
|
|
</div>
|
|
<div class="demo-field demo-field-model">
|
|
<label><i class="fas fa-robot"></i> Model</label>
|
|
<select class="tab-model-select"></select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="legend">
|
|
<div class="legend-item"><span class="legend-icon legend-yes">✓</span> Achieved</div>
|
|
<div class="legend-item"><span class="legend-icon legend-no">✗</span> Not Achieved</div>
|
|
<div class="legend-item"><span class="legend-icon legend-blank">—</span> Not Assessed (omitted)</div>
|
|
</div>
|
|
|
|
<div id="milestone-checklist"></div>
|
|
|
|
<div class="milestone-actions" id="milestone-actions" style="display:none">
|
|
<button id="ms-all-yes" class="btn-sm btn-success"><i class="fas fa-check-double"></i> All Yes</button>
|
|
<button id="ms-all-clear" class="btn-sm btn-ghost"><i class="fas fa-eraser"></i> Clear All</button>
|
|
<button id="ms-generate-btn" class="btn-generate btn-generate-teal"><i class="fas fa-wand-magic-sparkles"></i> Generate Narrative</button>
|
|
</div>
|
|
|
|
<div id="ms-output" class="card output-card hidden">
|
|
<div class="card-header output-header">
|
|
<h3><i class="fas fa-file-medical"></i> Developmental Assessment</h3>
|
|
<div class="output-actions">
|
|
<span id="ms-model-tag" class="model-tag"></span>
|
|
<button class="btn-sm btn-primary" data-action="copy" data-target="ms-narrative-text"><i class="fas fa-copy"></i> Copy</button>
|
|
<button class="btn-sm btn-success" id="btn-ms-copy-to-note"><i class="fas fa-clipboard-check"></i> Copy to Note</button>
|
|
<button class="btn-sm btn-ghost" data-action="speak" data-target="ms-narrative-text"><i class="fas fa-volume-high"></i> Read</button>
|
|
<button class="btn-sm btn-ghost" data-action="nc-export" data-target="ms-narrative-text" data-label="milestones"><i class="fas fa-cloud-arrow-up"></i></button>
|
|
</div>
|
|
</div>
|
|
<div id="ms-summary-bar" class="summary-bar hidden"></div>
|
|
<div id="ms-narrative-text" class="output-text" contenteditable="true"></div>
|
|
<div class="summary-section">
|
|
<div class="summary-section-header">
|
|
<button id="ms-quick-summary-btn" class="btn-generate-summary"><i class="fas fa-compress"></i> 3-Sentence Summary</button>
|
|
</div>
|
|
<div id="ms-quick-summary" class="hidden">
|
|
<div class="card-header summary-output-header">
|
|
<h3><i class="fas fa-clipboard-list"></i> Quick Summary</h3>
|
|
<div class="output-actions">
|
|
<button class="btn-sm btn-primary" data-action="copy" data-target="ms-summary-text"><i class="fas fa-copy"></i> Copy</button>
|
|
</div>
|
|
</div>
|
|
<div id="ms-summary-text" class="summary-output-text" contenteditable="true"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- SSHADESS sub-panel (age 12+) -->
|
|
<div id="wv-panel-shadess" class="wv-subpanel hidden">
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header">
|
|
<h3><i class="fas fa-brain"></i> SSHADESS Psychosocial Screening</h3>
|
|
<span style="font-size:12px;color:var(--g500);">Recommended age 12 and older</span>
|
|
</div>
|
|
<div style="padding:12px 16px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;border-bottom:1px solid var(--g100);">
|
|
<div class="demo-field"><label>Patient Age</label><input type="text" id="shadess-age" placeholder="e.g., 14 years" style="width:120px;"></div>
|
|
<div class="demo-field"><label>Gender</label><select id="shadess-gender"><option value="">Select</option><option>Male</option><option>Female</option><option>Non-binary/Other</option></select></div>
|
|
<div class="demo-field demo-field-model"><label><i class="fas fa-robot"></i> Model</label><select class="tab-model-select"></select></div>
|
|
<div style="margin-left:auto;display:flex;gap:8px;">
|
|
<button id="shadess-record-btn" class="btn-sm btn-ghost"><i class="fas fa-microphone"></i> Listen In</button>
|
|
<button id="shadess-pause-btn" class="btn-sm btn-ghost hidden"><i class="fas fa-pause"></i> Pause</button>
|
|
<div id="shadess-rec-indicator" class="recording-indicator hidden" style="font-size:12px;"><div class="pulse-dot"></div><span>Recording... <span id="shadess-timer">00:00</span></span></div>
|
|
</div>
|
|
</div>
|
|
<!-- Domains will be rendered by JS -->
|
|
<div id="shadess-domains" style="padding:8px 0;"></div>
|
|
<div style="padding:12px 16px;display:flex;gap:8px;flex-wrap:wrap;border-top:1px solid var(--g100);">
|
|
<button id="btn-shadess-generate" class="btn-generate" style="flex:1;"><i class="fas fa-wand-magic-sparkles"></i> Generate SSHADESS Assessment</button>
|
|
</div>
|
|
</div>
|
|
<!-- SSHADESS Output -->
|
|
<div id="shadess-output" class="card output-card hidden">
|
|
<div class="card-header output-header">
|
|
<h3><i class="fas fa-file-medical"></i> SSHADESS Assessment</h3>
|
|
<div class="output-actions">
|
|
<span id="shadess-model-tag" class="model-tag"></span>
|
|
<button class="btn-sm btn-ghost" id="btn-shadess-new-patient"><i class="fas fa-rotate-left"></i> New Patient</button>
|
|
<button class="btn-sm btn-primary" data-action="copy" data-target="shadess-result-text"><i class="fas fa-copy"></i> Copy</button>
|
|
<button class="btn-sm btn-ghost" data-action="speak" data-target="shadess-result-text"><i class="fas fa-volume-high"></i> Read</button>
|
|
</div>
|
|
</div>
|
|
<div id="shadess-result-text" class="output-text" contenteditable="true"></div>
|
|
<div style="padding:10px 16px;font-size:12px;color:var(--g500);">
|
|
<i class="fas fa-info-circle"></i> Use "Copy" to paste this into the Visit Note tab for a complete encounter note.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Visit Note sub-panel -->
|
|
<div id="wv-panel-note" class="wv-subpanel hidden">
|
|
|
|
<!-- Save/Load bar -->
|
|
<div class="save-bar-wrap">
|
|
<div class="save-bar" id="wv-save-bar">
|
|
<div style="display:flex;align-items:center;gap:8px;flex:1;">
|
|
<i class="fas fa-tag" style="color:var(--g400);font-size:13px;"></i>
|
|
<input type="text" id="wv-label" class="save-label-input" placeholder="Patient label (e.g. Jane D, Visit #7)">
|
|
</div>
|
|
<button id="btn-wv-save" class="btn-sm btn-ghost"><i class="fas fa-floppy-disk"></i> Save</button>
|
|
<button id="btn-wv-load" class="btn-sm btn-ghost"><i class="fas fa-folder-open"></i> Load</button>
|
|
<button id="btn-wv-new" class="btn-sm btn-ghost" title="Clear and start new patient" style="color:var(--red);"><i class="fas fa-rotate-left"></i> New</button>
|
|
</div>
|
|
<div id="wv-load-popover" class="enc-load-popover hidden">
|
|
<div class="enc-load-popover-inner">
|
|
<input type="text" id="wv-load-search" class="enc-load-search" placeholder="Search saved encounters...">
|
|
<button class="enc-pop-close btn-sm btn-ghost"><i class="fas fa-times"></i></button>
|
|
</div>
|
|
<div id="wv-pop-list" class="enc-pop-list"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header"><h3><i class="fas fa-stethoscope"></i> Visit Details</h3></div>
|
|
<div style="padding:12px 16px;display:flex;flex-wrap:wrap;gap:10px;">
|
|
<div class="demo-field"><label>Visit Age</label><input type="text" id="wv-note-age" placeholder="e.g., 9 years"></div>
|
|
<div class="demo-field"><label>Gender</label><select id="wv-note-gender"><option value="">Select</option><option>Male</option><option>Female</option></select></div>
|
|
<div class="demo-field demo-field-model"><label><i class="fas fa-robot"></i> Model</label><select class="tab-model-select"></select></div>
|
|
<div style="width:100%;display:flex;gap:8px;align-items:center;">
|
|
<label style="font-size:12px;font-weight:600;color:var(--g600);">Note style:</label>
|
|
<select id="wv-note-style" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
|
|
<option value="full">Full Encounter Note</option>
|
|
<option value="short">Brief SOAP</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header">
|
|
<h3><i class="fas fa-ruler-combined"></i> Vitals & Measurements</h3>
|
|
</div>
|
|
<div style="padding:12px 16px;">
|
|
<textarea id="wv-vitals" rows="3" style="width:100%;font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="e.g., Temp 98.6, HR 78, RR 18, BP 106/68, O2 99% Ht: 135cm (50th%), Wt: 32kg (55th%), BMI: 17.6 (60th%)"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header">
|
|
<h3><i class="fas fa-microphone"></i> Encounter Recording / Dictation</h3>
|
|
<div style="display:flex;gap:6px;align-items:center;">
|
|
<button id="wv-record-btn" class="btn-sm btn-ghost"><i class="fas fa-microphone"></i> Listen In</button>
|
|
<button id="wv-pause-btn" class="btn-sm btn-ghost hidden"><i class="fas fa-pause"></i> Pause</button>
|
|
<div id="wv-rec-indicator" class="recording-indicator hidden" style="font-size:12px;"><div class="pulse-dot"></div><span>Recording... <span id="wv-timer">00:00</span></span></div>
|
|
</div>
|
|
</div>
|
|
<div style="padding:8px 16px;">
|
|
<div id="wv-transcript" class="editable-box" contenteditable="true" style="min-height:80px;" data-placeholder="Transcript of the encounter appears here. You can also type or paste directly. Physician can dictate: 'All physical exam normal aside from...'"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header"><h3><i class="fas fa-syringe"></i> Screenings & Vaccines</h3></div>
|
|
<div style="padding:12px 16px;display:flex;flex-direction:column;gap:8px;">
|
|
<div>
|
|
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">Screenings completed today:</label>
|
|
<textarea id="wv-screenings" rows="2" style="width:100%;font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="e.g., Depression screen (PHQ-A): negative, Vision screen: 20/20 bilateral, Lead level: 2 ug/dL"></textarea>
|
|
</div>
|
|
<div>
|
|
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">Vaccines given today:</label>
|
|
<textarea id="wv-vaccines" rows="2" style="width:100%;font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="e.g., Tdap #1, Meningococcal (MenACWY) #1, HPV #1"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SSHADESS carry-over -->
|
|
<div class="card" style="margin-bottom:10px;" id="wv-shadess-card">
|
|
<div class="card-header">
|
|
<h3><i class="fas fa-brain"></i> SSHADESS Assessment</h3>
|
|
<span style="font-size:12px;color:var(--g500);">From SSHADESS tab (age 12+)</span>
|
|
</div>
|
|
<div style="padding:8px 16px;">
|
|
<textarea id="wv-shadess-text" rows="4" style="width:100%;font-size:12px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="Paste SSHADESS assessment here, or it auto-fills from the SSHADESS tab..."></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Milestones carry-over -->
|
|
<div class="card" style="margin-bottom:10px;" id="wv-milestones-card">
|
|
<div class="card-header">
|
|
<h3><i class="fas fa-baby"></i> Developmental Assessment</h3>
|
|
<span style="font-size:12px;color:var(--g500);">From Milestones tab</span>
|
|
</div>
|
|
<div style="padding:8px 16px;">
|
|
<textarea id="wv-milestones-text" rows="3" style="width:100%;font-size:12px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="Developmental assessment auto-fills when you click 'Copy to Note' on Milestones tab..."></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ROS Card -->
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header" style="display:flex;align-items:center;justify-content:space-between;">
|
|
<h3><i class="fas fa-list-check"></i> Review of Systems (ROS)</h3>
|
|
<button id="wv-ros-all-wnl" class="btn-sm btn-ghost" style="font-size:11px;"><i class="fas fa-check-double"></i> All WNL</button>
|
|
</div>
|
|
<div id="wv-ros-container" style="padding:8px 16px;"></div>
|
|
</div>
|
|
|
|
<!-- Physical Exam Card -->
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header" style="display:flex;align-items:center;justify-content:space-between;">
|
|
<h3><i class="fas fa-stethoscope"></i> Physical Examination (PE)</h3>
|
|
<button id="wv-pe-all-normal" class="btn-sm btn-ghost" style="font-size:11px;"><i class="fas fa-check-double"></i> All Normal</button>
|
|
</div>
|
|
<div id="wv-pe-container" style="padding:8px 16px;"></div>
|
|
</div>
|
|
|
|
<!-- Diagnoses Card -->
|
|
<div class="card" style="margin-bottom:10px;">
|
|
<div class="card-header"><h3><i class="fas fa-tag"></i> Diagnoses (ICD-10)</h3></div>
|
|
<div id="wv-dx-container" style="padding:12px 16px;"></div>
|
|
</div>
|
|
|
|
<button id="btn-wv-generate" class="btn-generate"><i class="fas fa-wand-magic-sparkles"></i> Generate Well Visit Note</button>
|
|
|
|
<div id="wv-note-output" class="card output-card hidden">
|
|
<div class="card-header output-header">
|
|
<h3><i class="fas fa-file-medical"></i> Well Visit Note</h3>
|
|
<div class="output-actions">
|
|
<span id="wv-note-model-tag" class="model-tag"></span>
|
|
<button class="btn-sm btn-ghost" id="btn-wv-new-patient"><i class="fas fa-rotate-left"></i> New Patient</button>
|
|
<button class="btn-sm btn-primary" data-action="copy" data-target="wv-note-text"><i class="fas fa-copy"></i> Copy</button>
|
|
<button class="btn-sm btn-ghost" data-action="speak" data-target="wv-note-text"><i class="fas fa-volume-high"></i> Read</button>
|
|
<button class="btn-sm btn-ghost" data-action="nc-export" data-target="wv-note-text" data-label="well-visit"><i class="fas fa-cloud-arrow-up"></i></button>
|
|
</div>
|
|
</div>
|
|
<div id="wv-note-text" class="output-text" contenteditable="true"></div>
|
|
<div class="refine-bar">
|
|
<input type="text" id="wv-refine-input" class="refine-input" placeholder="Tell AI to modify (e.g., 'add that patient has asthma', 'expand the plan section')">
|
|
<button class="btn-sm btn-primary" id="wv-refine-btn"><i class="fas fa-edit"></i> Refine</button>
|
|
<button class="btn-sm btn-ghost" id="wv-shorten-btn"><i class="fas fa-compress"></i> Shorter</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|