// Admin reservations page functionality let reservations = []; // Check authentication function checkAuth() { const token = localStorage.getItem('token'); const role = localStorage.getItem('userRole'); if (!token || role !== 'admin') { window.location.href = '/index.html'; } } // Initialize page async function initializePage() { checkAuth(); await loadReservations(); setupEventListeners(); displayUserInfo(); startAutoRefresh(); } // Display user info function displayUserInfo() { const username = localStorage.getItem('username'); document.getElementById('userInfo').textContent = `Admin: ${username}`; } // Load and filter reservations async function loadReservations() { try { const response = await fetch('/api/reservations', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); reservations = await response.json(); filterAndDisplayReservations(); } catch (error) { console.error('Error loading reservations:', error); alert('Failed to load reservations'); } } // Filter and display reservations function filterAndDisplayReservations() { const locationFilter = document.getElementById('locationFilter').value; const statusFilter = document.getElementById('statusFilter').value; const searchTerm = document.getElementById('searchInput').value.toLowerCase(); const filteredReservations = reservations.filter(reservation => { const locationMatch = locationFilter === 'all' || reservation.location === locationFilter; const statusMatch = statusFilter === 'all' || reservation.status === statusFilter; const searchMatch = searchTerm === '' || reservation.studentName.toLowerCase().includes(searchTerm) || reservation.itemName.toLowerCase().includes(searchTerm) || reservation.location.toLowerCase().includes(searchTerm); return locationMatch && statusMatch && searchMatch; }); const reservationsList = document.getElementById('reservationsList'); reservationsList.innerHTML = filteredReservations.map(reservation => ` ${reservation.studentName} ${reservation.itemName} ${reservation.quantity || 1} ${reservation.location} ${new Date(reservation.reservedDate).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })} ${reservation.status}
${reservation.status === 'PENDING' ? ` ` : reservation.status === 'RETURN_PENDING' ? ` ` : reservation.status === 'APPROVED' ? ` ` : reservation.status === 'RETURNED' ? ` ` : ''}
`).join(''); } // Update reservation status async function updateReservation(reservationId, status) { try { const response = await fetch(`/api/reservations/${reservationId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token')}` }, body: JSON.stringify({ status }) }); if (response.ok) { await loadReservations(); } else { const error = await response.json(); alert(error.message || 'Failed to update reservation'); } } catch (error) { console.error('Error updating reservation:', error); alert('Failed to update reservation'); } } // Delete reservation async function deleteReservation(reservationId) { if (!confirm('Are you sure you want to delete this reservation?')) return; try { const response = await fetch(`/api/reservations/${reservationId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (response.ok) { await loadReservations(); } else { const error = await response.json(); alert(error.message || 'Failed to delete reservation'); } } catch (error) { console.error('Error deleting reservation:', error); alert('Failed to delete reservation'); } } // Archive reservation async function archiveReservation(reservationId) { if (!confirm('Are you sure you want to archive this reservation? It will be hidden from the list but remain in the database.')) return; try { const response = await fetch(`/api/reservations/${reservationId}/archive`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (response.ok) { await loadReservations(); // Show success message const alert = document.createElement('div'); alert.className = 'alert alert-success alert-dismissible fade show'; alert.innerHTML = ` Reservation archived successfully! `; const container = document.querySelector('.container'); container.prepend(alert); setTimeout(() => alert.remove(), 3000); } else { const error = await response.json(); alert(error.message || 'Failed to archive reservation'); } } catch (error) { console.error('Error archiving reservation:', error); alert('Failed to archive reservation'); } } // Set up event listeners function setupEventListeners() { document.getElementById('locationFilter').addEventListener('change', filterAndDisplayReservations); document.getElementById('statusFilter').addEventListener('change', filterAndDisplayReservations); document.getElementById('logoutBtn').addEventListener('click', () => { localStorage.clear(); window.location.href = '/index.html'; }); // Search functionality const searchInput = document.getElementById('searchInput'); const clearSearch = document.getElementById('clearSearch'); searchInput.addEventListener('input', filterAndDisplayReservations); searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { filterAndDisplayReservations(); } }); clearSearch.addEventListener('click', () => { searchInput.value = ''; filterAndDisplayReservations(); searchInput.focus(); }); } // Auto refresh functionality let refreshInterval; let lastReservationsChecksum = ''; function startAutoRefresh() { // Refresh every 15 seconds for reservations (more frequent for status changes) refreshInterval = setInterval(async () => { await checkForReservationUpdates(); }, 15000); } function stopAutoRefresh() { if (refreshInterval) { clearInterval(refreshInterval); } } async function checkForReservationUpdates() { try { const response = await fetch('/api/reservations', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (response.ok) { const currentReservations = await response.json(); // Create a simple checksum of the reservations data const currentChecksum = JSON.stringify(currentReservations.map(res => ({ id: res._id, status: res.status, quantity: res.quantity || 1 }))); // If reservations changed, refresh the display if (lastReservationsChecksum && currentChecksum !== lastReservationsChecksum) { reservations = currentReservations; filterAndDisplayReservations(); // Show update notification showUpdateNotification(); } lastReservationsChecksum = currentChecksum; } } catch (error) { console.error('Error checking for reservation updates:', error); } } function showUpdateNotification() { const notification = document.createElement('div'); notification.className = 'alert alert-info alert-dismissible fade show'; notification.innerHTML = ` Reservations updated! `; const container = document.querySelector('.container'); container.prepend(notification); setTimeout(() => notification.remove(), 3000); } // Initialize the page when DOM is loaded document.addEventListener('DOMContentLoaded', initializePage);