fixed a bug for manage volunteers

This commit is contained in:
admin 2025-09-08 16:14:29 -06:00
parent 00a2117cb9
commit e3611c8300
4 changed files with 294 additions and 24 deletions

View File

@ -1406,17 +1406,17 @@
<script src="js/data-convert.js"></script> <script src="js/data-convert.js"></script>
<!-- Modular Admin JavaScript - Load in order of dependencies --> <!-- Modular Admin JavaScript - Load in order of dependencies -->
<script src="js/admin-core.js"></script> <!-- Core utilities, navigation, viewport --> <script data-cfasync="false" src="js/admin-core.js"></script> <!-- Core utilities, navigation, viewport -->
<script src="js/admin-auth.js"></script> <!-- Authentication and user management --> <script data-cfasync="false" src="js/admin-auth.js"></script> <!-- Authentication and user management -->
<script src="js/admin-map.js"></script> <!-- Map functionality and location management --> <script data-cfasync="false" src="js/admin-map.js"></script> <!-- Map functionality and location management -->
<script src="js/admin-walksheet.js"></script> <!-- Walk sheet configuration and preview --> <script data-cfasync="false" src="js/admin-walksheet.js"></script> <!-- Walk sheet configuration and preview -->
<script src="js/admin-shifts.js"></script> <!-- Shift management and CRUD operations --> <script data-cfasync="false" src="js/admin-shifts.js"></script> <!-- Shift management and CRUD operations -->
<script src="js/admin-shift-volunteers.js"></script> <!-- Volunteer management for shifts --> <script data-cfasync="false" src="js/admin-shift-volunteers.js"></script> <!-- Volunteer management for shifts -->
<script src="js/admin-users.js"></script> <!-- User management and CRUD operations --> <script data-cfasync="false" src="js/admin-users.js"></script> <!-- User management and CRUD operations -->
<script src="js/admin-email.js"></script> <!-- Email broadcasting and rich text editor --> <script data-cfasync="false" src="js/admin-email.js"></script> <!-- Email broadcasting and rich text editor -->
<script src="js/admin-integration.js"></script> <!-- NocoDB and Listmonk integration links --> <script data-cfasync="false" src="js/admin-integration.js"></script> <!-- NocoDB and Listmonk integration links -->
<!-- Main Admin Coordinator - Load last to coordinate all modules --> <!-- Main Admin Coordinator - Load last to coordinate all modules -->
<script src="js/admin.js"></script> <script data-cfasync="false" src="js/admin.js"></script>
</body> </body>
</html> </html>

View File

