// Global State let currentDate = new Date(); let currentFilter = 'all'; let isSidebarCollapsed = false; // Sample Appointment Data const appointments = [ { id: 1, patient: "John Smith", time: "09:00 AM", type: "general", color: "bg-blue-500", date: 15 }, { id: 2, patient: "Emma Wilson", time: "10:30 AM", type: "emergency", color: "bg-red-500", date: 15 }, { id: 3, patient: "Michael Brown", time: "02:00 PM", type: "followup", color: "bg-green-500", date: 15 }, { id: 4, patient: "Sarah Davis", time: "11:00 AM", type: "consultation", color: "bg-yellow-500", date: 16 }, { id: 5, patient: "James Miller", time: "03:30 PM", type: "general", color: "bg-blue-500", date: 16 }, { id: 6, patient: "Linda Garcia", time: "09:30 AM", type: "emergency", color: "bg-red-500", date: 17 }, { id: 7, patient: "Robert Taylor", time: "01:00 PM", type: "followup", color: "bg-green-500", date: 18 }, { id: 8, patient: "Patricia Martinez", time: "10:00 AM", type: "general", color: "bg-blue-500", date: 19 }, { id: 9, patient: "William Anderson", time: "04:00 PM", type: "consultation", color: "bg-yellow-500", date: 20 }, { id: 10, patient: "Elizabeth Thomas", time: "11:30 AM", type: "followup", color: "bg-green-500", date: 21 }, { id: 11, patient: "David Jackson", time: "02:30 PM", type: "general", color: "bg-blue-500", date: 22 }, { id: 12, patient: "Jennifer White", time: "09:00 AM", type: "emergency", color: "bg-red-500", date: 23 } ]; // Initialize document.addEventListener('DOMContentLoaded', () => { renderCalendar(); updateCurrentDate(); // Check window size for responsive sidebar window.addEventListener('resize', handleResize); handleResize(); }); // Sidebar Toggle function toggleSidebar() { const sidebar = document.getElementById('sidebar'); const mobileOverlay = document.getElementById('mobileOverlay'); const sidebarTexts = document.querySelectorAll('.sidebar-text'); if (window.innerWidth >= 1024) { // Desktop behavior isSidebarCollapsed = !isSidebarCollapsed; if (isSidebarCollapsed) { sidebar.classList.remove('w-64'); sidebar.classList.add('w-20'); sidebarTexts.forEach(text => { text.style.opacity = '0'; text.style.width = '0'; text.style.overflow = 'hidden'; }); } else { sidebar.classList.remove('w-20'); sidebar.classList.add('w-64'); sidebarTexts.forEach(text => { text.style.opacity = '1'; text.style.width = 'auto'; text.style.overflow = 'visible'; }); } } else { // Mobile behavior if (sidebar.classList.contains('-translate-x-full')) { sidebar.classList.remove('-translate-x-full'); mobileOverlay.classList.remove('hidden'); } else { sidebar.classList.add('-translate-x-full'); mobileOverlay.classList.add('hidden'); } } } function handleResize() { const sidebar = document.getElementById('sidebar'); const mobileOverlay = document.getElementById('mobileOverlay'); if (window.innerWidth >= 1024) { mobileOverlay.classList.add('hidden'); if (!isSidebarCollapsed) { sidebar.classList.remove('-translate-x-full'); sidebar.classList.add('w-64'); sidebar.classList.remove('w-20'); } } else { sidebar.classList.add('-translate-x-full'); sidebar.classList.remove('w-20'); sidebar.classList.add('w-64'); } } // Calendar Functions function renderCalendar() { const year = currentDate.getFullYear(); const month = currentDate.getMonth(); // Update header const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; document.getElementById('calendarMonth').textContent = `${monthNames[month]} ${year}`; const firstDay = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); const daysInPrevMonth = new Date(year, month, 0).getDate(); const grid = document.getElementById('calendarGrid'); grid.innerHTML = ''; // Previous month days for (let i = firstDay - 1; i >= 0; i--) { const dayDiv = document.createElement('div'); dayDiv.className = 'calendar-day bg-gray-50 p-2 border-b border-r border-gray-200 min-h-[120px] text-gray-400'; dayDiv.innerHTML = `${daysInPrevMonth - i}`; grid.appendChild(dayDiv); } // Current month days const today = new Date(); for (let day = 1; day <= daysInMonth; day++) { const dayDiv = document.createElement('div'); const isToday = today.getDate() === day && today.getMonth() === month && today.getFullYear() === year; dayDiv.className = `calendar-day bg-white p-2 border-b border-r border-gray-200 min-h-[120px] hover:bg-gray-50 transition-colors cursor-pointer ${isToday ? 'bg-blue-50/30' : ''}`; let dayContent = `
${day}
`; // Add appointments for this day const dayAppointments = appointments.filter(apt => apt.date === day); if (currentFilter !== 'all') { const filteredApts = dayAppointments.filter(apt => apt.type === currentFilter); dayContent += generateAppointmentHTML(filteredApts); } else { dayContent += generateAppointmentHTML(dayAppointments); } dayDiv.innerHTML = dayContent; dayDiv.onclick = () => openAddAppointment(day); grid.appendChild(dayDiv); } // Next month days to fill grid const remainingCells = 42 - (firstDay + daysInMonth); for (let i = 1; i <= remainingCells; i++) { const dayDiv = document.createElement('div'); dayDiv.className = 'calendar-day bg-gray-50 p-2 border-b border-r border-gray-200 min-h-[120px] text-gray-400'; dayDiv.innerHTML = `${i}`; grid.appendChild(dayDiv); } } function generateAppointmentHTML(appointments) { if (appointments.length === 0) return ''; let html = '
'; appointments.slice(0, 3).forEach(apt => { html += `

