// Sample data const appointments = [ { id: 'APT-2024-0092', date: '2024-01-15', time: '09:00 AM', duration: '30 min', provider: { name: 'Dr. Emily Chen', specialty: 'Internal Medicine', avatar: 'http://static.photos/people/320x240/2' }, category: 'Primary Care', type: 'In-person', location: 'Main Clinic, Room 304', status: 'Confirmed', notes: 2, reason: 'Annual physical examination', isUpcoming: true, history: [ { status: 'Created', time: 'Jan 8, 2024 2:30 PM', user: 'System' }, { status: 'Confirmed', time: 'Jan 8, 2024 2:35 PM', user: 'Dr. Chen' } ] }, { id: 'APT-2024-0095', date: '2024-01-18', time: '02:30 PM', duration: '45 min', provider: { name: 'Dr. James Wilson', specialty: 'Dermatology', avatar: 'http://static.photos/people/320x240/3' }, category: 'Dermatology', type: 'Telehealth', location: 'Video Consultation', status: 'Pending', notes: 0, reason: 'Rash follow-up consultation', isUpcoming: true, history: [ { status: 'Created', time: 'Jan 10, 2024 10:00 AM', user: 'Sarah Mitchell' } ] }, { id: 'APT-2024-0100', date: '2024-02-05', time: '11:00 AM', duration: '60 min', provider: { name: 'Dr. Sarah Park', specialty: 'Lab Services', avatar: 'http://static.photos/people/320x240/4' }, category: 'Lab', type: 'In-person', location: 'Lab Center, 2nd Floor', status: 'Confirmed', notes: 1, reason: 'Blood work and cholesterol panel', isUpcoming: true, history: [ { status: 'Created', time: 'Jan 20, 2024 9:00 AM', user: 'System' }, { status: 'Confirmed', time: 'Jan 20, 2024 9:15 AM', user: 'Staff' } ] }, { id: 'APT-2024-0085', date: '2023-12-15', time: '10:00 AM', duration: '30 min', provider: { name: 'Dr. Emily Chen', specialty: 'Internal Medicine', avatar: 'http://static.photos/people/320x240/2' }, category: 'Follow-up', type: 'In-person', location: 'Main Clinic, Room 304', status: 'Completed', notes: 3, reason: 'Medication review', isUpcoming: false, history: [ { status: 'Created', time: 'Dec 1, 2023 2:00 PM', user: 'System' }, { status: 'Confirmed', time: 'Dec 1, 2023 2:05 PM', user: 'Dr. Chen' }, { status: 'Checked-in', time: 'Dec 15, 2023 9:45 AM', user: 'Reception' }, { status: 'Completed', time: 'Dec 15, 2023 10:30 AM', user: 'Dr. Chen' } ] }, { id: 'APT-2024-0078', date: '2023-11-20', time: '03:00 PM', duration: '30 min', provider: { name: 'Dr. James Wilson', specialty: 'Dermatology', avatar: 'http://static.photos/people/320x240/3' }, category: 'Dermatology', type: 'In-person', location: 'Dermatology Suite, Room 105', status: 'Completed', notes: 2, reason: 'Skin examination', isUpcoming: false, history: [ { status: 'Created', time: 'Nov 10, 2023 11:00 AM', user: 'System' }, { status: 'Confirmed', time: 'Nov 10, 2023 11:05 AM', user: 'Auto-confirm' }, { status: 'Completed', time: 'Nov 20, 2023 3:30 PM', user: 'Dr. Wilson' } ] }, { id: 'APT-2024-0072', date: '2023-10-28', time: '09:30 AM', duration: '30 min', provider: { name: 'Dr. Emily Chen', specialty: 'Internal Medicine', avatar: 'http://static.photos/people/320x240/2' }, category: 'Primary Care', type: 'Telehealth', location: 'Phone Consultation', status: 'Canceled', notes: 0, reason: 'Prescription refill', isUpcoming: false, history: [ { status: 'Created', time: 'Oct 20, 2023 9:00 AM', user: 'Patient Portal' }, { status: 'Confirmed', time: 'Oct 20, 2023 9:05 AM', user: 'System' }, { status: 'Canceled', time: 'Oct 27, 2023 4:00 PM', user: 'Sarah Mitchell' } ] } ]; // State let currentView = 'list'; let currentCalendarView = 'month'; let selectedAppointment = null; // Initialize document.addEventListener('DOMContentLoaded', () => { renderListView(); renderCalendar(); renderUpcomingWeek(); // Re-initialize icons after all rendering is done if (typeof lucide !== 'undefined') { lucide.createIcons(); } }); // Sidebar Toggle function toggleSidebar() { const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('sidebarOverlay'); sidebar.classList.toggle('-translate-x-full'); overlay.classList.toggle('hidden'); } // Profile Dropdown function toggleProfileDropdown() { const dropdown = document.getElementById('profileDropdown'); dropdown.classList.toggle('hidden'); } // More Dropdown function toggleMoreDropdown() { const dropdown = document.getElementById('moreDropdown'); dropdown.classList.toggle('hidden'); } // Close dropdowns when clicking outside document.addEventListener('click', (e) => { if (!e.target.closest('.relative')) { const profileDropdown = document.getElementById('profileDropdown'); const moreDropdown = document.getElementById('moreDropdown'); if (profileDropdown) profileDropdown.classList.add('hidden'); if (moreDropdown) moreDropdown.classList.add('hidden'); } }); // View Switching function switchView(view) { currentView = view; const listView = document.getElementById('listView'); const calendarView = document.getElementById('calendarView'); const listBtn = document.getElementById('listViewBtn'); const calendarBtn = document.getElementById('calendarViewBtn'); const sortDropdown = document.getElementById('sortDropdown'); if (view === 'list') { listView.classList.remove('hidden'); calendarView.classList.add('hidden'); listBtn.classList.add('bg-teal-50', 'text-teal-700'); listBtn.classList.remove('text-gray-600', 'hover:text-gray-900'); calendarBtn.classList.remove('bg-teal-50', 'text-teal-700'); calendarBtn.classList.add('text-gray-600', 'hover:text-gray-900'); if (sortDropdown && sortDropdown.parentElement) { sortDropdown.parentElement.style.opacity = '1'; sortDropdown.parentElement.style.pointerEvents = 'auto'; } } else { listView.classList.add('hidden'); calendarView.classList.remove('hidden'); calendarBtn.classList.add('bg-teal-50', 'text-teal-700'); calendarBtn.classList.remove('text-gray-600', 'hover:text-gray-900'); listBtn.classList.remove('bg-teal-50', 'text-teal-700'); listBtn.classList.add('text-gray-600', 'hover:text-gray-900'); if (sortDropdown && sortDropdown.parentElement) { sortDropdown.parentElement.style.opacity = '0.5'; sortDropdown.parentElement.style.pointerEvents = 'none'; } } if (typeof lucide !== 'undefined') { lucide.createIcons(); } } // Render List View function renderListView() { const upcomingList = document.getElementById('upcomingList'); const historyList = document.getElementById('historyList'); const upcoming = appointments.filter(a => a.isUpcoming); const history = appointments.filter(a => !a.isUpcoming); if (upcomingList) { upcomingList.innerHTML = upcoming.map(appt => createAppointmentRow(appt)).join(''); } if (historyList) { historyList.innerHTML = history.map(appt => createAppointmentRow(appt)).join(''); } if (typeof lucide !== 'undefined') { lucide.createIcons(); } } function createAppointmentRow(appt) { if (!appt) return ''; const statusColors = { 'Confirmed': 'bg-green-100 text-green-700 border-green-200', 'Pending': 'bg-yellow-100 text-yellow-700 border-yellow-200', 'Completed': 'bg-gray-100 text-gray-700 border-gray-200', 'Canceled': 'bg-red-100 text-red-700 border-red-200', 'No-show': 'bg-orange-100 text-orange-700 border-orange-200' }; const categoryColors = { 'Primary Care': 'bg-blue-50 text-blue-700 border-blue-200', 'Dermatology': 'bg-purple-50 text-purple-700 border-purple-200', 'Lab': 'bg-pink-50 text-pink-700 border-pink-200', 'Follow-up': 'bg-indigo-50 text-indigo-700 border-indigo-200' }; const statusClass = statusColors[appt.status] || 'bg-gray-100 text-gray-700 border-gray-200'; const categoryClass = categoryColors[appt.category] || 'bg-gray-100 text-gray-700 border-gray-200'; return `
${appt.reason || ''}
Patient confirmed appointment via portal. No special requirements noted.
Requested morning slot due to work schedule.