/** * Main Admin Panel Coordinator * This refactored admin.js coordinates all admin modules while maintaining functionality * Modules: core, auth, map, walksheet, shifts, shift-volunteers, users, email, integration */ /** * Main Event Listener Setup * Coordinates event listeners across all modules */ function setupAllEventListeners() { // Setup authentication listeners if (window.adminAuth && typeof window.adminAuth.setupAuthEventListeners === 'function') { window.adminAuth.setupAuthEventListeners(); } // Setup map listeners if (window.adminMap && typeof window.adminMap.setupMapEventListeners === 'function') { window.adminMap.setupMapEventListeners(); } // Setup walk sheet listeners if (window.adminWalkSheet && typeof window.adminWalkSheet.setupWalkSheetEventListeners === 'function') { window.adminWalkSheet.setupWalkSheetEventListeners(); } // Setup shift listeners if (window.adminShifts && typeof window.adminShifts.setupShiftEventListeners === 'function') { window.adminShifts.setupShiftEventListeners(); } // Setup shift volunteer listeners if (window.adminShiftVolunteers && typeof window.adminShiftVolunteers.setupShiftVolunteerEventListeners === 'function') { window.adminShiftVolunteers.setupShiftVolunteerEventListeners(); } // Setup user listeners if (window.adminUsers && typeof window.adminUsers.setupUserEventListeners === 'function') { window.adminUsers.setupUserEventListeners(); } // Setup email listeners if (window.adminEmail && typeof window.adminEmail.setupEmailEventListeners === 'function') { window.adminEmail.setupEmailEventListeners(); } } // Main admin initialization when DOM is loaded document.addEventListener('DOMContentLoaded', () => { // Initialize core functionality if (window.adminCore && typeof window.adminCore.initializeAdminCore === 'function') { window.adminCore.initializeAdminCore(); } // Initialize authentication if (window.adminAuth && typeof window.adminAuth.checkAdminAuth === 'function') { window.adminAuth.checkAdminAuth(); } // Initialize admin map if (window.adminMap && typeof window.adminMap.initializeAdminMap === 'function') { window.adminMap.initializeAdminMap(); } // Load current start location if (window.adminMap && typeof window.adminMap.loadCurrentStartLocation === 'function') { window.adminMap.loadCurrentStartLocation(); } // Setup all event listeners setupAllEventListeners(); // Initialize integrations with a small delay to ensure DOM is ready setTimeout(() => { if (window.adminWalkSheet && typeof window.adminWalkSheet.loadWalkSheetConfig === 'function') { window.adminWalkSheet.loadWalkSheetConfig(); } if (window.adminIntegration && typeof window.adminIntegration.initializeAllIntegrations === 'function') { window.adminIntegration.initializeAllIntegrations(); } }, 100); // Check if URL has a hash to show specific section const hash = window.location.hash; if (hash === '#walk-sheet') { if (window.adminCore && typeof window.adminCore.showSection === 'function') { window.adminCore.showSection('walk-sheet'); } if (window.adminWalkSheet && typeof window.adminWalkSheet.checkAndLoadWalkSheetConfig === 'function') { window.adminWalkSheet.checkAndLoadWalkSheetConfig(); } } else if (hash === '#convert-data') { if (window.adminCore && typeof window.adminCore.showSection === 'function') { window.adminCore.showSection('convert-data'); } } else if (hash === '#cuts') { if (window.adminCore && typeof window.adminCore.showSection === 'function') { window.adminCore.showSection('cuts'); } } else { // Default to dashboard if (window.adminCore && typeof window.adminCore.showSection === 'function') { window.adminCore.showSection('dashboard'); } // Load dashboard data on initial page load if (typeof loadDashboardData === 'function') { loadDashboardData(); } } }); /** * Dashboard Functions * Loads dashboard data and displays summary statistics */ async function loadDashboardData() { try { const response = await fetch('/api/admin/dashboard'); const data = await response.json(); if (data.success) { document.getElementById('total-users').textContent = data.stats.totalUsers; document.getElementById('total-shifts').textContent = data.stats.totalShifts; document.getElementById('total-signups').textContent = data.stats.totalSignups; document.getElementById('this-month-users').textContent = data.stats.thisMonthUsers; } } catch (error) { console.error('Failed to load dashboard data:', error); } } /** * Legacy function redirects for backward compatibility * These ensure existing functionality continues to work */ window.loadDashboardData = loadDashboardData; // Export dashboard function for module coordination if (typeof window.adminDashboard === 'undefined') { window.adminDashboard = { loadDashboardData: loadDashboardData }; } // Add shift management functions async function loadAdminShifts() { const list = document.getElementById('admin-shifts-list'); if (list) { list.innerHTML = '
Loading shifts...
'; } try { console.log('Loading admin shifts...'); const response = await fetch('/api/shifts/admin'); const data = await response.json(); if (data.success) { console.log('Successfully loaded', data.shifts.length, 'shifts'); displayAdminShifts(data.shifts); } else { console.error('Failed to load shifts:', data.error); if (list) { list.innerHTML = 'Failed to load shifts
'; } showStatus('Failed to load shifts', 'error'); } } catch (error) { console.error('Error loading admin shifts:', error); if (list) { list.innerHTML = 'Error loading shifts
'; } showStatus('Failed to load shifts', 'error'); } } function displayAdminShifts(shifts) { const list = document.getElementById('admin-shifts-list'); if (!list) { console.error('Admin shifts list element not found'); return; } if (shifts.length === 0) { list.innerHTML = 'No shifts created yet.
'; return; } list.innerHTML = shifts.map(shift => { const shiftDate = createLocalDate(shift.Date); const signupCount = shift.signups ? shift.signups.length : 0; const isPublic = shift['Is Public'] !== false; console.log(`Shift "${shift.Title}" (ID: ${shift.ID}) has ${signupCount} volunteers:`, shift.signups?.map(s => s['User Email']) || []); return `📅 ${shiftDate.toLocaleDateString()} | ⏰ ${shift['Start Time']} - ${shift['End Time']}
📍 ${escapeHtml(shift.Location || 'TBD')}
👥 ${signupCount}/${shift['Max Volunteers']} volunteers
${shift.Status || 'Open'}
${isPublic ? '🌐 Public' : '🔒 Private'}
${isPublic ? `| Name | Role | Created | Actions | |
|---|---|---|---|---|
| ${escapeHtml(user.email || user.Email || 'N/A')} | ${escapeHtml(user.name || user.Name || 'N/A')} | ${userType.charAt(0).toUpperCase() + userType.slice(1)} ${expirationInfo} | ${formattedDate} |
|