/** * Admin Shifts Management Module * Handles shift CRUD operations, volunteer management, and email functionality */ // Shift state let editingShiftId = null; let currentShiftData = null; let allUsers = []; // 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
'; } window.adminCore.showStatus('Failed to load shifts', 'error'); } } catch (error) { console.error('Error loading admin shifts:', error); if (list) { list.innerHTML = 'Error loading shifts
'; } window.adminCore.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 = window.adminCore.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']) || []); // Generate list of first names for volunteers const firstNames = shift.signups ? shift.signups.map(volunteer => { const fullName = volunteer['User Name'] || volunteer['User Email'] || 'Unknown'; // Extract first name (everything before first space, or email username if no space) const firstName = fullName.includes(' ') ? fullName.split(' ')[0] : fullName.includes('@') ? fullName.split('@')[0] : fullName; return window.adminCore.escapeHtml(firstName); }).slice(0, 8) : []; // Limit to first 8 names to avoid overflow const namesDisplay = firstNames.length > 0 ? `(${firstNames.join(', ')}${firstNames.length === 8 && signupCount > 8 ? '...' : ''})` : ''; return `📅 ${shiftDate.toLocaleDateString()} | ⏰ ${shift['Start Time']} - ${shift['End Time']}
📍 ${window.adminCore.escapeHtml(shift.Location || 'TBD')}
👥 ${signupCount}/${shift['Max Volunteers']} volunteers ${namesDisplay}
${shift.Status || 'Open'}
${isPublic ? '🌐 Public' : '🔒 Private'}
${isPublic ? `