fixed a bug for manage volunteers
This commit is contained in:
parent
00a2117cb9
commit
e3611c8300
@ -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>
|
||||||
|
|||||||
@ -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,6 +542,45 @@ function setupVolunteerModalEventListeners() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Export shift volunteer functions
|
// Export shift volunteer functions
|
||||||
|
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 = {
|
window.adminShiftVolunteers = {
|
||||||
showShiftUserModal,
|
showShiftUserModal,
|
||||||
closeShiftUserModal,
|
closeShiftUserModal,
|
||||||
@ -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
|
||||||
|
|||||||
@ -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(/'/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(/'/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);
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user