class HealeoApp { constructor() { this.currentPatient = null; this.currentTab = 'overview'; this.currentFilter = 'all'; this.recommendations = []; this.approvalHistory = []; this.patients = [ { id: 1, name: "John Doe", age: 58, gender: "Male", avatar: "JD", conditions: ["Type 2 Diabetes", "Hypertension"], lastVisit: "2024-01-15", nextFollowup: "2024-02-01", adherence: 87, risk: "Moderate", status: "active", carePlan: { activeConditions: [ { condition: "Type 2 Diabetes", severity: "moderate", status: "managed" }, { condition: "Hypertension", severity: "mild", status: "improving" } ], medications: [ { name: "Metformin", dosage: "1000mg", frequency: "Twice daily", adherence: 95 }, { name: "Lisinopril", dosage: "10mg", frequency: "Once daily", adherence: 82 } ], goals: [ { text: "Reduce HbA1c to <7%", target: "6 months", progress: 65 }, { text: "Blood pressure <130/80", target: "3 months", progress: 45 } ], lifestyle: [ "Mediterranean diet - strict adherence", "30min walking 5x/week", "Sleep hygiene protocol" ] }, labs: [ { date: "2024-01-15", type: "HbA1c", value: "7.2", unit: "%", trend: "down" }, { date: "2024-01-15", type: "Blood Pressure", value: "138/85", unit: "mmHg", trend: "stable" } ] }, { id: 2, name: "Sarah Chen", age: 34, gender: "Female", avatar: "SC", conditions: ["Asthma", "Anxiety Disorder"], lastVisit: "2024-01-10", nextFollowup: "2024-01-25", adherence: 92, risk: "Low", status: "stable", carePlan: { activeConditions: [ { condition: "Asthma", severity: "moderate", status: "controlled" }, { condition: "Anxiety Disorder", severity: "mild", status: "managed" } ], medications: [ { name: "Albuterol", dosage: "90mcg", frequency: "As needed", adherence: 88 }, { name: "Sertraline", dosage: "50mg", frequency: "Once daily", adherence: 98 } ], goals: [ { text: "Reduce anxiety attacks to <2/month", target: "Ongoing", progress: 80 }, { text: "Peak flow >350 L/min", target: "Maintenance", progress: 90 } ], lifestyle: [ "Daily meditation practice", "Yoga 3x/week", "Air quality monitoring" ] }, labs: [ { date: "2024-01-10", type: "Spirometry", value: "85%", unit: "predicted", trend: "up" } ] }, { id: 3, name: "Robert Martinez", age: 67, gender: "Male", avatar: "RM", conditions: ["COPD", "Heart Failure"], lastVisit: "2024-01-08", nextFollowup: "2024-01-22", adherence: 73, risk: "High", status: "critical", carePlan: { activeConditions: [ { condition: "COPD", severity: "severe", status: "worsening" }, { condition: "Heart Failure", severity: "moderate", status: "stable" } ], medications: [ { name: "Furosemide", dosage: "40mg", frequency: "Once daily", adherence: 65 }, { name: "Spironolactone", dosage: "25mg", frequency: "Once daily", adherence: 70 } ], goals: [ { text: "Reduce ED visits", target: "6 months", progress: 30 }, { text: "Weight stability ±2lbs", target: "Monthly", progress: 60 } ], lifestyle: [ "Sodium restriction <2g/day", "Daily weight monitoring", "Pulmonary rehab 2x/week" ] }, labs: [ { date: "2024-01-08", type: "BNP", value: "450", unit: "pg/mL", trend: "up" }, { date: "2024-01-08", type: "eGFR", value: "45", unit: "mL/min", trend: "down" } ] }, { id: 4, name: "Emily Watson", age: 45, gender: "Female", avatar: "EW", conditions: ["Rheumatoid Arthritis"], lastVisit: "2024-01-12", nextFollowup: "2024-02-12", adherence: 96, risk: "Low", status: "review", carePlan: { activeConditions: [ { condition: "Rheumatoid Arthritis", severity: "moderate", status: "improving" } ], medications: [ { name: "Methotrexate", dosage: "15mg", frequency: "Weekly", adherence: 96 }, { name: "Folic Acid", dosage: "1mg", frequency: "Daily", adherence: 100 } ], goals: [ { text: "DAS28 <3.2", target: "3 months", progress: 75 }, { text: "Pain score <4/10", target: "Ongoing", progress: 60 } ], lifestyle: [ "Joint protection techniques", "Aquatic therapy", "Anti-inflammatory diet" ] }, labs: [ { date: "2024-01-12", type: "CRP", value: "8.5", unit: "mg/L", trend: "down" } ] } ]; this.aiRecommendations = [ { id: 1, patientId: 1, type: "medication", title: "Dosage Adjustment Suggested", description: "Increase Metformin to 1500mg based on current HbA1c trending and BMI.", rationale: "Current HbA1c of 7.2% suggests suboptimal glycemic control. Patient BMI 32 indicates insulin resistance.", confidence: 92, action: "Adjust prescription", timestamp: "10 mins ago" }, { id: 2, patientId: 1, type: "followup", title: "Follow-up Timeline Update", description: "Move next visit from 2/1 to 1/28 for earlier intervention.", rationale: "Recent lab trends show glucose variability. Earlier assessment recommended.", confidence: 87, action: "Reschedule visit", timestamp: "15 mins ago" }, { id: 3, patientId: 1, type: "monitoring", title: "Add Continuous Glucose Monitor", description: "Recommend CGM for 2 weeks to assess glycemic patterns.", rationale: "Identifying fasting vs post-prandial spikes will optimize medication timing.", confidence: 95, action: "Order device", timestamp: "20 mins ago" } ]; this.timeline = [ { date: "2024-01-15", type: "visit", title: "Routine Visit", description: "HbA1c discussed, adherence reviewed", icon: "stethoscope" }, { date: "2024-01-10", type: "medication", title: "Medication Refill", description: "Metformin 90-day supply issued", icon: "pill" }, { date: "2024-01-05", type: "lab", title: "Lab Results", description: "HbA1c: 7.2% (down from 7.8%)", icon: "flask-conical", highlight: true }, { date: "2023-12-20", type: "therapy", title: "Nutritionist Consult", description: "Mediterranean diet counseling", icon: "apple" }, { date: "2023-12-01", type: "visit", title: "Emergency Visit", description: "Hypoglycemic episode resolved", icon: "alert-circle", highlight: true } ]; this.init(); } init() { this.renderPatientList(); this.selectPatient(this.patients[0]); lucide.createIcons(); } filterPatients(query) { const filtered = this.patients.filter(p => p.name.toLowerCase().includes(query.toLowerCase()) || p.conditions.some(c => c.toLowerCase().includes(query.toLowerCase())) ); this.renderPatientList(filtered); } setFilter(filter) { this.currentFilter = filter; document.querySelectorAll('.filter-btn').forEach(btn => { if(btn.dataset.filter === filter) { btn.classList.remove('bg-gray-100', 'text-gray-600', 'border-gray-200'); btn.classList.add('bg-blue-100', 'text-blue-700', 'border-blue-200'); } else { btn.classList.add('bg-gray-100', 'text-gray-600', 'border-gray-200'); btn.classList.remove('bg-blue-100', 'text-blue-700', 'border-blue-200'); } }); let filtered = this.patients; if(filter === 'critical') filtered = this.patients.filter(p => p.status === 'critical'); if(filter === 'review') filtered = this.patients.filter(p => p.status === 'review'); this.renderPatientList(filtered); } renderPatientList(patients = this.patients) { const container = document.getElementById('patientList'); container.innerHTML = ''; patients.forEach(patient => { const card = document.createElement('div'); card.className = `p-3 rounded-lg border cursor-pointer transition-all hover:shadow-md ${this.currentPatient?.id === patient.id ? 'bg-blue-50 border-blue-300 shadow-sm' : 'bg-white border-gray-200 hover:border-blue-300'}`; card.onclick = () => this.selectPatient(patient); const statusColor = patient.status === 'critical' ? 'bg-red-100 text-red-700' : patient.status === 'review' ? 'bg-amber-100 text-amber-700' : 'bg-green-100 text-green-700'; card.innerHTML = `
${patient.avatar}

${patient.name}

${patient.status}

${patient.age}y • ${patient.gender}

${patient.conditions.slice(0, 2).map(c => `${c}`).join('')} ${patient.conditions.length > 2 ? `+${patient.conditions.length - 2}` : ''}
${patient.adherence}% adherence
`; container.appendChild(card); }); document.getElementById('patientCount').textContent = patients.length; lucide.createIcons(); } selectPatient(patient) { this.currentPatient = patient; this.renderPatientList(); this.updatePatientHeader(); this.renderTabContent(); this.renderRecommendations(); this.showToast(`Loaded care plan for ${patient.name}`, 'success'); } updatePatientHeader() { const p = this.currentPatient; document.getElementById('patientAvatar').textContent = p.avatar; document.getElementById('patientName').textContent = p.name; document.getElementById('patientMeta').textContent = `${p.age} years old • ${p.gender} • MRN: 00${p.id}2345`; document.getElementById('lastVisit').textContent = p.lastVisit; document.getElementById('nextFollowup').textContent = p.nextFollowup; document.getElementById('adherenceScore').textContent = p.adherence + '%'; const riskColors = { 'Low': 'text-green-600', 'Moderate': 'text-yellow-600', 'High': 'text-red-600' }; const riskEl = document.getElementById('riskLevel'); riskEl.textContent = p.risk; riskEl.className = `text-sm font-semibold ${riskColors[p.risk] || 'text-gray-600'}`; const tagsContainer = document.getElementById('patientTags'); tagsContainer.innerHTML = p.conditions.map(c => `${c}` ).join(''); } setTab(tab) { this.currentTab = tab; document.querySelectorAll('.tab-btn').forEach(btn => { if(btn.dataset.tab === tab) { btn.classList.add('border-blue-600', 'text-blue-600', 'active'); btn.classList.remove('border-transparent', 'text-gray-600'); } else { btn.classList.remove('border-blue-600', 'text-blue-600', 'active'); btn.classList.add('border-transparent', 'text-gray-600'); } }); this.renderTabContent(); } renderTabContent() { const container = document.getElementById('tabContent'); container.innerHTML = ''; if(this.currentTab === 'overview') this.renderOverview(container); else if(this.currentTab === 'timeline') this.renderTimeline(container); else if(this.currentTab === 'history') this.renderHistory(container); else if(this.currentTab === 'labs') this.renderLabs(container); lucide.createIcons(); } renderOverview(container) { const plan = this.currentPatient.carePlan; const sections = [ { id: 'conditions', title: 'Active Conditions', icon: 'activity', content: this.renderConditions(plan.activeConditions) }, { id: 'medications', title: 'Medication Plan', icon: 'pill', content: this.renderMedications(plan.medications) }, { id: 'goals', title: 'Treatment Goals', icon: 'target', content: this.renderGoals(plan.goals) }, { id: 'lifestyle', title: 'Lifestyle Recommendations', icon: 'heart', content: this.renderLifestyle(plan.lifestyle) } ]; sections.forEach(section => { const card = document.createElement('div'); card.className = 'bg-white rounded-xl border border-gray-200 overflow-hidden'; card.innerHTML = `

${section.title}

${section.content}
`; container.appendChild(card); }); } renderConditions(conditions) { return `
${conditions.map(c => `

${c.condition}

Severity: ${c.severity} • Status: ${c.status}

`).join('')}
`; } renderMedications(medications) { return `
${medications.map(m => `

${m.name}

${m.adherence}% adherence
${m.dosage} ${m.frequency}
`).join('')}
`; } renderGoals(goals) { return `
${goals.map(g => `

${g.text}

${g.target}
${g.progress}%
`).join('')}
`; } renderLifestyle(items) { return `
${items.map((item, idx) => `

${item}

`).join('')}
`; } renderTimeline(container) { const timelineHtml = `
${this.timeline.map((event, idx) => `

${event.title}

${event.date}

${event.highlight ? 'Key Event' : ''}

${event.description}

`).join('')}
`; container.innerHTML = timelineHtml; } renderHistory(container) { container.innerHTML = `

Care Plan Revisions

Medication dosage updated

By Dr. Smith • Jan 15, 2024 • 10:30 AM

Metformin: 500mg → 1000mg

AI Recommendation Approved

By Dr. Smith • Jan 14, 2024 • 3:45 PM

Added CGM monitoring for 14 days

`; } renderLabs(container) { const labs = this.currentPatient.labs || []; container.innerHTML = `
${labs.map(lab => `

${lab.type}

${lab.date}

${lab.value} ${lab.unit}

${lab.trend === 'up' ? 'Increased' : lab.trend === 'down' ? 'Decreased' : 'Stable'}

`).join('')}
`; } renderRecommendations() { const container = document.getElementById('recommendationList'); const recs = this.aiRecommendations.filter(r => r.patientId === this.currentPatient?.id); document.getElementById('pendingCount').textContent = recs.length; if(recs.length === 0) { container.innerHTML = `

All recommendations reviewed

No pending AI suggestions

`; lucide.createIcons(); return; } container.innerHTML = recs.map(rec => `
${rec.type}
${rec.confidence}

${rec.title}

${rec.description}

AI Rationale:

${rec.rationale}

`).join(''); // Update confidence based on pending recommendations const avgConfidence = recs.reduce((acc, r) => acc + r.confidence, 0) / recs.length; this.updateConfidence(avgConfidence); lucide.createIcons(); } approveRecommendation(id) { const rec = this.aiRecommendations.find(r => r.id === id); if(!rec) return; // Add to history this.approvalHistory.unshift({ ...rec, status: 'approved', timestamp: new Date().toLocaleTimeString() }); // Remove from pending this.aiRecommendations = this.aiRecommendations.filter(r => r.id !== id); // Update UI const card = document.getElementById(`rec-${id}`); if(card) { card.style.transform = 'translateX(100%)'; card.style.opacity = '0'; setTimeout(() => this.renderRecommendations(), 300); } this.showToast('Recommendation approved and applied to care plan', 'success'); this.updateApprovalHistory(); } rejectRecommendation(id) { const rec = this.aiRecommendations.find(r => r.id === id); if(!rec) return; this.approvalHistory.unshift({ ...rec, status: 'rejected', timestamp: new Date().toLocaleTimeString() }); this.aiRecommendations = this.aiRecommendations.filter(r => r.id !== id); const card = document.getElementById(`rec-${id}`); if(card) { card.style.transform = 'translateX(100%)'; card.style.opacity = '0'; setTimeout(() => this.renderRecommendations(), 300); } this.showToast('Recommendation rejected', 'info'); this.updateApprovalHistory(); } updateApprovalHistory() { const container = document.getElementById('approvalHistory'); container.innerHTML = this.approvalHistory.slice(0, 3).map(h => `
${h.title} ${h.status}

${h.timestamp}

`).join(''); } updateConfidence(score) { document.getElementById('confidenceValue').textContent = Math.round(score) + '%'; document.getElementById('confidenceBar').style.width = score + '%'; document.getElementById('lastUpdated').textContent = 'Just now'; } regenerateAI() { const btn = document.getElementById('regenerateBtn'); const originalContent = btn.innerHTML; btn.innerHTML = 'Analyzing...'; btn.disabled = true; lucide.createIcons(); // Simulate AI processing setTimeout(() => { // Add new random recommendation const newRec = { id: Date.now(), patientId: this.currentPatient.id, type: 'monitoring', title: 'New Symptom Pattern Detected', description: 'AI detected irregular glucose patterns during sleep hours.', rationale: 'Continuous monitoring data analysis reveals dawn phenomenon requiring adjustment.', confidence: Math.floor(Math.random() * 15) + 85, action: 'Review data', timestamp: 'Just now' }; this.aiRecommendations.push(newRec); this.renderRecommendations(); btn.innerHTML = originalContent; btn.disabled = false; lucide.createIcons(); this.showToast('AI analysis complete. New recommendations available.', 'success'); }, 2000); } saveCarePlan() { this.showToast('Care plan saved successfully', 'success'); } addTimelineEvent() { const today = new Date().toISOString().split('T')[0]; this.timeline.unshift({ date: today, type: 'note', title: 'New Clinical Note', description: 'Added via care plan engine', icon: 'file-text' }); this.renderTabContent(); this.showToast('Timeline event added', 'success'); } requestLab() { this.showToast('Lab order submitted to LIS', 'info'); } openAIChat() { this.showToast('AI Assistant coming soon', 'info'); } showToast(message, type = 'info') { const container = document.getElementById('toastContainer'); const toast = document.createElement('div'); const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500', warning: 'bg-amber-500' }; const icons = { success: 'check-circle', error: 'x-circle', info: 'info', warning: 'alert-triangle' }; toast.className = `${colors[type]} text-white px-4 py-3 rounded-lg shadow-lg flex items-center gap-3 min-w-[300px] toast-enter`; toast.innerHTML = `

${message}

`; container.appendChild(toast); lucide.createIcons(); setTimeout(() => toast.remove(), 5000); } } // Initialize app const app = new HealeoApp();