// Admin dashboard functionality let items = []; let reservations = []; let currentView = 'grid'; // Default view mode // 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() { try { checkAuth(); await loadItems(); displayUserInfo(); setupEventListeners(); // Move this after displayUserInfo to ensure DOM is ready console.log('Page initialization complete'); } catch (error) { console.error('Error during page initialization:', error); throw error; // Re-throw to be caught by the outer try-catch } } // Display user info function displayUserInfo() { const username = localStorage.getItem('username'); document.getElementById('userInfo').textContent = `Admin: ${username}`; } // Load items from server async function loadItems() { try { console.log('Loading items...'); const response = await fetch('/api/items', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); const data = await response.json(); console.log('Received items:', data); if (!response.ok) { throw new Error(data.message || 'Failed to load items'); } items = data; displayItems(); } catch (error) { console.error('Error loading items:', error); alert('Failed to load items: ' + error.message); } } // Display items based on current view mode function displayItems() { if (currentView === 'grid') { displayGridView(); } else { displayListView(); } } // Display items in grid view function displayGridView() { const itemsGrid = document.getElementById('itemsGrid'); document.getElementById('itemsList').classList.add('d-none'); itemsGrid.classList.remove('d-none'); itemsGrid.innerHTML = items.map(item => `
${item.name}
${item.name}

${item.description || 'No description available'}

Location: ${item.location}

Quantity: ${item.quantity}

Reserved: ${item.reserved || 0}