@ -3,10 +3,35 @@
* Handles volunteer management modals and shift email functionality * Handles volunteer management modals and shift email functionality
*/ */
// Prevent double loading
if (window.adminShiftVolunteersLoading) {
console.warn('admin-shift-volunteers.js already loading, skipping...');
} else {
window.adminShiftVolunteersLoading = true;
// Check if adminCore module is available
console.log('🔄 Loading admin-shift-volunteers.js...');
console.log('📦 adminCore available:', !!window.adminCore);
if (!window.adminCore) {
console.error('adminCore module not found - admin-shift-volunteers.js depends on admin-core.js');
// Don't stop loading, just note the dependency issue
}
// Volunteer management state // Volunteer management state
let currentShiftData = null; let currentShiftData = null;
let allUsers = []; let allUsers = [];
// Safe wrapper for adminCore functions
function safeAdminCore(funcName, ...args) {
if (window.adminCore && typeof window.adminCore[funcName] === 'function') {
return window.adminCore[funcName](...args);
} else {
console.error(`adminCore.${funcName} not available`);
return null;
}
}
// Load all users for the dropdown // Load all users for the dropdown
async function loadAllUsers() { async function loadAllUsers() {
try { try {
@ -51,7 +76,7 @@ async function showShiftUserModal(shiftId, shiftData) {
if (modalTitle) modalTitle.textContent = shiftData.Title; if (modalTitle) modalTitle.textContent = shiftData.Title;
if (modalDetails) { if (modalDetails) {
const shiftDate = window.adminCore.createLocalDate(shiftData.Date); const shiftDate = safeAdminCore('createLocalDate', shiftData.Date) || new Date(shiftData.Date);
modalDetails.textContent = modalDetails.textContent =
`${shiftDate.toLocaleDateString()} | ${shiftData['Start Time']} - ${shiftData['End Time']} | ${shiftData.Location || 'TBD'}`; `${shiftDate.toLocaleDateString()} | ${shiftData['Start Time']} - ${shiftData['End Time']} | ${shiftData.Location || 'TBD'}`;
} }
@ -85,8 +110,8 @@ function displayCurrentVolunteers(volunteers) {
container.innerHTML = volunteers.map(volunteer => ` container.innerHTML = volunteers.map(volunteer => `
<div class="volunteer-item"> <div class="volunteer-item">
<div class="volunteer-info"> <div class="volunteer-info">
<div class="volunteer-name">${window.adminCore.escapeHtml(volunteer['User Name'] || volunteer['User Email'] || 'Unknown')}</div> <div class="volunteer-name">${safeAdminCore('escapeHtml', volunteer['User Name'] || volunteer['User Email'] || 'Unknown') || 'Unknown'}</div>
<div class="volunteer-email">${window.adminCore.escapeHtml(volunteer['User Email'])}</div> <div class="volunteer-email">${safeAdminCore('escapeHtml', volunteer['User Email']) || volunteer['User Email'] || ''}</div>
</div> </div>
<div class="volunteer-actions"> <div class="volunteer-actions">
<button class="btn btn-danger btn-sm remove-volunteer-btn" <button class="btn btn-danger btn-sm remove-volunteer-btn"
@ -123,12 +148,12 @@ async function addUserToShift() {
const userEmail = userSelect?.value; const userEmail = userSelect?.value;
if (!userEmail) { if (!userEmail) {
window.adminCore.showStatus('Please select a user to add', 'error'); safeAdminCore('showStatus', 'Please select a user to add', 'error');
return; return;
} }
if (!currentShiftData || !currentShiftData.ID) { if (!currentShiftData || !currentShiftData.ID) {
window.adminCore.showStatus('No shift selected or invalid shift data', 'error'); safeAdminCore('showStatus', 'No shift selected or invalid shift data', 'error');
console.error('Invalid currentShiftData:', currentShiftData); console.error('Invalid currentShiftData:', currentShiftData);
return; return;
} }
@ -517,7 +542,46 @@ function setupVolunteerModalEventListeners() {
} }
// Export shift volunteer functions // Export shift volunteer functions
window.adminShiftVolunteers = { console.log('About to export adminShiftVolunteers module...');
console.log('Functions to export:', {
showShiftUserModal: typeof showShiftUserModal,
closeShiftUserModal: typeof closeShiftUserModal,
addUserToShift: typeof addUserToShift,
removeVolunteerFromShift: typeof removeVolunteerFromShift,
emailShiftDetails: typeof emailShiftDetails,
setupVolunteerModalEventListeners: typeof setupVolunteerModalEventListeners,
loadAllUsers: typeof loadAllUsers
});
// Ensure we have all required functions before exporting
const requiredFunctions = {
showShiftUserModal,
closeShiftUserModal,
addUserToShift,
removeVolunteerFromShift,
emailShiftDetails,
setupVolunteerModalEventListeners,
loadAllUsers
};
// Validate all functions exist
const missingFunctions = Object.entries(requiredFunctions)
.filter(([name, func]) => typeof func !== 'function')
.map(([name]) => name);
if (missingFunctions.length > 0) {
console.error('Missing functions in adminShiftVolunteers:', missingFunctions);
} else {
console.log('All required functions are available');
}
try {
// Clear any existing module to avoid conflicts
if (window.adminShiftVolunteers) {
console.log('Replacing existing adminShiftVolunteers module');
}
window.adminShiftVolunteers = {
showShiftUserModal, showShiftUserModal,
closeShiftUserModal, closeShiftUserModal,
addUserToShift, addUserToShift,
@ -526,5 +590,68 @@ window.adminShiftVolunteers = {
setupVolunteerModalEventListeners, setupVolunteerModalEventListeners,
loadAllUsers, loadAllUsers,
getCurrentShiftData: () => currentShiftData, getCurrentShiftData: () => currentShiftData,
getAllUsers: () => allUsers getAllUsers: () => allUsers,
// Add module info for debugging
moduleVersion: '1.0',
loadedAt: new Date().toISOString()
};
// Verify the export worked
if (window.adminShiftVolunteers && typeof window.adminShiftVolunteers.showShiftUserModal === 'function') {
console.log('✅ adminShiftVolunteers module loaded successfully');
console.log('✅ Available functions:', Object.keys(window.adminShiftVolunteers));
// Dispatch a custom event to signal the module is ready
setTimeout(() => {
window.dispatchEvent(new CustomEvent('adminShiftVolunteersReady', {
detail: {
module: 'adminShiftVolunteers',
functions: Object.keys(window.adminShiftVolunteers),
timestamp: Date.now()
}
}));
console.log('✅ adminShiftVolunteersReady event dispatched');
}, 50);
} else {
throw new Error('Module export verification failed');
}
} catch (error) {
console.error('❌ Error loading adminShiftVolunteers module:', error);
console.error('❌ Stack trace:', error.stack);
} finally {
// Mark loading as complete
window.adminShiftVolunteersLoading = false;
}
// Add a global debugging function
window.debugAdminShiftVolunteers = () => {
console.log('🔍 Admin Shift Volunteers Debug Info:');
console.log('Module exists:', !!window.adminShiftVolunteers);
if (window.adminShiftVolunteers) {
console.log('Available functions:', Object.keys(window.adminShiftVolunteers));
console.log('showShiftUserModal type:', typeof window.adminShiftVolunteers.showShiftUserModal);
console.log('Module version:', window.adminShiftVolunteers.moduleVersion);
console.log('Loaded at:', window.adminShiftVolunteers.loadedAt);
}
// Check if modal elements exist
console.log('Modal element exists:', !!document.getElementById('shift-user-modal'));
console.log('Modal title element exists:', !!document.getElementById('modal-shift-title'));
console.log('Volunteers list element exists:', !!document.getElementById('current-volunteers-list'));
// Check dependencies
console.log('adminCore exists:', !!window.adminCore);
console.log('Loading state:', window.adminShiftVolunteersLoading);
return {
moduleExists: !!window.adminShiftVolunteers,
functions: window.adminShiftVolunteers ? Object.keys(window.adminShiftVolunteers) : [],
modalExists: !!document.getElementById('shift-user-modal'),
dependencies: {
adminCore: !!window.adminCore
}
};
}; };
} // Close the initial if statement

View File

@ -114,10 +114,90 @@ function setupShiftActionListeners() {
console.log('Edit button clicked for shift:', shiftId); console.log('Edit button clicked for shift:', shiftId);
editShift(shiftId); editShift(shiftId);
} else if (e.target.classList.contains('manage-volunteers-btn')) { } else if (e.target.classList.contains('manage-volunteers-btn')) {
e.preventDefault();
e.stopPropagation();
const shiftId = e.target.getAttribute('data-shift-id'); const shiftId = e.target.getAttribute('data-shift-id');
const shiftData = JSON.parse(e.target.getAttribute('data-shift').replace(/&#39;/g, "'")); const shiftDataStr = e.target.getAttribute('data-shift');
console.log('Manage volunteers clicked for shift:', shiftId); console.log('Manage volunteers clicked for shift:', shiftId);
showShiftUserModal(shiftId, shiftData); console.log('Checking for adminShiftVolunteers module availability...');
console.log('adminShiftVolunteers exists:', !!window.adminShiftVolunteers);
if (window.adminShiftVolunteers) {
console.log('adminShiftVolunteers functions:', Object.keys(window.adminShiftVolunteers));
console.log('showShiftUserModal type:', typeof window.adminShiftVolunteers.showShiftUserModal);
}
// Parse the shift data
let shiftData;
try {
shiftData = JSON.parse(shiftDataStr.replace(/&#39;/g, "'"));
console.log('Parsed shift data:', shiftData);
} catch (error) {
console.error('Error parsing shift data:', error);
if (window.adminCore && window.adminCore.showStatus) {
window.adminCore.showStatus('Error parsing shift data', 'error');
}
return;
}
// Function to attempt showing the modal
const attemptShowModal = () => {
if (window.adminShiftVolunteers && typeof window.adminShiftVolunteers.showShiftUserModal === 'function') {
console.log('Module ready, showing modal for shift:', shiftId);
try {
window.adminShiftVolunteers.showShiftUserModal(shiftId, shiftData);
} catch (modalError) {
console.error('Error showing modal:', modalError);
if (window.adminCore && window.adminCore.showStatus) {
window.adminCore.showStatus('Error opening volunteer management modal', 'error');
}
}
return true;
} else {
console.log('Module not ready - adminShiftVolunteers:', !!window.adminShiftVolunteers);
if (window.adminShiftVolunteers) {
console.log('Available functions:', Object.keys(window.adminShiftVolunteers));
}
return false;
}
};
// Try immediately
if (!attemptShowModal()) {
// If not ready, wait for the ready event or use timeout
let attempts = 0;
const maxAttempts = 20;
const retryInterval = 250;
const retryTimer = setInterval(() => {
attempts++;
console.log(`Retry attempt ${attempts}/${maxAttempts} for volunteer modal...`);
if (attemptShowModal()) {
clearInterval(retryTimer);
} else if (attempts >= maxAttempts) {
clearInterval(retryTimer);
console.error('Failed to load volunteer management module after', maxAttempts, 'attempts');
console.log('Final state - adminShiftVolunteers:', window.adminShiftVolunteers);
if (window.adminCore && window.adminCore.showStatus) {
window.adminCore.showStatus('Volunteer management module failed to load. Please refresh the page.', 'error');
}
}
}, retryInterval);
// Also listen for the ready event as backup
const readyListener = () => {
console.log('Received adminShiftVolunteersReady event');
if (attemptShowModal()) {
clearInterval(retryTimer);
window.removeEventListener('adminShiftVolunteersReady', readyListener);
}
};
window.addEventListener('adminShiftVolunteersReady', readyListener);
}
} else if (e.target.classList.contains('copy-shift-link-btn')) { } else if (e.target.classList.contains('copy-shift-link-btn')) {
const shiftId = e.target.getAttribute('data-shift-id'); const shiftId = e.target.getAttribute('data-shift-id');
console.log('Copy link button clicked for shift:', shiftId); console.log('Copy link button clicked for shift:', shiftId);

View File

@ -29,9 +29,46 @@ function setupAllEventListeners() {
window.adminShifts.setupShiftEventListeners(); window.adminShifts.setupShiftEventListeners();
} }
// Setup shift volunteer listeners // Setup shift volunteer listeners with retry mechanism
if (window.adminShiftVolunteers && typeof window.adminShiftVolunteers.setupShiftVolunteerEventListeners === 'function') { const setupVolunteerModule = () => {
window.adminShiftVolunteers.setupShiftVolunteerEventListeners(); if (window.adminShiftVolunteers && typeof window.adminShiftVolunteers.setupVolunteerModalEventListeners === 'function') {
console.log('Setting up volunteer modal event listeners...');
window.adminShiftVolunteers.setupVolunteerModalEventListeners();
// Load users for volunteer management
if (typeof window.adminShiftVolunteers.loadAllUsers === 'function') {
console.log('Loading users for volunteer management...');
window.adminShiftVolunteers.loadAllUsers();
}
return true;
}
return false;
};
// Try to setup immediately
if (!setupVolunteerModule()) {
console.log('adminShiftVolunteers not ready, waiting for ready event...');
// Listen for the ready event
window.addEventListener('adminShiftVolunteersReady', (e) => {
console.log('adminShiftVolunteersReady event received:', e.detail);
if (setupVolunteerModule()) {
console.log('✅ Volunteer module setup completed after ready event');
}
});
// Also add a backup timer
let retryCount = 0;
const maxRetries = 10;
const retrySetup = setInterval(() => {
retryCount++;
if (setupVolunteerModule()) {
clearInterval(retrySetup);
console.log('✅ Volunteer module setup completed after', retryCount, 'retries');
} else if (retryCount >= maxRetries) {
clearInterval(retrySetup);
console.warn('⚠️ Failed to setup volunteer module after', maxRetries, 'retries');
}
}, 200);
} }
// Setup user listeners // Setup user listeners
@ -47,6 +84,8 @@ function setupAllEventListeners() {
// Main admin initialization when DOM is loaded // Main admin initialization when DOM is loaded
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
console.log('DOM loaded, initializing admin modules...');
// Initialize core functionality // Initialize core functionality
if (window.adminCore && typeof window.adminCore.initializeAdminCore === 'function') { if (window.adminCore && typeof window.adminCore.initializeAdminCore === 'function') {
window.adminCore.initializeAdminCore(); window.adminCore.initializeAdminCore();
@ -67,6 +106,30 @@ document.addEventListener('DOMContentLoaded', () => {
window.adminMap.loadCurrentStartLocation(); window.adminMap.loadCurrentStartLocation();
} }
// Check module loading status with detailed info
console.log('📊 Module loading status:', {
adminCore: !!window.adminCore,
adminAuth: !!window.adminAuth,
adminMap: !!window.adminMap,
adminShifts: !!window.adminShifts,
adminShiftVolunteers: !!window.adminShiftVolunteers,
adminUsers: !!window.adminUsers,
adminEmail: !!window.adminEmail
});
// Detailed check for adminShiftVolunteers
if (window.adminShiftVolunteers) {
console.log('📋 adminShiftVolunteers details:', {
exists: true,
functions: Object.keys(window.adminShiftVolunteers),
showShiftUserModal: typeof window.adminShiftVolunteers.showShiftUserModal,
moduleVersion: window.adminShiftVolunteers.moduleVersion,
loadedAt: window.adminShiftVolunteers.loadedAt
});
} else {
console.warn('⚠️ adminShiftVolunteers module not found');
}
// Setup all event listeners // Setup all event listeners
setupAllEventListeners(); setupAllEventListeners();