diff --git a/app/Views/administrator/events/event_charges.php b/app/Views/administrator/events/event_charges.php index 8b659b9..fcf2652 100644 --- a/app/Views/administrator/events/event_charges.php +++ b/app/Views/administrator/events/event_charges.php @@ -181,8 +181,7 @@ Add non-school participant -
After adding participants, click Submit to save them to the database.
-
+
Enrolled students are saved when you click Submit. Non-school participants are saved immediately and will then appear in all browsers.
@@ -290,8 +289,14 @@ ($charge['external_parent_lastname'] ?? '') ); $externalParentPhone = $charge['external_parent_phone'] ?? ''; + $externalParentEmail = $charge['external_parent_email'] ?? ''; $standardParentName = trim($charge['parent_firstname'] . ' ' . $charge['parent_lastname']); $parentColumnName = $externalParentLabel ?: ($standardParentName ?: '—'); + $externalInfoValue = trim(implode(' ', array_filter([ + $externalParentPhone, + $externalParentEmail, + $externalNote, + ]))); ?> @@ -300,10 +305,14 @@ - +
- + + +
+ + @@ -524,186 +533,11 @@ function loadStudentsWithCharges() { loadStudentsWithCharges(); } - const $externalHidden = $('#externalParticipantsHidden'); const $externalSaveButton = $('#externalParticipantSave'); - const storageKey = 'eventChargesExternalParticipants'; - let externalDrafts = []; - let editingKey = null; - - const escapeHtml = (value) => { - const s = String(value ?? ''); - return s.replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - }; - - function buildExternalRow(entry) { - const key = entry.key; - const isPaid = !!entry.paid; - const waiverSigned = !!entry.waiverSigned; - const firstEsc = escapeHtml(entry.firstname); - const lastEsc = escapeHtml(entry.lastname); - const noteEsc = escapeHtml(entry.note); - const parentFirstEsc = escapeHtml(entry.parentFirstname); - const parentLastEsc = escapeHtml(entry.parentLastname); - const parentPhoneEsc = escapeHtml(entry.parentPhone); - const parentEmailEsc = escapeHtml(entry.parentEmail); - const label = (firstEsc || lastEsc) - ? `${firstEsc || ''} ${lastEsc || ''}`.trim() - : 'Unnamed participant'; - const parentLabel = (parentFirstEsc || parentLastEsc) - ? `
Parent: ${parentFirstEsc} ${parentLastEsc}
` - : ''; - const phoneLabel = parentPhoneEsc - ? `
${parentPhoneEsc}
` - : ''; - const parentNameForRow = entry.parentDisplayName || '—'; - const amountDisplay = ((entry.eventAmount ?? 0) || 0.0).toFixed(2); - - const $wrapper = $(` -
- - - - - - - - - -
- `); - $externalHidden.append($wrapper); - - const $tableBody = $(`#eventTable_${entry.eventId} tbody`); - if (!$tableBody.length) { - return; - } - const createdDisplay = new Date().toLocaleString(); - const $previewRow = $(` - - — - ${escapeHtml(parentNameForRow)} - - ${label} - ${noteEsc ? `
${noteEsc}
` : ''} - - - ${phoneLabel} - ${phoneLabel ? '' : ''} - - External - $${amountDisplay} - ${createdDisplay} - -
- - ${waiverSigned ? 'Signed' : 'Unsigned'} -
- - - ${isPaid ? 'Paid' : 'Unpaid'} - - -
- - Paid -
- - - - - - - `); - $tableBody.append($previewRow); - applyActiveSort($tableBody.closest('table').get(0)); - } - - function persistDrafts() { - localStorage.setItem(storageKey, JSON.stringify(externalDrafts)); - } - - function saveExternalDraft(entry) { - entry.key = entry.key ?? `${Date.now()}_${Math.random().toString(36).slice(2)}`; - entry.paid = !!entry.paid; - entry.waiverSigned = !!entry.waiverSigned; - removeExternalEntryFromDom(entry.key); - externalDrafts = externalDrafts.filter((existing) => existing.key !== entry.key); - externalDrafts.push(entry); - persistDrafts(); - buildExternalRow(entry); - } - - function removeExternalEntryFromDom(key) { - $(`tr.external-preview[data-key="${key}"]`).remove(); - $externalHidden.find(`div[data-key="${key}"]`).remove(); - } - - function removeDraft(key) { - externalDrafts = externalDrafts.filter((entry) => entry.key !== key); - persistDrafts(); - } - - function loadDrafts() { - const raw = localStorage.getItem(storageKey); - if (!raw) { - return; - } - try { - const saved = JSON.parse(raw); - if (!Array.isArray(saved)) { - return; - } - externalDrafts = saved; - const currentEvent = $('#event_id').val(); - externalDrafts.forEach((entry) => { - if (String(entry.eventId) === String(currentEvent)) { - buildExternalRow(entry); - } - }); - } catch (e) { - console.error('Failed to load external drafts', e); - } - } - - function getDraftByKey(key) { - return externalDrafts.find((entry) => entry.key === key); - } - - function openExternalModalForEntry(key) { - const entry = getDraftByKey(key); - if (!entry) { - return; - } - editingKey = key; - $externalSaveButton.text('Save'); - $('#modalExternalFirstName').val(entry.firstname); - $('#modalExternalLastName').val(entry.lastname); - $('#modalExternalNote').val(entry.note); - $('#modalParentFirstName').val(entry.parentFirstname); - $('#modalParentLastName').val(entry.parentLastname); - $('#modalParentPhone').val(entry.parentPhone); - $('#modalParentEmail').val(entry.parentEmail); - if (modalInstance) { - modalInstance.show(); - } - } const modalElement = document.getElementById('externalParticipantModal'); const modalInstance = modalElement ? new bootstrap.Modal(modalElement) : null; - if (modalElement) { - modalElement.addEventListener('hidden.bs.modal', () => { - editingKey = null; - $externalSaveButton.text('Add to list'); - }); - } + function clearModalInputs() { $('#modalExternalFirstName').val(''); $('#modalExternalLastName').val(''); @@ -714,6 +548,46 @@ function loadStudentsWithCharges() { $('#modalParentEmail').val(''); } + function appendHiddenField(form, name, value) { + const input = document.createElement('input'); + input.type = 'hidden'; + input.name = name; + input.value = value; + form.appendChild(input); + } + + function escapeHtml(value) { + const s = String(value ?? ''); + return s.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + function submitExternalParticipant(payload) { + const form = document.createElement('form'); + form.method = 'post'; + form.action = ''; + + appendHiddenField(form, '', ''); + appendHiddenField(form, 'school_year', ''); + appendHiddenField(form, 'semester', ''); + appendHiddenField(form, 'event_id', payload.eventId); + appendHiddenField(form, 'external_participants[new][firstname]', payload.firstname); + appendHiddenField(form, 'external_participants[new][lastname]', payload.lastname); + appendHiddenField(form, 'external_participants[new][note]', payload.note); + appendHiddenField(form, 'external_participants[new][parent_firstname]', payload.parentFirstname); + appendHiddenField(form, 'external_participants[new][parent_lastname]', payload.parentLastname); + appendHiddenField(form, 'external_participants[new][parent_phone]', payload.parentPhone); + appendHiddenField(form, 'external_participants[new][parent_email]', payload.parentEmail); + appendHiddenField(form, 'external_participants[new][waiver_signed]', '0'); + appendHiddenField(form, 'external_participants[new][paid]', '0'); + + document.body.appendChild(form); + form.submit(); + } + function getSortValue(row, columnIndex, sortType) { const cell = row.children[columnIndex]; if (!cell) { @@ -910,7 +784,6 @@ function loadStudentsWithCharges() { alert('Select an event before adding a non-school participant.'); return; } - const eventAmount = parseFloat($('#event_id option:selected').data('amount')) || 0; const explicitParentName = `${parentFirst} ${parentLast}`.trim(); if (!explicitParentName) { alert('Please enter the external kid parent name.'); @@ -920,9 +793,7 @@ function loadStudentsWithCharges() { alert('Please enter the external kid parent email.'); return; } - const parentName = explicitParentName; - const draftEntry = editingKey ? getDraftByKey(editingKey) : null; - const entry = { + submitExternalParticipant({ firstname: firstName, lastname: lastName, note: note, @@ -930,91 +801,10 @@ function loadStudentsWithCharges() { parentLastname: parentLast, parentPhone: parentPhone, parentEmail: parentEmail, - eventId: (draftEntry && draftEntry.eventId) ? draftEntry.eventId : eventId, - eventAmount: (draftEntry && draftEntry.eventAmount) ? draftEntry.eventAmount : eventAmount, - parentDisplayName: (draftEntry && draftEntry.parentDisplayName) ? draftEntry.parentDisplayName : parentName, - waiverSigned: (draftEntry && typeof draftEntry.waiverSigned !== 'undefined') ? !!draftEntry.waiverSigned : false, - paid: (draftEntry && typeof draftEntry.paid !== 'undefined') ? !!draftEntry.paid : false, - }; - if (editingKey) { - entry.key = editingKey; - } - saveExternalDraft(entry); - editingKey = null; - $externalSaveButton.text('Add to list'); + eventId: eventId + }); clearModalInputs(); - if (modalInstance) { - modalInstance.hide(); - } }); - - $(document).on('click', '.remove-external-participant', function() { - const $entry = $(this).closest('[data-key]'); - const key = $entry.data('key'); - removeExternalEntryFromDom(key); - if (key) { - removeDraft(key); - } - }); - $(document).on('click', '.edit-external-participant', function() { - const key = $(this).data('key'); - if (key) { - openExternalModalForEntry(key); - } - }); - $(document).on('change', '.external-paid-toggle', function() { - const key = $(this).data('key'); - const paid = !!this.checked; - if (!key) { - return; - } - const entry = getDraftByKey(key); - if (entry) { - entry.paid = paid; - persistDrafts(); - } - $externalHidden - .find(`div[data-key="${key}"] input[name="external_participants[${key}][paid]"]`) - .val(paid ? '1' : '0'); - const $badge = $(`tr.external-preview[data-key="${key}"] .external-paid-badge`); - if (paid) { - $badge.removeClass('bg-danger').addClass('bg-success').text('Paid'); - } else { - $badge.removeClass('bg-success').addClass('bg-danger').text('Unpaid'); - } - const $row = $(`tr.external-preview[data-key="${key}"]`); - $row.children().eq(8).attr('data-sort-value', paid ? 'paid' : 'unpaid'); - $row.children().eq(9).attr('data-sort-value', paid ? 'paid' : 'unpaid'); - applyActiveSort($row.closest('table').get(0)); - }); - $(document).on('change', '.external-waiver-toggle', function() { - const key = $(this).data('key'); - const signed = !!this.checked; - if (!key) { - return; - } - const entry = getDraftByKey(key); - if (entry) { - entry.waiverSigned = signed; - persistDrafts(); - } - $externalHidden - .find(`div[data-key="${key}"] input[name="external_participants[${key}][waiver_signed]"]`) - .val(signed ? '1' : '0'); - const $label = $(`tr.external-preview[data-key="${key}"] .external-waiver-label`); - if (signed) { - $label.text('Signed'); - } else { - $label.text('Unsigned'); - } - const $row = $(`tr.external-preview[data-key="${key}"]`); - $row.children().eq(7).attr('data-sort-value', signed ? 'signed' : 'unsigned'); - applyActiveSort($row.closest('table').get(0)); - }); - $('#event-participant-form').on('submit', function() { - localStorage.removeItem(storageKey); - }); - loadDrafts(); }); endSection() ?>