337 lines
20 KiB
PHP
337 lines
20 KiB
PHP
<?= $this->extend('layout/management_layout') ?>
|
|
<?= $this->section('content') ?>
|
|
|
|
<div class="container-fluid py-4">
|
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
|
<div>
|
|
<h2 class="mb-1">Enrollment Administration</h2>
|
|
<div class="text-muted">Review school-year transition flags, exceptions, and placement follow-up.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (session()->getFlashdata('success')): ?>
|
|
<div class="alert alert-success"><?= esc(session()->getFlashdata('success')) ?></div>
|
|
<?php endif; ?>
|
|
<?php if (session()->getFlashdata('error')): ?>
|
|
<div class="alert alert-danger"><?= esc(session()->getFlashdata('error')) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="border rounded p-3 mb-3 bg-light">
|
|
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2">
|
|
<div>
|
|
<div class="fw-semibold">Registration Email Launch</div>
|
|
<?php if (!empty($launchState['approved'])): ?>
|
|
<div class="text-success small">Approved at <?= esc(local_datetime($launchState['approved_at'], 'm-d-Y H:i')) ?></div>
|
|
<?php elseif (!empty($launchState['missing'])): ?>
|
|
<div class="text-danger small">Missing: <?= esc(implode(', ', $launchState['missing'])) ?></div>
|
|
<?php else: ?>
|
|
<div class="text-muted small">Configuration is ready for launch approval.</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="d-flex flex-wrap gap-2 justify-content-end">
|
|
<?php if (!empty($previewParentId)): ?>
|
|
<a class="btn btn-outline-secondary" target="_blank" href="<?= site_url('administrator/enrollment-admin/email-preview?school_year=' . rawurlencode((string) $schoolYear) . '&parent_id=' . (int) $previewParentId) ?>">Preview Email</a>
|
|
<?php endif; ?>
|
|
<form method="post" action="<?= site_url('administrator/enrollment-admin/approve-launch') ?>">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="school_year" value="<?= esc($schoolYear ?? '') ?>">
|
|
<button type="submit" class="btn btn-success" <?= !empty($launchState['missing']) ? 'disabled' : '' ?>>Approve Launch</button>
|
|
</form>
|
|
<form method="post" action="<?= site_url('administrator/enrollment-admin/send-registration-emails') ?>" onsubmit="return confirm('Send real registration emails to parents for <?= esc((string) ($schoolYear ?? ''), 'js') ?>?');">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="school_year" value="<?= esc($schoolYear ?? '') ?>">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="checkbox" id="force_resend" name="force_resend" value="1">
|
|
<label class="form-check-label small" for="force_resend">Resend sent</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-danger" <?= empty($launchState['approved']) || !empty($launchState['missing']) || empty($emailExamples) ? 'disabled' : '' ?>>Send Real Emails</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h4 class="mb-3">Decision Email Examples</h4>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-sm table-bordered align-middle" data-no-mgmt-sticky>
|
|
<thead>
|
|
<tr>
|
|
<th>Parent</th>
|
|
<th>Recipient</th>
|
|
<th>Students</th>
|
|
<th>Subject</th>
|
|
<th>Delivery</th>
|
|
<th>Example</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (!empty($emailExamples)): ?>
|
|
<?php foreach ($emailExamples as $example): ?>
|
|
<?php
|
|
$deliveryStatus = (string) ($example['delivery_status'] ?? 'not sent');
|
|
$badgeClass = match ($deliveryStatus) {
|
|
'sent' => 'bg-success',
|
|
'failed' => 'bg-danger',
|
|
'generated' => 'bg-info text-dark',
|
|
default => 'bg-secondary',
|
|
};
|
|
?>
|
|
<tr>
|
|
<td><?= esc($example['parent_name'] ?? '') ?></td>
|
|
<td><?= esc(implode(', ', $example['recipients'] ?? [])) ?></td>
|
|
<td><?= esc(implode(', ', $example['student_names'] ?? [])) ?></td>
|
|
<td><?= esc($example['subject'] ?? '') ?></td>
|
|
<td>
|
|
<span class="badge <?= esc($badgeClass) ?>"><?= esc($deliveryStatus) ?></span>
|
|
<?php if (!empty($example['sent_at'])): ?>
|
|
<div class="small text-muted"><?= esc(local_datetime($example['sent_at'], 'm-d-Y H:i')) ?></div>
|
|
<?php endif; ?>
|
|
<?php if (!empty($example['failure_reason'])): ?>
|
|
<div class="small text-danger"><?= esc($example['failure_reason']) ?></div>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<a class="btn btn-sm btn-outline-secondary" target="_blank" href="<?= site_url('administrator/enrollment-admin/email-preview?school_year=' . rawurlencode((string) $schoolYear) . '&parent_id=' . (int) ($example['parent_user_id'] ?? 0)) ?>">View Example</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr>
|
|
<td colspan="6" class="text-center text-muted">No parent decision email examples found for this school year.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<form method="get" action="<?= site_url('administrator/enrollment-admin') ?>" class="row g-2 align-items-end mb-3">
|
|
<div class="col-md-3">
|
|
<label class="form-label" for="school_year">School Year</label>
|
|
<select class="form-select" id="school_year" name="school_year">
|
|
<?php foreach (($schoolYears ?? []) as $year): ?>
|
|
<?php $name = (string) ($year['name'] ?? ''); ?>
|
|
<option value="<?= esc($name) ?>" <?= $name === ($schoolYear ?? '') ? 'selected' : '' ?>><?= esc($name) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label" for="status">Status</label>
|
|
<select class="form-select" id="status" name="status">
|
|
<?php foreach (['open' => 'Open', 'resolved' => 'Resolved'] as $value => $label): ?>
|
|
<option value="<?= esc($value) ?>" <?= $value === ($status ?? '') ? 'selected' : '' ?>><?= esc($label) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label" for="flag_type">Flag Type</label>
|
|
<select class="form-select" id="flag_type" name="flag_type">
|
|
<option value="">All flag types</option>
|
|
<?php foreach (($flagTypes ?? []) as $type): ?>
|
|
<option value="<?= esc($type) ?>" <?= $type === ($flagType ?? '') ? 'selected' : '' ?>><?= esc($type) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label" for="assigned_to">Assigned To</label>
|
|
<select class="form-select" id="assigned_to" name="assigned_to">
|
|
<option value="">Anyone</option>
|
|
<?php foreach (($admins ?? []) as $admin): ?>
|
|
<?php
|
|
$adminId = (int) ($admin['id'] ?? 0);
|
|
$adminName = trim((string) ($admin['firstname'] ?? '') . ' ' . (string) ($admin['lastname'] ?? '')) ?: 'User #' . $adminId;
|
|
?>
|
|
<option value="<?= $adminId ?>" <?= (string) $adminId === (string) ($assignedTo ?? '') ? 'selected' : '' ?>><?= esc($adminName) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
|
</div>
|
|
</form>
|
|
|
|
<h4 class="mb-3">Enrollment Follow-up</h4>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-bordered table-striped align-middle" data-no-mgmt-sticky>
|
|
<thead>
|
|
<tr>
|
|
<th>Student</th>
|
|
<th>School ID</th>
|
|
<th>Enrollment Status</th>
|
|
<th>Decision</th>
|
|
<th>Placement</th>
|
|
<th>Class</th>
|
|
<th>Exception / Reason</th>
|
|
<th>Updated</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (!empty($enrollmentFollowups)): ?>
|
|
<?php foreach ($enrollmentFollowups as $row): ?>
|
|
<?php
|
|
$statusValue = (string) ($row['enrollment_status'] ?? '');
|
|
$placementValue = (string) ($row['placement_status'] ?? '');
|
|
$decisionValue = (string) ($row['deliberation_decision'] ?? '');
|
|
$statusClass = match (strtolower($statusValue)) {
|
|
'review & decision' => 'bg-warning text-dark',
|
|
'waitlist' => 'bg-info text-dark',
|
|
'denied' => 'bg-danger',
|
|
default => 'bg-secondary',
|
|
};
|
|
?>
|
|
<tr>
|
|
<td><?= esc($row['student_name'] ?? '') ?></td>
|
|
<td><?= esc($row['school_id'] ?? '') ?></td>
|
|
<td><span class="badge <?= esc($statusClass) ?>"><?= esc($statusValue) ?></span></td>
|
|
<td><?= esc($decisionValue !== '' ? $decisionValue : 'Pending') ?></td>
|
|
<td><?= esc($placementValue !== '' ? $placementValue : 'Pending') ?></td>
|
|
<td><?= esc($row['class_section_name'] ?? '') ?></td>
|
|
<td>
|
|
<?php if (!empty($row['exception_required'])): ?>
|
|
<span class="badge bg-warning text-dark">Exception</span>
|
|
<?php endif; ?>
|
|
<div class="small"><?= esc($row['exception_reason'] ?? '') ?></div>
|
|
</td>
|
|
<td><?= esc(!empty($row['updated_at']) ? local_datetime($row['updated_at'], 'm-d-Y H:i') : '') ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr>
|
|
<td colspan="8" class="text-center text-muted">No enrollment records need follow-up for this school year.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h4 class="mb-3">Enrollment Flags</h4>
|
|
<div class="table-responsive mb-4">
|
|
<table class="table table-bordered table-striped align-middle" data-no-mgmt-sticky>
|
|
<thead>
|
|
<tr>
|
|
<th>Student</th>
|
|
<th>School ID</th>
|
|
<th>Flag Type</th>
|
|
<th>Priority</th>
|
|
<th>Details</th>
|
|
<th>Assigned</th>
|
|
<th>Created</th>
|
|
<th style="min-width: 280px;">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (!empty($flags)): ?>
|
|
<?php foreach ($flags as $flag): ?>
|
|
<?php
|
|
$flagId = (int) ($flag['id'] ?? 0);
|
|
$flagTypeValue = (string) ($flag['flag_type'] ?? '');
|
|
$details = is_array($flag['details'] ?? null) ? $flag['details'] : [];
|
|
?>
|
|
<tr>
|
|
<td><?= esc($flag['student_name'] ?? '') ?></td>
|
|
<td><?= esc($flag['school_id'] ?? '') ?></td>
|
|
<td><span class="badge bg-secondary"><?= esc($flagTypeValue) ?></span></td>
|
|
<td><?= esc($flag['priority'] ?? 'normal') ?></td>
|
|
<td>
|
|
<?php if ($details !== []): ?>
|
|
<?php foreach ($details as $key => $value): ?>
|
|
<div><span class="text-muted"><?= esc((string) $key) ?>:</span> <?= esc(is_scalar($value) ? (string) $value : json_encode($value)) ?></div>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<span class="text-muted">No details</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?= esc($flag['assignee_name'] ?: '') ?></td>
|
|
<td><?= esc(!empty($flag['created_at']) ? local_datetime($flag['created_at'], 'm-d-Y H:i') : '') ?></td>
|
|
<td>
|
|
<?php if (($flag['status'] ?? '') === 'open'): ?>
|
|
<?php if ($flagTypeValue === 'CLASS_REASSIGNMENT_REQUIRED'): ?>
|
|
<form method="post" action="<?= site_url('administrator/enrollment-admin/flags/' . $flagId . '/assign-class') ?>" class="mb-2">
|
|
<?= csrf_field() ?>
|
|
<select class="form-select form-select-sm mb-2" name="class_section_id" required>
|
|
<option value="">Select class section</option>
|
|
<?php foreach (($classSections ?? []) as $section): ?>
|
|
<option value="<?= (int) ($section['class_section_id'] ?? 0) ?>"><?= esc($section['class_section_name'] ?? '') ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<input class="form-control form-control-sm mb-2" name="resolution_notes" placeholder="Reason / notes" required>
|
|
<button class="btn btn-sm btn-primary" type="submit">Assign Class</button>
|
|
</form>
|
|
<?php elseif ($flagTypeValue === 'PENDING_MAKE_UP_EXAM_PROMOTION'): ?>
|
|
<form method="post" action="<?= site_url('administrator/enrollment-admin/flags/' . $flagId . '/makeup-promotion') ?>" class="mb-2">
|
|
<?= csrf_field() ?>
|
|
<select class="form-select form-select-sm mb-2" name="exam_result" required>
|
|
<option value="">Exam result</option>
|
|
<option value="passed">Passed</option>
|
|
<option value="failed">Failed</option>
|
|
</select>
|
|
<select class="form-select form-select-sm mb-2" name="class_section_id">
|
|
<option value="">Promoted class section if passed</option>
|
|
<?php foreach (($classSections ?? []) as $section): ?>
|
|
<option value="<?= (int) ($section['class_section_id'] ?? 0) ?>"><?= esc($section['class_section_name'] ?? '') ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<input class="form-control form-control-sm mb-2" name="resolution_notes" placeholder="Resolution notes" required>
|
|
<button class="btn btn-sm btn-primary" type="submit">Resolve Exam</button>
|
|
</form>
|
|
<?php elseif (in_array($flagTypeValue, ['AGE_EXCEPTION_REQUIRED', 'LATE_REGISTRATION_EXCEPTION', 'FINANCIAL_REVIEW_REQUIRED', 'CLASS_CAPACITY_EXCEPTION_REQUIRED'], true)): ?>
|
|
<form method="post" action="<?= site_url('administrator/enrollment-admin/flags/' . $flagId . '/approve-exception') ?>" class="mb-2">
|
|
<?= csrf_field() ?>
|
|
<input class="form-control form-control-sm mb-2" name="reason" placeholder="Approval reason" required>
|
|
<button class="btn btn-sm btn-warning" type="submit">Approve Exception</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
|
|
<form method="post" action="<?= site_url('administrator/enrollment-admin/flags/' . $flagId . '/resolve') ?>">
|
|
<?= csrf_field() ?>
|
|
<input class="form-control form-control-sm mb-2" name="resolution_notes" placeholder="Resolution notes" required>
|
|
<button class="btn btn-sm btn-outline-secondary" type="submit">Resolve Manually</button>
|
|
</form>
|
|
<?php else: ?>
|
|
<div class="text-muted small"><?= esc($flag['resolution_notes'] ?? '') ?></div>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr>
|
|
<td colspan="8" class="text-center text-muted">No formal enrollment flags found. Check Enrollment Follow-up above for status-based items.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h4 class="mb-3">Recent Enrollment Audit</h4>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-bordered align-middle" data-no-mgmt-sticky>
|
|
<thead>
|
|
<tr>
|
|
<th>When</th>
|
|
<th>Student</th>
|
|
<th>Action</th>
|
|
<th>Administrator</th>
|
|
<th>Reason</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (!empty($auditRows)): ?>
|
|
<?php foreach ($auditRows as $row): ?>
|
|
<tr>
|
|
<td><?= esc(!empty($row['created_at']) ? local_datetime($row['created_at'], 'm-d-Y H:i') : '') ?></td>
|
|
<td><?= esc($row['student_name'] ?? '') ?></td>
|
|
<td><?= esc($row['action'] ?? '') ?></td>
|
|
<td><?= esc($row['performed_by_name'] ?? '') ?></td>
|
|
<td><?= esc($row['reason'] ?? '') ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr>
|
|
<td colspan="5" class="text-center text-muted">No enrollment audit records found. Audit rows appear after actions are completed from this dashboard or through the transition service.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<?= $this->endSection() ?>
|