Files
alrahma_sunday_school/app/Views/parent/enroll_classes.php
T
root 1ef2800f12
Tests / PHPUnit (push) Successful in 1m26s
fix enrollment for the new school-year
2026-08-07 23:43:31 -04:00

408 lines
20 KiB
PHP

<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container my-5">
<h3 class="text-center text-success" style="font-family: Arial, sans-serif;">Enroll in Classes</h3>
<?php if (!empty($selectedYear)): ?>
<div class="text-center text-muted small">School Year: <?= esc($selectedYear) ?></div>
<?php endif; ?>
</div>
<?php
// Put this near the very top of the file (before output), or right after the extend/section lines.
$tz = (string) (config('School')->attendance['timezone'] ?? user_timezone());
$deadlineObj = (new DateTime($lastDayOfRegistration, new DateTimeZone($tz)))->setTime(23, 59, 59);
$nowObj = new DateTime('now', new DateTimeZone($tz));
$deadlinePassed = $nowObj > $deadlineObj;
$deadlineISO = $deadlineObj->format('Y-m-d\TH:i:sP'); // for JS
$familyFinancialSummary = is_array($familyFinancialSummary ?? null) ? $familyFinancialSummary : [];
$money = static function ($amount) use ($familyFinancialSummary): string {
$currency = (string) ($familyFinancialSummary['currency'] ?? '$');
return $currency . number_format((float) $amount, 2);
};
?>
<!-- Registration Info -->
<div class="alert alert-info mb-3">
<p>Enrollment is the process of officially signing up your child for the upcoming school year.</p>
<ul>
<li>Last Day for Enrollment is <strong><?= esc(local_date($lastDayOfRegistration, 'm-d-Y')) ?></strong>.</li>
<li>Once you click "Save", the enrollment status will change to <strong>admission under review</strong>.</li>
<li>Payments are processed on the first day of school: <strong><?= esc(local_date($schoolStartDate, 'm-d-Y')) ?></strong>.</li>
</ul>
</div>
<?php if ($familyFinancialSummary !== []): ?>
<div class="border rounded p-3 mb-3 bg-light">
<div class="fw-semibold mb-2">Family Account Information</div>
<div class="row g-2">
<div class="col-md-4">
<span class="text-muted">Previous-year carry-over balance:</span>
<strong><?= esc($money($familyFinancialSummary['carry_over_balance'] ?? 0)) ?></strong>
</div>
<div class="col-md-4">
<span class="text-muted">Registration fee:</span>
<strong><?= esc($money($familyFinancialSummary['registration_fee'] ?? 0)) ?></strong>
</div>
<div class="col-md-4">
<span class="text-muted">Tuition due now:</span>
<strong><?= esc($money($familyFinancialSummary['tuition_due_at_registration'] ?? 0)) ?></strong>
</div>
<div class="col-md-4">
<span class="text-muted">Mandatory fees:</span>
<strong><?= esc($money($familyFinancialSummary['mandatory_fees'] ?? 0)) ?></strong>
</div>
<div class="col-md-4">
<span class="text-muted">Current-year account balance:</span>
<strong><?= esc($money($familyFinancialSummary['current_balance'] ?? 0)) ?></strong>
</div>
<div class="col-md-4">
<span class="text-muted">Total currently due:</span>
<strong><?= esc($money($familyFinancialSummary['amount_due'] ?? 0)) ?></strong>
</div>
</div>
<?php if (!empty($familyFinancialSummary['policy_message'])): ?>
<div class="small text-muted mt-2"><?= esc($familyFinancialSummary['policy_message']) ?></div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger"><?= esc(session()->getFlashdata('error')) ?></div>
<?php endif; ?>
<?php $hasAcceptedSchoolPolicy = (bool) ($hasAcceptedSchoolPolicy ?? false); ?>
<?php if (!empty($students)): ?>
<form action="<?= base_url('/parent/enroll_classes_handler') ?>" method="post">
<?= csrf_field() ?>
<input type="hidden" id="accept_school_policy_input" name="accept_school_policy" value="<?= $hasAcceptedSchoolPolicy ? '1' : '0' ?>">
<div class="table-responsive">
<table class="table table-striped table-bordered align-middle">
<thead>
<tr>
<th>#</th>
<th>School ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Gender</th>
<th>Grade</th>
<th>Decision</th>
<th>Required Action</th>
<th>Enroll</th>
<th>Withdraw</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($students as $index => $student): ?>
<?php $eligibilityMessage = is_array($student['enrollment_eligibility_message'] ?? null) ? $student['enrollment_eligibility_message'] : ['message' => '', 'blocking' => false, 'level' => 'info']; ?>
<tr>
<td><?= $index + 1 ?></td>
<td><?= esc($student['school_id'] ?? 'N/A') ?></td>
<td><?= esc($student['firstname'] ?? 'N/A') ?></td>
<td><?= esc($student['lastname'] ?? 'N/A') ?></td>
<td><?= esc($student['age'] ?? 'N/A') ?></td>
<td><?= esc($student['gender'] ?? 'N/A') ?></td>
<td>
<?php
$section = $student['class_section'] ?? null;
echo $section
? esc(preg_replace_callback('/\byouth\b/i', fn($m) => ucfirst(strtolower($m[0])), $section))
: 'Not Assigned';
?>
</td>
<td><?= esc($student['transition_evaluation']['decision_label'] ?? 'Pending') ?></td>
<td><?= esc($student['required_action_label'] ?? 'Contact the school administration.') ?></td>
<!-- Enroll Checkbox -->
<td>
<?php if ($student['enrollment_status'] === 'not enrolled'): ?>
<?php $disableEnrollUI = $deadlinePassed || !$isEditable || (bool) ($eligibilityMessage['blocking'] ?? false); ?>
<input type="checkbox"
name="enroll[]"
value="<?= esc($student['id']) ?>"
data-decision-message="<?= esc($eligibilityMessage['message'] ?? '') ?>"
data-decision-blocking="<?= !empty($eligibilityMessage['blocking']) ? '1' : '0' ?>"
data-decision-message-target="enrollment-decision-message-<?= esc($student['id']) ?>"
<?= $disableEnrollUI ? 'disabled' : '' ?>>
<?php elseif (in_array($student['enrollment_status'], ['enrolled', 'admission under review', 'review & decision', 'payment pending', 'withdraw under review'])): ?>
<input type="checkbox" checked disabled>
<?php else: ?>
<input type="checkbox" disabled>
<?php endif; ?>
</td>
<!-- Withdraw Checkbox -->
<td>
<?php if ($student['enrollment_status'] === 'enrolled'): ?>
<input type="checkbox" name="withdraw[]" value="<?= esc($student['id']) ?>" <?= !$isEditable ? 'disabled' : '' ?>>
<?php elseif ($student['enrollment_status'] === 'withdrawn'): ?>
<input type="checkbox" checked disabled>
<?php else: ?>
<input type="checkbox" disabled>
<?php endif; ?>
</td>
<!-- Status -->
<td>
<?php
$status = strtolower(trim($student['enrollment_status'] ?? ''));
switch ($status) {
case 'admission under review':
echo '<span class="badge bg-primary">admission under review</span>';
break;
case 'review & decision':
echo '<span class="badge bg-secondary">review &amp; decision</span>';
break;
case 'payment pending':
echo '<span class="badge bg-warning text-dark">payment pending</span>';
break;
case 'enrolled':
echo '<span class="badge bg-success">enrolled</span>';
break;
case 'withdraw under review':
echo '<span class="badge bg-warning text-dark">withdraw under review</span>';
break;
case 'refund pending':
echo '<span class="badge bg-info text-dark">refund pending</span>';
break;
case 'withdrawn':
echo '<span class="badge bg-danger">withdrawn</span>';
break;
case 'waitlist':
echo '<span class="badge bg-secondary">waitlist</span>'; // lighter and neutral
break;
case 'denied':
echo '<span class="badge bg-danger">denied</span>'; // red stands out clearly
break;
case 'not enrolled':
echo '<span class="badge bg-light text-dark">not enrolled</span>'; // very neutral
break;
default:
echo '<span class="badge bg-light text-dark">unknown</span>';
}
?>
</td>
</tr>
<?php if (($eligibilityMessage['message'] ?? '') !== ''): ?>
<tr id="enrollment-decision-message-<?= esc($student['id']) ?>" class="enrollment-decision-message-row">
<td colspan="12">
<div class="alert alert-<?= esc($eligibilityMessage['level'] ?? 'info') ?> mb-0">
<?= esc($eligibilityMessage['message']) ?>
</div>
</td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- Save Button -->
<?php
$today = local_date(utc_now(), 'Y-m-d');
$disableDueToDate = ($today >= $lastDayOfRegistration);
// Allow submit for withdrawals even after deadline; keep editability guard only
$disableSave = !$isEditable;
?>
<div class="d-flex justify-content-center">
<button type="submit"
class="btn btn-lg btn-success <?= $disableSave ? 'disabled' : '' ?>"
<?= $disableSave ? 'disabled' : '' ?>
title="<?php
if (!$isEditable) {
echo 'Editing is not allowed for this record.';
}
?>">
Submit
</button>
</div>
<br>
</form>
<?php else: ?>
<p>No students found for the selected school year. Please register your kids first.</p>
<?php endif; ?>
<!-- School Policy Modal -->
<div class="modal fade" id="schoolPolicyModal" tabindex="-1" aria-labelledby="schoolPolicyModalLabel" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header bg-success text-white">
<h5 class="modal-title" id="schoolPolicyModalLabel">School Policies</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<iframe src="<?= base_url('policy/school_policy') ?>" width="100%" height="520" frameborder="0" title="School Policies"></iframe>
<div class="form-check mt-3">
<input class="form-check-input" type="checkbox" value="1" id="schoolPolicyAcceptedCheckbox" <?= $hasAcceptedSchoolPolicy ? 'checked disabled' : '' ?>>
<label class="form-check-label" for="schoolPolicyAcceptedCheckbox">
I have read and accept all school policies.
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-success" id="acceptSchoolPolicyButton" <?= $hasAcceptedSchoolPolicy ? '' : 'disabled' ?>>
Accept Policy
</button>
</div>
</div>
</div>
</div>
<!-- Enrollment Deadline Modal -->
<div class="modal fade" id="deadlineModal" tabindex="-1" aria-labelledby="deadlineModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title" id="deadlineModalLabel">Enrollment Closed</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Enrollment for the selected school year closed on
<strong><?= esc($deadlineObj->format('m-d-Y')) ?></strong>.
You can still request a withdrawal (if applicable), but new enrollments are no longer accepted.
<br><br>
If you believe this is an error, please contact the school office.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
document.addEventListener("DOMContentLoaded", function() {
// Values from PHP
const deadlinePassed = <?= $deadlinePassed ? 'true' : 'false' ?>;
const enrollmentDeadline = new Date("<?= esc($deadlineISO) ?>");
let hasAcceptedSchoolPolicy = <?= $hasAcceptedSchoolPolicy ? 'true' : 'false' ?>;
// Bootstrap Modal
const modalEl = document.getElementById('deadlineModal');
const deadlineModal = modalEl ? new bootstrap.Modal(modalEl) : null;
const policyModalEl = document.getElementById('schoolPolicyModal');
const policyModal = policyModalEl ? new bootstrap.Modal(policyModalEl) : null;
const policyAcceptedInput = document.getElementById('accept_school_policy_input');
const policyAcceptedCheckbox = document.getElementById('schoolPolicyAcceptedCheckbox');
const acceptPolicyButton = document.getElementById('acceptSchoolPolicyButton');
const showDeadlineModal = () => {
if (deadlineModal) deadlineModal.show();
};
const showPolicyModal = () => {
if (policyModal) policyModal.show();
};
const setDecisionMessageVisible = (checkbox, visible) => {
const targetId = checkbox.dataset.decisionMessageTarget || '';
const target = targetId ? document.getElementById(targetId) : null;
if (target) {
target.classList.toggle('d-none', !visible);
}
};
const hideAllDecisionMessages = () => {
document.querySelectorAll('.enrollment-decision-message-row').forEach(row => {
row.classList.add('d-none');
});
};
if (policyAcceptedCheckbox && acceptPolicyButton) {
policyAcceptedCheckbox.addEventListener('change', function() {
acceptPolicyButton.disabled = !this.checked;
});
}
if (acceptPolicyButton) {
acceptPolicyButton.addEventListener('click', function() {
if (policyAcceptedCheckbox && !policyAcceptedCheckbox.checked) {
return;
}
hasAcceptedSchoolPolicy = true;
if (policyAcceptedInput) {
policyAcceptedInput.value = '1';
}
if (policyModal) {
policyModal.hide();
}
});
}
// The enrollment form
const form = document.querySelector("form[action*='enroll_classes_handler']");
// 1) Block clicking "enroll" checkboxes after deadline
document.querySelectorAll("input[name='enroll[]']").forEach(cb => {
cb.addEventListener("click", function(e) {
if (deadlinePassed) {
e.preventDefault();
e.stopImmediatePropagation();
this.checked = false;
showDeadlineModal();
return;
}
if (!hasAcceptedSchoolPolicy) {
e.preventDefault();
e.stopImmediatePropagation();
this.checked = false;
showPolicyModal();
return;
}
if (this.checked && this.dataset.decisionMessage) {
setDecisionMessageVisible(this, true);
if (this.dataset.decisionBlocking === '1') {
e.preventDefault();
e.stopImmediatePropagation();
this.checked = false;
return;
}
} else {
setDecisionMessageVisible(this, false);
}
});
});
// 2) Prevent submission if any enroll[] is checked after deadline
if (form) {
form.addEventListener("submit", function(e) {
const anyBoxesChecked = form.querySelectorAll("input[name='enroll[]']:checked").length > 0;
const anyWithdrawChecked = form.querySelectorAll("input[name='withdraw[]']:checked").length > 0;
if (!anyBoxesChecked && !anyWithdrawChecked) {
e.preventDefault();
alert("Please select at least one student to enroll or withdraw before saving.");
return;
}
if (!hasAcceptedSchoolPolicy && anyBoxesChecked) {
e.preventDefault();
showPolicyModal();
return;
}
if (deadlinePassed && anyBoxesChecked) {
e.preventDefault();
showDeadlineModal();
return;
}
// 3) If only withdrawals are selected, ask for a quick confirmation
if (!anyBoxesChecked && anyWithdrawChecked) {
const ok = confirm('Confirm withdrawal request for the selected student(s)?');
if (!ok) {
e.preventDefault();
return;
}
}
});
}
});
</script>
<?= $this->endSection() ?>