feat: implement autonomous clinical summarization and persistent review store
Build Curio HMS / build-and-deploy (push) Successful in 48s
Details
Build Curio HMS / build-and-deploy (push) Successful in 48s
Details
This commit is contained in:
parent
f44abca4f9
commit
3b0115bbac
|
|
@ -628,7 +628,36 @@
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-scribe {
|
.clinical-workspace-area {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card {
|
||||||
|
background: linear-gradient(135deg, #F0FDF4 0%, #DCFCE7 100%);
|
||||||
|
border: 1px solid #BBF7D0;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
box-shadow: 0 4px 12px rgba(34, 197, 94, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-content {
|
||||||
|
background: white;
|
||||||
|
padding: 1.2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin: 1rem 0;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #166534;
|
||||||
|
line-height: 1.6;
|
||||||
|
border-left: 4px solid #22C55E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
background: var(--secondary);
|
background: var(--secondary);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
||||||
|
|
@ -100,10 +100,22 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="zen-grid">
|
<div class="zen-grid">
|
||||||
<div class="clinical-notes-card">
|
<div class="clinical-workspace-area">
|
||||||
<div class="card-header">Consultation Notes</div>
|
<div class="clinical-notes-card">
|
||||||
<textarea placeholder="Start typing or use Voice AI..." class="zen-textarea"></textarea>
|
<div class="card-header">Consultation Notes</div>
|
||||||
|
<textarea id="consultationNotes" placeholder="Start typing or use Voice AI..." class="zen-textarea"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="aiSummaryCard" class="summary-card hidden">
|
||||||
|
<div class="card-header">✨ AI Clinical Summary</div>
|
||||||
|
<div id="summaryText" class="summary-content"></div>
|
||||||
|
<div class="summary-actions">
|
||||||
|
<button class="btn-small secondary" onclick="shareSummary()">📤 Send to Patient</button>
|
||||||
|
<button class="btn-small secondary" onclick="printSummary()">🖨️ Print Summary</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="quick-links">
|
<div class="quick-links">
|
||||||
<div class="card-header">Quick References</div>
|
<div class="card-header">Quick References</div>
|
||||||
<button class="btn-small secondary">Diabetes Guidelines</button>
|
<button class="btn-small secondary">Diabetes Guidelines</button>
|
||||||
|
|
|
||||||
84
dashboard.js
84
dashboard.js
|
|
@ -131,13 +131,19 @@ if (startRecordBtn) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. AI Scribe & Context Switching Logic
|
// 6. AI Scribe, Summarization & Context Switching Logic
|
||||||
let isScribing = false;
|
let isScribing = false;
|
||||||
|
let currentPatientId = "#012";
|
||||||
|
const patientDataStore = {
|
||||||
|
"#012": { notes: "", summary: "" },
|
||||||
|
"#013": { notes: "", summary: "" },
|
||||||
|
"#014": { notes: "", summary: "" }
|
||||||
|
};
|
||||||
|
|
||||||
window.toggleZenScribe = () => {
|
window.toggleZenScribe = () => {
|
||||||
const btn = document.getElementById("zenScribeBtn");
|
const btn = document.getElementById("zenScribeBtn");
|
||||||
const status = document.getElementById("scribeStatus");
|
const status = document.getElementById("scribeStatus");
|
||||||
const notes = document.querySelector(".zen-textarea");
|
const notesArea = document.getElementById("consultationNotes");
|
||||||
|
|
||||||
isScribing = !isScribing;
|
isScribing = !isScribing;
|
||||||
|
|
||||||
|
|
@ -146,42 +152,90 @@ window.toggleZenScribe = () => {
|
||||||
btn.style.background = "#EF4444";
|
btn.style.background = "#EF4444";
|
||||||
status.classList.remove("hidden");
|
status.classList.remove("hidden");
|
||||||
|
|
||||||
// Simulate AI Scribe capturing notes
|
// Simulate AI capturing notes
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (isScribing) {
|
if (isScribing) {
|
||||||
notes.value += "Patient reports symptoms of fatigue and persistent dry cough for 3 days. No fever recorded today. \n";
|
notesArea.value += "Patient reports symptoms of fatigue and persistent dry cough for 3 days. No fever recorded today. \n";
|
||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
} else {
|
} else {
|
||||||
btn.innerText = "🎙️ Start AI Scribe";
|
btn.innerText = "🎙️ Start AI Scribe";
|
||||||
btn.style.background = "";
|
btn.style.background = "";
|
||||||
status.classList.add("hidden");
|
status.classList.add("hidden");
|
||||||
|
generateSummary();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function generateSummary() {
|
||||||
|
const notes = document.getElementById("consultationNotes").value;
|
||||||
|
if (!notes) return;
|
||||||
|
|
||||||
|
const summaryCard = document.getElementById("aiSummaryCard");
|
||||||
|
const summaryText = document.getElementById("summaryText");
|
||||||
|
|
||||||
|
// AI Summarization simulation
|
||||||
|
const summary = `📋 CLINICAL SUMMARY: Patient presents with persistent dry cough (3 days). Fatigue noted. No fever. Recommended hydration and follow-up if symptoms persist.`;
|
||||||
|
|
||||||
|
summaryText.innerText = summary;
|
||||||
|
summaryCard.classList.remove("hidden");
|
||||||
|
|
||||||
|
// Persist in store
|
||||||
|
patientDataStore[currentPatientId].notes = notes;
|
||||||
|
patientDataStore[currentPatientId].summary = summary;
|
||||||
|
console.log(`Saved summary for ${currentPatientId}`);
|
||||||
|
}
|
||||||
|
|
||||||
window.switchPatientContext = (name, token, triage) => {
|
window.switchPatientContext = (name, token, triage) => {
|
||||||
// 1. Reset Scribe State
|
// 1. Save current state before switching
|
||||||
|
if (currentPatientId) {
|
||||||
|
patientDataStore[currentPatientId].notes = document.getElementById("consultationNotes").value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Reset UI for new context
|
||||||
isScribing = false;
|
isScribing = false;
|
||||||
const btn = document.getElementById("zenScribeBtn");
|
const btn = document.getElementById("zenScribeBtn");
|
||||||
if (btn) {
|
if (btn) { btn.innerText = "🎙️ Start AI Scribe"; btn.style.background = ""; }
|
||||||
btn.innerText = "🎙️ Start AI Scribe";
|
|
||||||
btn.style.background = "";
|
|
||||||
}
|
|
||||||
const status = document.getElementById("scribeStatus");
|
const status = document.getElementById("scribeStatus");
|
||||||
if (status) status.classList.add("hidden");
|
if (status) status.classList.add("hidden");
|
||||||
|
|
||||||
// 2. Clear Current Workspace
|
// 3. Update Current Patient ID
|
||||||
const notes = document.querySelector(".zen-textarea");
|
currentPatientId = token;
|
||||||
if (notes) notes.value = "";
|
|
||||||
|
|
||||||
// 3. Update Headers
|
// 4. Load or Clear Workspace
|
||||||
|
const notesArea = document.getElementById("consultationNotes");
|
||||||
|
const summaryCard = document.getElementById("aiSummaryCard");
|
||||||
|
const summaryText = document.getElementById("summaryText");
|
||||||
|
|
||||||
|
if (patientDataStore[token] && patientDataStore[token].notes) {
|
||||||
|
notesArea.value = patientDataStore[token].notes;
|
||||||
|
if (patientDataStore[token].summary) {
|
||||||
|
summaryText.innerText = patientDataStore[token].summary;
|
||||||
|
summaryCard.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
summaryCard.classList.add("hidden");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
notesArea.value = "";
|
||||||
|
summaryCard.classList.add("hidden");
|
||||||
|
// Initialize new store entry if needed
|
||||||
|
if (!patientDataStore[token]) patientDataStore[token] = { notes: "", summary: "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Update Headers
|
||||||
const h1 = document.querySelector(".current-patient h1");
|
const h1 = document.querySelector(".current-patient h1");
|
||||||
if (h1) h1.innerHTML = `${name} <small>(32y, Female)</small>`;
|
if (h1) h1.innerHTML = `${name} <small>(32y, Female)</small>`;
|
||||||
|
|
||||||
const meta = document.querySelector(".patient-meta");
|
const meta = document.querySelector(".patient-meta");
|
||||||
if (meta) meta.innerHTML = `<span>${token}</span> • <span>${triage}</span> • <span class="visit-timer">00:00</span>`;
|
if (meta) meta.innerHTML = `<span>${token}</span> • <span>${triage}</span> • <span class="visit-timer">00:00</span>`;
|
||||||
|
};
|
||||||
|
|
||||||
alert(`Switched context to: ${name}. AI Scribe reset.`);
|
window.shareSummary = () => {
|
||||||
|
const summary = document.getElementById("summaryText").innerText;
|
||||||
|
alert(`📤 Sent to Patient's WhatsApp:\n\n${summary}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.printSummary = () => {
|
||||||
|
const summary = document.getElementById("summaryText").innerText;
|
||||||
|
alert(`🖨️ Printing Handover Note:\n\n${summary}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue