document.querySelectorAll('.club-action-modal').forEach(modal => { const form = modal.querySelector('form'); if (!form) return; let saving = false; modal.addEventListener('shown.bs.modal', () => { form.querySelector('input:not([type="hidden"]),select,textarea')?.focus(); }); modal.addEventListener('hide.bs.modal', event => { if (saving) event.preventDefault(); }); form.addEventListener('submit', async event => { event.preventDefault(); if (saving || !form.reportValidity()) return; const error = modal.querySelector('.club-modal-error'); error.hidden = true; const data = new FormData(form); const buttons = Array.from(modal.querySelectorAll('button')); const disabled = buttons.map(button => button.disabled); saving = true; buttons.forEach(button => button.disabled = true); try { // The existing hidden field named "action" shadows form.action. const response = await fetch(form.getAttribute('action') || 'main.php', { method: 'POST', credentials: 'same-origin', body: data, headers: {'X-Requested-With': 'XMLHttpRequest', 'X-HCR-Modal': '1'} }); const result = await response.json(); if (!response.ok || !result.ok) throw new Error(result.error || 'Your change could not be saved.'); window.location.assign(result.redirect); } catch (failure) { error.textContent = failure instanceof SyntaxError || failure instanceof TypeError ? 'Your change could not be confirmed. Reload the club page before retrying.' : failure.message; error.hidden = false; error.focus(); } finally { saving = false; buttons.forEach((button, index) => button.disabled = disabled[index]); } }); });