Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Medical Admin - Patient Calendar</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/lucide@latest"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| body { font-family: 'Inter', sans-serif; } | |
| .sidebar-transition { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } | |
| .calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; } | |
| .calendar-day { min-height: 120px; } | |
| .scrollbar-hide::-webkit-scrollbar { display: none; } | |
| .scrollbar-hide { -ms-overflow-style: none; scrollbar-width: none; } | |
| .fade-in { animation: fadeIn 0.3s ease-in-out; } | |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } | |
| .category-dot { box-shadow: 0 0 0 2px white, 0 0 0 4px currentColor; } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 text-gray-800 overflow-hidden"> | |
| <!-- Mobile Overlay --> | |
| <div id="mobileOverlay" class="fixed inset-0 bg-black bg-opacity-50 z-20 hidden lg:hidden" onclick="toggleSidebar()"></div> | |
| <div class="flex h-screen w-full"> | |
| <!-- Sidebar --> | |
| <aside id="sidebar" class="sidebar-transition bg-white shadow-xl z-30 flex flex-col h-full absolute lg:relative w-64 lg:w-64 -translate-x-full lg:translate-x-0"> | |
| <!-- Logo Area --> | |
| <div class="h-16 flex items-center justify-between px-6 border-b border-gray-100"> | |
| <div class="flex items-center gap-3 overflow-hidden"> | |
| <div class="bg-blue-600 p-2 rounded-lg flex-shrink-0"> | |
| <i data-lucide="activity" class="w-5 h-5 text-white"></i> | |
| </div> | |
| <span class="font-bold text-xl text-gray-900 whitespace-nowrap sidebar-text">MedAdmin</span> | |
| </div> | |
| <button onclick="toggleSidebar()" class="lg:hidden text-gray-500 hover:text-gray-700"> | |
| <i data-lucide="x" class="w-6 h-6"></i> | |
| </button> | |
| </div> | |
| <!-- Navigation --> | |
| <nav class="flex-1 overflow-y-auto py-4 px-3 scrollbar-hide"> | |
| <ul class="space-y-1"> | |
| <!-- Dashboard --> | |
| <li> | |
| <a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-gray-600 hover:bg-gray-50 hover:text-gray-900 transition-colors group"> | |
| <i data-lucide="layout-dashboard" class="w-5 h-5 flex-shrink-0"></i> | |
| <span class="sidebar-text whitespace-nowrap font-medium">Dashboard</span> | |
| </a> | |
| </li> | |
| <!-- Patients --> | |
| <li> | |
| <a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-gray-600 hover:bg-gray-50 hover:text-gray-900 transition-colors group"> | |
| <i data-lucide="users" class="w-5 h-5 flex-shrink-0"></i> | |
| <span class="sidebar-text whitespace-nowrap font-medium">Patients</span> | |
| </a> | |
| </li> | |
| <!-- Appointments (Expanded) --> | |
| <li class="mt-2"> | |
| <div class="px-3 py-2.5 rounded-lg bg-blue-50 text-blue-700"> | |
| <div class="flex items-center gap-3"> | |
| <i data-lucide="calendar-check" class="w-5 h-5 flex-shrink-0"></i> | |
| <span class="sidebar-text whitespace-nowrap font-semibold">Appointments</span> | |
| <i data-lucide="chevron-down" class="w-4 h-4 ml-auto sidebar-text"></i> | |
| </div> | |
| </div> | |
| <!-- Submenu --> | |
| <ul class="mt-1 ml-8 space-y-1 sidebar-text"> | |
| <li> | |
| <a href="#" class="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-600 hover:text-blue-600 hover:bg-blue-50/50 transition-colors text-sm"> | |
| <i data-lucide="plus-circle" class="w-4 h-4"></i> | |
| Add Appointment | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-600 hover:text-blue-600 hover:bg-blue-50/50 transition-colors text-sm"> | |
| <i data-lucide="list" class="w-4 h-4"></i> | |
| All Appointments | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center gap-2 px-3 py-2 rounded-lg bg-blue-100 text-blue-800 font-medium text-sm"> | |
| <i data-lucide="calendar-days" class="w-4 h-4"></i> | |
| Calendar | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-600 hover:text-blue-600 hover:bg-blue-50/50 transition-colors text-sm"> | |
| <i data-lucide="file-text" class="w-4 h-4"></i> | |
| Reports | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-600 hover:text-blue-600 hover:bg-blue-50/50 transition-colors text-sm"> | |
| <i data-lucide="settings" class="w-4 h-4"></i> | |
| Settings | |
| </a> | |
| </li> | |
| </ul> | |
| </li> | |
| <!-- Doctors --> | |
| <li> | |
| <a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-gray-600 hover:bg-gray-50 hover:text-gray-900 transition-colors group"> | |
| <i data-lucide="stethoscope" class="w-5 h-5 flex-shrink-0"></i> | |
| <span class="sidebar-text whitespace-nowrap font-medium">Doctors</span> | |
| </a> | |
| </li> | |
| <!-- Medical Records --> | |
| <li> | |
| <a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-gray-600 hover:bg-gray-50 hover:text-gray-900 transition-colors group"> | |
| <i data-lucide="file-heart" class="w-5 h-5 flex-shrink-0"></i> | |
| <span class="sidebar-text whitespace-nowrap font-medium">Medical Records</span> | |
| </a> | |
| </li> | |
| <!-- Billing --> | |
| <li> | |
| <a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-gray-600 hover:bg-gray-50 hover:text-gray-900 transition-colors group"> | |
| <i data-lucide="credit-card" class="w-5 h-5 flex-shrink-0"></i> | |
| <span class="sidebar-text whitespace-nowrap font-medium">Billing</span> | |
| </a> | |
| </li> | |
| </ul> | |
| </nav> | |
| <!-- User Profile --> | |
| <div class="border-t border-gray-100 p-4"> | |
| <div class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-gray-50 cursor-pointer transition-colors"> | |
| <img src="http://static.photos/people/200x200/42" alt="Doctor" class="w-8 h-8 rounded-full object-cover flex-shrink-0"> | |
| <div class="sidebar-text overflow-hidden"> | |
| <p class="text-sm font-semibold text-gray-900 truncate">Dr. Sarah Johnson</p> | |
| <p class="text-xs text-gray-500 truncate">Cardiologist</p> | |
| </div> | |
| <i data-lucide="log-out" class="w-4 h-4 text-gray-400 ml-auto sidebar-text flex-shrink-0"></i> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- Main Content --> | |
| <main class="flex-1 flex flex-col h-full overflow-hidden relative"> | |
| <!-- Top Header --> | |
| <header class="h-16 bg-white border-b border-gray-200 flex items-center justify-between px-4 lg:px-8 flex-shrink-0"> | |
| <div class="flex items-center gap-4"> | |
| <button onclick="toggleSidebar()" class="p-2 hover:bg-gray-100 rounded-lg transition-colors text-gray-600"> | |
| <i data-lucide="menu" class="w-6 h-6"></i> | |
| </button> | |
| <h1 class="text-xl font-semibold text-gray-900 hidden sm:block">Appointment Calendar</h1> | |
| </div> | |
| <div class="flex items-center gap-3"> | |
| <button class="p-2 hover:bg-gray-100 rounded-full relative transition-colors"> | |
| <i data-lucide="bell" class="w-5 h-5 text-gray-600"></i> | |
| <span class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full"></span> | |
| </button> | |
| <button class="p-2 hover:bg-gray-100 rounded-full transition-colors"> | |
| <i data-lucide="search" class="w-5 h-5 text-gray-600"></i> | |
| </button> | |
| <div class="hidden md:flex items-center gap-2 text-sm text-gray-600 bg-gray-100 px-3 py-1.5 rounded-lg"> | |
| <i data-lucide="calendar" class="w-4 h-4"></i> | |
| <span id="currentDateDisplay"></span> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Filter & Controls Bar --> | |
| <div class="bg-white border-b border-gray-200 p-4 lg:p-6 flex-shrink-0"> | |
| <div class="flex flex-col xl:flex-row gap-4 justify-between items-start xl:items-center"> | |
| <!-- Category Filters --> | |
| <div class="flex flex-wrap items-center gap-2 w-full xl:w-auto"> | |
| <button onclick="filterCategory('all')" class="category-btn active flex items-center gap-2 px-4 py-2 rounded-full bg-gray-900 text-white text-sm font-medium transition-all" data-category="all"> | |
| <span class="w-2 h-2 rounded-full bg-white"></span> | |
| All | |
| </button> | |
| <button onclick="filterCategory('general')" class="category-btn flex items-center gap-2 px-4 py-2 rounded-full bg-white border border-gray-200 text-gray-700 hover:bg-gray-50 text-sm font-medium transition-all" data-category="general"> | |
| <span class="w-2 h-2 rounded-full bg-blue-500 category-dot text-blue-500"></span> | |
| General | |
| </button> | |
| <button onclick="filterCategory('emergency')" class="category-btn flex items-center gap-2 px-4 py-2 rounded-full bg-white border border-gray-200 text-gray-700 hover:bg-gray-50 text-sm font-medium transition-all" data-category="emergency"> | |
| <span class="w-2 h-2 rounded-full bg-red-500 category-dot text-red-500"></span> | |
| Emergency | |
| </button> | |
| <button onclick="filterCategory('followup')" class="category-btn flex items-center gap-2 px-4 py-2 rounded-full bg-white border border-gray-200 text-gray-700 hover:bg-gray-50 text-sm font-medium transition-all" data-category="followup"> | |
| <span class="w-2 h-2 rounded-full bg-green-500 category-dot text-green-500"></span> | |
| Follow-up | |
| </button> | |
| <button onclick="filterCategory('consultation')" class="category-btn flex items-center gap-2 px-4 py-2 rounded-full bg-white border border-gray-200 text-gray-700 hover:bg-gray-50 text-sm font-medium transition-all" data-category="consultation"> | |
| <span class="w-2 h-2 rounded-full bg-yellow-500 category-dot text-yellow-500"></span> | |
| Consultation | |
| </button> | |
| </div> | |
| <!-- Controls --> | |
| <div class="flex flex-wrap items-center gap-3 w-full xl:w-auto justify-start xl:justify-end"> | |
| <!-- Filter Dropdown --> | |
| <div class="relative"> | |
| <select class="appearance-none bg-white border border-gray-300 text-gray-700 py-2 pl-4 pr-10 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm font-medium cursor-pointer hover:border-gray-400 transition-colors"> | |
| <option>All Status</option> | |
| <option>Confirmed</option> | |
| <option>Pending</option> | |
| <option>Cancelled</option> | |
| <option>Completed</option> | |
| </select> | |
| <i data-lucide="chevron-down" class="w-4 h-4 absolute right-3 top-3 text-gray-500 pointer-events-none"></i> | |
| </div> | |
| <!-- Date Range Dropdown --> | |
| <div class="relative"> | |
| <select id="dateRangeSelect" onchange="changeDateRange(this.value)" class="appearance-none bg-white border border-gray-300 text-gray-700 py-2 pl-4 pr-10 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm font-medium cursor-pointer hover:border-gray-400 transition-colors"> | |
| <option value="month">This Month</option> | |
| <option value="week">This Week</option> | |
| <option value="today">Today</option> | |
| <option value="next7">Next 7 Days</option> | |
| <option value="next30">Next 30 Days</option> | |
| </select> | |
| <i data-lucide="chevron-down" class="w-4 h-4 absolute right-3 top-3 text-gray-500 pointer-events-none"></i> | |
| </div> | |
| <div class="h-8 w-px bg-gray-300 mx-1 hidden sm:block"></div> | |
| <!-- Action Buttons --> | |
| <button onclick="generateReports()" class="flex items-center gap-2 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-colors text-sm font-medium"> | |
| <i data-lucide="bar-chart-3" class="w-4 h-4"></i> | |
| <span class="hidden sm:inline">Reports</span> | |
| </button> | |
| <button onclick="exportData()" class="flex items-center gap-2 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-colors text-sm font-medium"> | |
| <i data-lucide="download" class="w-4 h-4"></i> | |
| <span class="hidden sm:inline">Export</span> | |
| </button> | |
| <button onclick="openAddAppointment()" class="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium shadow-lg shadow-blue-200"> | |
| <i data-lucide="plus" class="w-4 h-4"></i> | |
| Add Appointment | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Calendar Content --> | |
| <div class="flex-1 overflow-y-auto p-4 lg:p-6 bg-gray-50"> | |
| <!-- Calendar Header --> | |
| <div class="flex items-center justify-between mb-6"> | |
| <div class="flex items-center gap-4"> | |
| <h2 id="calendarMonth" class="text-2xl font-bold text-gray-900"></h2> | |
| <div class="flex items-center gap-1 bg-white rounded-lg border border-gray-200 p-1 shadow-sm"> | |
| <button onclick="changeMonth(-1)" class="p-1.5 hover:bg-gray-100 rounded-md transition-colors"> | |
| <i data-lucide="chevron-left" class="w-5 h-5 text-gray-600"></i> | |
| </button> | |
| <button onclick="goToToday()" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-md transition-colors">Today</button> | |
| <button onclick="changeMonth(1)" class="p-1.5 hover:bg-gray-100 rounded-md transition-colors"> | |
| <i data-lucide="chevron-right" class="w-5 h-5 text-gray-600"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex items-center gap-2 text-sm text-gray-600"> | |
| <span class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-blue-500"></span> General</span> | |
| <span class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-red-500"></span> Emergency</span> | |
| <span class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-green-500"></span> Follow-up</span> | |
| </div> | |
| </div> | |
| <!-- Calendar Grid --> | |
| <div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden"> | |
| <!-- Days Header --> | |
| <div class="grid grid-cols-7 border-b border-gray-200 bg-gray-50"> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Sun</div> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Mon</div> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Tue</div> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Wed</div> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Thu</div> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Fri</div> | |
| <div class="py-3 text-center text-sm font-semibold text-gray-700">Sat</div> | |
| </div> | |
| <!-- Calendar Days --> | |
| <div id="calendarGrid" class="calendar-grid bg-gray-200"> | |
| <!-- Generated by JavaScript --> | |
| </div> | |
| </div> | |
| <!-- Quick Stats --> | |
| <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mt-6"> | |
| <div class="bg-white p-4 rounded-xl border border-gray-200 shadow-sm flex items-center gap-4"> | |
| <div class="p-3 bg-blue-100 rounded-lg"> | |
| <i data-lucide="calendar-check" class="w-6 h-6 text-blue-600"></i> | |
| </div> | |
| <div> | |
| <p class="text-2xl font-bold text-gray-900">24</p> | |
| <p class="text-sm text-gray-500">Today's Appointments</p> | |
| </div> | |
| </div> | |
| <div class="bg-white p-4 rounded-xl border border-gray-200 shadow-sm flex items-center gap-4"> | |
| <div class="p-3 bg-green-100 rounded-lg"> | |
| <i data-lucide="check-circle" class="w-6 h-6 text-green-600"></i> | |
| </div> | |
| <div> | |
| <p class="text-2xl font-bold text-gray-900">18</p> | |
| <p class="text-sm text-gray-500">Confirmed</p> | |
| </div> | |
| </div> | |
| <div class="bg-white p-4 rounded-xl border border-gray-200 shadow-sm flex items-center gap-4"> | |
| <div class="p-3 bg-yellow-100 rounded-lg"> | |
| <i data-lucide="clock" class="w-6 h-6 text-yellow-600"></i> | |
| </div> | |
| <div> | |
| <p class="text-2xl font-bold text-gray-900">4</p> | |
| <p class="text-sm text-gray-500">Pending</p> | |
| </div> | |
| </div> | |
| <div class="bg-white p-4 rounded-xl border border-gray-200 shadow-sm flex items-center gap-4"> | |
| <div class="p-3 bg-red-100 rounded-lg"> | |
| <i data-lucide="alert-circle" class="w-6 h-6 text-red-600"></i> | |
| </div> | |
| <div> | |
| <p class="text-2xl font-bold text-gray-900">2</p> | |
| <p class="text-sm text-gray-500">Emergency</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| <!-- Add Appointment Modal --> | |
| <div id="addModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center p-4"> | |
| <div class="bg-white rounded-2xl shadow-2xl w-full max-w-md fade-in"> | |
| <div class="p-6 border-b border-gray-100 flex items-center justify-between"> | |
| <h3 class="text-lg font-semibold text-gray-900">Add New Appointment</h3> | |
| <button onclick="closeAddAppointment()" class="text-gray-400 hover:text-gray-600"> | |
| <i data-lucide="x" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| <div class="p-6 space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Patient Name</label> | |
| <input type="text" class="w-full border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Search patient..."> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Date</label> | |
| <input type="date" class="w-full border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Time</label> | |
| <input type="time" class="w-full border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Type</label> | |
| <select class="w-full border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"> | |
| <option>General Checkup</option> | |
| <option>Emergency</option> | |
| <option>Follow-up</option> | |
| <option>Consultation</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Notes</label> | |
| <textarea class="w-full border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent h-20 resize-none" placeholder="Additional notes..."></textarea> | |
| </div> | |
| </div> | |
| <div class="p-6 border-t border-gray-100 flex gap-3"> | |
| <button onclick="closeAddAppointment()" class="flex-1 px-4 py-2.5 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 font-medium transition-colors">Cancel</button> | |
| <button onclick="saveAppointment()" class="flex-1 px-4 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium transition-colors">Save Appointment</button> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="script.js"></script> | |
| <script> | |
| lucide.createIcons(); | |
| </script> | |
| <script src="https://deepsite.hf.co/deepsite-badge.js"></script> | |
| </body> | |
| </html> |