// Student reservations page functionality let reservations = []; // Check authentication function checkAuth() { const token = localStorage.getItem('token'); const role = localStorage.getItem('userRole'); if (!token || role !== 'student') { 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 = `Student: ${username}`; } // Load and filter reservations async function loadReservations() { try { const response = await fetch('/api/reservations/my', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || `HTTP ${response.status}`); } reservations = await response.json(); filterAndDisplayReservations(); } catch (error) { console.error('Error loading reservations:', error); // Display a user-friendly error message const reservationsList = document.getElementById('reservationsList'); reservationsList.innerHTML = ` Failed to load reservations: ${error.message}
Please try refreshing the page `; } } // Filter and display reservations function filterAndDisplayReservations() { const locationFilter = document.getElementById('locationFilter').value; const statusFilter = document.getElementById('statusFilter').value; const filteredReservations = reservations.filter(reservation => { const locationMatch = locationFilter === 'all' || reservation.location === locationFilter; const statusMatch = statusFilter === 'all' || reservation.status === statusFilter; return locationMatch && statusMatch; }); const reservationsList = document.getElementById('reservationsList'); reservationsList.innerHTML = filteredReservations.map(reservation => ` ${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 === 'APPROVED' ? ` ` : reservation.status === 'REJECTED' ? ` Rejected ` : reservation.status === 'RETURN_PENDING' ? ` Return Pending Approval ` : reservation.status === 'RETURNED' ? ` Returned ` : ''} `).join(''); } // Delete (cancel) reservation async function deleteReservation(reservationId) { if (!confirm('Are you sure you want to cancel 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 cancel reservation'); } } catch (error) { console.error('Error canceling reservation:', error); alert('Failed to cancel reservation'); } } // Return reservation (mark as returned) async function returnReservation(reservationId) { if (!confirm('Are you sure you want to request return for this item? An admin will need to approve the return.')) return; try { const response = await fetch(`/api/reservations/${reservationId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token')}` }, body: JSON.stringify({ status: 'RETURN_PENDING' }) }); if (response.ok) { // Successfully requested return, reload reservations await loadReservations(); // Show success message const alert = document.createElement('div'); alert.className = 'alert alert-success alert-dismissible fade show'; alert.innerHTML = ` Return requested successfully! An admin will review your request. `; const container = document.querySelector('.container'); container.prepend(alert); setTimeout(() => alert.remove(), 5000); } else { const error = await response.json(); throw new Error(error.message || 'Failed to request return'); } } catch (error) { console.error('Error requesting return:', error); alert(`Failed to request return: ${error.message}`); } } // 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'; }); } // 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/my', { 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 }))); // 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);