new updates
Build Curio HMS / build-and-deploy (push) Successful in 45s
Details
Build Curio HMS / build-and-deploy (push) Successful in 45s
Details
This commit is contained in:
parent
e693ba30f3
commit
34ffbf6339
|
|
@ -302,6 +302,25 @@
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section-page-header {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-page-header h1 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
color: var(--text-main);
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-page-header p {
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-body.role-doctor .section-page-header:not(.hidden) + #doctor-zen-section {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Dashboard page layout & components --- */
|
/* --- Dashboard page layout & components --- */
|
||||||
.dash-header {
|
.dash-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,15 @@
|
||||||
<span class="logo-icon">C</span>
|
<span class="logo-icon">C</span>
|
||||||
<span class="logo-text" data-tenant-name>Curio</span>
|
<span class="logo-text" data-tenant-name>Curio</span>
|
||||||
</div>
|
</div>
|
||||||
<nav class="side-nav">
|
<nav class="side-nav" id="sideNav">
|
||||||
<a href="#" class="active" onclick="showSection('overview')"><span>🏠</span> Overview</a>
|
<a href="#" data-section="overview" class="active"><span>🏠</span> Overview</a>
|
||||||
<a href="#" onclick="showSection('queue')"><span>👥</span> Queue</a>
|
<a href="#" data-section="queue"><span>👥</span> Queue</a>
|
||||||
<a href="#" onclick="showSection('patients')"><span>📂</span> Patients</a>
|
<a href="#" data-section="patients"><span>📂</span> Patients</a>
|
||||||
<a href="#" onclick="showSection('pharmacy')"><span>💊</span> Pharmacy</a>
|
<a href="#" data-section="pharmacy"><span>💊</span> Pharmacy</a>
|
||||||
<a href="#" onclick="showSection('lab')"><span>🔬</span> Lab</a>
|
<a href="#" data-section="lab"><span>🔬</span> Lab</a>
|
||||||
<a href="billing.html"><span>💳</span> Billing & Accounts</a>
|
<a href="billing.html" data-section="billing" data-external><span>💳</span> Billing & Accounts</a>
|
||||||
<a href="staff.html"><span>👔</span> Staff & Payroll</a>
|
<a href="staff.html" data-section="staff" data-external><span>👔</span> Staff & Payroll</a>
|
||||||
<a href="settings.html"><span>⚙️</span> Settings</a>
|
<a href="settings.html" data-section="settings" data-external><span>⚙️</span> Settings</a>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="user-profile">
|
<div class="user-profile">
|
||||||
<div class="avatar">DS</div>
|
<div class="avatar">DS</div>
|
||||||
|
|
@ -55,6 +55,11 @@
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<div id="section-page-header" class="section-page-header hidden">
|
||||||
|
<h1 id="sectionPageTitle"></h1>
|
||||||
|
<p id="sectionPageSubtitle"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- DOCTOR ZEN VIEW (Clinical Focus) -->
|
<!-- DOCTOR ZEN VIEW (Clinical Focus) -->
|
||||||
<div id="doctor-zen-section" class="hidden">
|
<div id="doctor-zen-section" class="hidden">
|
||||||
<div class="zen-layout">
|
<div class="zen-layout">
|
||||||
|
|
@ -427,6 +432,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="dashboard.js?v=18"></script>
|
<script src="dashboard.js?v=19"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
174
dashboard.js
174
dashboard.js
|
|
@ -25,36 +25,139 @@ const patientDataStore = {
|
||||||
"#014": { notes: "", summary: "" }
|
"#014": { notes: "", summary: "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SECTION_META = {
|
||||||
|
overview: {
|
||||||
|
target: 'overview-section',
|
||||||
|
title: 'Clinic Overview',
|
||||||
|
subtitle: 'Live queue, stats, and AI insights for today.'
|
||||||
|
},
|
||||||
|
queue: {
|
||||||
|
target: 'overview-section',
|
||||||
|
title: 'Live Queue',
|
||||||
|
subtitle: 'Patients waiting and in consultation.'
|
||||||
|
},
|
||||||
|
patients: {
|
||||||
|
target: 'patients-section',
|
||||||
|
title: 'Patient Records',
|
||||||
|
subtitle: 'Search history, visits, and contact details.'
|
||||||
|
},
|
||||||
|
pharmacy: {
|
||||||
|
target: 'pharmacy-section',
|
||||||
|
title: 'Pharmacy',
|
||||||
|
subtitle: 'Inventory, prescriptions, and stock alerts.'
|
||||||
|
},
|
||||||
|
lab: {
|
||||||
|
target: 'lab-section',
|
||||||
|
title: 'Laboratory',
|
||||||
|
subtitle: 'Orders, sample collection, and results.'
|
||||||
|
},
|
||||||
|
zen: {
|
||||||
|
target: 'doctor-zen-section',
|
||||||
|
title: 'Clinical Workspace',
|
||||||
|
subtitle: 'Document visits, prescribe, and review vitals.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ROLE_CONFIG = {
|
||||||
|
DOCTOR: {
|
||||||
|
hideSections: ['overview', 'billing', 'staff'],
|
||||||
|
defaultSection: 'zen',
|
||||||
|
displayName: 'Dr. Sharma'
|
||||||
|
},
|
||||||
|
OWNER: {
|
||||||
|
hideSections: [],
|
||||||
|
defaultSection: 'overview',
|
||||||
|
displayName: null
|
||||||
|
},
|
||||||
|
RECEPTIONIST: {
|
||||||
|
hideSections: ['pharmacy', 'lab'],
|
||||||
|
defaultSection: 'queue',
|
||||||
|
displayName: 'Reception'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getUserRole() {
|
||||||
|
return localStorage.getItem('userRole') || 'OWNER';
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveSectionTarget(sectionId) {
|
||||||
|
const role = getUserRole();
|
||||||
|
const config = ROLE_CONFIG[role] || ROLE_CONFIG.OWNER;
|
||||||
|
|
||||||
|
if (sectionId === 'queue' && role === 'DOCTOR') return 'doctor-zen-section';
|
||||||
|
if (sectionId === 'zen') return 'doctor-zen-section';
|
||||||
|
|
||||||
|
const meta = SECTION_META[sectionId];
|
||||||
|
return meta ? meta.target : 'overview-section';
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSectionPageHeader(sectionId) {
|
||||||
|
const header = document.getElementById('section-page-header');
|
||||||
|
const titleEl = document.getElementById('sectionPageTitle');
|
||||||
|
const subtitleEl = document.getElementById('sectionPageSubtitle');
|
||||||
|
if (!header || !titleEl || !subtitleEl) return;
|
||||||
|
|
||||||
|
const isDoctor = getUserRole() === 'DOCTOR';
|
||||||
|
const isClinicalView = sectionId === 'zen' || sectionId === 'queue';
|
||||||
|
const meta = SECTION_META[sectionId];
|
||||||
|
|
||||||
|
if (isDoctor && !isClinicalView && meta) {
|
||||||
|
titleEl.textContent = meta.title;
|
||||||
|
subtitleEl.textContent = meta.subtitle;
|
||||||
|
header.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
header.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActiveNavLink(sectionId) {
|
||||||
|
const isDoctor = getUserRole() === 'DOCTOR';
|
||||||
|
const activeKey = (sectionId === 'zen' || (sectionId === 'queue' && isDoctor)) ? 'queue' : sectionId;
|
||||||
|
|
||||||
|
document.querySelectorAll('.side-nav a[data-section]').forEach(link => {
|
||||||
|
link.classList.toggle('active', link.dataset.section === activeKey);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyRoleNav() {
|
||||||
|
const role = getUserRole();
|
||||||
|
const config = ROLE_CONFIG[role] || ROLE_CONFIG.OWNER;
|
||||||
|
|
||||||
|
document.querySelectorAll('.side-nav a[data-section]').forEach(link => {
|
||||||
|
const hidden = config.hideSections.includes(link.dataset.section);
|
||||||
|
link.style.display = hidden ? 'none' : '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Initialization & Speech Recognition Setup
|
// 2. Initialization & Speech Recognition Setup
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const userRole = localStorage.getItem('userRole') || 'OWNER';
|
const userRole = getUserRole();
|
||||||
const userEmail = localStorage.getItem('userEmail') || 'admin@curio.app';
|
const userEmail = localStorage.getItem('userEmail') || 'admin@curio.app';
|
||||||
|
const config = ROLE_CONFIG[userRole] || ROLE_CONFIG.OWNER;
|
||||||
// Set Sidebar Profile
|
|
||||||
const roleDisplay = document.querySelector(".user-profile .info strong");
|
const roleDisplay = document.querySelector(".user-profile .info strong");
|
||||||
const emailDisplay = document.querySelector(".user-profile .info span");
|
const emailDisplay = document.querySelector(".user-profile .info span");
|
||||||
if (roleDisplay) roleDisplay.innerText = userRole.charAt(0) + userRole.slice(1).toLowerCase();
|
|
||||||
|
if (roleDisplay) {
|
||||||
|
roleDisplay.innerText = config.displayName || (userRole.charAt(0) + userRole.slice(1).toLowerCase());
|
||||||
|
}
|
||||||
if (emailDisplay) emailDisplay.innerText = userEmail;
|
if (emailDisplay) emailDisplay.innerText = userEmail;
|
||||||
|
|
||||||
// Apply Role-Based Filtering
|
|
||||||
if (userRole === 'DOCTOR') {
|
if (userRole === 'DOCTOR') {
|
||||||
document.body.classList.add('role-doctor');
|
document.body.classList.add('role-doctor');
|
||||||
|
|
||||||
document.querySelectorAll('.side-nav a').forEach(link => {
|
|
||||||
const text = link.innerText;
|
|
||||||
if (text.includes('Billing') || text.includes('Staff') || text.includes('Overview')) {
|
|
||||||
link.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (roleDisplay) roleDisplay.innerText = 'Dr. Sharma';
|
|
||||||
if (emailDisplay) emailDisplay.innerText = userEmail;
|
|
||||||
|
|
||||||
showSection('zen');
|
|
||||||
} else {
|
|
||||||
showSection('overview');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyRoleNav();
|
||||||
|
|
||||||
|
document.getElementById('sideNav')?.addEventListener('click', (e) => {
|
||||||
|
const link = e.target.closest('a[data-section]');
|
||||||
|
if (!link || link.hasAttribute('data-external')) return;
|
||||||
|
e.preventDefault();
|
||||||
|
showSection(link.dataset.section);
|
||||||
|
});
|
||||||
|
|
||||||
|
showSection(config.defaultSection === 'zen' ? 'zen' : config.defaultSection);
|
||||||
|
|
||||||
// AI Nudge Simulation Logic
|
// AI Nudge Simulation Logic
|
||||||
const notesArea = document.getElementById("consultationNotes");
|
const notesArea = document.getElementById("consultationNotes");
|
||||||
const nudgeText = document.getElementById("aiNudgeText");
|
const nudgeText = document.getElementById("aiNudgeText");
|
||||||
|
|
@ -99,24 +202,24 @@ window.showSection = (sectionId) => {
|
||||||
const el = document.getElementById(id);
|
const el = document.getElementById(id);
|
||||||
if (el) el.classList.add('hidden');
|
if (el) el.classList.add('hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
const target = (sectionId === 'zen' || (sectionId === 'queue' && localStorage.getItem('userRole') === 'DOCTOR'))
|
const target = resolveSectionTarget(sectionId);
|
||||||
? 'doctor-zen-section'
|
|
||||||
: (sectionId === 'patients' ? 'patients-section'
|
|
||||||
: (sectionId === 'pharmacy' ? 'pharmacy-section'
|
|
||||||
: (sectionId === 'lab' ? 'lab-section' : 'overview-section')));
|
|
||||||
|
|
||||||
const targetEl = document.getElementById(target);
|
const targetEl = document.getElementById(target);
|
||||||
if (targetEl) targetEl.classList.remove('hidden');
|
if (targetEl) targetEl.classList.remove('hidden');
|
||||||
|
|
||||||
document.querySelectorAll('.side-nav a').forEach(link => {
|
if (sectionId === 'queue' && target === 'overview-section') {
|
||||||
link.classList.remove('active');
|
document.getElementById('queue-section')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
if (sectionId === 'zen' && link.innerText.includes('Queue')) {
|
}
|
||||||
link.classList.add('active');
|
|
||||||
} else if (link.innerText.toLowerCase().includes(sectionId)) {
|
const headerSection = (sectionId === 'queue' && getUserRole() === 'DOCTOR') ? 'zen' : sectionId;
|
||||||
link.classList.add('active');
|
updateSectionPageHeader(headerSection);
|
||||||
}
|
setActiveNavLink(sectionId);
|
||||||
});
|
|
||||||
|
if (window.innerWidth <= 768) {
|
||||||
|
document.getElementById('sidebar')?.classList.remove('open');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 4. Clinical Context & Scribe Logic
|
// 4. Clinical Context & Scribe Logic
|
||||||
|
|
@ -243,8 +346,7 @@ window.openConsultation = () => {
|
||||||
window.shareSummary = () => alert("📤 Summary sent to Patient's WhatsApp.");
|
window.shareSummary = () => alert("📤 Summary sent to Patient's WhatsApp.");
|
||||||
window.printSummary = () => alert("🖨️ Printing Handover Note...");
|
window.printSummary = () => alert("🖨️ Printing Handover Note...");
|
||||||
window.toggleSidebar = () => {
|
window.toggleSidebar = () => {
|
||||||
const sb = document.getElementById('sidebar');
|
document.getElementById('sidebar')?.classList.toggle('open');
|
||||||
sb.style.display = (sb.style.display === 'flex') ? 'none' : 'flex';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Global Listeners
|
// Global Listeners
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue