thors1's picture
Initial DeepSite commit
5fc8d22 verified
// Initialize Lucide icons
document.addEventListener('DOMContentLoaded', function() {
lucide.createIcons();
initializeDate();
initializeMockPatients();
});
// Sidebar Management
let sidebarCollapsed = false;
function toggleSidebar() {
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('sidebarOverlay');
sidebar.classList.toggle('-translate-x-full');
overlay.classList.toggle('active');
}
function toggleSidebarDesktop() {
const sidebar = document.getElementById('sidebar');
const mainContent = document.querySelector('.flex-1.flex.flex-col');
sidebarCollapsed = !sidebarCollapsed;
if (sidebarCollapsed) {
sidebar.classList.remove('w-72');
sidebar.classList.add('w-20', 'collapsed');
} else {
sidebar.classList.remove('w-20', 'collapsed');
sidebar.classList.add('w-72');
}
// Re-render icons to ensure proper sizing
setTimeout(() => lucide.createIcons(), 300);
}
function toggleSubmenu() {
const submenu = document.getElementById('appointmentsSubmenu');
const icon = document.getElementById('submenuIcon');
submenu.classList.toggle('expanded');
if (submenu.classList.contains('expanded')) {
icon.style.transform = 'rotate(180deg)';
} else {
icon.style.transform = 'rotate(0deg)';
}
}
// Patient Type Management
let currentPatientType = 'new';
function setPatientType(type) {
currentPatientType = type;
const btnNew = document.getElementById('btnNewPatient');
const btnExisting = document.getElementById('btnExistingPatient');
const newForm = document.getElementById('newPatientForm');
const existingForm = document.getElementById('existingPatientForm');
if (type === 'new') {
btnNew.classList.add('active');
btnExisting.classList.remove('active');
newForm.classList.remove('hidden');
existingForm.classList.add('hidden');
} else {
btnNew.classList.remove('active');
btnExisting.classList.add('active');
newForm.classList.add('hidden');
existingForm.classList.remove('hidden');
}
}
// Mock Patient Data
const mockPatients = [
{ id: 1, name: 'John Anderson', email: 'john.a@email.com', phone: '(555) 123-4567', age: 45, lastVisit: '2024-01-15' },
{ id: 2, name: 'Maria Garcia', email: 'maria.g@email.com', phone: '(555) 234-5678', age: 32, lastVisit: '2024-02-20' },
{ id: 3, name: 'Robert Chen', email: 'robert.c@email.com', phone: '(555) 345-6789', age: 28, lastVisit: '2024-03-01' },
{ id: 4, name: 'Sarah Johnson', email: 'sarah.j@email.com', phone: '(555) 456-7890', age: 56, lastVisit: '2024-01-28' },
{ id: 5, name: 'Michael Brown', email: 'mike.b@email.com', phone: '(555) 567-8901', age: 41, lastVisit: '2024-02-14' },
{ id: 6, name: 'Emily Davis', email: 'emily.d@email.com', phone: '(555) 678-9012', age: 29, lastVisit: '2024-03-10' }
];
function initializeMockPatients() {
// Pre-populate with all patients
displayPatientResults(mockPatients);
}
function searchPatients(query) {
const filtered = mockPatients.filter(patient =>
patient.name.toLowerCase().includes(query.toLowerCase()) ||
patient.email.toLowerCase().includes(query.toLowerCase()) ||
patient.phone.includes(query)
);
displayPatientResults(filtered);
}
function displayPatientResults(patients) {
const container = document.getElementById('patientResults');
if (patients.length === 0) {
container.innerHTML = `
<div class="text-center py-8 text-gray-400">
<p class="text-sm">No patients found</p>
</div>
`;
return;
}
container.innerHTML = patients.map(patient => `
<div onclick="selectPatient(${patient.id})" class="flex items-center gap-3 p-3 rounded-xl border border-gray-200 hover:border-blue-500 hover:bg-blue-50 cursor-pointer transition-all group">
<div class="w-10 h-10 bg-gradient-to-br from-blue-400 to-blue-600 rounded-full flex items-center justify-center text-white font-semibold text-sm">
${patient.name.split(' ').map(n => n[0]).join('')}
</div>
<div class="flex-1 min-w-0">
<p class="font-medium text-gray-900 truncate group-hover:text-blue-700">${patient.name}</p>
<p class="text-xs text-gray-500 truncate">${patient.email}${patient.phone}</p>
</div>
<div class="text-xs text-gray-400">
Age: ${patient.age}
</div>
</div>
`).join('');
}
function selectPatient(id) {
const patient = mockPatients.find(p => p.id === id);
showToast(`Selected patient: ${patient.name}`);
// In a real app, this would fill the form or mark as selected
}
// Category Selection
function selectCategory(category) {
// Remove active class from all
document.querySelectorAll('.category-btn').forEach(btn => {
btn.classList.remove('border-blue-500', 'bg-blue-50', 'border-red-500', 'bg-red-50');
btn.classList.add('border-gray-200');
});
// Add active class to selected
const selectedBtn = document.querySelector(`[data-category="${category}"]`);
if (category === 'emergency') {
selectedBtn.classList.remove('border-gray-200');
selectedBtn.classList.add('border-red-500', 'bg-red-50');
} else {
selectedBtn.classList.remove('border-gray-200');
selectedBtn.classList.add('border-blue-500', 'bg-blue-50');
}
document.getElementById('selectedCategory').value = category;
}
// Time Slot Management
const timeSlotsData = {
'dr-mitchell': ['09:00 AM', '09:30 AM', '10:00 AM', '10:30 AM', '11:00 AM', '02:00 PM', '02:30 PM', '03:00 PM', '03:30 PM', '04:00 PM'],
'dr-johnson': ['08:00 AM', '08:30 AM', '09:00 AM', '11:30 AM', '01:00 PM', '01:30 PM', '03:30 PM', '04:30 PM'],
'dr-williams': ['09:00 AM', '10:30 AM', '12:00 PM', '02:30 PM', '03:30 PM', '04:30 PM'],
'dr-brown': ['08:30 AM', '09:30 AM', '10:30 AM', '01:30 PM', '02:30 PM', '03:00 PM'],
'dr-davis': ['09:00 AM', '11:00 AM', '01:00 PM', '02:00 PM', '04:00 PM', '04:30 PM']
};
// Randomly book some slots to simulate reality
const bookedSlots = {};
function initializeDate() {
const today = new Date().toISOString().split('T')[0];
document.getElementById('appointmentDate').value = today;
document.getElementById('appointmentDate').min = today;
document.getElementById('currentDate').textContent = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
}
function updateTimeSlots() {
const physician = document.getElementById('physicianSelect').value;
const date = document.getElementById('appointmentDate').value;
const container = document.getElementById('timeSlotsContainer');
const dateDisplay = document.getElementById('selectedDateDisplay');
if (!physician || !date) {
container.innerHTML = `
<div class="text-center py-12 text-gray-400">
<i data-lucide="calendar-days" class="w-12 h-12 mx-auto mb-3 opacity-50"></i>
<p class="text-sm">Please select a physician and date to view available time slots</p>
</div>
`;
lucide.createIcons();
return;
}
dateDisplay.textContent = new Date(date).toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' });
const slots = timeSlotsData[physician] || [];
const booked = bookedSlots[`${physician}-${date}`] || [];
// Generate morning and afternoon sections
const morningSlots = slots.filter(time => {
const hour = parseInt(time.split(':')[0]);
const isPM = time.includes('PM');
return (!isPM && hour < 12) || (isPM && hour === 12);
});
const afternoonSlots = slots.filter(time => {
const hour = parseInt(time.split(':')[0]);
const isPM = time.includes('PM');
return isPM && hour !== 12;
});
let html = '';
if (morningSlots.length > 0) {
html += `
<div class="mb-4">
<p class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3">Morning</p>
<div class="grid grid-cols-2 gap-2">
${morningSlots.map(time => createTimeSlotButton(time, booked.includes(time))).join('')}
</div>
</div>
`;
}
if (afternoonSlots.length > 0) {
html += `
<div>
<p class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3">Afternoon</p>
<div class="grid grid-cols-2 gap-2">
${afternoonSlots.map(time => createTimeSlotButton(time, booked.includes(time))).join('')}
</div>
</div>
`;
}
container.innerHTML = html;
}
function createTimeSlotButton(time, isBooked) {
if (isBooked) {
return `<button disabled class="time-slot booked py-2 px-3 rounded-lg border border-gray-200 text-sm font-medium">${time}</button>`;
}
return `<button onclick="selectTime('${time}')" class="time-slot py-2 px-3 rounded-lg border border-gray-200 text-sm font-medium text-gray-700 hover:border-blue-500 hover:text-blue-600 bg-white" data-time="${time}">${time}</button>`;
}
function selectTime(time) {
// Remove previous selection
document.querySelectorAll('.time-slot').forEach(btn => {
btn.classList.remove('selected');
});
// Add selection to clicked button
const buttons = document.querySelectorAll(`[data-time="${time}"]`);
buttons.forEach(btn => btn.classList.add('selected'));
// Show selected time display
document.getElementById('selectedTimeDisplay').classList.remove('hidden');
document.getElementById('confirmedTime').textContent = time;
}
// Form Actions
function saveAppointment() {
const physician = document.getElementById('physicianSelect').value;
const date = document.getElementById('appointmentDate').value;
const category = document.getElementById('selectedCategory').value;
const selectedTime = document.querySelector('.time-slot.selected');
if (!physician) {
showToast('Please select a physician', 'error');
return;
}
if (!date) {
showToast('Please select a date', 'error');
return;
}
if (!category) {
showToast('Please select an appointment category', 'error');
return;
}
if (!selectedTime) {
showToast('Please select a time slot', 'error');
return;
}
// Simulate saving
const time = selectedTime.getAttribute('data-time');
// Mark slot as booked
const key = `${physician}-${date}`;
if (!bookedSlots[key]) bookedSlots[key] = [];
bookedSlots[key].push(time);
showToast('Appointment scheduled successfully!');
// Reset after delay
setTimeout(() => {
resetForm();
}, 2000);
}
function resetForm() {
// Reset patient type
setPatientType('new');
// Reset inputs
document.querySelectorAll('input[type="text"], input[type="email"], input[type="tel"], textarea').forEach(input => {
input.value = '';
});
document.getElementById('physicianSelect').value = '';
document.getElementById('selectedCategory').value = '';
// Reset categories
document.querySelectorAll('.category-btn').forEach(btn => {
btn.classList.remove('border-blue-500', 'bg-blue-50', 'border-red-500', 'bg-red-50');
btn.classList.add('border-gray-200');
});
// Reset time slots
document.getElementById('timeSlotsContainer').innerHTML = `
<div class="text-center py-12 text-gray-400">
<i data-lucide="calendar-days" class="w-12 h-12 mx-auto mb-3 opacity-50"></i>
<p class="text-sm">Please select a physician and date to view available time slots</p>
</div>
`;
document.getElementById('selectedTimeDisplay').classList.add('hidden');
document.getElementById('selectedDateDisplay').textContent = 'Select a date to view times';
// Reset date to today
initializeDate();
lucide.createIcons();
}
function showToast(message, type = 'success') {
const toast = document.getElementById('toast');
const toastMessage = document.getElementById('toastMessage');
toastMessage.textContent = message;
if (type === 'error') {
toast.querySelector('i').classList.remove('text-green-400');
toast.querySelector('i').classList.add('text-red-400');
toast.querySelector('i').setAttribute('data-lucide', 'alert-circle');
} else {
toast.querySelector('i').classList.remove('text-red-400');
toast.querySelector('i').classList.add('text-green-400');
toast.querySelector('i').setAttribute('data-lucide', 'check-circle');
}
lucide.createIcons();
toast.classList.remove('translate-y-20', 'opacity-0');
setTimeout(() => {
toast.classList.add('translate-y-20', 'opacity-0');
}, 3000);
}
// Close sidebar when clicking outside on mobile
document.addEventListener('click', function(e) {
const sidebar = document.getElementById('sidebar');
const toggleBtn = document.querySelector('button[onclick="toggleSidebar()"]');
if (window.innerWidth < 1024) {
if (!sidebar.contains(e.target) && !toggleBtn.contains(e.target)) {
sidebar.classList.add('-translate-x-full');
document.getElementById('sidebarOverlay').classList.remove('active');
}
}
});