// Sample patient data let patients = [ { id: 1, name: "Emma Thompson", avatar: "http://static.photos/people/200x200/1", tags: ["Critical", "VIP"], created: "2024-01-15", approved: "2024-01-16", expires: "2025-01-16", notes: "Severe allergy to penicillin. Requires constant monitoring.", phone: "+1 (555) 123-4567", email: "emma.t@email.com", status: "approved" }, { id: 2, name: "James Wilson", avatar: "http://static.photos/people/200x200/2", tags: ["New Patient"], created: "2024-03-20", approved: "2024-03-21", expires: "2024-09-21", notes: "Post-surgery recovery. Physical therapy scheduled.", phone: "+1 (555) 234-5678", email: "j.wilson@email.com", status: "expired" }, { id: 3, name: "Sarah Chen", avatar: "http://static.photos/people/200x200/3", tags: ["Follow-up"], created: "2024-02-10", approved: "2024-02-11", expires: "2025-02-11", notes: "Routine diabetes check. Blood sugar levels stable.", phone: "+1 (555) 345-6789", email: "sarah.chen@email.com", status: "approved" }, { id: 4, name: "Michael Brown", avatar: "http://static.photos/people/200x200/4", tags: ["Urgent"], created: "2024-04-05", approved: "2024-04-05", expires: "2024-10-05", notes: "Cardiac monitoring required. High blood pressure history.", phone: "+1 (555) 456-7890", email: "mbrown@email.com", status: "expired" }, { id: 5, name: "Lisa Anderson", avatar: "http://static.photos/people/200x200/5", tags: ["Regular"], created: "2024-01-28", approved: "2024-01-29", expires: "2025-01-29", notes: "Annual physical completed. All vitals normal.", phone: "+1 (555) 567-8901", email: "lisa.a@email.com", status: "approved" }, { id: 6, name: "David Martinez", avatar: "http://static.photos/people/200x200/6", tags: ["New Patient", "Insurance Pending"], created: "2024-05-12", approved: "2024-05-13", expires: "2025-05-13", notes: "Initial consultation completed. Awaiting test results.", phone: "+1 (555) 678-9012", email: "d.martinez@email.com", status: "approved" }, { id: 7, name: "Jennifer Taylor", avatar: "http://static.photos/people/200x200/7", tags: ["Critical"], created: "2023-11-15", approved: "2023-11-16", expires: "2024-05-16", notes: "Oncology patient. Chemotherapy cycle 4 of 6.", phone: "+1 (555) 789-0123", email: "jtaylor@email.com", status: "expired" }, { id: 8, name: "Robert Johnson", avatar: "http://static.photos/people/200x200/8", tags: ["Senior"], created: "2024-03-01", approved: "2024-03-02", expires: "2025-03-02", notes: "Arthritis management. Mobility assistance required.", phone: "+1 (555) 890-1234", email: "r.johnson@email.com", status: "approved" }, { id: 9, name: "Amanda White", avatar: "http://static.photos/people/200x200/9", tags: ["Pediatric"], created: "2024-04-20", approved: "2024-04-21", expires: "2025-04-21", notes: "Vaccination schedule up to date. Growth chart normal.", phone: "+1 (555) 901-2345", email: "amanda.w@email.com", status: "approved" }, { id: 10, name: "Christopher Lee", avatar: "http://static.photos/people/200x200/10", tags: ["Follow-up", "Physical Therapy"], created: "2024-02-28", approved: "2024-02-29", expires: "2024-08-29", notes: "Knee replacement recovery. PT exercises 3x weekly.", phone: "+1 (555) 012-3456", email: "chris.lee@email.com", status: "expired" }, { id: 11, name: "Maria Garcia", avatar: "http://static.photos/people/200x200/11", tags: ["Prenatal"], created: "2024-01-10", approved: "2024-01-11", expires: "2024-10-11", notes: "Second trimester. Ultrasound scheduled next week.", phone: "+1 (555) 111-2222", email: "maria.g@email.com", status: "approved" }, { id: 12, name: "Kevin Davis", avatar: "http://static.photos/people/200x200/12", tags: ["Emergency"], created: "2024-05-15", approved: "2024-05-15", expires: "2024-11-15", notes: "Fractured wrist. Cast applied, follow-up in 2 weeks.", phone: "+1 (555) 222-3333", email: "kevin.d@email.com", status: "expired" } ]; // State management let currentPage = 1; let itemsPerPage = 10; let sortColumn = null; let sortDirection = 'asc'; let filteredData = [...patients]; // Initialize document.addEventListener('DOMContentLoaded', () => { renderTable(); lucide.createIcons(); }); // Sidebar toggle for mobile function toggleSidebar() { const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('mobile-overlay'); const isClosed = sidebar.classList.contains('-translate-x-full'); if (isClosed) { sidebar.classList.remove('-translate-x-full'); overlay.classList.remove('hidden'); } else { sidebar.classList.add('-translate-x-full'); overlay.classList.add('hidden'); } } // Sorting functionality function sortTable(column) { // Reset all sort icons document.querySelectorAll('.sort-icon').forEach(icon => { icon.setAttribute('data-lucide', 'chevrons-up-down'); icon.classList.remove('sort-asc', 'sort-desc'); }); // Toggle direction if same column if (sortColumn === column) { sortDirection = sortDirection === 'asc' ? 'desc' : 'asc'; } else { sortColumn = column; sortDirection = 'asc'; } // Update icon for current column const currentIcon = document.getElementById(`sort-${column}`); if (currentIcon) { currentIcon.setAttribute('data-lucide', sortDirection === 'asc' ? 'chevron-up' : 'chevron-down'); currentIcon.classList.add(sortDirection === 'asc' ? 'sort-asc' : 'sort-desc'); } // Sort data filteredData.sort((a, b) => { let valA = a[column]; let valB = b[column]; if (column === 'name') { valA = a.name.toLowerCase(); valB = b.name.toLowerCase(); } if (valA < valB) return sortDirection === 'asc' ? -1 : 1; if (valA > valB) return sortDirection === 'asc' ? 1 : -1; return 0; }); lucide.createIcons(); renderTable(); } // Filter functionality function filterTable() { const searchTerm = document.getElementById('searchInput').value.toLowerCase(); const statusFilter = document.getElementById('statusFilter').value; filteredData = patients.filter(patient => { const matchesSearch = patient.name.toLowerCase().includes(searchTerm) || patient.email.toLowerCase().includes(searchTerm) || patient.phone.includes(searchTerm); const matchesStatus = statusFilter === 'all' || patient.status === statusFilter; return matchesSearch && matchesStatus; }); currentPage = 1; renderTable(); } // Render table function renderTable() { const tbody = document.getElementById('tableBody'); const start = (currentPage - 1) * itemsPerPage; const end = start + itemsPerPage; const paginatedData = filteredData.slice(start, end); tbody.innerHTML = paginatedData.map(patient => { const statusColors = { approved: 'bg-emerald-100 text-emerald-800 border-emerald-200', expired: 'bg-rose-100 text-rose-800 border-rose-200' }; const statusIcons = { approved: 'check-circle', expired: 'x-circle' }; const tagColors = { 'Critical': 'bg-red-100 text-red-700', 'VIP': 'bg-purple-100 text-purple-700', 'New Patient': 'bg-blue-100 text-blue-700', 'Follow-up': 'bg-amber-100 text-amber-700', 'Urgent': 'bg-orange-100 text-orange-700', 'Regular': 'bg-gray-100 text-gray-700', 'Insurance Pending': 'bg-yellow-100 text-yellow-700', 'Senior': 'bg-indigo-100 text-indigo-700', 'Pediatric': 'bg-pink-100 text-pink-700', 'Prenatal': 'bg-teal-100 text-teal-700', 'Emergency': 'bg-red-100 text-red-700', 'Physical Therapy': 'bg-cyan-100 text-cyan-700' }; return `
${patient.name}
ID: #${String(patient.id).padStart(4, '0')}
${patient.tags.map(tag => ` ${tag} `).join('')}
${formatDate(patient.created)} ${formatDate(patient.approved)} ${formatDate(patient.expires)}
${patient.notes}
${patient.phone}
${patient.email}
${patient.status}
`; }).join(''); // Update pagination info document.getElementById('showingStart').textContent = filteredData.length > 0 ? start + 1 : 0; document.getElementById('showingEnd').textContent = Math.min(end, filteredData.length); document.getElementById('totalItems').textContent = filteredData.length; // Update pagination buttons document.getElementById('prevBtn').disabled = currentPage === 1; document.getElementById('nextBtn').disabled = end >= filteredData.length; renderPaginationNumbers(); lucide.createIcons(); } function renderPaginationNumbers() { const totalPages = Math.ceil(filteredData.length / itemsPerPage); const container = document.getElementById('paginationNumbers'); let html = ''; for (let i = 1; i <= totalPages; i++) { if (i === 1 || i === totalPages || (i >= currentPage - 1 && i <= currentPage + 1)) { html += ` `; } else if (i === currentPage - 2 || i === currentPage + 2) { html += `...`; } } container.innerHTML = html; } function changePage(direction) { const totalPages = Math.ceil(filteredData.length / itemsPerPage); const newPage = currentPage + direction; if (newPage >= 1 && newPage <= totalPages) { currentPage = newPage; renderTable(); } } function goToPage(page) { currentPage = page; renderTable(); } function formatDate(dateString) { const options = { year: 'numeric', month: 'short', day: 'numeric' }; return new Date(dateString).toLocaleDateString('en-US', options); } // Action handlers function viewPatient(id) { showToast('Viewing patient details...'); } function editPatient(id) { showToast('Opening edit mode...'); } function deletePatient(id) { if (confirm('Are you sure you want to delete this patient record?')) { patients = patients.filter(p => p.id !== id); filterTable(); showToast('Patient deleted successfully'); } } function openAddModal() { document.getElementById('addModal').classList.remove('hidden'); } function closeAddModal() { document.getElementById('addModal').classList.add('hidden'); } function savePatient() { closeAddModal(); showToast('New patient added successfully'); } function exportData() { showToast('Exporting patient data to CSV...'); } function showToast(message) { const toast = document.getElementById('toast'); const toastMessage = document.getElementById('toastMessage'); toastMessage.textContent = message; toast.classList.remove('translate-y-20', 'opacity-0'); setTimeout(() => { toast.classList.add('translate-y-20', 'opacity-0'); }, 3000); } // Close modal on escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeAddModal(); } });