recreate project

This commit is contained in:
root
2026-02-10 22:11:06 -05:00
commit 663c0cdbda
10149 changed files with 1379710 additions and 0 deletions
+286
View File
@@ -0,0 +1,286 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<!-- Flash Messages -->
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success">
<?= session()->getFlashdata('success') ?>
</div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger">
<?= session()->getFlashdata('error') ?>
</div>
<?php endif; ?>
<div class="container mt-5">
<!-- Button to toggle the display of previously saved parent information -->
<button class="btn btn-primary mb-4" type="button" data-bs-toggle="collapse" data-bs-target="#savedInfo"
aria-expanded="false" aria-controls="savedInfo" id="viewSecondParentBtn">
View Parent/AuthorizedUser Information
</button>
<!-- Collapsible section for the previously saved parent information -->
<div class="collapse" id="savedInfo">
<div class="card card-body">
<h4>Parent/Authorized User Information</h4>
<table class="table table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Relation</th>
<th>Phone</th>
<th>Status</th>
</tr>
</thead>
<tbody id="parentTable">
<!-- Rows will be dynamically populated here -->
</tbody>
</table>
</div>
</div>
<form action="<?= base_url('/parent/saveSecondParent') ?>" method="post" id="parentForm">
<?= csrf_field() ?>
<!-- First Name -->
<div class="row mb-3">
<div class="col-md-6">
<label for="secondParentFirstName" class="form-label fw-bold">First Name <span
style="color: red;">*</span></label>
<input type="text" class="form-control" id="secondParentFirstName" name="secondParentFirstName"
placeholder="First Name" value="<?= old('secondParentFirstName') ?>" pattern="[A-Za-z\s]+"
title="Letters only" required>
</div>
</div>
<!-- Last Name -->
<div class="row mb-3">
<div class="col-md-6">
<label for="secondParentLastName" class="form-label fw-bold">Last Name <span
style="color: red;">*</span></label>
<input type="text" class="form-control" id="secondParentLastName" name="secondParentLastName"
placeholder="Last Name" value="<?= old('secondParentLastName') ?>" pattern="[A-Za-z\s]+"
title="Letters only" required>
</div>
</div>
<!-- Email -->
<div class="row mb-3">
<div class="col-md-6">
<label for="secondParentEmail" class="form-label fw-bold">Email Address <span
style="color: red;">*</span></label>
<input type="email" class="form-control" id="secondParentEmail" name="secondParentEmail"
placeholder="Email Address" value="<?= old('secondParentEmail') ?>" required>
<small id="emailError" class="text-danger"></small>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="relationToStudent" class="form-label fw-bold">Relation To Student <span
style="color: red;">*</span></label>
<select id="relationToStudent" name="relationToStudent" class="form-select" required>
<option value="" disabled <?= old('relationToStudent') === null ? 'selected' : '' ?>>Select
Relation</option>
<option value="Husband" <?= old('relationToStudent') === 'Husband' ? 'selected' : '' ?>>Father
</option>
<option value="Wife" <?= old('relationToStudent') === 'Wife' ? 'selected' : '' ?>>Mother
</option>
<option value="Brother" <?= old('relationToStudent') === 'Brother' ? 'selected' : '' ?>>Brother
</option>
<option value="Sister" <?= old('relationToStudent') === 'Sister' ? 'selected' : '' ?>>Sister
</option>
</select>
</div>
</div>
<!-- Phone Number with Pattern Validation -->
<div class="row mb-3">
<div class="col-md-6">
<label for="secondParentCellPhone" class="form-label fw-bold">Phone Number <span
style="color: red;">*</span></label>
<input type="text" class="form-control" id="secondParentCellPhone" name="secondParentCellPhone"
placeholder="Phone Number (xxx)-xxx-xxxx" value="<?= old('secondParentCellPhone') ?>" required>
<small class="text-muted">Format: (xxx)-xxx-xxxx</small>
</div>
</div>
<!-- Submit Button -->
<div class="row">
<div class="col-md-6 d-flex justify-content-end">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
<br>
<?php include(__DIR__ . '/../partials/footer.php'); ?>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<!-- JavaScript for Phone and Email Validation -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const phoneInput = document.getElementById('secondParentCellPhone');
const emailInput = document.getElementById('secondParentEmail');
const firstNameInput = document.getElementById('secondParentFirstName');
const lastNameInput = document.getElementById('secondParentLastName');
const emailError = document.getElementById('emailError');
const nameError = document.createElement('small');
nameError.classList.add('text-danger');
const lastNameError = document.createElement('small');
lastNameError.classList.add('text-danger');
// Comprehensive domain extension list for validation
const validExtensions = [
'com', 'net', 'edu', 'org', 'gov', 'mil', 'int',
'biz', 'info', 'name', 'pro', 'aero', 'coop', 'museum',
'io', 'tech', 'ai', 'app', 'dev', 'xyz', 'store',
'us', 'uk', 'ca', 'au', 'de', 'fr', 'it', 'es', 'nl', 'se',
'co', 'tv', 'me', 'cc', 'ly', 'in', 'jp', 'cn', 'br', 'ru'
];
// Real-time validation for first and last names (no numbers allowed)
const namePattern = /^[a-zA-Z\s]+$/;
function validateName(input, errorElement, fieldName) {
if (!namePattern.test(input.value)) {
errorElement.textContent = `Please enter a valid ${fieldName} without numbers.`;
input.insertAdjacentElement('afterend', errorElement);
} else {
errorElement.textContent = '';
}
}
firstNameInput.addEventListener('input', function() {
validateName(firstNameInput, nameError, 'first name');
});
lastNameInput.addEventListener('input', function() {
validateName(lastNameInput, lastNameError, 'last name');
});
// Phone number input formatting
phoneInput.addEventListener('input', function(e) {
let input = phoneInput.value.replace(/\D/g, ''); // Remove non-digit characters
if (input.length > 3 && input.length <= 6) {
input = `(${input.substring(0, 3)})-${input.substring(3)}`;
} else if (input.length > 6) {
input = `(${input.substring(0, 3)})-${input.substring(3, 6)}-${input.substring(6, 10)}`;
} else if (input.length > 0) {
input = `(${input}`;
}
phoneInput.value = input;
});
// Email validation
emailInput.addEventListener('input', function() {
const emailValue = emailInput.value;
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const domainExtension = emailValue.split('.').pop(); // Get the domain extension
if (emailValue && !emailPattern.test(emailValue)) {
emailError.textContent = 'Please enter a valid email address.';
} else if (domainExtension && !validExtensions.includes(domainExtension)) {
emailError.textContent =
'Please enter an email with a valid domain extension (e.g., .com, .net, .edu).';
} else {
emailError.textContent = ''; // Clear error message if email is valid
}
});
// Form submission validation
document.getElementById('parentForm').addEventListener('submit', function(e) {
const phoneValue = phoneInput.value;
const emailValue = emailInput.value;
const domainExtension = emailValue.split('.').pop();
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const phonePattern = /^\(\d{3}\)-\d{3}-\d{4}$/;
// Ensure no numbers in the first or last name
if (!namePattern.test(firstNameInput.value)) {
e.preventDefault();
alert('Please enter a valid first name without numbers.');
}
if (!namePattern.test(lastNameInput.value)) {
e.preventDefault();
alert('Please enter a valid last name without numbers.');
}
if (!phonePattern.test(phoneValue)) {
e.preventDefault();
alert('Please enter a valid phone number in the format (xxx)-xxx-xxxx.');
}
if (!emailPattern.test(emailValue)) {
e.preventDefault();
alert('Please enter a valid email address.');
} else if (!validExtensions.includes(domainExtension)) {
e.preventDefault();
alert('Please enter an email with a valid domain extension (e.g., .com, .net, .edu).');
}
});
});
</script>
<script>
document.getElementById('viewSecondParentBtn').addEventListener('click', function() {
const xhr = new XMLHttpRequest();
xhr.open('GET', '<?= base_url('/parent/viewSecondParent') ?>', true);
xhr.onload = function() {
console.log('Response:', xhr.responseText); // Debugging: Log the raw response
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
if (response.error) {
alert(response.error); // Handle error messages
return;
}
const savedParent = response.savedParent;
// Clear existing rows in the table
const parentTable = document.getElementById('parentTable');
parentTable.innerHTML = ''; // Clear previous data
// Populate the table with each entry in savedParent
savedParent.forEach(parent => {
const row = `
<tr>
<td>${parent.firstName}</td>
<td>${parent.lastName}</t>
<td>${parent.email}</td>
<td>${parent.relation}</td>
<td>${parent.phone}</td>
<td>${parent.status || 'N/A'}</td> <!-- Status for authorized users -->
</tr>
`;
parentTable.innerHTML += row;
});
} catch (error) {
console.error('Error parsing JSON response:', error);
}
} else {
console.error('Failed to load parent and authorized user information. Status:', xhr.status);
}
};
xhr.onerror = function() {
console.error('An error occurred while fetching parent and authorized user information.');
};
xhr.send();
});
</script>
<?= $this->endSection() ?>
+139
View File
@@ -0,0 +1,139 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<!-- Sidebar -->
<nav class="col-md-3 col-lg-2 d-md-block bg-light sidebar">
<div class="sidebar-sticky pt-3">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">
<i class="bi bi-house-door"></i>
Dashboard
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/attendance">
<i class="bi bi-calendar-check"></i>
Attendance
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/register_kid_form">
<i class="bi bi-person-plus"></i>
Register Kids
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/enroll_classes">
<i class="bi bi-pencil-square"></i>
Enroll in Classes
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/payment">
<i class="bi bi-credit-card"></i>
Payment
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/messages">
<i class="bi bi-chat-dots"></i>
Messages
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/support">
<i class="bi bi-life-preserver"></i>
Support
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="calendar">
<i class="bi bi-calendar"></i>
Calendar
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/contact">
<i class="bi bi-telephone"></i>
Contact Us
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/scores">
<i class="bi bi-clipboard-data"></i>
Grades
</a>
</li>
</ul>
</div>
</nav>
<!-- Main Content -->
<main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="pt-3 pb-2 mb-3 border-bottom" style="margin-left: -2in;">
<h2>Assignment</h2>
<h5 class="h5 mt-2">Enroll your kids in the available classes for the upcoming term.</h5>
</div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success"><?= session()->getFlashdata('success') ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger"><?= session()->getFlashdata('error') ?></div>
<?php endif; ?>
<div class="table-responsive">
<form action="<?= base_url('/parent/enroll_classes_handler') ?>" method="post">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Select</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Gender</th>
<th>Grade</th>
</tr>
</thead>
<tbody>
<?php if (!empty($students)): ?>
<?php foreach ($students as $student): ?>
<tr>
<td>
<input type="checkbox" name="enroll[]" value="<?= $student['student_id'] ?>">
</td>
<td><?= $student['firstname'] ?></td>
<td><?= $student['lastname'] ?></td>
<td><?= $student['age'] ?></td>
<td><?= $student['gender'] ?></td>
<td><?= $student['grade'] ?></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="6">No students found. Please register your kids first.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<div class="form-group">
<label for="class_section_id">Select Class</label>
<select class="form-control" id="class_section_id" name="class_section_id" required>
<option value="">Select Class</option>
<?php foreach ($classes as $class): ?>
<option value="<?= $class['class_section_id'] ?>"><?= $class['class_name'] ?>
(<?= $class['schedule'] ?>)</option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="btn btn-primary">Enroll Selected Students</button>
</form>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>
+61
View File
@@ -0,0 +1,61 @@
<?= $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;">Attendance Record</h2>
</div>
<!-- Filter Form -->
<form action="" method="get" class="form-inline">
<div class="d-flex align-items-center">
<select name="school_year" id="school_year" class="form-control me-3"> <!-- Added me-3 (right margin) -->
<?php foreach ($schoolYears as $year): ?>
<option value="<?= esc($year['school_year']) ?>" <?= $selectedYear === $year['school_year'] ? 'selected' : '' ?>>
<?= esc($year['school_year']) ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-success">Filter</button>
</div>
</form>
<!-- Error Message -->
<?php if (isset($error)): ?>
<div class="alert alert-danger"><?= esc($error) ?></div>
<?php endif; ?>
<!-- Attendance Table (one record per row; no regrouping) -->
<?php if (!empty($attendance)): ?>
<table class="table table-striped table-bordered mt-3">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Date</th>
<th>Status</th>
<th>Reason</th>
</tr>
</thead>
<tbody>
<?php foreach ($attendance as $row): ?>
<?php $status = strtolower(trim((string)($row['status'] ?? ''))); ?>
<?php if ($status === 'absent' || $status === 'late'): ?>
<tr>
<td><?= esc($row['firstname'] ?? '') ?></td>
<td><?= esc($row['lastname'] ?? '') ?></td>
<td><?= esc(!empty($row['date']) ? local_date($row['date'], 'm-d-Y') : '') ?></td>
<td><?= esc($row['status'] ?? '') ?></td>
<td><?= esc($row['reason'] ?? '') ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<div class="alert alert-info mb-3 d-inline-block">No attendance records found for the selected school year.</div>
<?php endif; ?>
</main>
</div>
</div>
<?= $this->endSection() ?>
+76
View File
@@ -0,0 +1,76 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-xxl py-2">
<div class="container">
<h3 class="text-center text-danger mt-4 mb-3" style="font-family: Arial, sans-serif;">
Flip your phone for a zoomed out view of the calendar.
</h3>
<div class="d-flex align-items-center gap-3 mb-3">
<strong>Legend:</strong>
<span class="d-inline-flex align-items-center"><span style="display:inline-block;width:12px;height:12px;border-radius:3px;background:#3788d8;border:1px solid rgba(0,0,0,.2);margin-right:6px"></span>General Event</span>
<span class="d-inline-flex align-items-center"><span style="display:inline-block;width:12px;height:12px;border-radius:3px;background:#ffc107;border:1px solid rgba(0,0,0,.2);margin-right:6px"></span>No School Day</span>
</div>
<div class="main-content">
<div id="calendar-container">
<div id="calendar"></div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
const calendarEl = document.getElementById('calendar');
const isMobile = window.innerWidth <= 576;
const calendar = new FullCalendar.Calendar(calendarEl, {
initialView: isMobile ? 'listWeek' : 'dayGridMonth',
height: 'auto',
contentHeight: 'auto',
expandRows: true,
events: <?= json_encode($events) ?>,
eventDidMount: function(info) {
if (info.event.extendedProps.description) {
$(info.el).tooltip({
title: info.event.extendedProps.description,
placement: 'top',
trigger: 'hover',
container: 'body'
});
}
},
eventContent: function(arg) {
const event = arg.event;
const bg = event.extendedProps.backgroundColor || '#3788d8';
return {
html: `
<div style="
background-color: ${bg};
padding: 4px;
border-radius: 4px;
color: #fff;
font-size: 0.8rem;
text-align: center;">
${event.title}
</div>`
};
},
windowResize: function(view) {
if (window.innerWidth <= 576 && calendar.view.type !== 'listWeek') {
calendar.changeView('listWeek');
} else if (window.innerWidth > 576 && calendar.view.type !== 'dayGridMonth') {
calendar.changeView('dayGridMonth');
}
calendar.updateSize();
}
});
calendar.render();
window.calendar = calendar;
});
</script>
<?= $this->endSection() ?>
+86
View File
@@ -0,0 +1,86 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container py-4">
<div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
<div>
<h3 class="mb-0">Class Progress</h3>
<div class="text-muted">Review the weekly reports your childs teachers submit.</div>
</div>
<div class="text-end text-muted small">
Reports are grouped by Sunday; click any row to read the full details.
</div>
</div>
<?php if (! $hasSections): ?>
<div class="alert alert-info">
We couldnt find any current enrollment for your account. Once your child is assigned to a Sunday class, their teachers progress reports will appear here.
</div>
<?php endif; ?>
<?php if (empty($reportGroups)): ?>
<div class="alert alert-secondary">No reports submitted yet.</div>
<?php else: ?>
<div class="card shadow-sm">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light">
<tr>
<th>Week</th>
<th>Subjects</th>
<th class="text-end">Details</th>
</tr>
</thead>
<tbody>
<?php foreach ($reportGroups as $group): ?>
<?php
$start = $group['week_start'] ?? '';
$end = $group['week_end'] ?? '';
$weekLabel = $start ? date('M d, Y', strtotime($start)) : '-';
if ($end) {
$weekLabel .= ' ' . date('M d, Y', strtotime($end));
}
$reports = $group['reports'] ?? [];
$exampleReport = $reports ? reset($reports) : null;
?>
<tr>
<td>
<div class="fw-semibold"><?= esc($weekLabel) ?></div>
<?php if (!empty($group['class_section_name'])): ?>
<div class="text-muted small">Class: <?= esc($group['class_section_name']) ?></div>
<?php endif; ?>
</td>
<td>
<div class="d-flex flex-column gap-2">
<?php foreach ($subjectSections as $slug => $section): ?>
<?php
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
$report = $reports[$subjectName] ?? null;
$statusLabel = $report ? ($report['status_label'] ?? 'Unknown') : 'No submission';
$badgeClass = $report ? 'bg-secondary' : 'bg-light text-muted';
?>
<div class="border rounded-3 p-2">
<div class="d-flex justify-content-between align-items-center">
<strong class="small mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
<span class="badge <?= esc($badgeClass) ?>"><?= esc($statusLabel) ?></span>
</div>
<div class="small text-muted">
<?= $report ? esc($report['unit_title'] ?: '-') : 'No submission' ?>
</div>
</div>
<?php endforeach; ?>
</div>
</td>
<td class="text-end">
<?php if ($exampleReport): ?>
<a href="<?= base_url('parent/progress/view/' . $exampleReport['id']) ?>" class="btn btn-sm btn-outline-primary">View Weekly Details</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
</div>
<?= $this->endSection() ?>
+136
View File
@@ -0,0 +1,136 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container py-4">
<div class="d-flex align-items-center justify-content-between mb-3">
<div>
<h3 class="mb-0">Progress Report</h3>
<div class="text-muted">
<?= esc($row['class_section_name'] ?? '-') ?> • <?= esc($row['week_start'] ?? '-') ?>
</div>
</div>
<a href="<?= base_url('parent/progress') ?>" class="btn btn-outline-secondary">Back</a>
</div>
<?php
$weeklyReports = $weeklyReports ?? [];
$subjectSections = $subjectSections ?? [];
$reportsBySubject = [];
$attachments = [];
foreach ($weeklyReports as $report) {
$reportsBySubject[$report['subject']] = $report;
foreach (($report['attachments'] ?? []) as $attachment) {
$attachments[] = [
'subject' => $report['subject'] ?? 'Attachment',
'attachment' => $attachment,
'report_id' => $report['id'] ?? null,
];
}
}
?>
<div class="row g-3">
<div class="col-lg-8">
<?php foreach ($subjectSections as $slug => $section): ?>
<?php
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
$isQuran = $subjectName === 'Quran/Arabic';
$unitLabel = $isQuran ? 'Surah / Custom Arabic' : 'Unit / Chapter';
$homeworkLabel = $isQuran ? 'Arabic Practice / Homework' : 'Assigned Homework';
$report = $reportsBySubject[$subjectName] ?? null;
?>
<div class="card shadow-sm mb-3">
<div class="card-header bg-white d-flex align-items-center justify-content-between">
<strong class="mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
</div>
<div class="card-body">
<?php if (! $report): ?>
<div class="text-muted">No entry submitted for this subject this week.</div>
<?php else: ?>
<?php if (!empty($report['materials'])): ?>
<div class="mb-2"><strong>Materials:</strong> <?= esc($report['materials']) ?></div>
<?php endif; ?>
<div class="mb-2"><strong><?= $unitLabel ?>:</strong> <?= esc($report['unit_title'] ?: '-') ?></div>
<div class="mb-3">
<strong>Activities / Notes</strong>
<div class="mt-1"><?= nl2br(esc($report['covered'] ?? '-')) ?></div>
</div>
<div class="mb-3">
<strong><?= $homeworkLabel ?>:</strong>
<div class="mt-1"><?= nl2br(esc($report['homework'] ?: '-')) ?></div>
</div>
<?php if (!empty($report['attachments'])): ?>
<div class="mt-3">
<strong>Attachments:</strong>
<div class="d-flex flex-column gap-2 mt-2">
<?php foreach ($report['attachments'] as $attachment): ?>
<?php
$linkId = $attachment['id'] ?? $report['id'];
$link = !empty($attachment['legacy'])
? base_url('parent/progress/attachment/' . $linkId)
: base_url('parent/progress/attachment-file/' . $linkId);
?>
<a class="btn btn-sm btn-outline-secondary text-start" href="<?= $link ?>" target="_blank" rel="noreferrer">
<?= esc($attachment['name'] ?? 'Attachment') ?>
</a>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="col-lg-4">
<div class="card shadow-sm mb-3">
<div class="card-header bg-white"><strong>Summary</strong></div>
<div class="card-body">
<div class="mb-2"><strong>Teacher:</strong> <?= esc($row['teacher_name'] ?? '-') ?></div>
<div class="mb-2"><strong>Submitted:</strong> <?= esc($row['created_at'] ? date('M d, Y g:i A', strtotime($row['created_at'])) : '-') ?></div>
<?php if (!empty($row['status_label'])): ?>
<div><strong>Status:</strong> <?= esc($row['status_label']) ?></div>
<?php endif; ?>
</div>
</div>
<?php if (!empty($row['flags'])): ?>
<div class="card shadow-sm mb-3">
<div class="card-header bg-white"><strong>Highlights</strong></div>
<div class="card-body">
<div class="d-flex flex-wrap gap-2">
<?php foreach ($row['flags'] as $flag): ?>
<span class="badge bg-info text-dark"><?= esc(str_replace('_', ' ', $flag)) ?></span>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($attachments)): ?>
<div class="card shadow-sm">
<div class="card-header bg-white"><strong>Attachments</strong></div>
<div class="card-body">
<?php foreach ($attachments as $entry): ?>
<?php
$attachment = $entry['attachment'] ?? [];
$linkId = $attachment['id'] ?? ($entry['report_id'] ?? null);
if (!$linkId) {
continue;
}
$link = !empty($attachment['legacy'])
? base_url('parent/progress/attachment/' . $linkId)
: base_url('parent/progress/attachment-file/' . $linkId);
$label = trim(($entry['subject'] ?? 'Attachment') . ' • ' . ($attachment['name'] ?? 'Attachment'));
?>
<a class="btn btn-outline-primary w-100 text-start mb-2" href="<?= $link ?>" target="_blank" rel="noreferrer">
<?= esc($label) ?>
</a>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?= $this->endSection() ?>
+138
View File
@@ -0,0 +1,138 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<!-- Sidebar -->
<nav class="col-md-3 col-lg-2 d-md-block bg-light sidebar">
<div class="sidebar-sticky pt-3">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">
<i class="bi bi-house-door"></i>
Dashboard
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/attendance">
<i class="bi bi-calendar-check"></i>
Attendance
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/register_kid_form">
<i class="bi bi-person-plus"></i>
Register Kids
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/enroll_classes">
<i class="bi bi-pencil-square"></i>
Enroll in Classes
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/payment">
<i class="bi bi-credit-card"></i>
Payment
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/messages">
<i class="bi bi-chat-dots"></i>
Messages
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/support">
<i class="bi bi-life-preserver"></i>
Support
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="calendar">
<i class="bi bi-calendar"></i>
Calendar
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/contact">
<i class="bi bi-telephone"></i>
Contact Us
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/parent/scores">
<i class="bi bi-clipboard-data"></i>
Grades
</a>
</li>
</ul>
</div>
</nav>
<!-- Main Content -->
<main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="pt-3 pb-2 mb-3 border-bottom" style="margin-left: -2in;">
<h2>Enroll in Classes</h2>
<h5 class="h5 mt-2">Enroll your kids in the available classes for the upcoming term.</h5>
</div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success"><?= session()->getFlashdata('success') ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger"><?= session()->getFlashdata('error') ?></div>
<?php endif; ?>
<div class="table-responsive">
<form action="<?= base_url('/parent/enroll_classes_handler') ?>" method="post">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Select</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Gender</th>
<th>Grade</th>
</tr>
</thead>
<tbody>
<?php if (!empty($students)): ?>
<?php foreach ($students as $student): ?>
<tr>
<td>
<input type="checkbox" name="enroll[]" value="<?= $student['student_id'] ?>">
</td>
<td><?= $student['firstname'] ?></td>
<td><?= $student['lastname'] ?></td>
<td><?= $student['age'] ?></td>
<td><?= $student['gender'] ?></td>
<td><?= $student['grade'] ?></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="6">No students found. Please register your kids first.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<div class="form-group">
<label for="class_section_id">Select Class</label>
<select class="form-control" id="class_section_id" name="class_section_id" required>
<option value="">Select Class</option>
<?php foreach ($classes as $class): ?>
<option value="<?= $class['class_section_id'] ?>"><?= $class['class_name'] ?>
(<?= $class['schedule'] ?>)</option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="btn btn-primary">Enroll Selected Students</button>
</form>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>
+112
View File
@@ -0,0 +1,112 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-xxl bg-white p-0">
<!-- Contact Start -->
<div class="container-xxl py-5">
<div class="container">
<div class="text-center mx-auto mb-5 wow fadeInUp" data-wow-delay="0.1s" style="max-width: 600px;">
<h1 class="mb-3">Get In Touch</h1>
<p>Get in touch with us today to learn more about our programs and how you can get involved.</p>
</div>
<div class="row g-4 mb-5">
<div class="col-md-6 col-lg-4 text-center wow fadeInUp" data-wow-delay="0.1s">
<div class="bg-light rounded-circle d-inline-flex align-items-center justify-content-center mb-4"
style="width: 75px; height: 75px;">
<i class="fa fa-map-marker-alt fa-2x text-success"></i>
</div>
<h6>5 Courthouse Lane, Chelmsford, MA 01824</h6>
</div>
<div class="col-md-6 col-lg-4 text-center wow fadeInUp" data-wow-delay="0.3s">
<div class="bg-light rounded-circle d-inline-flex align-items-center justify-content-center mb-4"
style="width: 75px; height: 75px;">
<i class="fa fa-envelope-open fa-2x text-success"></i>
</div>
<h6>alrahma.isgl@gmail.com</h6>
</div>
<div class="col-md-6 col-lg-4 text-center wow fadeInUp" data-wow-delay="0.5s">
<div class="bg-light rounded-circle d-inline-flex align-items-center justify-content-center mb-4"
style="width: 75px; height: 75px;">
<i class="fa fa-phone-alt fa-2x text-success"></i>
</div>
<h6>+1 978-364-0219</h6>
</div>
</div>
<div class="bg-light rounded">
<div class="row g-0">
<div class="col-lg-6 wow fadeIn" data-wow-delay="0.1s">
<div class="h-100 d-flex flex-column justify-content-center p-5">
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success">
<?= session()->getFlashdata('success') ?>
</div>
<?php endif; ?>
<?php if (isset($validation)): ?>
<div class="alert alert-danger">
<?= $validation->listErrors() ?>
</div>
<?php endif; ?>
<form action="<?= base_url('/parent/contact/submit') ?>" method="post">
<div class="row g-3">
<div class="col-sm-6">
<div class="form-floating">
<input type="text" class="form-control border-0" id="name" name="name"
placeholder="Your Name" value="<?= set_value('name') ?>" required>
<label for="name">Your Name</label>
</div>
</div>
<div class="col-sm-6">
<div class="form-floating">
<input type="email" class="form-control border-0" id="email"
name="email" placeholder="Your Email"
value="<?= set_value('email') ?>" required>
<label for="email">Your Email</label>
</div>
</div>
<div class="col-12">
<div class="form-floating">
<input type="text" class="form-control border-0" id="subject"
name="subject" placeholder="Subject"
value="<?= set_value('subject') ?>" required>
<label for="subject">Subject</label>
</div>
</div>
<div class="col-12">
<div class="form-floating">
<textarea class="form-control border-0"
placeholder="Leave a message here" id="message" name="message"
style="height: 100px"
required><?= set_value('message') ?></textarea>
<label for="message">Message</label>
</div>
</div>
<div class="col-12">
<button class="btn btn-success w-100 py-3" type="submit">Send
Message</button>
</div>
</div>
</form>
</div>
</div>
<div class="col-lg-6 wow fadeIn" data-wow-delay="0.5s" style="min-height: 400px;">
<div class="position-relative h-100">
<iframe class="position-relative rounded w-100 h-100"
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2949.902891223497!2d-71.3606721845427!3d42.59682637917086!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89e3a489bb344a85%3A0xeaba1b29330726cb!2s5%20Courthouse%20Ln%2C%20Chelmsford%2C%20MA%2001824%2C%20USA!5e0!3m2!1sen!2sbd!4v1627993075161!5m2!1sen!2sbd"
frameborder="0" style="min-height: 400px; border:0;" allowfullscreen=""
aria-hidden="false" tabindex="0"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Contact End -->
<!-- Back to Top -->
<a href="#" class="btn btn-lg btn-success btn-lg-square back-to-top"><i class="bi bi-arrow-up"></i></a>
</div>
<?= $this->endSection() ?>
@@ -0,0 +1,93 @@
<?php
$fullName = trim($contact['emergency_contact_name'] ?? '');
$nameParts = explode(' ', $fullName, 2);
$firstName = $nameParts[0] ?? '';
$lastName = $nameParts[1] ?? '';
?>
<div class="modal fade" id="editEmergencyContact<?= $contact['id'] ?>" tabindex="-1" aria-labelledby="editEmergencyContactLabel<?= $contact['id'] ?>" aria-hidden="true">
<div class="modal-dialog">
<form method="post" action="<?= site_url('parent/edit_emergency_contact/' . $contact['id']) ?>" onsubmit="return validateEmergencyContactForm(<?= $contact['id'] ?>)">
<?= csrf_field() ?>
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editEmergencyContactLabel<?= $contact['id'] ?>">Edit Emergency Contact</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- First Name -->
<div class="form-group mb-3">
<label for="emergencyFirstName<?= $contact['id'] ?>">First Name</label>
<input type="text"
id="emergencyFirstName<?= $contact['id'] ?>"
name="emergency_first_name"
class="form-control"
value="<?= esc($firstName) ?>"
required
maxlength="30"
title="Only letters, spaces, hyphens, and apostrophes allowed">
</div>
<!-- Last Name -->
<div class="form-group mb-3">
<label for="emergencyLastName<?= $contact['id'] ?>">Last Name</label>
<input type="text"
id="emergencyLastName<?= $contact['id'] ?>"
name="emergency_last_name"
class="form-control"
value="<?= esc($lastName) ?>"
required
maxlength="30"
title="Only letters, spaces, hyphens, and apostrophes allowed">
</div>
<!-- Phone -->
<div class="form-group mb-3">
<label for="cellPhone<?= $contact['id'] ?>">Cell Phone</label>
<input type="tel"
id="cellPhone<?= $contact['id'] ?>"
name="cellphone"
class="form-control"
value="<?= esc($contact['cellphone']) ?>"
required
maxlength="14"
inputmode="numeric"
title="Enter a valid 10-digit phone number">
</div>
<!-- Email -->
<div class="form-group mb-3">
<label for="email<?= $contact['id'] ?>">Email</label>
<input type="email"
id="email<?= $contact['id'] ?>"
name="email"
class="form-control"
value="<?= esc($contact['email'] ?? '') ?>"
required
maxlength="50"
title="Enter a valid email address">
</div>
<!-- Relation -->
<div class="form-group mb-3">
<label for="relation<?= $contact['id'] ?>">Relation</label>
<input type="text"
id="relation<?= $contact['id'] ?>"
name="relation"
class="form-control"
value="<?= esc($contact['relation']) ?>"
required
maxlength="30"
title="Only letters, spaces, hyphens, and apostrophes allowed">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Save Changes</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</form>
</div>
</div>
+94
View File
@@ -0,0 +1,94 @@
<?php
// add this *inside* your foreach loop
$modalId = "editStudentModal{$student['id']}";
$formId = "studentEditForm{$student['id']}";
$actionUrl = site_url('parent/edit_student/' . $student['id']);
?>
<!--–––– MODAL ––––-->
<div class="modal fade" id="<?= $modalId ?>" tabindex="-1" aria-labelledby="<?= $modalId ?>Label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<!-- one form only -->
<form method="post"
action="<?= $actionUrl ?>"
id="<?= $formId ?>"
class="student-edit-form needs-live-validation">
<?= csrf_field() ?>
<div class="modal-header">
<h5 class="modal-title" id="<?= $modalId ?>Label">
Edit Student: <?= esc($student['firstname'] . ' ' . $student['lastname']) ?>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- First / Last -->
<div class="row mb-2">
<div class="col-md-6">
<label class="form-label">First Name</label>
<input type="text" name="firstname" class="form-control" value="<?= esc($student['firstname']) ?>" maxlength="30" required>
</div>
<div class="col-md-6">
<label class="form-label">Last Name</label>
<input type="text" name="lastname" class="form-control" value="<?= esc($student['lastname']) ?>" maxlength="30" required>
</div>
</div>
<!-- DOB / Gender -->
<div class="row mb-2">
<div class="col-md-6">
<label class="form-label">Date of Birth</label>
<input type="date" name="dob" class="form-control" value="<?= esc($student['dob']) ?>" required>
</div>
<div class="col-md-6">
<label class="form-label">Gender</label>
<select name="gender" class="form-select" required>
<option value="">-- Select --</option>
<option value="Male" <?= strtolower($student['gender']) === 'male' ? 'selected' : '' ?>>Male</option>
<option value="Female" <?= strtolower($student['gender']) === 'female' ? 'selected' : '' ?>>Female</option>
</select>
</div>
</div>
<!-- Allergies / Conditions -->
<div class="row mb-2">
<div class="col-md-6">
<label class="form-label">Allergies (comma-separated)</label>
<input type="text" name="allergies" class="form-control"
value="<?= esc(is_array($student['allergies']) ? implode(', ', $student['allergies']) : $student['allergies']) ?>">
</div>
<div class="col-md-6">
<label class="form-label">Medical Conditions (comma-separated)</label>
<input type="text" name="medical_conditions" class="form-control"
value="<?= esc(is_array($student['medical_conditions']) ? implode(', ', $student['medical_conditions']) : $student['medical_conditions']) ?>">
</div>
</div>
<!-- Consent / Grade -->
<div class="row mb-2">
<div class="col-md-6">
<label class="form-label">Photo Consent</label>
<select name="photo_consent" class="form-select" required>
<option value="">-- Select --</option>
<option value="1" <?= $student['photo_consent'] ? 'selected' : '' ?>>Yes</option>
<option value="0" <?= !$student['photo_consent'] ? 'selected' : '' ?>>No</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Registration Grade</label>
<input type="text" name="registration_grade" class="form-control" value="<?= esc($student['registration_grade']) ?>" required>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">
<i class="fas fa-save"></i> Save Changes
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</form>
</div>
</div>
</div>
+254
View File
@@ -0,0 +1,254 @@
<?= $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>
</div>
<!-- School Year Filter -->
<form action="<?= base_url('/parent/enroll_classes') ?>" method="get" class="form-inline mb-3">
<div class="d-flex align-items-center">
<select name="school_year" id="school_year" class="form-control me-3">
<?php foreach ($schoolYears as $year): ?>
<option value="<?= esc($year['school_year']) ?>" <?= $selectedYear === $year['school_year'] ? 'selected' : '' ?>>
<?= esc($year['school_year']) ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-success">Filter</button>
</div>
</form>
<?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
?>
<!-- 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 (!empty($students)): ?>
<form action="<?= base_url('/parent/enroll_classes_handler') ?>" method="post">
<?= csrf_field() ?>
<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>Enroll</th>
<th>Withdraw</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($students as $index => $student): ?>
<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>
<!-- Enroll Checkbox -->
<td>
<?php if ($student['enrollment_status'] === 'not enrolled'): ?>
<?php $disableEnrollUI = $deadlinePassed || !$isEditable; ?>
<input type="checkbox"
name="enroll[]"
value="<?= esc($student['id']) ?>"
<?= $disableEnrollUI ? 'disabled' : '' ?>>
<?php elseif (in_array($student['enrollment_status'], ['enrolled', 'admission under review', '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 '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 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; ?>
<!-- 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) ?>");
// Bootstrap Modal
const modalEl = document.getElementById('deadlineModal');
const deadlineModal = modalEl ? new bootstrap.Modal(modalEl) : null;
const showDeadlineModal = () => {
if (deadlineModal) deadlineModal.show();
};
// 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();
}
});
});
// 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 (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() ?>
+15
View File
@@ -0,0 +1,15 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="alert alert-danger mt-4">
<h4 class="alert-heading">Failure!</h4>
<p>There was an issue enrolling the students. Please try again later.</p>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>
+22
View File
@@ -0,0 +1,22 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="alert alert-success mt-4">
<h4 class="alert-heading">Success!</h4>
<p>The student(s) has/have been successfully enrolled.</p>
<p>You will be redirected to the enroll page shortly...</p>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
setTimeout(function() {
window.location.href = "<?= base_url('/parent/enroll_classes'); ?>";
}, 5000); // 2500 milliseconds = 2.5 seconds
</script>
<?= $this->endSection() ?>
+100
View File
@@ -0,0 +1,100 @@
<?= $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;">Events
<span class="badge bg-info"><?= count($activeEvents) ?></span>
</h3>
<!-- Flash messages -->
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success">
<?= session()->getFlashdata('success') ?>
</div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger">
<?= session()->getFlashdata('error') ?>
</div>
<?php endif; ?>
<?php if (empty($activeEvents)): ?>
<div class="alert alert-info mb-3 d-inline-block">
There are no active events at this time.
</div>
<?php else: ?>
<?php foreach ($activeEvents as $event): ?>
<div class="card mb-4">
<div class="card-body">
<!-- Event Title -->
<h5 class="card-title">
<?= esc($event['event_name']) ?>
<small class="text-muted">(Expires: <?= esc(!empty($event['expiration_date']) ? local_date($event['expiration_date'], 'm-d-Y') : '') ?>)</small>
</h5>
<!-- Image -->
<div class="text-center mb-3">
<?php if ($event['flyer']): ?>
<img src="<?= base_url('uploads/' . $event['flyer']) ?>" class="img-fluid" alt="Event Flyer">
<?php else: ?>
<div class="text-muted">No Flyer</div>
<?php endif; ?>
</div>
<!-- Event Description -->
<p class="card-text"><?= esc($event['description']) ?></p>
<!-- Participation Table -->
<form method="post" action="<?= site_url('parent/updateParticipation') ?>">
<?= csrf_field() ?>
<input type="hidden" name="event_id" value="<?= $event['id'] ?>">
<div class="table-responsive">
<table class="table table-sm table-bordered">
<thead class="table-light">
<tr>
<th>Student First Name</th>
<th>Student Last Name</th>
<th class="text-center">Participate</th>
</tr>
</thead>
<tbody>
<?php foreach ($yourStudents as $student): ?>
<?php
$key = $student['id'] . ':' . $event['id'];
$current = $charges[$key]['participation'] ?? '';
?>
<tr>
<td><?= esc($student['firstname']) ?></td>
<td><?= esc($student['lastname']) ?></td>
<td class="text-center align-middle">
<div class="d-inline-flex align-items-center gap-3">
<div class="form-check">
<input class="form-check-input" type="radio"
name="participation[<?= $key ?>]" value="yes"
<?= $current === 'yes' ? 'checked' : '' ?>>
<label class="form-check-label">Yes</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio"
name="participation[<?= $key ?>]" value="no"
<?= $current === 'no' ? 'checked' : '' ?>>
<label class="form-check-label">No</label>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<button type="submit" class="btn btn-primary mt-2">Save</button>
</form>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?= $this->endSection() ?>
+173
View File
@@ -0,0 +1,173 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<?php
// ---- Local helper: parse DB date/datetime safely and convert to display TZ ----
if (!function_exists('parseDbDateTime')) {
/**
* @param mixed $raw String "Y-m-d H:i:s" or "Y-m-d", DateTimeInterface, or null
* @param string $sourceTz Timezone of stored value (DB). Default: UTC
* @param string|null $displayTz Target timezone (defaults to user_timezone() or configured school timezone)
* @param string|null $defaultTime If $raw is date-only, set this default time ("HH:MM:SS") or null to keep 00:00:00
*/
function parseDbDateTime($raw, string $sourceTz = 'UTC', ?string $displayTz = null, ?string $defaultTime = null): ?DateTime
{
if (!$raw) return null;
// Resolve display timezone dynamically if not provided
if ($displayTz === null || $displayTz === '') {
try {
$displayTz = (string) (config('School')->attendance['timezone'] ?? user_timezone());
} catch (Throwable $e) {
$displayTz = user_timezone();
}
}
if ($raw instanceof DateTimeInterface) {
$dt = new DateTime('@' . $raw->getTimestamp());
return $dt->setTimezone(new DateTimeZone($displayTz));
}
$s = trim((string)$raw);
if ($s === '' || preg_match('/^0{4}-0{2}-0{2}/', $s)) return null;
$srcTz = new DateTimeZone($sourceTz);
$outTz = new DateTimeZone($displayTz);
// Try full datetime first
$dt = DateTime::createFromFormat('Y-m-d H:i:s', $s, $srcTz);
if ($dt !== false) {
return $dt->setTimezone($outTz);
}
// Try date-only
$d = DateTime::createFromFormat('Y-m-d', $s, $srcTz);
if ($d !== false) {
if ($defaultTime) {
[$H, $i, $sec] = array_map('intval', explode(':', $defaultTime));
$d->setTime($H, $i, $sec);
} // else leave 00:00:00
return $d->setTimezone($outTz);
}
// Fallback parser
try {
$fallback = new DateTime($s, $srcTz);
return $fallback->setTimezone($outTz);
} catch (Throwable $e) {
return null;
}
}
}
?>
<div class="container my-5">
<h3 class="text-center text-success" style="font-family: Arial, sans-serif;">Invoices and Payments</h3>
</div>
<!-- School Year Filter -->
<form action="<?= base_url('/parent/invoice_payment') ?>" method="get" class="form-inline mb-3">
<div class="d-flex align-items-center justify-content-center">
<select name="school_year" id="school_year" class="form-control me-3">
<?php foreach ($schoolYears as $year): ?>
<option value="<?= esc($year['school_year']) ?>"
<?= ($selectedYear === $year['school_year']) ? 'selected' : '' ?>
<?= ($currentSchoolYear === $year['school_year']) ? 'data-current="true"' : '' ?>>
<?= esc($year['school_year']) ?><?= ($currentSchoolYear === $year['school_year']) ? ' (Current)' : '' ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-success">Filter</button>
</div>
</form>
<!-- Display Payment Notice / Deadline -->
<?php
$displayTz = user_timezone();
$deadline = parseDbDateTime($dueDate, 'UTC', $displayTz); // format either DATE or DATETIME safely
?>
<div class="alert alert-info mb-3 d-inline-block" style="display: inline-block; width: auto; padding: 10px;">
<ul class="mb-0">
<li>
This website release version does not have an option to pay your invoice online.
All payments this school year will be made in person on first day of school
(<strong><?= esc($deadline ? $deadline->format('m-d-Y') : 'TBD') ?></strong>).
</li>
<li>
Cash, checks and debit/credit cards are all accepted forms of payment. However, if you elect to pay in
installments, only cash and checks will be accepted.
</li>
</ul>
</div>
<!-- Invoice Table -->
<?php if (!empty($invoices)): ?>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>#</th>
<th>Invoice Number</th>
<th>Issue Date</th>
<th>Due Date</th>
<th>Balance</th>
<th>Last Payment Amount</th>
<th>Last Payment Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($invoices as $index => $invoice): ?>
<?php
$issueDt = parseDbDateTime($invoice['issue_date'] ?? null, 'UTC', $displayTz); // assume stored UTC
$dueDt = parseDbDateTime($invoice['due_date'] ?? null, 'UTC', $displayTz, '12:00:00'); // if date-only, set noon
$lastPay = parseDbDateTime($invoice['last_payment_date'] ?? null, 'UTC', $displayTz);
?>
<tr>
<td><?= (int)$index + 1 ?></td>
<td><?= esc($invoice['invoice_number']) ?></td>
<td><?= $issueDt ? esc($issueDt->format('m-d-Y h:i A')) : '—' ?></td>
<td><?= $dueDt ? esc($dueDt->format('m-d-Y')) : '—' ?></td>
<td>$<?= number_format((float)($invoice['balance'] ?? 0), 2) ?></td>
<td>$<?= number_format((float)($invoice['last_paid_amount'] ?? 0), 2) ?></td>
<td><?= $lastPay ? esc($lastPay->format('m-d-Y h:i A')) : '—' ?></td>
<td><?= esc($invoice['status'] ?? '') ?></td>
<td>
<a href="<?= base_url('invoice/pdf/' . (int)($invoice['id'] ?? 0)) ?>" target="_blank"
class="btn btn-info btn-sm external-link">View/Print PDF</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="alert alert-info mb-3 d-inline-block">
No invoice found for the selected school year.
</div>
<?php endif; ?>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
const dropdown = document.getElementById('school_year');
const options = dropdown.options;
for (let i = 0; i < options.length; i++) {
if (options[i].dataset.current === "true") {
options[i].style.fontWeight = 'bold';
if (!dropdown.value) dropdown.selectedIndex = i;
break;
}
}
});
function showPaymentDevelopmentMessage(event) {
event.preventDefault();
alert('The payment method is currently under development. Please contact the school administration at alrahma.isgl@gmail.com');
}
</script>
<?= $this->endSection() ?>
+13
View File
@@ -0,0 +1,13 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container mt-5">
<div class="alert alert-info mb-3 d-inline-block">
No students found. Please register your child first. To do so, click the button below.
</div>
<div class="d-block"> <!-- Force new line -->
<a href="<?= site_url('/parent/child_register') ?>" class="btn btn-primary">Register Student</a>
</div>
</div>
<?= $this->endSection() ?>
+69
View File
@@ -0,0 +1,69 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<main class="col-12 px-md-4">
<div class="pt-3 pb-2 mb-3 dashboard-title">
<h1 class="h2">Messages</h1>
<h5 class="h5 mt-2">Send and receive messages from teachers and school administrators.</h5>
</div>
<!-- Section to display received messages -->
<div class="mb-4">
<h3>Received Messages</h3>
<?php if (!empty($receivedMessages)): ?>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Message Number</th>
<th scope="col">From</th>
<th scope="col">Subject</th>
<th scope="col">Message</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
<?php foreach ($receivedMessages as $message): ?>
<tr>
<td><?= $message['message_number'] ?></td>
<td><?= $message['sender_name'] ?></td>
<td><?= $message['subject'] ?></td>
<td><?= $message['message'] ?></td>
<td><?= !empty($message['date_sent']) ? esc(local_datetime($message['date_sent'], 'm-d-Y H:i')) : '' ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<p>No messages found.</p>
<?php endif; ?>
</div>
<!-- Section to send new messages -->
<div class="mb-4">
<h3>Send a Message</h3>
<form action="<?= base_url('messages/send') ?>" method="post">
<div class="form-group">
<label for="recipient">Recipient</label>
<select class="form-control" id="recipient" name="recipient" required>
<option value="teacher">Teacher</option>
<option value="administration">Administration</option>
</select>
</div>
<div class="form-group">
<label for="subject">Subject</label>
<input type="text" class="form-control" id="subject" name="subject" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea class="form-control" id="message" name="message" rows="4" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Message</button>
</form>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>
+20
View File
@@ -0,0 +1,20 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="pt-3 pb-2 mb-3" style="margin-left: -2in;">
<h1 class="h2">Payment Success</h1>
<h5 class="h5 mt-2">Your tuition fees have been successfully paid.</h5>
</div>
<!-- Main content -->
<div class="alert alert-success" style="margin-left: -2in;">
<strong>Success!</strong> Your tuition fees have been successfully paid.
</div>
<div class="text-center" style="margin-left: -2in;">
<a href="<?= base_url('/parent/dashboard') ?>" class="btn btn-primary">Go to Dashboard</a>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>
+52
View File
@@ -0,0 +1,52 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container mt-5">
<h2 class="text-center">Payment Details</h2>
<div class="row mt-4">
<div class="col-md-6">
<h4>Payment Plan</h4>
<table class="table table-bordered">
<tr>
<th>Invoice Number</th>
<td><?= esc($payment['invoice_number']) ?></td>
</tr>
<tr>
<th>Total Amount</th>
<td><?= number_format($payment['total_amount'], 2) ?></td>
</tr>
<tr>
<th>Paid Amount</th>
<td><?= number_format($payment['paid_amount'], 2) ?></td>
</tr>
<tr>
<th>Balance</th>
<td><?= number_format($payment['balance_amount'], 2) ?></td>
</tr>
<tr>
<th>Number of Installments</th>
<td><?= esc($payment['number_of_installments']) ?></td>
</tr>
<tr>
<th>Semester</th>
<td><?= esc($payment['semester']) ?></td>
</tr>
<tr>
<th>Status</th>
<td><?= esc($payment['status']) ?></td>
</tr>
</table>
</div>
<div class="col-md-6">
<h4>Payment Options</h4>
<form method="post" action="<?= base_url('payments/createPaypalPayment/' . $payment['id']) ?>">
<?= csrf_field(); ?>
<button type="submit" class="btn btn-primary btn-block">
Pay via PayPal
</button>
</form>
</div>
</div>
</div>
<?= $this->endSection() ?>
+350
View File
@@ -0,0 +1,350 @@
<?php
$disableStudentBtn = count($existingKids) >= $maxChilds;
$disableEmergencyBtn = count($emergencies) >= $maxEmergency;
?>
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container my-5">
<h3 class="text-center text-success mb-3" style="font-family: Arial, sans-serif;">Student Registration</h3>
<?php if ($disableStudentBtn): ?>
<div class="alert alert-info mt-2">You've reached the maximum number of students (<?= $maxChilds ?>).</div>
<?php endif; ?>
<?php if ($disableEmergencyBtn): ?>
<!--div class="alert alert-info mt-2">You've reached the maximum number of emergency contacts (<--?= $maxEmergency ?>).</div-->
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger">
<?= esc(session()->getFlashdata('error')) ?>
</div>
<?php endif; ?>
<?php if (session('errors')): ?>
<div class="alert alert-danger">
<ul>
<?php foreach (session('errors') as $error): ?>
<li><?= esc($error) ?></li>
<?php endforeach ?>
</ul>
</div>
<?php endif; ?>
<?php
// Check if at least one student is not enrolled
$hasUnenrolled = false;
foreach ($existingKids as $kid) {
if ($kid['enrollment'] == 0) {
$hasUnenrolled = true;
break;
}
}
?>
<?php if ($hasUnenrolled): ?>
<div class="p-3 mb-4 border border-danger rounded bg-light text-center">
<h5 class="text-danger mb-2">
⚠ Please ensure that all of your students are enrolled.
</h5>
<p class="mb-3">
Please complete their enrollment using the button below to ensure they are able to attend classes.
</p>
<a href="<?= base_url('/parent/enroll_classes') ?>"
class="btn btn-lg btn-success bi bi-pencil-square"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
title="Enroll registered students in their appropriate grade level or course.">
Enroll in Classes
</a>
</div>
<?php endif; ?>
<?php if (!empty($existingKids)): ?>
<h5>Student Information</h5>
<table class="table table-bordered">
<thead class="table-light">
<tr>
<th>School ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>DOB</th>
<th>Grade</th>
<th>Medical Conditions</th>
<th>Allergies</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($existingKids as $kid): ?>
<tr>
<td><?= esc($kid['school_id']) ?></td>
<td><?= esc($kid['firstname']) ?></td>
<td><?= esc($kid['lastname']) ?></td>
<td><?= esc((new DateTime($kid['dob']))->format('m-d-Y')) ?></td>
<td><?= esc($kid['registration_grade']) ?></td>
<td>
<?php
$mc = is_array($kid['medical_conditions'] ?? null)
? $kid['medical_conditions']
: (strlen($kid['medical_conditions'] ?? '') > 0
? array_map('trim', explode(',', $kid['medical_conditions']))
: ['N/A']);
// Escape each item, then join with real <br> (not escaped)
echo implode('<br>', array_map('esc', $mc));
?>
</td>
<td>
<?php
$al = is_array($kid['allergies'] ?? null)
? $kid['allergies']
: (strlen($kid['alalergies'] ?? '') > 0
? array_map('trim', explode(',', $kid['allergies']))
: ['N/A']);
echo implode('<br>', array_map('esc', $al));
?>
</td>
<td class="text-center">
<?php if ($kid['enrollment'] == 0): ?>
<form action="<?= base_url('/parent/delete_student/' . $kid['id']) ?>"
method="post"
style="display:inline">
<?= csrf_field() ?>
<button
type="button"
class="btn btn-sm btn-outline-danger"
aria-label="Delete this student"
title="Delete this student"
onclick="if (confirm('Are you sure you want to delete this student?')) { this.closest('form').submit(); }">
<i class="fas fa-trash" aria-hidden="true"></i>
<span class="ms-1">Delete</span>
</button>
</form>
<?php else: ?>
<button type="button" class="btn btn-sm btn-outline-secondary" disabled title="Student is already enrolled">
<i class="fas fa-ban"></i> Delete
</button>
<?php endif; ?>
</td>
</tr>
<?php $student = $kid; ?>
<?php include(APPPATH . 'Views/parent/edit_student_modal.php'); ?>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php if (!empty($emergencies)): ?>
<h5 class="mt-4">Emergency Contacts</h5>
<table class="table table-bordered">
<thead class="table-light">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
<th>Relation</th>
</tr>
</thead>
<tbody>
<?php foreach ($emergencies as $contact): ?>
<?php
$fullName = $contact['emergency_contact_name'] ?? '';
$nameParts = explode(' ', trim($fullName), 2);
$firstName = $nameParts[0] ?? '';
$lastName = $nameParts[1] ?? '';
?>
<tr>
<td><?= esc($firstName) ?></td>
<td><?= esc($lastName) ?></td>
<td><?= esc($contact['cellphone']) ?></td>
<td><?= esc($contact['relation']) ?></td>
</tr>
<?php include(APPPATH . 'Views/parent/edit_emergency_contact.php'); ?>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php
$today = local_date(utc_now(), 'Y-m-d');
$disableDueToDate = ($today >= $lastDayOfRegistration);
$disableAll = $disableStudentBtn || $disableDueToDate;
?>
<form action="<?= base_url('/parent/register_student/save') ?>"
method="post"
id="studentRegistrationForm"
data-max-students="<?= $maxChilds ?>"
data-existing-students="<?= count($existingKids) ?>"
data-max-emergency="<?= $maxEmergency ?>"
data-existing-emergencies="<?= count($emergencies) ?>">
<?= csrf_field() ?>
<div id="studentFormsContainer"></div>
<div id="emergencyFormsContainer"></div>
<div class="text-center mb-3" id="initialButtons">
<button type="button"
class="btn btn-outline-primary me-2 <?= $disableAll ? 'disabled' : '' ?>"
id="addStudentBtn"
title="<?php
if ($disableStudentBtn) {
echo "Maximum of $maxChilds students reached.";
} elseif ($disableDueToDate) {
echo "Registration is closed after $lastDayOfRegistration.";
}
?>"
<?= $disableAll ? 'disabled' : '' ?>>
<i class="fas fa-user-plus"></i> Add Student
</button>
</div>
<div class="text-center mb-3 d-none" id="formActionButtons">
<button type="button"
class="btn btn-outline-primary me-2 <?= $disableAll ? 'disabled' : '' ?>"
id="addAnotherStudentBtn"
title="<?php
if ($disableStudentBtn) {
echo "Maximum of $maxChilds students reached.";
} elseif ($disableDueToDate) {
echo "Registration is closed after $lastDayOfRegistration.";
}
?>"
<?= $disableAll ? 'disabled' : '' ?>>
<i class="fas fa-user-plus"></i> Add Another Student
</button>
<button type="button"
class="btn btn-outline-primary me-2"
id="doneWithStudentBtn">
<i class="fas fa-check"></i> Done With Student(s)
</button>
<button type="submit" class="btn btn-success d-none" id="saveFormBtn">
<i class="fas fa-save"></i> Save
</button>
</div>
</form>
<!-- Picture Policy Modal -->
<div class="modal fade" id="picturePolicyModal" tabindex="-1" aria-labelledby="picturePolicyModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-success" id="picturePolicyModalLabel">Picture & Media Agreement</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" style="white-space: pre-wrap;">
<?php
$picturePolicy = include(APPPATH . 'Views/policy/picture_policy_partial.php');
$sections = $picturePolicy['sections'] ?? [];
$title = $picturePolicy['title'] ?? '';
?>
<h3 class="text-success"><?= esc($title) ?></h3>
<?php if (!empty($sections)): ?>
<?php foreach ($sections as $section): ?>
<h4 class="mt-4"><?= esc($section['heading']) ?></h4>
<?php if (isset($section['subsections'][0])): ?>
<?php foreach ($section['subsections'] as $sub): ?>
<?php if (!empty($sub['title'])): ?>
<h5><?= esc($sub['title']) ?></h5>
<?php endif; ?>
<p><?= nl2br(esc($sub['body'] ?? '')) ?></p>
<?php endforeach; ?>
<?php elseif (isset($section['subsections']['body'])): ?>
<p><?= nl2br(esc($section['subsections']['body'])) ?></p>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-outline-primary" onclick="window.print()">Print</button>
</div>
</div>
</div>
</div>
</div>
<!-- Hidden Templates -->
<div id="studentFormTemplate" class="d-none">
<?= view('partials/student_form') ?>
</div>
<div id="emergencyFormTemplate" class="d-none">
<?= view('partials/emergencycontact_form') ?>
</div>
<?php
$tz = new DateTimeZone((string) (config('School')->attendance['timezone'] ?? user_timezone()));
$now = new DateTime('now', $tz);
$closeAt = new DateTime($lastDayOfRegistration . ' 00:00:00', $tz);
// Closed at the start of the close date
$disableDueToDate = ($now >= $closeAt);
// Last usable calendar day (date - 1)
$lastDayFmt = (clone $closeAt)->modify('-1 day')->format('m-d-Y');
// Also prepare a precise closing moment string
$closeAtFmt24 = $closeAt->format('m-d-Y H:i T'); // e.g., 10-01-2025 00:00 EDT
$closeAtFmt12 = $closeAt->format('m-d-Y g:i A T'); // e.g., 10-01-2025 12:00 AM EDT
?>
<?php if ($disableDueToDate): ?>
<!-- Registration Closed Modal -->
<div class="modal fade" id="regClosedModal" tabindex="-1" aria-labelledby="regClosedModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-danger">
<div class="modal-header">
<h5 class="modal-title text-danger" id="regClosedModalLabel">Registration & Enrollment Closed</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Registration/enrollment is over for this school year.<br>
<strong>Last day:</strong> <?= esc($lastDayFmt) ?> (until 11:59 PM)<br>
<strong>Closed at:</strong> <?= esc($closeAtFmt24) ?> <!-- or <?= esc($closeAtFmt12) ?> -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<!-- Optional inline banner as well -->
<div class="alert alert-danger d-flex align-items-center my-3" role="alert">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
Registration/enrollment is closed.<br>
Last day to register was <strong><?= esc($lastDayFmt) ?></strong> (until <strong>11:59 PM</strong>).<br>
It closed at <strong><?= esc($closeAtFmt24) ?></strong> <!-- or <?= esc($closeAtFmt12) ?> -->
</div>
</div>
<?php endif; ?>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<?php if ($disableDueToDate): ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
var modalEl = document.getElementById('regClosedModal');
if (modalEl && window.bootstrap) {
var m = new bootstrap.Modal(modalEl);
m.show();
}
});
</script>
<?php endif; ?>
<script>
window.appConfig = {
registrationAgeDeadline: "<?= esc($registrationAgeDeadline) ?>"
};
</script>
<!-- Only keep the script imports -->
<script type="module" src="/assets/js/name_validation.js"></script>
<script type="module" src="/assets/js/age_validation.js"></script>
<script type="module" src="/assets/js/phone_validation.js"></script>
<script type="module" src="/assets/js/validate_student.js"></script>
<?= $this->endSection() ?>
+475
View File
@@ -0,0 +1,475 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container my-5" style="max-width: 880px;">
<h3 class="text-center text-success mb-4" style="font-family: Arial, sans-serif;">
Report Absence/Late/Early Dismissal
</h3>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger"><?= esc(session()->getFlashdata('error')) ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('message')): ?>
<div class="alert alert-success">
<?= session()->getFlashdata('message') ?>
</div>
<?php endif; ?>
<?php
// Build preview/edit table for upcoming reports
$myReports = is_array($myReports ?? null) ? $myReports : [];
$tzName = 'UTC';
try { $tzName = (string)(config('School')->attendance['timezone'] ?? user_timezone()); } catch (\Throwable $e) { $tzName = user_timezone(); }
$nowTz = new DateTime('now', new DateTimeZone($tzName));
?>
<?php if (!empty($myReports)): ?>
<div class="card shadow-sm mb-4">
<div class="card-header bg-light"><strong>Upcoming Submissions (Preview & Edit)</strong></div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-bordered align-middle">
<thead class="table-light">
<tr>
<th>Student</th>
<th>Date</th>
<th>Type</th>
<th>Time</th>
<th>Reason</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($myReports as $r): ?>
<?php
$reportDate = (string)($r['report_date'] ?? '');
$reportDateLabel = $reportDate !== '' ? local_date($reportDate, 'm-d-Y') : '';
$type = (string)($r['type'] ?? '');
$isLate = ($type === 'late');
$isED = ($type === 'early_dismissal');
$timeVal = $isLate ? ($r['arrival_time'] ?? '') : ($isED ? ($r['dismiss_time'] ?? '') : '');
$status = (string)($r['status'] ?? '');
$cutoff = null; $editable = false;
try { $cutoff = new DateTime($reportDate . ' 09:00:00', new DateTimeZone($tzName)); } catch (\Throwable $e) { $cutoff = null; }
if ($cutoff) {
$editable = ($status === 'new') && ($nowTz < $cutoff);
}
?>
<tr>
<td><?= esc(trim(($r['firstname'] ?? '') . ' ' . ($r['lastname'] ?? ''))) ?></td>
<td><?= esc($reportDateLabel) ?></td>
<td><?= esc(ucwords(str_replace('_', ' ', $type))) ?></td>
<td><?= esc($timeVal ?: '—') ?></td>
<td><?= esc($r['reason'] ?? '') ?></td>
<td><?= esc($status ?: 'new') ?></td>
<td>
<?php if ($editable): ?>
<button type="button" class="btn btn-sm btn-outline-primary" data-edit-row="<?= (int)$r['id'] ?>">Edit</button>
<?php else: ?>
<span class="text-muted">—</span>
<?php endif; ?>
</td>
</tr>
<?php if ($editable): ?>
<tr class="d-none" data-edit-form-row="<?= (int)$r['id'] ?>">
<td colspan="7">
<form method="post" action="<?= site_url('parent/report-attendance/update') ?>" class="row g-2 align-items-end">
<?= csrf_field() ?>
<input type="hidden" name="id" value="<?= (int)$r['id'] ?>">
<div class="col-md-3">
<label class="form-label">Type</label>
<input type="text" class="form-control" value="<?= esc(ucwords(str_replace('_', ' ', $type))) ?>" disabled>
</div>
<?php if ($isLate): ?>
<div class="col-md-3">
<label class="form-label">Arrival Time</label>
<input type="time" class="form-control" name="arrival_time" value="<?= esc(substr((string)$timeVal,0,5)) ?>">
</div>
<?php elseif ($isED): ?>
<div class="col-md-3">
<label class="form-label">Dismissal Time</label>
<input type="time" class="form-control" name="dismiss_time" value="<?= esc(substr((string)$timeVal,0,5)) ?>">
</div>
<?php else: ?>
<div class="col-md-3">
<label class="form-label">Time</label>
<input type="text" class="form-control" value="—" disabled>
</div>
<?php endif; ?>
<div class="col-md-5">
<label class="form-label">Reason</label>
<input type="text" class="form-control" name="reason" value="<?= esc((string)($r['reason'] ?? '')) ?>" placeholder="Optional">
</div>
<div class="col-md-1">
<button type="submit" class="btn btn-success btn-sm">Save</button>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-secondary btn-sm" data-cancel-edit="<?= (int)$r['id'] ?>">Cancel</button>
</div>
</form>
</td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="text-muted small">Editing allowed until 9:00 AM on the report date.</div>
</div>
</div>
<?php endif; ?>
<div class="card shadow-sm">
<div class="card-body">
<form id="reportForm"
method="post"
action="<?= site_url('parent/report-attendance') ?>"
data-csrf-name="<?= esc(csrf_token()) ?>"
data-csrf-value="<?= esc(csrf_hash()) ?>"
data-check-url="<?= site_url('api/parent/report-attendance/check') ?>">
<input type="hidden" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>">
<div id="clientCheckAlert" class="alert d-none" role="alert"></div>
<div class="mb-3">
<label class="form-label fw-semibold">Select Child(ren)</label>
<div class="row g-2">
<?php if (!empty($students)): ?>
<?php foreach ($students as $s): ?>
<div class="col-md-6">
<div class="form-check border rounded p-2" data-student-box="<?= (int)$s['id'] ?>">
<?php
$oldStudents = (array) old('student_ids');
$isChecked = in_array((string)$s['id'], array_map('strval', $oldStudents ?? []), true);
?>
<input class="form-check-input" type="checkbox" name="student_ids[]" id="stu<?= (int)$s['id'] ?>" value="<?= (int)$s['id'] ?>" <?= $isChecked ? 'checked' : '' ?>>
<label class="form-check-label" for="stu<?= (int)$s['id'] ?>">
<?= esc($s['firstname'] . ' ' . $s['lastname']) ?>
</label>
<div class="small mt-1 d-none" data-role="conflict-msg"></div>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="col-12">
<div class="alert alert-warning mb-0">No students found under your account.</div>
</div>
<?php endif; ?>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-md-6">
<label class="form-label fw-semibold">Sunday Date(s)</label>
<select name="dates[]" class="form-select" required multiple size="6" style="max-height: 220px; overflow-y: auto;">
<?php
$list = $sundays ?? [];
$oldDatesRaw = old('dates');
$selectedDates = [];
if (is_array($oldDatesRaw)) {
$selectedDates = array_map('strval', $oldDatesRaw);
} elseif ($oldDatesRaw !== null) {
$selectedDates = [(string) $oldDatesRaw];
} elseif (old('date')) {
$selectedDates = [(string) old('date')];
} elseif (!empty($defaultDate)) {
$selectedDates = [(string) $defaultDate];
}
$selectedDates = array_unique(array_filter($selectedDates));
foreach ($list as $opt):
$v = $opt['value'] ?? '';
$label = $opt['label'] ?? $v;
$isSel = in_array((string)$v, $selectedDates, true);
?>
<option value="<?= esc($v) ?>" <?= $isSel ? 'selected' : '' ?>><?= esc($label) ?></option>
<?php endforeach; ?>
</select>
<div class="form-text">Select one or more Sundays (hold Ctrl/Cmd or Shift to pick multiple). Scroll for future dates through early June.</div>
</div>
<div class="col-md-3">
<label class="form-label fw-semibold">Type</label>
<select name="type" id="reportType" class="form-select" required>
<?php $oldType = (string) (old('type') ?: 'absent'); ?>
<option value="absent" <?= $oldType === 'absent' ? 'selected' : '' ?>>Absent</option>
<option value="late" <?= $oldType === 'late' ? 'selected' : '' ?>>Late</option>
<option value="early_dismissal" <?= $oldType === 'early_dismissal' ? 'selected' : '' ?>>Early Dismissal</option>
</select>
</div>
<div class="col-md-3" id="arrivalTimeWrap" style="display:none;">
<label class="form-label fw-semibold">Expected Arrival Time</label>
<input type="time" name="arrival_time" class="form-control" placeholder="HH:MM" value="<?= esc(old('arrival_time') ?: '') ?>">
</div>
<div class="col-md-3" id="dismissTimeWrap" style="display:none;">
<label class="form-label fw-semibold">Dismissal Time</label>
<input type="time" name="dismiss_time" class="form-control" placeholder="HH:MM" value="<?= esc(old('dismiss_time') ?: '') ?>">
</div>
</div>
<div class="mb-3">
<label class="form-label fw-semibold" id="reasonLabel">Reason</label>
<textarea name="reason" id="reasonInput" rows="3" class="form-control" placeholder="Brief reason to help teachers plan."><?= esc(old('reason') ?: '') ?></textarea>
<div class="form-text" id="reasonHelp">Required for Absence/Late so we can support your child.</div>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-success">Submit</button>
<?php $prev = previous_url() ?: site_url('/parent/attendance'); ?>
<a href="<?= esc($prev) ?>" class="btn btn-outline-secondary">Cancel</a>
</div>
</form>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
const typeSel = document.getElementById('reportType');
const arrivalWrap = document.getElementById('arrivalTimeWrap');
const dismissWrap = document.getElementById('dismissTimeWrap');
const reasonField = document.getElementById('reasonInput');
const reasonHelp = document.getElementById('reasonHelp');
const reasonLabel = document.getElementById('reasonLabel');
function updateFields() {
const v = (typeSel.value || '').toLowerCase();
arrivalWrap.style.display = (v === 'late') ? '' : 'none';
dismissWrap.style.display = (v === 'early_dismissal') ? '' : 'none';
const reasonRequired = (v === 'absent' || v === 'late');
if (reasonField) {
reasonField.required = reasonRequired;
}
if (reasonLabel) {
reasonLabel.innerHTML = reasonRequired
? 'Reason <span class="text-danger">*</span>'
: 'Reason (optional)';
}
if (reasonHelp) {
reasonHelp.textContent = reasonRequired
? 'Required for absence/late so teachers can plan.'
: 'Optional for early dismissal.';
}
// Nudge visibility into view so parents notice the time field
if (v === 'late') {
try { arrivalWrap.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } catch(e) {}
} else if (v === 'early_dismissal') {
try { dismissWrap.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } catch(e) {}
}
}
typeSel.addEventListener('change', updateFields);
updateFields();
});
</script>
<script>
// Inline edit toggling for the preview table
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('[data-edit-row]').forEach(function(btn){
btn.addEventListener('click', function(){
const id = this.getAttribute('data-edit-row');
const row = document.querySelector('[data-edit-form-row="' + id + '"]');
if (!row) return;
row.classList.toggle('d-none');
try { row.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } catch(_) {}
});
});
document.querySelectorAll('[data-cancel-edit]').forEach(function(btn){
btn.addEventListener('click', function(){
const id = this.getAttribute('data-cancel-edit');
const row = document.querySelector('[data-edit-form-row="' + id + '"]');
if (!row) return;
row.classList.add('d-none');
});
});
});
</script>
<script>
// Conflict check with CSRF refresh
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('reportForm');
if (!form) return;
let checkUrl = form.getAttribute('data-check-url') || '';
let csrfName = form.getAttribute('data-csrf-name') || '';
let csrfVal = form.getAttribute('data-csrf-value') || '';
const typeSel = document.getElementById('reportType');
const dateSel = form.querySelector('select[name="dates[]"]');
const submitBtn = form.querySelector('button[type="submit"]');
const alertBox = document.getElementById('clientCheckAlert');
function selectedIds() {
const ids = [];
form.querySelectorAll('input[name="student_ids[]"]:checked').forEach(cb => {
const v = parseInt(cb.value, 10);
if (v > 0) ids.push(v);
});
return ids;
}
function setAlert(kind, html) {
if (!alertBox) return;
if (!html) {
alertBox.className = 'alert d-none';
alertBox.innerHTML = '';
return;
}
let cls = 'alert-info';
if (kind === 'error') cls = 'alert-danger';
else if (kind === 'warn') cls = 'alert-warning';
else if (kind === 'ok') cls = 'alert-success';
alertBox.className = 'alert ' + cls;
alertBox.innerHTML = html;
}
function setStudentMsg(studentId, msg, kind) {
const box = form.querySelector('[data-student-box="' + studentId + '"] [data-role="conflict-msg"]');
if (!box) return;
if (!msg) {
box.classList.add('d-none');
box.textContent = '';
return;
}
box.classList.remove('d-none');
box.classList.remove('text-danger', 'text-info');
box.classList.add(kind === 'info' ? 'text-info' : 'text-danger');
box.textContent = msg;
}
function selectedDates() {
if (!dateSel) return [];
return Array.from(dateSel.selectedOptions || [])
.map(opt => opt.value)
.filter(v => v);
}
async function runCheck() {
setAlert('', '');
const ids = selectedIds();
const dates = selectedDates();
if (!checkUrl || !dateSel || !typeSel) return;
if (!ids.length || !dates.length) {
if (submitBtn) submitBtn.disabled = false;
return;
}
form.querySelectorAll('[data-student-box] input[type="checkbox"]').forEach(cb => {
cb.disabled = false;
});
form.querySelectorAll('[data-role="conflict-msg"]').forEach(el => {
el.classList.add('d-none');
el.textContent = '';
});
const body = new URLSearchParams();
body.append(csrfName, csrfVal);
dates.forEach(function(d) {
body.append('dates[]', d);
});
body.append('type', typeSel.value || '');
ids.forEach(id => body.append('student_ids[]', String(id)));
try {
const res = await fetch(checkUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
[csrfName]: csrfVal
},
body: body.toString()
});
const data = await res.json();
// ✅ Refresh CSRF token if returned
if (data?.csrf) {
csrfName = data.csrf.name;
csrfVal = data.csrf.hash;
form.setAttribute('data-csrf-name', csrfName);
form.setAttribute('data-csrf-value', csrfVal);
const hidden = form.querySelector('input[name="' + csrfName + '"]');
if (hidden) hidden.value = csrfVal;
}
if (!data || !data.ok) {
if (submitBtn) submitBtn.disabled = false;
return;
}
const byId = {};
(data.students || []).forEach(s => {
byId[s.student_id] = s;
});
const type = (typeSel.value || '').toLowerCase();
const conflicts = [];
const infoOnly = [];
ids.forEach(id => {
const s = byId[id];
const dateTypes = (s && s.dates) ? s.dates : {};
const fullname = (s ? ((s.firstname || '') + ' ' + (s.lastname || '')) : ('Student #' + id)).trim();
const conflictDates = [];
const infoDates = [];
dates.forEach(function(dateVal) {
const entry = dateTypes && dateTypes[dateVal];
const typesForDate = Array.isArray(entry) ? entry : [];
if (!typesForDate.length) return;
if (type === 'early_dismissal') {
if (typesForDate.includes('absent') || typesForDate.includes('late')) {
conflictDates.push(dateVal);
} else if (typesForDate.includes('early_dismissal')) {
infoDates.push(dateVal);
}
} else {
conflictDates.push(dateVal);
}
});
if (conflictDates.length) {
conflicts.push(fullname + ' (' + conflictDates.join(', ') + ')');
setStudentMsg(id, 'Already submitted for: ' + conflictDates.join(', '), 'error');
const cb = form.querySelector('[data-student-box="' + id + '"] input[type="checkbox"]');
if (cb) {
cb.checked = false;
cb.disabled = true;
}
} else if (infoDates.length) {
infoOnly.push(fullname + ' (' + infoDates.join(', ') + ')');
setStudentMsg(id, 'Early dismissal already submitted for: ' + infoDates.join(', ') + ' — time will be updated.', 'info');
}
});
if (conflicts.length && ids.length === conflicts.length) {
setAlert('warn', 'All selected students have existing submissions for the chosen date(s).');
} else if (conflicts.length) {
setAlert('warn', 'Some selections disabled due to existing submissions on selected dates.');
} else if (infoOnly.length) {
setAlert('info', 'Note: some students already have early dismissal on these dates—time will be updated.');
} else {
setAlert('', '');
}
if (submitBtn) submitBtn.disabled = (selectedIds().length === 0);
} catch (e) {
setAlert('warn', 'Could not verify submissions right now. You may proceed; server will validate.');
if (submitBtn) submitBtn.disabled = false;
}
}
form.addEventListener('change', function(e) {
const tgt = e.target;
if (!tgt) return;
if (tgt.matches('select[name="dates[]"], #reportType, input[name="student_ids[]"]')) {
runCheck();
}
});
runCheck();
});
</script>
<?= $this->endSection() ?>
+121
View File
@@ -0,0 +1,121 @@
<?= $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;">Scores</h2>
</div>
<!-- Filter Form -->
<form action="" method="get" class="form-inline">
<div class="d-flex align-items-center">
<select name="school_year" id="school_year" class="form-control me-3"> <!-- Added me-3 (right margin) -->
<?php foreach ($schoolYears as $year): ?>
<option value="<?= esc($year) ?>" <?= $selectedYear === $year ? 'selected' : '' ?>>
<?= esc($year) ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-success">Filter</button>
</div>
</form>
<!-- Scores Table -->
<?php $yearScores = $organizedScores[$selectedYear] ?? []; ?>
<?php $semesterOrder = $semesterOrder ?? ['Fall', 'Spring']; ?>
<?php
$showExamScores = $showExamScores ?? true;
$showExamScoresBySemester = $showExamScoresBySemester ?? [];
?>
<?php if (empty($yearScores)): ?>
<div class="alert alert-info mb-3 d-inline-block">No scores available for the selected year.</div>
<?php else: ?>
<div class="accordion mt-4" id="parentScoresAccordion">
<?php foreach ($semesterOrder as $index => $semester): ?>
<?php
$semesterScores = $yearScores[$semester] ?? [];
$showExamScoresForSemester = $showExamScoresBySemester[$semester] ?? $showExamScores;
$columnCount = $showExamScoresForSemester ? 11 : 8;
$headingId = 'heading' . strtolower($semester);
$collapseId = 'collapse' . strtolower($semester);
$isActive = $index === 0;
?>
<div class="accordion-item">
<h2 class="accordion-header" id="<?= esc($headingId) ?>">
<button class="accordion-button <?= $isActive ? '' : 'collapsed' ?>" type="button"
data-bs-toggle="collapse" data-bs-target="#<?= esc($collapseId) ?>"
aria-expanded="<?= $isActive ? 'true' : 'false' ?>" aria-controls="<?= esc($collapseId) ?>">
<?= esc($semester) ?> Semester
</button>
</h2>
<div id="<?= esc($collapseId) ?>" class="accordion-collapse collapse <?= $isActive ? 'show' : '' ?>"
aria-labelledby="<?= esc($headingId) ?>" data-bs-parent="#parentScoresAccordion">
<div class="accordion-body p-0">
<?php if (!empty($semesterScores)): ?>
<div class="table-responsive">
<table class="table table-striped table-bordered mb-0">
<thead>
<tr>
<th>School ID</th>
<th>Student Name</th>
<th>Class Section</th>
<th>Homework</th>
<th>Project</th>
<th>Participation</th>
<th>Quiz</th>
<th>Attendance</th>
<?php if ($showExamScoresForSemester): ?><th>PTAP</th><?php endif; ?>
<?php if ($semester === 'Fall'): ?>
<?php if ($showExamScoresForSemester): ?><th>Midterm</th><?php endif; ?>
<?php elseif ($semester === 'Spring'): ?>
<?php if ($showExamScoresForSemester): ?><th>Final Exam</th><?php endif; ?>
<?php else: ?>
<?php if ($showExamScoresForSemester): ?><th>Exam</th><?php endif; ?>
<?php endif; ?>
<?php if ($showExamScoresForSemester): ?><th>Semester Score</th><?php endif; ?>
</tr>
</thead>
<tbody>
<?php foreach ($semesterScores as $student): ?>
<tr>
<td><?= esc($student['school_id']) ?></td>
<td><?= esc($student['student_firstname'] . ' ' . $student['student_lastname']) ?></td>
<td><?= esc($student['class_section_name']) ?></td>
<td><?= esc($student['scores']['homework']['score'] ?? '-') ?></td>
<td><?= esc($student['scores']['project']['score'] ?? '-') ?></td>
<td><?= esc($student['scores']['participation_score']['score'] ?? '-') ?></td>
<td><?= esc($student['scores']['quiz']['score'] ?? '-') ?></td>
<td><?= esc($student['scores']['attendance']['score'] ?? '-') ?></td>
<?php if ($showExamScoresForSemester): ?><td><?= esc($student['scores']['ptap']['score'] ?? '-') ?></td><?php endif; ?>
<?php if ($semester === 'Fall'): ?>
<?php if ($showExamScoresForSemester): ?><td><?= esc($student['scores']['midterm_exam']['score'] ?? '-') ?></td><?php endif; ?>
<?php elseif ($semester === 'Spring'): ?>
<?php if ($showExamScoresForSemester): ?><td><?= esc($student['scores']['final_exam']['score'] ?? '-') ?></td><?php endif; ?>
<?php else: ?>
<?php if ($showExamScoresForSemester): ?><td><?= esc($student['scores']['midterm_exam']['score'] ?? $student['scores']['final_exam']['score'] ?? '-') ?></td><?php endif; ?>
<?php endif; ?>
<?php if ($showExamScoresForSemester): ?><td><?= esc($student['scores']['semester']['score'] ?? '-') ?></td><?php endif; ?>
</tr>
<?php if (!empty($student['comment'])): ?>
<tr>
<td colspan="<?= esc($columnCount) ?>"><strong>Teacher Comment:</strong> <?= esc($student['comment']) ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="alert alert-secondary mb-0">No <?= esc($semester) ?> semester scores recorded yet.</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</main>
</div>
</div>
<?= $this->endSection() ?>
+18
View File
@@ -0,0 +1,18 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="message">
<img src="<?= base_url('public/images/registration-1.png') ?>" alt="Registration Success">
<h1>Your kid(s) has been Successfully registered!</h1>
<p>You will be redirected to the home page shortly.</p>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
window.location.href = "<?= base_url('/parent_dashboard') ?>";
}, 5000);
});
</script>
<?= $this->endSection() ?>
+14
View File
@@ -0,0 +1,14 @@
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<div class="container-fluid">
<div class="row">
<main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="alert alert-success mt-4">
<h4 class="alert-heading">Success!</h4>
<p>Students have been successfully withdrawn from the selected classes.</p>
</div>
</main>
</div>
</div>
<?= $this->endSection() ?>