Feat: left sidebar nav, tab persistence, admin models fix, hospital/chart save
- Replace horizontal tab-nav with collapsible left sidebar (sticky desktop, slide-in mobile with hamburger toggle) - Fix tab persistence: use localStorage instead of URL hash; restore last tab after login in enterApp() - Fix admin CMS models loading: move autoDeleteDays read inside .then() callback (was ReferenceError), switch admin loading from click-only to tabChanged event - Add Save/Load bars to Hospital Course and Chart Review tabs with popover support - Add wv (well visit) save handler in encounters.js - Register load handlers for hospital and chart tabs - Expand popover prefix list to include hosp and chart
This commit is contained in:
parent
97f8009d38
commit
bc47be371a
8 changed files with 241 additions and 98 deletions
|
|
@ -50,15 +50,25 @@ body{font-family:'Inter',system-ui,sans-serif;background:var(--g50);color:var(--
|
|||
.btn-header{background:rgba(255,255,255,0.15);border:none;color:white;width:36px;height:36px;border-radius:8px;cursor:pointer;font-size:14px;transition:background 0.2s;}
|
||||
.btn-header:hover{background:rgba(255,255,255,0.3);}
|
||||
|
||||
/* TABS */
|
||||
.tab-nav{display:flex;background:white;border-bottom:2px solid var(--g200);max-width:1200px;margin:0 auto;overflow-x:auto;}
|
||||
.tab-btn{display:flex;align-items:center;gap:6px;padding:12px 18px;border:none;border-bottom:3px solid transparent;background:none;color:var(--g500);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap;font-family:inherit;transition:all 0.2s;}
|
||||
.tab-btn:hover{color:var(--g700);background:var(--g50);}
|
||||
.tab-btn.active{color:var(--blue);border-bottom-color:var(--blue);}
|
||||
.tab-btn i{font-size:15px;}
|
||||
/* APP BODY LAYOUT */
|
||||
.app-body{display:flex;min-height:calc(100vh - 66px);}
|
||||
|
||||
/* SIDEBAR */
|
||||
.sidebar{width:210px;flex-shrink:0;background:white;border-right:1.5px solid var(--g200);display:flex;flex-direction:column;position:sticky;top:0;height:calc(100vh - 66px);overflow-y:auto;z-index:100;}
|
||||
.sidebar-header{display:none;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--g200);}
|
||||
.sidebar-title{font-size:13px;font-weight:700;color:var(--g700);}
|
||||
.sidebar-nav{display:flex;flex-direction:column;padding:8px 0;flex:1;}
|
||||
.sidebar-section-label{font-size:10px;font-weight:700;color:var(--g400);text-transform:uppercase;letter-spacing:0.7px;padding:10px 16px 4px;}
|
||||
.tab-btn{display:flex;align-items:center;gap:10px;padding:10px 16px;border:none;border-left:3px solid transparent;background:none;color:var(--g600);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap;font-family:inherit;transition:all 0.15s;width:100%;text-align:left;}
|
||||
.tab-btn:hover{background:var(--g50);color:var(--g900);}
|
||||
.tab-btn.active{background:var(--blue-light);color:var(--blue);border-left-color:var(--blue);font-weight:600;}
|
||||
.tab-btn i{width:16px;text-align:center;flex-shrink:0;font-size:14px;}
|
||||
.tab-btn span{overflow:hidden;text-overflow:ellipsis;}
|
||||
.sidebar-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:199;}
|
||||
.btn-menu-toggle{display:none;}
|
||||
|
||||
/* MAIN */
|
||||
.main-content{max-width:1200px;margin:0 auto;padding:20px 16px;}
|
||||
.main-content{flex:1;min-width:0;padding:20px 20px;}
|
||||
.tab-content{display:none;}
|
||||
.tab-content.active{display:block;animation:fadeIn 0.25s ease;}
|
||||
@keyframes fadeIn{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:translateY(0);}}
|
||||
|
|
@ -223,13 +233,18 @@ body{font-family:'Inter',system-ui,sans-serif;background:var(--g50);color:var(--
|
|||
|
||||
/* RESPONSIVE */
|
||||
@media(max-width:768px){
|
||||
.header-top{flex-direction:column;align-items:flex-start;}
|
||||
.header-right{width:100%;flex-wrap:wrap;}
|
||||
.header-top{flex-direction:row;align-items:center;}
|
||||
.header-right{flex-wrap:wrap;}
|
||||
.model-selector{flex:1;}
|
||||
.model-selector select{max-width:100%;flex:1;}
|
||||
.tab-btn span{display:none;}
|
||||
.tab-btn{flex:1;justify-content:center;padding:10px;}
|
||||
.tab-btn i{font-size:16px;}
|
||||
.model-selector select{max-width:160px;flex:1;}
|
||||
.btn-menu-toggle{display:flex;align-items:center;justify-content:center;}
|
||||
/* Sidebar: hidden off-screen on mobile, slides in */
|
||||
.app-body{display:block;}
|
||||
.sidebar{position:fixed;left:-220px;top:0;width:220px;height:100vh;z-index:200;transition:left 0.28s ease;box-shadow:none;}
|
||||
.sidebar.open{left:0;box-shadow:4px 0 20px rgba(0,0,0,0.18);}
|
||||
.sidebar.open~.sidebar-overlay{display:block;}
|
||||
.sidebar-header{display:flex;}
|
||||
.main-content{padding:12px;}
|
||||
.demographics-bar{flex-direction:column;}
|
||||
.demo-field input,.demo-field select{min-width:100%;}
|
||||
.note-meta{flex-direction:column;}
|
||||
|
|
|
|||
|
|
@ -102,11 +102,16 @@
|
|||
<header class="app-header">
|
||||
<div class="header-content">
|
||||
<div class="header-top">
|
||||
<div class="logo">
|
||||
<i class="fas fa-stethoscope"></i>
|
||||
<div>
|
||||
<h1>Pediatric AI Scribe</h1>
|
||||
<p class="tagline">Welcome, <span id="user-name">Doctor</span></p>
|
||||
<div style="display:flex;align-items:center;gap:10px;">
|
||||
<button id="btn-menu-toggle" class="btn-header btn-menu-toggle" title="Menu" aria-label="Toggle menu">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<div class="logo">
|
||||
<i class="fas fa-stethoscope"></i>
|
||||
<div>
|
||||
<h1>Pediatric AI Scribe</h1>
|
||||
<p class="tagline">Welcome, <span id="user-name">Doctor</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
|
|
@ -135,50 +140,66 @@
|
|||
<button class="announcement-close" onclick="this.parentElement.classList.add('hidden')" aria-label="Dismiss"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
|
||||
<!-- TAB NAVIGATION -->
|
||||
<nav class="tab-nav">
|
||||
<button class="tab-btn active" data-tab="encounter">
|
||||
<i class="fas fa-comments"></i>
|
||||
<span>Encounter HPI</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="dictation">
|
||||
<i class="fas fa-microphone"></i>
|
||||
<span>Dictation HPI</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="hospital">
|
||||
<i class="fas fa-hospital"></i>
|
||||
<span>Hospital Course</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="chart">
|
||||
<i class="fas fa-clipboard-list"></i>
|
||||
<span>Chart Review</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="soap">
|
||||
<i class="fas fa-file-waveform"></i>
|
||||
<span>SOAP Note</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="milestones">
|
||||
<i class="fas fa-baby"></i>
|
||||
<span>Milestones</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="wellvisit">
|
||||
<i class="fas fa-calendar-check"></i>
|
||||
<span>Well Visit</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="sickvisit">
|
||||
<i class="fas fa-thermometer-half"></i>
|
||||
<span>Sick Visit</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="settings">
|
||||
<i class="fas fa-cog"></i>
|
||||
<span>Settings</span>
|
||||
</button>
|
||||
<button class="tab-btn hidden" data-tab="admin" id="admin-tab-btn">
|
||||
<i class="fas fa-user-shield"></i>
|
||||
<span>Admin</span>
|
||||
</button>
|
||||
<div class="app-body">
|
||||
|
||||
<!-- SIDEBAR NAVIGATION -->
|
||||
<nav class="sidebar" id="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<span class="sidebar-title"><i class="fas fa-stethoscope"></i> Menu</span>
|
||||
<button id="btn-sidebar-close" class="btn-sm btn-ghost" title="Close menu" style="padding:4px 8px;">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="sidebar-nav">
|
||||
<span class="sidebar-section-label">Encounters</span>
|
||||
<button class="tab-btn active" data-tab="encounter">
|
||||
<i class="fas fa-comments"></i>
|
||||
<span>Encounter HPI</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="dictation">
|
||||
<i class="fas fa-microphone"></i>
|
||||
<span>Dictation HPI</span>
|
||||
</button>
|
||||
<span class="sidebar-section-label">Notes</span>
|
||||
<button class="tab-btn" data-tab="hospital">
|
||||
<i class="fas fa-hospital"></i>
|
||||
<span>Hospital Course</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="chart">
|
||||
<i class="fas fa-clipboard-list"></i>
|
||||
<span>Chart Review</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="soap">
|
||||
<i class="fas fa-file-waveform"></i>
|
||||
<span>SOAP Note</span>
|
||||
</button>
|
||||
<span class="sidebar-section-label">Pediatric</span>
|
||||
<button class="tab-btn" data-tab="milestones">
|
||||
<i class="fas fa-baby"></i>
|
||||
<span>Milestones</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="wellvisit">
|
||||
<i class="fas fa-calendar-check"></i>
|
||||
<span>Well Visit</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="sickvisit">
|
||||
<i class="fas fa-thermometer-half"></i>
|
||||
<span>Sick Visit</span>
|
||||
</button>
|
||||
<span class="sidebar-section-label">Account</span>
|
||||
<button class="tab-btn" data-tab="settings">
|
||||
<i class="fas fa-cog"></i>
|
||||
<span>Settings</span>
|
||||
</button>
|
||||
<button class="tab-btn hidden" data-tab="admin" id="admin-tab-btn">
|
||||
<i class="fas fa-user-shield"></i>
|
||||
<span>Admin</span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
||||
|
||||
<main class="main-content">
|
||||
|
||||
<!-- ===== TAB: ENCOUNTER HPI ===== -->
|
||||
|
|
@ -386,6 +407,25 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Save/Load bar -->
|
||||
<div class="save-bar-wrap">
|
||||
<div class="save-bar" id="hosp-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="hosp-label" class="save-label-input" placeholder="Patient label (e.g. John D, Visit #42)">
|
||||
</div>
|
||||
<button id="btn-hosp-save" class="btn-sm btn-ghost"><i class="fas fa-floppy-disk"></i> Save</button>
|
||||
<button id="btn-hosp-load" class="btn-sm btn-ghost"><i class="fas fa-folder-open"></i> Load</button>
|
||||
</div>
|
||||
<div id="hosp-load-popover" class="enc-load-popover hidden">
|
||||
<div class="enc-load-popover-inner">
|
||||
<input type="text" id="hosp-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="hosp-pop-list" class="enc-pop-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ED Note -->
|
||||
<div class="card">
|
||||
<div class="card-header"><h3><i class="fas fa-truck-medical"></i> ED Note (before admission)</h3></div>
|
||||
|
|
@ -513,6 +553,25 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Save/Load bar -->
|
||||
<div class="save-bar-wrap">
|
||||
<div class="save-bar" id="chart-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="chart-label" class="save-label-input" placeholder="Patient label (e.g. John D, Visit #42)">
|
||||
</div>
|
||||
<button id="btn-chart-save" class="btn-sm btn-ghost"><i class="fas fa-floppy-disk"></i> Save</button>
|
||||
<button id="btn-chart-load" class="btn-sm btn-ghost"><i class="fas fa-folder-open"></i> Load</button>
|
||||
</div>
|
||||
<div id="chart-load-popover" class="enc-load-popover hidden">
|
||||
<div class="enc-load-popover-inner">
|
||||
<input type="text" id="chart-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="chart-pop-list" class="enc-pop-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Visits -->
|
||||
<div id="cr-visits-container">
|
||||
<div class="card visit-card">
|
||||
|
|
@ -1285,7 +1344,7 @@
|
|||
</section>
|
||||
|
||||
<!-- ===== TAB: SETTINGS ===== -->
|
||||
<section id="settings-tab" class="tab-content hidden">
|
||||
<section id="settings-tab" class="tab-content">
|
||||
<div class="module-header">
|
||||
<h2><i class="fas fa-cog"></i> Settings</h2>
|
||||
<p>Account security, integrations, and personal templates</p>
|
||||
|
|
@ -1388,6 +1447,8 @@
|
|||
|
||||
</main>
|
||||
|
||||
</div><!-- /.app-body -->
|
||||
|
||||
<!-- dummy settings-modal kept for any stale JS references -->
|
||||
<div id="settings-modal" class="hidden" style="display:none !important;"></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@
|
|||
|
||||
var loaded = false;
|
||||
|
||||
// Load admin panel when tab is clicked
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.tab-btn');
|
||||
if (btn && btn.getAttribute('data-tab') === 'admin') {
|
||||
// Load admin panel when admin tab is activated
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail && e.detail.tab === 'admin') {
|
||||
if (!loaded) { loadAdmin(); loaded = true; }
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
// Refresh button
|
||||
if (e.target.closest('#btn-refresh-users')) {
|
||||
loadUsers();
|
||||
|
|
@ -237,12 +239,14 @@
|
|||
|
||||
var cmsLoaded = false;
|
||||
|
||||
// Load CMS when admin tab is opened
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.tab-btn');
|
||||
if (btn && btn.getAttribute('data-tab') === 'admin') {
|
||||
// Load CMS when admin tab is opened (via tabChanged event or click)
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail && e.detail.tab === 'admin') {
|
||||
if (!cmsLoaded) { loadCms(); cmsLoaded = true; }
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
|
||||
// Save buttons
|
||||
if (e.target.closest('#btn-save-announcement')) saveAnnouncement();
|
||||
|
|
@ -288,6 +292,13 @@
|
|||
if (flagReadAloud) flagReadAloud.value = cfg['feature.read_aloud'] !== undefined ? cfg['feature.read_aloud'] : 'true';
|
||||
if (flagNextcloud) flagNextcloud.value = cfg['feature.nextcloud'] !== undefined ? cfg['feature.nextcloud'] : 'true';
|
||||
|
||||
// Auto-delete setting
|
||||
var autoDeleteDays = cfg['site.auto_delete_days'] || '7';
|
||||
var el = document.getElementById('cms-auto-delete-days');
|
||||
if (el) el.value = autoDeleteDays;
|
||||
el = document.getElementById('admin-auto-delete-days');
|
||||
if (el) el.textContent = autoDeleteDays;
|
||||
|
||||
// Email — load verify template by default
|
||||
window._adminEmailConfig = cfg;
|
||||
loadEmailFields('verify');
|
||||
|
|
@ -297,13 +308,6 @@
|
|||
loadPromptList();
|
||||
loadSmtp();
|
||||
loadModels();
|
||||
|
||||
// Auto-delete setting
|
||||
var autoDeleteDays = cfg['site.auto_delete_days'] || '7';
|
||||
var el = document.getElementById('cms-auto-delete-days');
|
||||
if (el) el.value = autoDeleteDays;
|
||||
el = document.getElementById('admin-auto-delete-days');
|
||||
if (el) el.textContent = autoDeleteDays;
|
||||
}
|
||||
|
||||
// ---- ANNOUNCEMENT ----
|
||||
|
|
|
|||
|
|
@ -35,21 +35,41 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
btn.classList.add('active');
|
||||
var tabEl = document.getElementById(tabName + '-tab');
|
||||
if (tabEl) tabEl.classList.add('active');
|
||||
window.location.hash = tabName;
|
||||
// Persist last tab in localStorage (restored after login in auth.js)
|
||||
try { localStorage.setItem('ped_last_tab', tabName); } catch(e) {}
|
||||
document.dispatchEvent(new CustomEvent('tabChanged', { detail: { tab: tabName } }));
|
||||
// Close sidebar on mobile after tab click
|
||||
var sidebar = document.getElementById('sidebar');
|
||||
if (sidebar && window.innerWidth <= 768) {
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Expose activateTab globally so auth.js can call it after login
|
||||
window.activateTab = activateTab;
|
||||
|
||||
document.querySelectorAll('.tab-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
activateTab(btn.getAttribute('data-tab'));
|
||||
});
|
||||
});
|
||||
|
||||
// Restore tab from URL hash on load
|
||||
var hash = window.location.hash.replace('#', '');
|
||||
if (!hash || !activateTab(hash)) {
|
||||
activateTab('encounter'); // default
|
||||
// --- SIDEBAR TOGGLE ---
|
||||
var sidebar = document.getElementById('sidebar');
|
||||
var sidebarOverlay = document.getElementById('sidebar-overlay');
|
||||
document.addEventListener('click', function(e) {
|
||||
if (e.target.closest('#btn-menu-toggle')) {
|
||||
if (sidebar) sidebar.classList.toggle('open');
|
||||
}
|
||||
if (e.target.closest('#btn-sidebar-close') || e.target.closest('#sidebar-overlay')) {
|
||||
if (sidebar) sidebar.classList.remove('open');
|
||||
}
|
||||
});
|
||||
if (sidebarOverlay) {
|
||||
sidebarOverlay.addEventListener('click', function() {
|
||||
if (sidebar) sidebar.classList.remove('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Load settings data when settings tab is activated
|
||||
|
|
|
|||
|
|
@ -94,6 +94,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
|
||||
console.log('[Auth] ✅ Entered app as:', user.email, 'Role:', user.role);
|
||||
|
||||
// Restore last visited tab (saved by activateTab)
|
||||
var lastTab = null;
|
||||
try { lastTab = localStorage.getItem('ped_last_tab'); } catch(e) {}
|
||||
if (typeof window.activateTab === 'function') {
|
||||
if (!lastTab || !window.activateTab(lastTab)) {
|
||||
window.activateTab('encounter');
|
||||
}
|
||||
}
|
||||
|
||||
// Load announcement banner if function is available
|
||||
if (typeof loadAnnouncement === 'function') loadAnnouncement();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,5 +113,15 @@
|
|||
document.getElementById('cr-refine-btn').addEventListener('click', function() { refineDocument('cr-review-text', 'cr-refine-input'); });
|
||||
document.getElementById('cr-shorten-btn').addEventListener('click', function() { shortenDocument('cr-review-text'); });
|
||||
|
||||
// Register load handler for saved encounters
|
||||
window.registerEncounterLoadHandler('chart', function(enc) {
|
||||
if (enc.generated_note) {
|
||||
var reviewText = document.getElementById('cr-review-text');
|
||||
var outputCard = document.getElementById('cr-output');
|
||||
if (reviewText) reviewText.textContent = enc.generated_note;
|
||||
if (outputCard) outputCard.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ Chart Review module loaded');
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@
|
|||
_savedEncounters = data.encounters || [];
|
||||
renderSavedList();
|
||||
// Refresh any open popovers
|
||||
['enc', 'dict', 'wv', 'sick'].forEach(function(pfx) {
|
||||
['enc', 'dict', 'wv', 'sick', 'hosp', 'chart'].forEach(function(pfx) {
|
||||
var pop = document.getElementById(pfx + '-load-popover');
|
||||
if (pop && !pop.classList.contains('hidden')) {
|
||||
var search = pop.querySelector('.enc-load-search');
|
||||
|
|
@ -190,7 +190,7 @@
|
|||
if (!popover) return;
|
||||
var isHidden = popover.classList.contains('hidden');
|
||||
// Close all popovers first
|
||||
['enc', 'dict', 'wv', 'sick'].forEach(function(p) {
|
||||
['enc', 'dict', 'wv', 'sick', 'hosp', 'chart'].forEach(function(p) {
|
||||
var pop = document.getElementById(p + '-load-popover');
|
||||
if (pop) pop.classList.add('hidden');
|
||||
});
|
||||
|
|
@ -228,15 +228,16 @@
|
|||
if (!data.success) { showToast(data.error || 'Failed', 'error'); return; }
|
||||
var enc = data.encounter;
|
||||
// Close all popovers
|
||||
['enc', 'dict', 'wv', 'sick'].forEach(function(p) {
|
||||
['enc', 'dict', 'wv', 'sick', 'hosp', 'chart'].forEach(function(p) {
|
||||
var pop = document.getElementById(p + '-load-popover');
|
||||
if (pop) pop.classList.add('hidden');
|
||||
});
|
||||
|
||||
// Navigate to correct tab
|
||||
var tabMap = {
|
||||
encounter: 'encounter', dictation: 'dictation', hospital: 'hospital',
|
||||
chart: 'chart', soap: 'soap', milestones: 'milestones',
|
||||
encounter: 'encounter', dictation: 'dictation',
|
||||
hospital: 'hospital', chart: 'chart',
|
||||
soap: 'soap', milestones: 'milestones',
|
||||
wellvisit: 'wellvisit', sickvisit: 'sickvisit'
|
||||
};
|
||||
var tabName = tabMap[enc.enc_type] || 'encounter';
|
||||
|
|
@ -294,17 +295,23 @@
|
|||
loadSavedEncountersList();
|
||||
}
|
||||
// Save buttons per tab
|
||||
if (e.target.closest('#btn-enc-save')) saveFromTab('encounter', 'enc');
|
||||
if (e.target.closest('#btn-dict-save')) saveFromTab('dictation', 'dict');
|
||||
if (e.target.closest('#btn-enc-save')) saveFromTab('encounter', 'enc');
|
||||
if (e.target.closest('#btn-dict-save')) saveFromTab('dictation', 'dict');
|
||||
if (e.target.closest('#btn-hosp-save')) saveFromTab('hospital', 'hosp');
|
||||
if (e.target.closest('#btn-chart-save')) saveFromTab('chart', 'chart');
|
||||
if (e.target.closest('#btn-wv-save')) saveFromTab('wellvisit', 'wv');
|
||||
// Load buttons — open inline popovers
|
||||
if (e.target.closest('#btn-enc-load')) openLoadPopover('enc');
|
||||
if (e.target.closest('#btn-dict-load')) openLoadPopover('dict');
|
||||
if (e.target.closest('#btn-wv-load')) openLoadPopover('wv');
|
||||
if (e.target.closest('#btn-sick-load')) openLoadPopover('sick');
|
||||
// Close popovers when clicking outside (popover stops its own propagation so this only fires for outside clicks)
|
||||
if (!e.target.closest('#btn-enc-load') && !e.target.closest('#btn-dict-load') &&
|
||||
!e.target.closest('#btn-wv-load') && !e.target.closest('#btn-sick-load')) {
|
||||
['enc', 'dict', 'wv', 'sick'].forEach(function(p) {
|
||||
if (e.target.closest('#btn-enc-load')) openLoadPopover('enc');
|
||||
if (e.target.closest('#btn-dict-load')) openLoadPopover('dict');
|
||||
if (e.target.closest('#btn-wv-load')) openLoadPopover('wv');
|
||||
if (e.target.closest('#btn-sick-load')) openLoadPopover('sick');
|
||||
if (e.target.closest('#btn-hosp-load')) openLoadPopover('hosp');
|
||||
if (e.target.closest('#btn-chart-load')) openLoadPopover('chart');
|
||||
// Close popovers when clicking outside
|
||||
var loadBtnIds = ['#btn-enc-load','#btn-dict-load','#btn-wv-load','#btn-sick-load','#btn-hosp-load','#btn-chart-load'];
|
||||
var clickedLoadBtn = loadBtnIds.some(function(id) { return e.target.closest(id); });
|
||||
if (!clickedLoadBtn) {
|
||||
['enc', 'dict', 'wv', 'sick', 'hosp', 'chart'].forEach(function(p) {
|
||||
var pop = document.getElementById(p + '-load-popover');
|
||||
if (pop) pop.classList.add('hidden');
|
||||
});
|
||||
|
|
@ -313,13 +320,20 @@
|
|||
|
||||
function saveFromTab(type, prefix) {
|
||||
var labelEl = document.getElementById(prefix + '-label');
|
||||
var transcriptEl = document.getElementById(prefix + '-transcript');
|
||||
var noteEl = document.getElementById(prefix + '-hpi-text');
|
||||
var label = labelEl ? labelEl.value.trim() : '';
|
||||
if (!label) { showToast('Enter a patient label before saving', 'error'); return; }
|
||||
|
||||
var savedId = window['_savedEncId_' + type] || null;
|
||||
|
||||
var transcriptEl = document.getElementById(prefix + '-transcript');
|
||||
// Each tab stores its generated note in a different element
|
||||
var noteIdMap = {
|
||||
encounter: 'enc-hpi-text', dictation: 'dict-hpi-text',
|
||||
hospital: 'hc-course-text', chart: 'cr-review-text',
|
||||
wellvisit: 'wv-note-text'
|
||||
};
|
||||
var noteEl = document.getElementById(noteIdMap[type] || (prefix + '-hpi-text'));
|
||||
|
||||
window.saveEncounter({
|
||||
id: savedId,
|
||||
label: label,
|
||||
|
|
|
|||
|
|
@ -191,5 +191,15 @@
|
|||
.catch(function(err) { hideLoading(); showToast(err.message, 'error'); });
|
||||
});
|
||||
|
||||
// Register load handler for saved encounters
|
||||
window.registerEncounterLoadHandler('hospital', function(enc) {
|
||||
if (enc.generated_note) {
|
||||
var courseText = document.getElementById('hc-course-text');
|
||||
var outputCard = document.getElementById('hc-output');
|
||||
if (courseText) courseText.textContent = enc.generated_note;
|
||||
if (outputCard) outputCard.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ Hospital Course module loaded');
|
||||
})();
|
||||
|
|
|
|||
Loading…
Reference in a new issue