fix school year and enrollment steps
Tests / PHPUnit (push) Failing after 58s

This commit is contained in:
root
2026-08-15 21:15:05 -04:00
parent 4603d9ced2
commit 3cbfc40934
18 changed files with 1142 additions and 163 deletions
+266 -32
View File
@@ -11,7 +11,7 @@
.enrollment-stepper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(4, 1fr);
gap: .5rem;
}
@@ -162,6 +162,7 @@ $nowObj = new DateTime('now', new DateTimeZone($tz));
$deadlinePassed = $nowObj > $deadlineObj;
$hasAcceptedSchoolPolicy = (bool) ($hasAcceptedSchoolPolicy ?? false);
$familyFinancialSummary = is_array($familyFinancialSummary ?? null) ? $familyFinancialSummary : [];
$enrollmentFeeSchedule = is_array($enrollmentFeeSchedule ?? null) ? $enrollmentFeeSchedule : [];
$money = static function ($amount) use ($familyFinancialSummary): string {
$currency = (string) ($familyFinancialSummary['currency'] ?? '$');
return $currency . number_format((float) $amount, 2);
@@ -220,12 +221,12 @@ foreach (($students ?? []) as $student) {
<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 class="col-md-4"><span class="text-muted">Previous-year carry-over balance:</span> <strong data-financial-value="carry_over_balance"><?= esc($money($familyFinancialSummary['carry_over_balance'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Registration fee:</span> <strong data-financial-value="registration_fee"><?= esc($money($familyFinancialSummary['registration_fee'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Tuition due now:</span> <strong data-financial-value="tuition_due_at_registration"><?= esc($money($familyFinancialSummary['tuition_due_at_registration'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Mandatory fees:</span> <strong data-financial-value="mandatory_fees"><?= esc($money($familyFinancialSummary['mandatory_fees'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Current-year account balance:</span> <strong data-financial-value="current_balance"><?= esc($money($familyFinancialSummary['current_balance'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Total currently due:</span> <strong data-financial-value="amount_due"><?= 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>
@@ -244,7 +245,7 @@ foreach (($students ?? []) as $student) {
<div class="col-lg">
<div class="fw-semibold">Enrollment process</div>
<div class="text-muted small">
Select students, review policy information, then submit enrollment.
Review student information, acknowledge policies, review tuition and balances, then submit enrollment.
</div>
</div>
<div class="col-lg-auto">
@@ -322,19 +323,20 @@ foreach (($students ?? []) as $student) {
<div class="modal-dialog modal-xl modal-dialog-scrollable modal-fullscreen-sm-down">
<div class="modal-content">
<div class="modal-header bg-success text-white">
<h5 class="modal-title" id="enrollmentFlowModalLabel">Enroll your childs</h5>
<h5 class="modal-title" id="enrollmentFlowModalLabel">Submit Enrollment</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="enrollment-stepper mb-3" aria-label="Enrollment steps">
<div class="enrollment-step is-active" data-step-indicator="0">Students</div>
<div class="enrollment-step" data-step-indicator="1">Policy</div>
<div class="enrollment-step" data-step-indicator="2">Submit</div>
<div class="enrollment-step is-active" data-step-indicator="0">Student Info</div>
<div class="enrollment-step" data-step-indicator="1">Policies</div>
<div class="enrollment-step" data-step-indicator="2">Tuition</div>
<div class="enrollment-step" data-step-indicator="3">Submit</div>
</div>
<div data-step-panel="0">
<h6 class="fw-semibold">Select student names</h6>
<div class="text-muted small mb-3">Tap each student you want to enroll for <?= esc($selectedYear ?? 'the selected school year') ?>.</div>
<h6 class="fw-semibold">Review student information</h6>
<div class="text-muted small mb-3">Select each student you want to enroll for <?= esc($selectedYear ?? 'the selected school year') ?> and update their information if needed.</div>
<div class="d-grid gap-2">
<?php foreach ($students as $student): ?>
<?php
@@ -353,6 +355,10 @@ foreach (($students ?? []) as $student) {
<div class="student-select-card <?= $canEnroll ? '' : 'is-disabled' ?>"
data-student-card
data-student-id="<?= esc($student['id']) ?>"
data-school-id="<?= esc($student['school_id'] ?? 'N/A') ?>"
data-current-grade="<?= esc($gradeLabel) ?>"
data-required-action="<?= esc($student['required_action_label'] ?? 'Contact administration') ?>"
data-expected-placement="<?= esc($student['expected_placement_label'] ?? $gradeLabel) ?>"
data-selectable="<?= $canEnroll ? '1' : '0' ?>">
<div class="d-flex gap-3 align-items-start">
<span class="student-select-icon" aria-hidden="true"><i class="bi bi-check2"></i></span>
@@ -361,7 +367,55 @@ foreach (($students ?? []) as $student) {
<div class="fw-semibold"><?= esc($studentName) ?></div>
<?= $statusBadge($student['enrollment_status'] ?? '') ?>
</div>
<div class="small text-muted">Grade: <?= esc($gradeLabel) ?> &middot; School ID: <?= esc($student['school_id'] ?? 'N/A') ?></div>
<div class="small text-muted">Current grade: <?= esc($gradeLabel) ?> &middot; School ID: <?= esc($student['school_id'] ?? 'N/A') ?></div>
<?php if ($canEnroll): ?>
<div class="row g-2 mt-2" data-student-edit-fields>
<div class="col-md-6">
<label class="form-label small fw-semibold" for="student-firstname-<?= esc($student['id']) ?>">First name</label>
<input class="form-control form-control-sm" type="text" id="student-firstname-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][firstname]" value="<?= esc($student['firstname'] ?? '') ?>" required maxlength="30" disabled data-student-edit-input>
</div>
<div class="col-md-6">
<label class="form-label small fw-semibold" for="student-lastname-<?= esc($student['id']) ?>">Last name</label>
<input class="form-control form-control-sm" type="text" id="student-lastname-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][lastname]" value="<?= esc($student['lastname'] ?? '') ?>" required maxlength="30" disabled data-student-edit-input>
</div>
<div class="col-md-4">
<label class="form-label small fw-semibold" for="student-dob-<?= esc($student['id']) ?>">Date of birth</label>
<input class="form-control form-control-sm" type="date" id="student-dob-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][dob]" value="<?= esc($student['dob'] ?? '') ?>" required disabled data-student-edit-input>
</div>
<div class="col-md-4">
<label class="form-label small fw-semibold" for="student-gender-<?= esc($student['id']) ?>">Gender</label>
<select class="form-select form-select-sm" id="student-gender-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][gender]" required disabled data-student-edit-input>
<option value="">Select</option>
<option value="Male" <?= ($student['gender'] ?? '') === 'Male' ? 'selected' : '' ?>>Male</option>
<option value="Female" <?= ($student['gender'] ?? '') === 'Female' ? 'selected' : '' ?>>Female</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-semibold" for="student-grade-<?= esc($student['id']) ?>">Registration grade</label>
<input class="form-control form-control-sm" type="text" id="student-grade-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][registration_grade]" value="<?= esc($student['registration_grade'] ?? '') ?>" required maxlength="50" disabled data-student-edit-input>
</div>
<div class="col-md-6">
<label class="form-label small fw-semibold" for="student-photo-consent-<?= esc($student['id']) ?>">Photo consent</label>
<select class="form-select form-select-sm" id="student-photo-consent-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][photo_consent]" required disabled data-student-edit-input>
<option value="">Select</option>
<option value="1" <?= (string) ($student['photo_consent'] ?? '') === '1' ? 'selected' : '' ?>>Yes</option>
<option value="0" <?= (string) ($student['photo_consent'] ?? '') === '0' ? 'selected' : '' ?>>No</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label small fw-semibold">Expected placement</label>
<div class="form-control form-control-sm bg-light"><?= esc($student['expected_placement_label'] ?? $gradeLabel) ?></div>
</div>
</div>
<?php else: ?>
<div class="small text-muted">
Date of birth: <?= esc(!empty($student['dob']) ? local_date($student['dob'], 'm-d-Y') : 'N/A') ?>
<?php if (isset($student['age'])): ?>
&middot; Age: <?= esc($student['age']) ?>
<?php endif; ?>
</div>
<div class="small text-muted">Expected placement: <?= esc($student['expected_placement_label'] ?? $gradeLabel) ?></div>
<?php endif; ?>
<div class="small">Required action: <?= esc($student['required_action_label'] ?? 'Contact administration') ?></div>
<?php if (($eligibilityMessage['message'] ?? '') !== ''): ?>
<div class="alert alert-<?= esc($eligibilityMessage['level'] ?? 'info') ?> py-2 px-3 mt-2 mb-0 small">
@@ -379,7 +433,7 @@ foreach (($students ?? []) as $student) {
</div>
<div class="d-none" data-step-panel="1">
<h6 class="fw-semibold">Policy info update</h6>
<h6 class="fw-semibold">Acknowledge school policies</h6>
<div class="text-muted small mb-3">Review the current school policies before submitting enrollment.</div>
<iframe src="<?= base_url('policy/school_policy') ?>" class="enrollment-policy-frame" frameborder="0" title="School Policies"></iframe>
<div class="form-check mt-3">
@@ -391,11 +445,76 @@ foreach (($students ?? []) as $student) {
</div>
<div class="d-none" data-step-panel="2">
<h6 class="fw-semibold">Enroll submit</h6>
<div class="text-muted small mb-3">Review the selected students, then submit enrollment.</div>
<div id="enrollmentReviewList" class="d-grid gap-2"></div>
<div class="alert alert-warning mt-3 mb-0 small">
Submitting sends the selected enrollment(s) to admission review.
<h6 class="fw-semibold">Review tuition, fees, and balance</h6>
<div class="text-muted small mb-3">Review the family account information before submitting enrollment.</div>
<?php if ($familyFinancialSummary !== []): ?>
<div class="border rounded p-3 bg-light">
<div class="row g-2">
<div class="col-md-4"><span class="text-muted">Previous-year carry-over balance:</span> <strong data-financial-value="carry_over_balance"><?= esc($money($familyFinancialSummary['carry_over_balance'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Registration fee:</span> <strong data-financial-value="registration_fee"><?= esc($money($familyFinancialSummary['registration_fee'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Tuition due now:</span> <strong data-financial-value="tuition_due_at_registration"><?= esc($money($familyFinancialSummary['tuition_due_at_registration'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Mandatory fees:</span> <strong data-financial-value="mandatory_fees"><?= esc($money($familyFinancialSummary['mandatory_fees'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Current-year account balance:</span> <strong data-financial-value="current_balance"><?= esc($money($familyFinancialSummary['current_balance'] ?? 0)) ?></strong></div>
<div class="col-md-4"><span class="text-muted">Total currently due:</span> <strong data-financial-value="amount_due"><?= 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 class="small mt-2"><a href="<?= site_url('parent/financial-aid') ?>">Request financial aid</a></div>
</div>
<?php else: ?>
<div class="alert alert-warning mb-0">Family account information is not available. Please contact the administration if you have questions about tuition or balance.</div>
<?php endif; ?>
</div>
<div class="d-none" data-step-panel="3">
<h6 class="fw-semibold">Submit enrollment</h6>
<div class="text-muted small mb-3">Review the enrollment summary before submitting.</div>
<div class="mb-3">
<div class="fw-semibold mb-2">Fees by student</div>
<div id="enrollmentFeeReviewList" class="d-grid gap-2"></div>
</div>
<div class="row g-3 mb-3">
<div class="col-md-6">
<div class="border rounded p-3 h-100">
<div class="fw-semibold mb-2">School dates</div>
<div class="small"><span class="text-muted">First school day:</span> <strong><?= esc(!empty($schoolStartDate) ? local_date($schoolStartDate, 'm-d-Y') : 'TBD') ?></strong></div>
<div class="small"><span class="text-muted">Make-up exam date:</span> <strong><?= esc(!empty($fallMakeupExamOn) ? local_date($fallMakeupExamOn, 'm-d-Y') : 'No make-up exam date currently listed') ?></strong></div>
<div class="small"><span class="text-muted">Enrollment deadline:</span> <strong><?= esc(local_date($lastDayOfRegistration, 'm-d-Y')) ?></strong></div>
</div>
</div>
<div class="col-md-6">
<div class="border rounded p-3 h-100">
<div class="fw-semibold mb-2">Financial information</div>
<?php if ($familyFinancialSummary !== []): ?>
<div class="small"><span class="text-muted">Carry-over balance:</span> <strong data-financial-value="carry_over_balance"><?= esc($money($familyFinancialSummary['carry_over_balance'] ?? 0)) ?></strong></div>
<div class="small"><span class="text-muted">Registration fee:</span> <strong data-financial-value="registration_fee"><?= esc($money($familyFinancialSummary['registration_fee'] ?? 0)) ?></strong></div>
<div class="small"><span class="text-muted">Tuition due now:</span> <strong data-financial-value="tuition_due_at_registration"><?= esc($money($familyFinancialSummary['tuition_due_at_registration'] ?? 0)) ?></strong></div>
<div class="small"><span class="text-muted">Mandatory fees:</span> <strong data-financial-value="mandatory_fees"><?= esc($money($familyFinancialSummary['mandatory_fees'] ?? 0)) ?></strong></div>
<div class="small"><span class="text-muted">Current-year account balance:</span> <strong data-financial-value="current_balance"><?= esc($money($familyFinancialSummary['current_balance'] ?? 0)) ?></strong></div>
<div class="small"><span class="text-muted">Total currently due:</span> <strong data-financial-value="amount_due"><?= esc($money($familyFinancialSummary['amount_due'] ?? 0)) ?></strong></div>
<?php else: ?>
<div class="small text-muted">Financial information is not available.</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="alert alert-warning mb-0 small">
<div class="fw-semibold mb-1">Important information</div>
<ul class="mb-0 ps-3">
<li>Submitting sends the selected enrollment(s) to admission review.</li>
<li>Payments are processed on the first day of school.</li>
<?php if (!empty($familyFinancialSummary['policy_message'])): ?>
<li><?= esc($familyFinancialSummary['policy_message']) ?></li>
<?php endif; ?>
<?php if (!empty($fallMakeupExamOn)): ?>
<li>Students with a make-up exam decision may initially remain in the same grade until the make-up exam result is confirmed.</li>
<?php endif; ?>
<li>Contact administration if any student information, fee, or placement detail looks incorrect.</li>
</ul>
</div>
</div>
</div>
@@ -447,7 +566,24 @@ foreach (($students ?? []) as $student) {
const backButton = document.getElementById('enrollmentBackButton');
const nextButton = document.getElementById('enrollmentNextButton');
const submitButton = document.getElementById('enrollmentSubmitButton');
const reviewList = document.getElementById('enrollmentReviewList');
const feeReviewList = document.getElementById('enrollmentFeeReviewList');
const finalStep = 3;
const feeSchedule = <?= json_encode([
'currency' => (string) ($enrollmentFeeSchedule['currency'] ?? '$'),
'firstStudentFee' => (float) ($enrollmentFeeSchedule['first_student_fee'] ?? 0),
'secondStudentFee' => (float) ($enrollmentFeeSchedule['second_student_fee'] ?? 0),
'registrationFee' => (float) ($enrollmentFeeSchedule['registration_fee'] ?? 0),
'tuitionDueAtRegistration' => (float) ($enrollmentFeeSchedule['tuition_due_at_registration'] ?? 0),
'mandatoryFees' => (float) ($enrollmentFeeSchedule['mandatory_fees'] ?? 0),
], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) ?>;
const familyFinancial = <?= json_encode([
'carryOverBalance' => (float) ($familyFinancialSummary['carry_over_balance'] ?? 0),
'registrationFee' => (float) ($familyFinancialSummary['registration_fee'] ?? 0),
'tuitionDueAtRegistration' => (float) ($familyFinancialSummary['tuition_due_at_registration'] ?? 0),
'mandatoryFees' => (float) ($familyFinancialSummary['mandatory_fees'] ?? 0),
'currentBalance' => (float) ($familyFinancialSummary['current_balance'] ?? 0),
'amountDue' => (float) ($familyFinancialSummary['amount_due'] ?? 0),
], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) ?>;
let currentStep = 0;
let hasAcceptedSchoolPolicy = <?= $hasAcceptedSchoolPolicy ? 'true' : 'false' ?>;
@@ -455,7 +591,7 @@ foreach (($students ?? []) as $student) {
const selectedWithdrawInputs = () => form ? Array.from(form.querySelectorAll("input[name='withdraw[]']:checked")) : [];
function setStep(step) {
currentStep = Math.max(0, Math.min(2, step));
currentStep = Math.max(0, Math.min(finalStep, step));
document.querySelectorAll('[data-step-panel]').forEach(panel => {
panel.classList.toggle('d-none', Number(panel.dataset.stepPanel) !== currentStep);
});
@@ -463,21 +599,100 @@ foreach (($students ?? []) as $student) {
indicator.classList.toggle('is-active', Number(indicator.dataset.stepIndicator) === currentStep);
});
backButton.classList.toggle('d-none', currentStep === 0);
nextButton.classList.toggle('d-none', currentStep === 2);
submitButton.classList.toggle('d-none', currentStep !== 2);
if (currentStep === 2) {
nextButton.classList.toggle('d-none', currentStep === finalStep);
submitButton.classList.toggle('d-none', currentStep !== finalStep);
if (currentStep >= 2) {
updateFinancialReview();
}
if (currentStep === finalStep) {
renderReview();
}
}
function calculateSelectedTuition() {
return selectedEnrollInputs().reduce((total, input, index) => {
return total + (index === 0 ? Number(feeSchedule.firstStudentFee || 0) : Number(feeSchedule.secondStudentFee || 0));
}, 0);
}
function updateFinancialReview() {
const selectedCount = selectedEnrollInputs().length;
const tuitionDue = selectedCount > 0 ? calculateSelectedTuition() : 0;
const carryOver = Number(familyFinancial.carryOverBalance || 0);
const registrationFee = Number(familyFinancial.registrationFee || feeSchedule.registrationFee || 0);
const mandatoryFees = Number(familyFinancial.mandatoryFees || feeSchedule.mandatoryFees || 0);
const currentBalance = Number(familyFinancial.currentBalance || 0);
const amountDue = Math.max(0, carryOver) + Math.max(0, currentBalance) + registrationFee + tuitionDue + mandatoryFees;
const values = {
carry_over_balance: carryOver,
registration_fee: registrationFee,
tuition_due_at_registration: tuitionDue,
mandatory_fees: mandatoryFees,
current_balance: currentBalance,
amount_due: amountDue,
};
Object.keys(values).forEach(key => {
document.querySelectorAll('[data-financial-value="' + key + '"]').forEach(node => {
node.textContent = formatMoney(values[key]);
});
});
}
function renderReview() {
updateFinancialReview();
const cards = selectedEnrollInputs().map(input => {
const card = input.closest('[data-student-card]');
const name = card ? card.querySelector('.fw-semibold')?.textContent?.trim() : 'Student';
const meta = card ? card.querySelector('.small.text-muted')?.textContent?.trim() : '';
return '<div class="border rounded p-3"><div class="fw-semibold">' + escapeHtml(name || 'Student') + '</div><div class="small text-muted">' + escapeHtml(meta || '') + '</div></div>';
const firstName = card ? card.querySelector("input[name$='[firstname]']")?.value?.trim() : '';
const lastName = card ? card.querySelector("input[name$='[lastname]']")?.value?.trim() : '';
const dob = card ? card.querySelector("input[name$='[dob]']")?.value?.trim() : '';
const grade = card ? card.querySelector("input[name$='[registration_grade]']")?.value?.trim() : '';
const gender = card ? card.querySelector("select[name$='[gender]']")?.value?.trim() : '';
const schoolId = card?.dataset.schoolId || 'N/A';
const currentGrade = card?.dataset.currentGrade || '';
const expectedPlacement = card?.dataset.expectedPlacement || '';
const requiredAction = card?.dataset.requiredAction || '';
const name = (firstName + ' ' + lastName).trim() || card?.querySelector('.fw-semibold')?.textContent?.trim() || 'Student';
const metaParts = [];
if (grade) metaParts.push('Registration grade: ' + grade);
if (dob) metaParts.push('DOB: ' + dob);
if (gender) metaParts.push('Gender: ' + gender);
if (schoolId) metaParts.push('School ID: ' + schoolId);
return {
name,
meta: metaParts.join(' - '),
currentGrade,
expectedPlacement,
requiredAction,
};
});
reviewList.innerHTML = cards.length ? cards.join('') : '<div class="alert alert-warning mb-0">No students selected.</div>';
if (!feeReviewList) {
return;
}
if (!cards.length) {
feeReviewList.innerHTML = '<div class="alert alert-warning mb-0">No students selected.</div>';
return;
}
feeReviewList.innerHTML = cards.map((student, index) => {
const tuitionFee = index === 0 ? feeSchedule.firstStudentFee : feeSchedule.secondStudentFee;
const tier = index === 0 ? 'First student tuition tier' : 'Additional student tuition tier';
return '<div class="border rounded p-3">' +
'<div class="d-flex flex-wrap justify-content-between gap-2">' +
'<div><div class="fw-semibold">' + escapeHtml(student.name) + '</div>' +
'<div class="small text-muted">' + escapeHtml(student.meta) + '</div></div>' +
'<div class="text-md-end"><div class="fw-semibold">' + escapeHtml(formatMoney(tuitionFee)) + '</div>' +
'<div class="small text-muted">' + escapeHtml(tier) + '</div></div>' +
'</div>' +
'<div class="row g-2 small mt-2">' +
'<div class="col-md-4"><span class="text-muted">Current grade:</span> ' + escapeHtml(student.currentGrade || 'N/A') + '</div>' +
'<div class="col-md-4"><span class="text-muted">Expected placement:</span> ' + escapeHtml(student.expectedPlacement || 'Pending') + '</div>' +
'<div class="col-md-4"><span class="text-muted">Required action:</span> ' + escapeHtml(student.requiredAction || 'Contact administration') + '</div>' +
'</div>' +
'</div>';
}).join('');
}
function escapeHtml(value) {
@@ -486,6 +701,11 @@ foreach (($students ?? []) as $student) {
});
}
function formatMoney(amount) {
const numericAmount = Number(amount || 0);
return String(feeSchedule.currency || '$') + numericAmount.toFixed(2);
}
function syncPolicyAccepted() {
hasAcceptedSchoolPolicy = !!(policyAcceptedCheckbox && policyAcceptedCheckbox.checked);
if (policyAcceptedInput) {
@@ -493,6 +713,12 @@ foreach (($students ?? []) as $student) {
}
}
function setStudentFieldsEnabled(card, enabled) {
card.querySelectorAll('[data-student-edit-input]').forEach(field => {
field.disabled = !enabled;
});
}
if (startButton && flowModal) {
startButton.addEventListener('click', function() {
if (deadlinePassed) {
@@ -505,7 +731,10 @@ foreach (($students ?? []) as $student) {
}
document.querySelectorAll('[data-student-card]').forEach(card => {
card.addEventListener('click', function() {
card.addEventListener('click', function(event) {
if (event.target.closest('input, select, textarea, label')) {
return;
}
if (this.dataset.selectable !== '1') {
return;
}
@@ -515,6 +744,7 @@ foreach (($students ?? []) as $student) {
}
input.checked = !input.checked;
this.classList.toggle('is-selected', input.checked);
setStudentFieldsEnabled(this, input.checked);
});
});
@@ -550,7 +780,11 @@ foreach (($students ?? []) as $student) {
if (e.submitter && e.submitter.id === 'withdrawSubmitButton') {
selectedEnrollInputs().forEach(input => {
input.checked = false;
input.closest('[data-student-card]')?.classList.remove('is-selected');
const card = input.closest('[data-student-card]');
card?.classList.remove('is-selected');
if (card) {
setStudentFieldsEnabled(card, false);
}
});
}
+6 -2
View File
@@ -58,7 +58,7 @@
</div>
<?php endif; ?>
<?php if (empty($openRequest)): ?>
<?php if (empty($existingRequest)): ?>
<form method="post" action="<?= site_url('parent/financial-aid') ?>" class="border rounded p-3 bg-light">
<?= csrf_field() ?>
<div class="mb-3">
@@ -87,7 +87,11 @@
<button class="btn btn-success" type="submit">Submit request</button>
</form>
<?php else: ?>
<div class="alert alert-info">You already have an open request. Administration will update it after review. Remember to bring recent pay stubs and last years tax return to the school office.</div>
<div class="alert alert-info">
You already submitted a financial aid application for <?= esc($schoolYear ?: 'this school year') ?>.
Parents can submit only one application per school year. Administration will update your request after review.
Remember to bring recent pay stubs and last years tax return to the school office.
</div>
<?php endif; ?>
</div>
<?= $this->endSection() ?>
+7 -2
View File
@@ -48,6 +48,7 @@
$viewedAt = $ack['viewed_at'] ?? '';
$signedAt = $ack['signed_at'] ?? '';
$signedName = $ack['signed_name'] ?? '';
$hasReport = !empty(($reportAvailableMap ?? [])[$sid]);
?>
<tr>
<td><?= esc(trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''))) ?></td>
@@ -62,8 +63,12 @@
<?php endif; ?>
</td>
<td class="text-end">
<a class="btn btn-sm btn-outline-primary" target="_blank" href="<?= base_url('parent/report-cards/view/' . $sid) ?>">View Report</a>
<?php if (! $signedAt): ?>
<?php if ($hasReport): ?>
<a class="btn btn-sm btn-outline-primary" target="_blank" href="<?= base_url('parent/report-cards/view/' . $sid) ?>">View Report</a>
<?php else: ?>
<button class="btn btn-sm btn-outline-secondary" type="button" disabled>No report available</button>
<?php endif; ?>
<?php if ($hasReport && ! $signedAt): ?>
<form class="d-inline-flex align-items-center gap-2 ms-2" method="post" action="<?= base_url('parent/report-cards/sign/' . $sid) ?>">
<?= csrf_field() ?>
<input type="text" name="signed_name" class="form-control form-control-sm" placeholder="Full name" required<?= $disabledAttr ?>>