`).join(''); } // Display items in list view function displayListView() { const itemsList = document.getElementById('itemsList'); const itemsGrid = document.getElementById('itemsGrid'); itemsGrid.classList.add('d-none'); itemsList.classList.remove('d-none'); const itemsListBody = document.getElementById('itemsListBody'); itemsListBody.innerHTML = items.map(item => ` ${item.name} ${item.name} ${item.description || 'No description available'} ${item.location} ${item.quantity} ${item.reserved || 0} `).join(''); } // Load reservations async function loadReservations() { try { const response = await fetch('/api/reservations', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); reservations = await response.json(); displayReservations(); } catch (error) { console.error('Error loading reservations:', error); alert('Failed to load reservations'); } } // Display reservations in table function displayReservations() { const reservationsList = document.getElementById('reservationsList'); reservationsList.innerHTML = reservations.map(reservation => ` ${reservation.studentName} ${reservation.itemName} ${reservation.location} ${new Date(reservation.reservedDate).toLocaleDateString()} ${reservation.status} ${reservation.status === 'PENDING' ? ` ` : ''} `).join(''); } // Delete item async function deleteItem(itemId) { if (!confirm('Are you sure you want to delete this item?')) return; try { const response = await fetch(`/api/items/${itemId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (response.ok) { await loadItems(); } else { const error = await response.json(); alert(error.message || 'Failed to delete item'); } } catch (error) { console.error('Error deleting item:', error); alert('Failed to delete item'); } } // 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(); await loadItems(); // Refresh items to update quantities } 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'); } } // Edit item functionality let editModal = null; // Initialize Bootstrap modal when DOM is loaded function initializeModal() { const modalElement = document.getElementById('editItemModal'); if (!modalElement) { console.error('Modal element not found in the DOM'); return; } try { editModal = new bootstrap.Modal(modalElement); console.log('Modal initialized successfully'); } catch (error) { console.error('Error initializing modal:', error); } } async function editItem(itemId) { try { console.log('Fetching item with ID:', itemId); // Debug log const response = await fetch(`/api/items/${itemId}`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); const data = await response.json(); console.log('Response data:', data); // Debug log if (!response.ok) { console.error('Server error:', data); throw new Error(data.message || 'Failed to fetch item'); } if (!data || !data._id) { throw new Error('Invalid item data received'); } document.getElementById('editItemId').value = data._id; document.getElementById('editItemName').value = data.name; document.getElementById('editItemDescription').value = data.description || ''; document.getElementById('editItemLocation').value = data.location; document.getElementById('editItemQuantity').value = data.quantity; // Show current image if it exists const imagePreview = document.getElementById('editImagePreview'); const removeButton = document.getElementById('editRemoveImage'); imagePreview.innerHTML = ''; if (data.imageUrl) { const img = document.createElement('img'); img.src = data.imageUrl; img.classList.add('modal-item-image'); imagePreview.appendChild(img); removeButton.style.display = 'block'; imagePreview.dataset.currentImageUrl = data.imageUrl; } else { removeButton.style.display = 'none'; imagePreview.dataset.currentImageUrl = ''; } // Show the modal if (!editModal) { console.log('Modal not initialized, attempting to initialize now'); initializeModal(); } if (editModal) { editModal.show(); } else { throw new Error('Could not initialize modal. Please try again.'); } } catch (error) { console.error('Error fetching item:', error); alert('Error loading item details: ' + error.message); } } async function submitEditItem() { const itemId = document.getElementById('editItemId').value; const formData = new FormData(); formData.append('name', document.getElementById('editItemName').value); formData.append('description', document.getElementById('editItemDescription').value); formData.append('location', document.getElementById('editItemLocation').value); formData.append('quantity', document.getElementById('editItemQuantity').value); const imagePreview = document.getElementById('editImagePreview'); const imageFile = document.getElementById('editItemImage').files[0]; const currentImageUrl = imagePreview.dataset.currentImageUrl; try { // Handle image update if (imageFile) { // Upload new image const imageFormData = new FormData(); imageFormData.append('image', imageFile); const uploadResponse = await fetch('/api/upload', { method: 'POST', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }, body: imageFormData }); if (!uploadResponse.ok) { throw new Error('Failed to upload image'); } const { imageUrl } = await uploadResponse.json(); formData.append('imageUrl', imageUrl); } else if (!currentImageUrl) { // If no new image and no current image, explicitly set imageUrl to null formData.append('imageUrl', ''); } } catch (error) { console.error('Error uploading image:', error); alert('Failed to upload image'); return; } try { const response = await fetch(`/api/items/${itemId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token')}` }, body: JSON.stringify(Object.fromEntries(formData)) }); if (!response.ok) { throw new Error('Update failed'); } await loadItems(); // Refresh the items list bootstrap.Modal.getInstance(document.getElementById('editItemModal')).hide(); alert('Item updated successfully'); } catch (error) { console.error('Error updating item:', error); alert('Error updating item'); } } // Set up event listeners function setupEventListeners() { // Common elements const logoutBtn = document.getElementById('logoutBtn'); if (logoutBtn) { logoutBtn.addEventListener('click', () => { localStorage.clear(); window.location.href = '/index.html'; }); } // View mode toggle const viewModeBtns = document.querySelectorAll('.view-mode-btn'); if (viewModeBtns.length > 0) { viewModeBtns.forEach(btn => { btn.addEventListener('click', function() { document.querySelectorAll('.view-mode-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); currentView = this.dataset.mode; displayItems(); }); }); } // Edit form elements const editItemImage = document.getElementById('editItemImage'); if (editItemImage) { editItemImage.addEventListener('change', function(e) { const file = e.target.files[0]; const imagePreview = document.getElementById('editImagePreview'); const removeButton = document.getElementById('editRemoveImage'); if (file) { const reader = new FileReader(); reader.onload = function(e) { imagePreview.innerHTML = ''; const img = document.createElement('img'); img.src = e.target.result; img.classList.add('modal-item-image'); imagePreview.appendChild(img); removeButton.style.display = 'block'; }; reader.readAsDataURL(file); } else { imagePreview.innerHTML = ''; if (!imagePreview.dataset.currentImageUrl) { removeButton.style.display = 'none'; } } }); } // Remove image button const editRemoveImage = document.getElementById('editRemoveImage'); if (editRemoveImage) { editRemoveImage.addEventListener('click', function() { const imagePreview = document.getElementById('editImagePreview'); const imageInput = document.getElementById('editItemImage'); const removeButton = document.getElementById('editRemoveImage'); imagePreview.innerHTML = ''; imageInput.value = ''; imagePreview.dataset.currentImageUrl = ''; removeButton.style.display = 'none'; }); } } // Initialize the page when DOM is loaded document.addEventListener('DOMContentLoaded', async () => { try { console.log('Initializing page...'); await initializePage(); console.log('Page initialized'); // Ensure modal is initialized after Bootstrap is loaded setTimeout(() => { console.log('Initializing modal...'); initializeModal(); console.log('Modal initialized'); }, 100); } catch (error) { console.error('Error during page initialization:', error); alert('Error initializing page: ' + error.message); } });