// Verify MC - Add Encounter Application // Enterprise-grade medical marijuana SaaS workflow class VerifyMCApp { constructor() { this.currentStep = 1; this.totalSteps = 5; this.patients = []; this.selectedPatient = null; this.encounterData = { conditions: [], therapies: [], productForms: [], compliance: {}, details: {} }; this.transcript = []; this.isRecording = false; this.isPaused = false; this.recordingTime = 0; this.recordingInterval = null; this.currentFilter = 'all'; this.copilotOpen = false; this.init(); } init() { this.generateMockPatients(); this.renderStepper(); this.renderPatients(); this.initWaveform(); this.updateProgress(); this.startAutoSave(); // Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.metaKey && e.key === 'k') { e.preventDefault(); this.toggleCopilot(); } if (e.key === 'Escape') { this.closeWalkInModal(); this.closePreview(); } }); } // Data Generation generateMockPatients() { const conditions = ['Chronic Pain', 'PTSD', 'Neuropathy', 'MS Spasticity', 'Cancer-related Nausea']; const statuses = ['checked-in', 'in-room', 'waiting', 'renewal', 'high-risk']; this.patients = [ { id: 1, firstName: 'James', lastName: 'Wilson', dob: '1985-03-15', mrn: 'MRN-2024-001', registryId: 'CA-MMJ-789456', status: 'checked-in', lastVisit: '2024-01-15', nextRenewal: '2025-01-15', conditions: ['Chronic Pain', 'PTSD'], avatar: 'JW', aiSuggested: true, reason: 'Follow-up appointment scheduled' }, { id: 2, firstName: 'Maria', lastName: 'Garcia', dob: '1978-11-22', mrn: 'MRN-2024-002', registryId: 'CA-MMJ-123789', status: 'in-room', lastVisit: '2024-11-20', nextRenewal: '2024-12-20', conditions: ['Neuropathy'], avatar: 'MG', aiSuggested: true, reason: 'Renewal due in 30 days' }, { id: 3, firstName: 'Robert', lastName: 'Chen', dob: '1990-07-08', mrn: 'MRN-2024-003', registryId: null, status: 'waiting', lastVisit: null, nextRenewal: null, conditions: [], avatar: 'RC', aiSuggested: false, reason: 'New patient - initial certification' }, { id: 4, firstName: 'Sarah', lastName: 'Johnson', dob: '1982-04-30', mrn: 'MRN-2024-004', registryId: 'CA-MMJ-456123', status: 'renewal', lastVisit: '2024-10-01', nextRenewal: '2024-12-01', conditions: ['MS Spasticity', 'Chronic Pain'], avatar: 'SJ', aiSuggested: true, reason: 'Renewal overdue' }, { id: 5, firstName: 'David', lastName: 'Smith', dob: '1975-09-12', mrn: 'MRN-2024-005', registryId: 'CA-MMJ-789123', status: 'high-risk', lastVisit: '2024-11-10', nextRenewal: '2025-02-10', conditions: ['PTSD'], avatar: 'DS', aiSuggested: false, reason: 'Multiple medications - review required' }, { id: 6, firstName: 'Emily', lastName: 'Davis', dob: '1988-12-05', mrn: 'MRN-2024-006', registryId: 'CA-MMJ-321654', status: 'checked-in', lastVisit: '2024-09-20', nextRenewal: '2025-09-20', conditions: ['Cancer-related Nausea'], avatar: 'ED', aiSuggested: false, reason: 'Regular follow-up' } ]; } // Stepper Navigation renderStepper() { const steps = [ { num: 1, label: 'Patient' }, { num: 2, label: 'Details' }, { num: 3, label: 'Scribe' }, { num: 4, label: 'Notes' }, { num: 5, label: 'Review' } ]; const container = document.getElementById('stepper-container'); if (!container) return; container.innerHTML = steps.map((step, index) => { const isActive = step.num === this.currentStep; const isCompleted = step.num < this.currentStep; const isLast = index === steps.length - 1; let classes = 'w-10 h-10 rounded-full flex items-center justify-center text-sm font-bold transition-all '; if (isActive) { classes += 'bg-emerald-600 text-white shadow-lg ring-4 ring-emerald-100'; } else if (isCompleted) { classes += 'bg-emerald-100 text-emerald-700'; } else { classes += 'bg-gray-100 text-gray-500'; } return `
${!isLast ? '
' : ''}
`; }).join(''); // Update footer const stepNames = ['Patient Selection', 'Encounter Details', 'AI Scribe', 'AI Documentation', 'Review & Finalize']; document.getElementById('footer-step-current').textContent = this.currentStep; document.getElementById('footer-step-total').textContent = this.totalSteps; document.getElementById('footer-step-name').textContent = stepNames[this.currentStep - 1]; // Update buttons document.getElementById('btn-prev').disabled = this.currentStep === 1; if (this.currentStep === this.totalSteps) { document.getElementById('btn-next').classList.add('hidden'); document.getElementById('btn-submit-final').classList.remove('hidden'); } else { document.getElementById('btn-next').classList.remove('hidden'); document.getElementById('btn-submit-final').classList.add('hidden'); } lucide.createIcons(); } goToStep(stepNum) { if (stepNum < 1 || stepNum > this.totalSteps) return; // Validation before moving forward if (stepNum > this.currentStep) { if (this.currentStep === 1 && !this.selectedPatient) { this.showToast('Please select a patient first', 'error'); return; } } this.currentStep = stepNum; this.renderStepper(); // Hide all steps document.querySelectorAll('.step-content').forEach(el => { el.classList.remove('active'); }); // Show current step document.getElementById(`step-${this.currentStep}`).classList.add('active'); // Scroll to top document.getElementById('main-container').scrollTop = 0; } nextStep() { if (this.currentStep < this.totalSteps) { this.goToStep(this.currentStep + 1); } } prevStep() { if (this.currentStep > 1) { this.goToStep(this.currentStep - 1); } } // Patient Selection renderPatients() { const grid = document.getElementById('patient-grid'); const aiContainer = document.getElementById('ai-suggested-container'); if (!grid) return; // Filter patients let filtered = this.patients; if (this.currentFilter !== 'all') { filtered = this.patients.filter(p => p.status === this.currentFilter); } // Render AI suggested const aiSuggested = this.patients.filter(p => p.aiSuggested); aiContainer.innerHTML = aiSuggested.map(p => this.createPatientCard(p, true)).join(''); // Render main grid grid.innerHTML = filtered.map(p => this.createPatientCard(p, false)).join(''); lucide.createIcons(); } createPatientCard(patient, isCompact) { const isSelected = this.selectedPatient?.id === patient.id; const statusColors = { 'checked-in': 'bg-blue-100 text-blue-700', 'in-room': 'bg-emerald-100 text-emerald-700', 'waiting': 'bg-amber-100 text-amber-700', 'renewal': 'bg-purple-100 text-purple-700', 'high-risk': 'bg-red-100 text-red-700' }; if (isCompact) { return `
${patient.avatar}
${patient.firstName} ${patient.lastName}
MRN: ${patient.mrn}
${patient.status.replace('-', ' ')} ${patient.reason}
`; } return `
${patient.avatar}
${patient.firstName} ${patient.lastName}
DOB: ${patient.dob}
${patient.status.replace('-', ' ')}
MRN: ${patient.mrn}
Registry: ${patient.registryId || 'Pending'}
${patient.conditions.length ? `
${patient.conditions.map(c => `${c}`).join('')}
` : ''}
Last visit: ${patient.lastVisit || 'New patient'} Renewal: ${patient.nextRenewal || 'N/A'}
`; } selectPatient(patientId) { this.selectedPatient = this.patients.find(p => p.id === patientId); this.renderPatients(); this.updateProgress(); this.showToast(`Selected ${this.selectedPatient.firstName} ${this.selectedPatient.lastName}`, 'success'); } filterPatients(query) { const grid = document.getElementById('patient-grid'); const filtered = this.patients.filter(p => p.firstName.toLowerCase().includes(query.toLowerCase()) || p.lastName.toLowerCase().includes(query.toLowerCase()) || p.mrn.toLowerCase().includes(query.toLowerCase()) ); grid.innerHTML = filtered.map(p => this.createPatientCard(p, false)).join(''); lucide.createIcons(); } sortPatients(method) { // Implementation for sorting this.renderPatients(); } setFilter(filter) { this.currentFilter = filter; // Update chip styles document.querySelectorAll('.filter-chip').forEach(chip => { if (chip.dataset.filter === filter) { chip.className = 'filter-chip px-3 py-1.5 rounded-full text-xs font-medium bg-emerald-100 text-emerald-700 border border-emerald-200 transition-all'; } else { chip.className = 'filter-chip px-3 py-1.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600 border border-gray-200 hover:bg-gray-200 transition-all'; } }); this.renderPatients(); } // Walk-in Modal openWalkInModal() { document.getElementById('walkin-modal').classList.remove('hidden'); } closeWalkInModal() { document.getElementById('walkin-modal').classList.add('hidden'); } createWalkIn() { const first = document.getElementById('walkin-first').value; const last = document.getElementById('walkin-last').value; const dob = document.getElementById('walkin-dob').value; const phone = document.getElementById('walkin-phone').value; if (!first || !last || !dob) { this.showToast('Please fill in all required fields', 'error'); return; } const newPatient = { id: Date.now(), firstName: first, lastName: last, dob: dob, mrn: `MRN-${Date.now()}`, registryId: null, status: 'waiting', lastVisit: null, nextRenewal: null, conditions: [], avatar: `${first[0]}${last[0]}`.toUpperCase(), aiSuggested: false, reason: 'Walk-in patient' }; this.patients.unshift(newPatient); this.selectPatient(newPatient.id); this.closeWalkInModal(); this.showToast('New walk-in patient created', 'success'); } // Encounter Details updateEncounterDetail(field, value) { this.encounterData.details[field] = value; if (field === 'severity') { document.getElementById('severity-value').textContent = value; } this.updateProgress(); this.updatePreSummary(); } addCondition(condition) { if (!condition || this.encounterData.conditions.includes(condition)) return; this.encounterData.conditions.push(condition); this.renderConditionTags(); this.updatePreSummary(); document.getElementById('condition-select').value = ''; } renderConditionTags() { const container = document.getElementById('condition-tags'); container.innerHTML = this.encounterData.conditions.map(c => ` ${c} `).join(''); lucide.createIcons(); } removeCondition(condition) { this.encounterData.conditions = this.encounterData.conditions.filter(c => c !== condition); this.renderConditionTags(); this.updatePreSummary(); } toggleTherapy(therapy) { if (this.encounterData.therapies.includes(therapy)) { this.encounterData.therapies = this.encounterData.therapies.filter(t => t !== therapy); } else { this.encounterData.therapies.push(therapy); } this.updatePreSummary(); } toggleProductForm(btn, form) { btn.classList.toggle('bg-emerald-100'); btn.classList.toggle('text-emerald-700'); btn.classList.toggle('border-emerald-500'); if (this.encounterData.productForms.includes(form)) { this.encounterData.productForms = this.encounterData.productForms.filter(f => f !== form); } else { this.encounterData.productForms.push(form); } } updateCompliance(type, value) { this.encounterData.compliance[type] = value; this.updatePreSummary(); } updatePreSummary() { const qualification = document.getElementById('summary-qualification'); const missing = document.getElementById('summary-missing'); const complexityBar = document.getElementById('complexity-bar'); const complexityText = document.getElementById('complexity-text'); // Update qualification if (this.encounterData.conditions.length > 0) { qualification.textContent = 'Likely Eligible - ' + this.encounterData.conditions.join(', '); qualification.className = 'text-sm font-semibold text-emerald-700'; } else { qualification.textContent = 'Select conditions to assess'; qualification.className = 'text-sm font-semibold text-gray-500'; } // Update missing items const missingItems = []; if (!this.encounterData.compliance.residency) missingItems.push('Residency verification'); if (!this.encounterData.compliance.identity) missingItems.push('Identity check'); if (!this.encounterData.compliance.consent) missingItems.push('Consent forms'); missing.innerHTML = missingItems.length ? missingItems.map(item => `
  • ${item}
  • `).join('') : '
  • All required items complete
  • '; // Update complexity const complexity = Math.min(100, (this.encounterData.conditions.length * 15) + (this.encounterData.therapies.length * 5) + 10); complexityBar.style.width = `${complexity}%`; if (complexity < 30) { complexityText.textContent = 'Low'; complexityBar.className = 'h-full bg-emerald-500 rounded-full'; } else if (complexity < 70) { complexityText.textContent = 'Moderate'; complexityBar.className = 'h-full bg-amber-500 rounded-full'; } else { complexityText.textContent = 'High'; complexityBar.className = 'h-full bg-red-500 rounded-full'; } lucide.createIcons(); } simulateUpload() { this.showToast('Uploading document...', 'info'); setTimeout(() => { this.showToast('Document uploaded successfully', 'success'); }, 1500); } // AI Scribe initWaveform() { const container = document.getElementById('waveform-container'); if (!container) return; container.innerHTML = Array(40).fill(0).map(() => `
    ` ).join(''); } startRecording() { this.isRecording = true; this.isPaused = false; document.getElementById('recording-status').textContent = 'Recording'; document.getElementById('recording-status').className = 'px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-600 recording-pulse'; document.getElementById('btn-start').classList.add('hidden'); document.getElementById('btn-pause').classList.remove('hidden'); document.getElementById('btn-stop').classList.remove('hidden'); document.getElementById('waveform-container').classList.remove('opacity-30'); this.recordingInterval = setInterval(() => { this.recordingTime++; const mins = Math.floor(this.recordingTime / 60).toString().padStart(2, '0'); const secs = (this.recordingTime % 60).toString().padStart(2, '0'); document.getElementById('recording-timer').textContent = `${mins}:${secs}`; }, 1000); // Simulate transcript generation this.simulateTranscriptGeneration(); } pauseRecording() { this.isPaused = true; clearInterval(this.recordingInterval); document.getElementById('recording-status').textContent = 'Paused'; document.getElementById('recording-status').className = 'px-2 py-1 rounded-full text-xs font-medium bg-amber-100 text-amber-600'; document.getElementById('btn-pause').classList.add('hidden'); document.getElementById('btn-resume').classList.remove('hidden'); document.getElementById('recording-overlay').classList.remove('hidden'); document.getElementById('waveform-container').classList.add('opacity-30'); } resumeRecording() { this.isPaused = false; document.getElementById('recording-status').textContent = 'Recording'; document.getElementById('recording-status').className = 'px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-600 recording-pulse'; document.getElementById('btn-resume').classList.add('hidden'); document.getElementById('btn-pause').classList.remove('hidden'); document.getElementById('recording-overlay').classList.add('hidden'); document.getElementById('waveform-container').classList.remove('opacity-30'); this.recordingInterval = setInterval(() => { this.recordingTime++; const mins = Math.floor(this.recordingTime / 60).toString().padStart(2, '0'); const secs = (this.recordingTime % 60).toString().padStart(2, '0'); document.getElementById('recording-timer').textContent = `${mins}:${secs}`; }, 1000); } stopRecording() { this.isRecording = false; clearInterval(this.recordingInterval); document.getElementById('recording-status').textContent = 'Completed'; document.getElementById('recording-status').className = 'px-2 py-1 rounded-full text-xs font-medium bg-emerald-100 text-emerald-600'; document.getElementById('btn-pause').classList.add('hidden'); document.getElementById('btn-resume').classList.add('hidden'); document.getElementById('btn-stop').classList.add('hidden'); document.getElementById('btn-start').classList.remove('hidden'); document.getElementById('btn-start').innerHTML = ' New Recording'; document.getElementById('waveform-container').classList.add('opacity-30'); document.getElementById('recording-overlay').classList.add('hidden'); this.showToast('Recording saved', 'success'); this.updateProgress(); } simulateTranscriptGeneration() { const lines = [ { speaker: 'Dr', text: 'Good morning, James. How are you feeling today?' }, { speaker: 'Pt', text: 'Good morning, Doctor. The back pain is still there, maybe a 7 out of 10.' }, { speaker: 'Dr', text: 'I see. And how about the sleep issues we discussed last time?' }, { speaker: 'Pt', text: 'Still having nightmares. Maybe 3 or 4 times a week.' }, { speaker: 'Dr', text: 'Have you tried the physical therapy exercises?' }, { speaker: 'Pt', text: 'Yes, but they only help for an hour or so, then the pain returns.' } ]; let delay = 0; lines.forEach((line, index) => { delay += 2000 + Math.random() * 1000; setTimeout(() => { if (this.isRecording && !this.isPaused) { this.addTranscriptLine(line.speaker, line.text); } }, delay); }); } addTranscriptLine(speaker, text) { const container = document.getElementById('transcript-lines'); // Remove placeholder if exists if (container.querySelector('.italic')) { container.innerHTML = ''; } const line = document.createElement('div'); line.className = 'transcript-line flex gap-3 p-2 rounded-lg hover:bg-gray-50'; line.innerHTML = `
    ${speaker}:
    ${text}
    ${new Date().toLocaleTimeString()}
    `; container.appendChild(line); container.scrollTop = container.scrollHeight; // Update word count const words = container.innerText.split(/\s+/).length; document.getElementById('word-count').textContent = `${words} words`; } simulateConversation() { this.startRecording(); this.showToast('Simulating conversation...', 'info'); } uploadAudio() { this.showToast('Audio upload feature would open file picker', 'info'); } useSampleVisit() { document.getElementById('transcript-lines').innerHTML = ''; const sampleLines = [ { speaker: 'Dr', text: 'Hello James, I see you\'re here for your initial certification visit.' }, { speaker: 'Pt', text: 'Yes, I\'ve been dealing with chronic pain from an old injury.' }, { speaker: 'Dr', text: 'Can you describe the pain for me?' }, { speaker: 'Pt', text: 'It\'s a sharp burning sensation in my lower back, radiating down my left leg.' }, { speaker: 'Dr', text: 'Rate the pain on a scale of 1-10.' }, { speaker: 'Pt', text: 'Usually around a 7, sometimes 8 in the evenings.' }, { speaker: 'Dr', text: 'What treatments have you tried?' }, { speaker: 'Pt', text: 'Physical therapy, ibuprofen, gabapentin... nothing really helps long-term.' }, { speaker: 'Dr', text: 'I see. And you mentioned PTSD in your intake form?' }, { speaker: 'Pt', text: 'Yes, from my time in the service. The nightmares are the worst part.' } ]; sampleLines.forEach((line, index) => { setTimeout(() => { this.addTranscriptLine(line.speaker, line.text); }, index * 500); }); this.showToast('Sample visit loaded', 'success'); } switchTab(tabName) { // Hide all tabs document.querySelectorAll('.tab-panel').forEach(p => p.classList.add('hidden')); document.getElementById(`tab-${tabName}`).classList.remove('hidden'); // Update button styles document.querySelectorAll('.tab-btn').forEach(btn => { if (btn.dataset.tab === tabName) { btn.className = 'tab-btn active px-3 py-1.5 text-xs font-medium rounded-md bg-emerald-100 text-emerald-700'; } else { btn.className = 'tab-btn px-3 py-1.5 text-xs font-medium rounded-md text-gray-600 hover:bg-gray-100'; } }); } clearTranscript() { document.getElementById('transcript-lines').innerHTML = '
    Recording not started. Click "Start Recording" or "Simulate Conversation" to begin.
    '; document.getElementById('word-count').textContent = '0 words'; } copyTranscript() { const text = document.getElementById('transcript-lines').innerText; navigator.clipboard.writeText(text); this.showToast('Transcript copied to clipboard', 'success'); } expandTranscript() { this.showToast('Expand view would open full-screen transcript', 'info'); } insertCommand(command) { this.showToast(`Voice command: "${command}"`, 'info'); if (this.isRecording && !this.isPaused) { setTimeout(() => { this.addTranscriptLine('System', `[AI Command: ${command}]`); }, 500); } } // AI Notes generateAINotes() { const btn = document.getElementById('btn-generate-notes'); btn.innerHTML = ' Generating...'; lucide.createIcons(); setTimeout(() => { document.getElementById('ai-notes-container').style.opacity = '1'; document.getElementById('ai-notes-container').style.pointerEvents = 'auto'; document.getElementById('quality-score-card').classList.remove('hidden'); btn.innerHTML = ' Regenerate'; lucide.createIcons(); this.showToast('AI notes generated successfully', 'success'); this.updateProgress(); }, 2000); } regenerateSection(section) { this.showToast(`Regenerating ${section} section...`, 'info'); setTimeout(() => { this.showToast(`${section} section updated`, 'success'); }, 1000); } lockSection(section) { this.showToast(`${section} section locked`, 'success'); } selectCode(element) { document.querySelectorAll('#coding-suggestions > div').forEach(el => { el.classList.remove('bg-purple-50', 'border-purple-300'); }); element.classList.add('bg-purple-50', 'border-purple-300'); } showMoreCodes() { this.showToast('Additional coding suggestions would appear here', 'info'); } jumpToSection(section) { this.showToast(`Navigating to ${section}...`, 'info'); } generateCertPDF() { this.showToast('Generating certification PDF...', 'info'); setTimeout(() => { this.showToast('PDF generated and ready for download', 'success'); }, 1500); } generateRegistryDoc() { this.showToast('Preparing registry documents...', 'info'); } sendToRegistry() { this.showToast('Submitting to state registry...', 'info'); setTimeout(() => { this.showToast('Registry submission successful', 'success'); }, 2000); } // Review & Finalize toggleComplianceCheck(checkbox, type) { this.showToast(`${type} compliance ${checkbox.checked ? 'verified' : 'pending'}`, 'info'); } submitEncounter() { this.showToast('Submitting encounter...', 'info'); setTimeout(() => { this.showToast('Encounter submitted successfully!', 'success'); setTimeout(() => { if (confirm('Encounter complete! Return to dashboard?')) { this.showToast('Returning to dashboard...', 'info'); } }, 500); }, 2000); } saveDraft() { this.showToast('Draft saved successfully', 'success'); } scheduleFollowUp() { this.showToast('Opening scheduling calendar...', 'info'); } previewDoc(type) { const titles = { soap: 'SOAP Note Preview', cert: 'Certification Letter Preview', registry: 'Registry Form Preview', bill: 'Encounter Bill Preview' }; document.getElementById('preview-title').textContent = titles[type]; document.getElementById('preview-content').innerHTML = `

    ${titles[type]}

    Verify MC Medical Marijuana Platform

    Patient: ${this.selectedPatient?.firstName} ${this.selectedPatient?.lastName}
    Date: ${new Date().toLocaleDateString()}
    Provider: Dr. Sarah Chen, MD
    Document content would appear here
    `; document.getElementById('preview-modal').classList.remove('hidden'); } closePreview() { document.getElementById('preview-modal').classList.add('hidden'); } downloadPreview() { this.showToast('Downloading PDF...', 'success'); } // AI Copilot toggleCopilot() { this.copilotOpen = !this.copilotOpen; const panel = document.getElementById('copilot-panel'); if (this.copilotOpen) { panel.classList.remove('hidden'); document.getElementById('copilot-badge').classList.add('hidden'); } else { panel.classList.add('hidden'); } } sendCopilotMessage() { const input = document.getElementById('copilot-input'); const message = input.value.trim(); if (!message) return; this.addCopilotMessage('user', message); input.value = ''; // Simulate AI response setTimeout(() => { const responses = [ 'Based on the patient profile, I recommend documenting chronic pain with severity rating.', 'Would you like me to suggest appropriate dosing guidelines for this condition?', 'I can help generate the assessment section. Should I focus on prior treatment failures?', 'Reminder: This patient needs registry ID verification before submission.' ]; const randomResponse = responses[Math.floor(Math.random() * responses.length)]; this.addCopilotMessage('ai', randomResponse); }, 1000); } quickAsk(query) { document.getElementById('copilot-input').value = query; this.sendCopilotMessage(); } addCopilotMessage(sender, text) { const container = document.getElementById('copilot-messages'); const messageDiv = document.createElement('div'); if (sender === 'ai') { messageDiv.className = 'p-3 bg-blue-50 rounded-lg border border-blue-200'; messageDiv.innerHTML = `
    ${text}
    `; } else { messageDiv.className = 'p-3 bg-gray-100 rounded-lg border border-gray-200 ml-8'; messageDiv.innerHTML = `
    ${text}
    `; } container.appendChild(messageDiv); container.scrollTop = container.scrollHeight; lucide.createIcons(); } // Progress & Status updateProgress() { let completed = 0; const total = 5; if (this.selectedPatient) completed++; if (this.encounterData.conditions.length > 0) completed++; if (this.recordingTime > 0) completed++; if (document.getElementById('ai-notes-container')?.style.opacity === '1') completed++; if (this.currentStep === 5) completed = 5; const percentage = Math.round((completed / total) * 100); // Update circle progress const circle = document.getElementById('progress-circle'); const radius = 20; const circumference = radius * 2 * Math.PI; const offset = circumference - (percentage / 100) * circumference; if (circle) { circle.style.strokeDashoffset = offset; } document.getElementById('progress-text').textContent = `${percentage}%`; // Update title and badges const titles = ['Needs Data', 'Getting Started', 'In Progress', 'Almost Complete', 'Ready to Submit']; const titleIndex = Math.floor((completed / total) * (titles.length - 1)); document.getElementById('readiness-title').textContent = titles[titleIndex]; const missingItems = []; if (!this.selectedPatient) missingItems.push('Select patient'); if (this.encounterData.conditions.length === 0) missingItems.push('Add conditions'); if (this.recordingTime === 0) missingItems.push('Record encounter'); document.getElementById('missing-items').textContent = missingItems.length > 0 ? `Missing: ${missingItems.join(', ')}` : 'All requirements met'; // Update status badges const badgesContainer = document.getElementById('status-badges'); if (percentage === 100) { badgesContainer.innerHTML = 'Ready to Submit'; } else if (percentage > 50) { badgesContainer.innerHTML = 'In Progress'; } else { badgesContainer.innerHTML = 'Draft'; } } // Auto-save startAutoSave() { setInterval(() => { const now = new Date(); const timeStr = now.toLocaleTimeString(); const statusEl = document.getElementById('auto-save-status'); if (statusEl) { statusEl.textContent = `Auto-saved ${Math.floor(Math.random() * 10) + 1}s ago`; } }, 10000); } // Footer Actions quickAction(action) { switch(action) { case 'help': this.toggleCopilot(); break; case 'calculator': this.showToast('Dosage calculator would open', 'info'); break; case 'print': window.print(); break; } } saveAndExit() { this.showToast('Saving encounter...', 'info'); setTimeout(() => { this.showToast('Saved! You can safely exit.', 'success'); }, 1000); } submitFinal() { this.submitEncounter(); } // Utilities showToast(message, type = 'info') { const container = document.getElementById('toast-container'); const toast = document.createElement('div'); const colors = { success: 'bg-emerald-50 border-emerald-200 text-emerald-800', error: 'bg-red-50 border-red-200 text-red-800', info: 'bg-blue-50 border-blue-200 text-blue-800', warning: 'bg-amber-50 border-amber-200 text-amber-800' }; const icons = { success: 'check-circle', error: 'x-circle', info: 'info', warning: 'alert-triangle' }; toast.className = `flex items-center gap-2 px-4 py-3 rounded-lg border shadow-lg ${colors[type]} fade-in`; toast.innerHTML = ` ${message} `; container.appendChild(toast); lucide.createIcons(); setTimeout(() => { toast.style.opacity = '0'; toast.style.transform = 'translateY(10px)'; setTimeout(() => toast.remove(), 300); }, 4000); } } // Initialize app const app = new VerifyMCApp();