${apt.time}

${apt.patient}

`; }); if (appointments.length > 3) { html += `
+${appointments.length - 3} more
`; } html += '
'; return html; } function changeMonth(direction) { currentDate.setMonth(currentDate.getMonth() + direction); renderCalendar(); } function goToToday() { currentDate = new Date(); renderCalendar(); } function changeDateRange(value) { if (value === 'today') { // Filter to show only today's appointments in a list view (simplified for demo) alert('Switched to Today view - showing today\'s schedule'); } else if (value === 'week') { alert('Switched to Week view - showing weekly schedule'); } // Month view is default } // Category Filter function filterCategory(category) { currentFilter = category; // Update UI document.querySelectorAll('.category-btn').forEach(btn => { if (btn.dataset.category === category) { btn.classList.remove('bg-white', 'text-gray-700', 'border', 'border-gray-200'); btn.classList.add('bg-gray-900', 'text-white'); btn.querySelector('span').classList.remove('category-dot'); if (category !== 'all') { btn.querySelector('span').className = 'w-2 h-2 rounded-full bg-white'; } } else { btn.classList.add('bg-white', 'text-gray-700', 'border', 'border-gray-200'); btn.classList.remove('bg-gray-900', 'text-white'); const colors = { 'general': 'bg-blue-500 text-blue-500', 'emergency': 'bg-red-500 text-red-500', 'followup': 'bg-green-500 text-green-500', 'consultation': 'bg-yellow-500 text-yellow-500' }; if (btn.dataset.category !== 'all') { btn.querySelector('span').className = `w-2 h-2 rounded-full ${colors[btn.dataset.category]} category-dot`; } else { btn.querySelector('span').className = 'w-2 h-2 rounded-full bg-gray-900'; } } }); renderCalendar(); } // Modal Functions function openAddAppointment(day = null) { const modal = document.getElementById('addModal'); modal.classList.remove('hidden'); lucide.createIcons(); } function closeAddAppointment() { document.getElementById('addModal').classList.add('hidden'); } function saveAppointment() { closeAddAppointment(); // Show success notification (simplified) const notification = document.createElement('div'); notification.className = 'fixed bottom-4 right-4 bg-green-600 text-white px-6 py-3 rounded-lg shadow-lg z-50 fade-in flex items-center gap-2'; notification.innerHTML = ' Appointment saved successfully!'; document.body.appendChild(notification); lucide.createIcons(); setTimeout(() => { notification.remove(); }, 3000); } // Export and Reports function exportData() { const notification = document.createElement('div'); notification.className = 'fixed bottom-4 right-4 bg-blue-600 text-white px-6 py-3 rounded-lg shadow-lg z-50 fade-in flex items-center gap-2'; notification.innerHTML = ' Exporting calendar data...'; document.body.appendChild(notification); lucide.createIcons(); setTimeout(() => { notification.innerHTML = ' Export complete!'; setTimeout(() => notification.remove(), 2000); }, 1500); } function generateReports() { const notification = document.createElement('div'); notification.className = 'fixed bottom-4 right-4 bg-purple-600 text-white px-6 py-3 rounded-lg shadow-lg z-50 fade-in flex items-center gap-2'; notification.innerHTML = ' Generating report...'; document.body.appendChild(notification); lucide.createIcons(); setTimeout(() => { notification.innerHTML = ' Report generated!'; setTimeout(() => notification.remove(), 2000); }, 1500); } // Utility function updateCurrentDate() { const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; document.getElementById('currentDateDisplay').textContent = new Date().toLocaleDateString('en-US', options); } // Close modal on outside click document.getElementById('addModal').addEventListener('click', (e) => { if (e.target === document.getElementById('addModal')) { closeAddAppointment(); } });