363 lines
16 KiB
PHP
363 lines
16 KiB
PHP
<?= $this->extend('layout/main_layout') ?>
|
|
|
|
<?= $this->section('styles') ?>
|
|
<style>
|
|
.volunteer-openings-modal .modal-header {
|
|
background: linear-gradient(135deg, #0f766e, #2563eb);
|
|
color: #fff;
|
|
}
|
|
|
|
.volunteer-openings-modal .btn-close {
|
|
filter: invert(1) grayscale(100%) brightness(200%);
|
|
}
|
|
|
|
.volunteer-opening-card {
|
|
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
border-radius: 8px;
|
|
padding: 1rem;
|
|
background: #fff;
|
|
}
|
|
|
|
.volunteer-opening-card + .volunteer-opening-card {
|
|
margin-top: 0.85rem;
|
|
}
|
|
|
|
.volunteer-opening-meta {
|
|
color: #64748b;
|
|
font-size: 0.92rem;
|
|
}
|
|
</style>
|
|
<?= $this->endSection() ?>
|
|
|
|
<?= $this->section('content') ?>
|
|
<?php $openPositions = $openPositions ?? []; ?>
|
|
|
|
<!-- Circle Styles -->
|
|
|
|
<link rel="stylesheet" href="<?= base_url('assets/css/parent_dashboard.css?v=1.1') ?>">
|
|
<!-- Dashboard Circles -->
|
|
<div class="container py-5">
|
|
<div class="row g-4 justify-content-center text-center">
|
|
|
|
<!-- Parent_Guide -->
|
|
<div class="col-auto">
|
|
<a href="<?= base_url('parent_guide.pdf') ?>"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="d-inline-block text-decoration-none">
|
|
<div class="circle-box bg-info position-relative" role="button" aria-label="Open Parent Guide PDF">
|
|
<h4 class="fw-bold mb-0">Your Quick Guide</h4>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<!-- School Policies -->
|
|
<div class="col-auto">
|
|
<a href="<?= base_url('policy/school_policy') ?>"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="d-inline-block text-decoration-none">
|
|
<div class="circle-box bg-success position-relative" role="button" aria-label="Open School Policies">
|
|
<h4 class="fw-bold mb-0">School Policies</h4>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<!-- Notifications -->
|
|
<div class="col-auto">
|
|
<div class="circle-box bg-primary position-relative">
|
|
<h4 class="fw-bold">Notifications</h4>
|
|
<small><?= count($notifications ?? []) ?> new</small>
|
|
<div class="hover-popup" style="max-height: 250px; overflow-y: auto;">
|
|
<?php if (!empty($notifications)): ?>
|
|
<ul class="mb-0 ps-3">
|
|
<?php foreach ($notifications as $n): ?>
|
|
<li class="mb-2">
|
|
<strong><?= esc($n['title'] ?? 'Notification') ?></strong><br>
|
|
<small class="text-muted">
|
|
<?= isset($n['created_at']) && strtotime($n['created_at'])
|
|
? esc(local_datetime($n['created_at'], 'm-d-Y H:i'))
|
|
: 'No date' ?>
|
|
</small>
|
|
<?php if (!empty($n['message'] ?? '')): ?>
|
|
<br>
|
|
<span><?= esc($n['message']) ?></span>
|
|
<?php endif; ?>
|
|
<br>
|
|
<span class="badge bg-light text-dark"><?= esc(ucfirst((string) ($n['notification_type'] ?? 'notice'))) ?></span>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php else: ?>
|
|
<p class="mb-0">No new notifications.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Student Info -->
|
|
<div class="col-auto">
|
|
<div class="circle-box bg-success">
|
|
<h4 class="fw-bold">Students</h4>
|
|
<small><?= count($students ?? []) ?> total</small>
|
|
<div class="hover-popup">
|
|
<?php if (!empty($students)): ?>
|
|
<ul class="mb-0 ps-3">
|
|
<?php foreach ($students as $student): ?>
|
|
<li><?= esc($student['firstname']) ?> <?= esc($student['lastname']) ?> - <?= esc($student['grade'] ?? 'N/A') ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php else: ?>
|
|
<p class="mb-0">No student data.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Attendance -->
|
|
<div class="col-auto">
|
|
<div class="circle-box bg-danger">
|
|
<h4 class="fw-bold">Absences</h4>
|
|
<?php
|
|
$absentCount = 0;
|
|
foreach ($attendance ?? [] as $a) {
|
|
if (strtolower($a['status']) === 'absent') $absentCount++;
|
|
}
|
|
?>
|
|
<small><?= $absentCount ?> absent</small>
|
|
<div class="hover-popup">
|
|
<?php if ($absentCount): ?>
|
|
<ul class="mb-0 ps-3">
|
|
<?php foreach ($attendance as $a): ?>
|
|
<?php if (strtolower($a['status']) === 'absent'): ?>
|
|
<li><?= esc($a['date'] ? local_date($a['date'], 'm-d-Y') : '') ?> - <?= esc($a['firstname']) ?> <?= esc($a['lastname']) ?></li>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php else: ?>
|
|
<p class="mb-0">No absences.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Report Absence -->
|
|
<div class="col-auto">
|
|
<a href="<?= base_url('parent/report-attendance') ?>" class="d-inline-block text-decoration-none">
|
|
<div class="circle-box bg-secondary text-white position-relative" role="button" aria-label="Report absence or late">
|
|
<h4 class="fw-bold mb-0">Report Absence</h4>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Scores -->
|
|
<div class="col-auto">
|
|
<div class="circle-box bg-warning text-dark">
|
|
<h4 class="fw-bold">Scores</h4>
|
|
<small><?= count($scores ?? []) ?> entries</small>
|
|
<div class="hover-popup">
|
|
<?php if (!empty($scores)): ?>
|
|
<ul class="mb-0 ps-3">
|
|
<?php foreach ($scores as $score): ?>
|
|
<li><?= esc($score['grade'] ?? 'N/A') ?> - <?= esc($score['firstname']) ?> <?= esc($score['lastname']) ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php else: ?>
|
|
<p class="mb-0">No scores yet.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Report Cards -->
|
|
<div class="col-auto">
|
|
<a href="<?= base_url('parent/report-cards') ?>" class="d-inline-block text-decoration-none">
|
|
<div class="circle-box bg-dark text-white position-relative" role="button" aria-label="Open report cards">
|
|
<h4 class="fw-bold mb-0">Report Cards</h4>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Enrollment -->
|
|
<div class="col-auto">
|
|
<div class="circle-box bg-info text-white">
|
|
<h4 class="fw-bold">Enrollment</h4>
|
|
<small>Info</small>
|
|
<div class="hover-popup">
|
|
<div>
|
|
<strong>Enrollment deadline:</strong>
|
|
<?= $lastDayOfRegistration ? local_date($lastDayOfRegistration, 'm-d-Y') : 'N/A' ?>
|
|
</div>
|
|
<!-- <div><strong>Withdrawal:</strong> <?= esc($withdrawalDeadline ?? 'N/A') ?></div> -->
|
|
<hr class="my-2">
|
|
<?php if (!empty($enrollments)): ?>
|
|
<ul class="mb-0 ps-3">
|
|
<?php foreach ($enrollments as $e): ?>
|
|
<li><?= esc($e['class_name'] ?? 'N/A') ?> on <?= esc(!empty($e['enrollment_date']) ? local_date($e['enrollment_date'], 'm-d-Y') : 'N/A') ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php else: ?>
|
|
<p class="mb-0">No enrollment records.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Payment -->
|
|
<div class="col-auto">
|
|
<div class="circle-box bg-secondary position-relative">
|
|
<h4 class="fw-bold">Payment</h4>
|
|
<small>$<?= number_format($paymentBalance, 2) ?></small>
|
|
<div class="hover-popup">
|
|
<p class="mb-0">Current account balance for this school year, including any previous-year carry-over.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!empty($openPositions)): ?>
|
|
<div class="modal fade volunteer-openings-modal" id="volunteerOpeningsModal" tabindex="-1" aria-labelledby="volunteerOpeningsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<div>
|
|
<h5 class="modal-title mb-1" id="volunteerOpeningsModalLabel">Volunteer openings</h5>
|
|
<div class="small opacity-75">Al Rahma Sunday School is looking for help from our community.</div>
|
|
</div>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p class="mb-3">
|
|
Please review the current openings below. If you or someone you know can help, submit an application or share the opportunity.
|
|
</p>
|
|
|
|
<?php foreach ($openPositions as $position): ?>
|
|
<?php
|
|
$positionId = (string) ($position['position_id'] ?? '');
|
|
$detailsUrl = site_url('careers/' . rawurlencode($positionId));
|
|
$applyUrl = site_url('careers/' . rawurlencode($positionId) . '/apply');
|
|
$meta = array_filter([
|
|
$position['department'] ?? '',
|
|
$position['location'] ?? '',
|
|
$position['employment_type'] ?? '',
|
|
]);
|
|
?>
|
|
<div class="volunteer-opening-card">
|
|
<div class="d-flex flex-column flex-md-row justify-content-between gap-3">
|
|
<div>
|
|
<h6 class="mb-1"><?= esc($position['title'] ?? 'Volunteer position') ?></h6>
|
|
<?php if (!empty($meta)): ?>
|
|
<div class="volunteer-opening-meta mb-2"><?= esc(implode(' | ', $meta)) ?></div>
|
|
<?php endif; ?>
|
|
<?php if (!empty($position['description'])): ?>
|
|
<div class="small text-muted"><?= esc($position['description']) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="d-flex align-items-start gap-2 flex-shrink-0">
|
|
<a class="btn btn-outline-secondary btn-sm" href="<?= esc($detailsUrl) ?>">Details</a>
|
|
<a class="btn btn-primary btn-sm" href="<?= esc($applyUrl) ?>">Apply</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<div class="form-check me-auto text-start">
|
|
<input
|
|
class="form-check-input"
|
|
type="checkbox"
|
|
value="1"
|
|
id="hideJobOpeningsPopup"
|
|
data-save-url="<?= esc(site_url('parent_dashboard/job-openings-popup')) ?>"
|
|
data-csrf-name="<?= esc(csrf_token()) ?>"
|
|
data-csrf-value="<?= esc(csrf_hash()) ?>">
|
|
<label class="form-check-label" for="hideJobOpeningsPopup">
|
|
Do not show again
|
|
</label>
|
|
<div class="small text-muted d-none" id="hideJobOpeningsPopupStatus"></div>
|
|
</div>
|
|
<a class="btn btn-outline-secondary" href="<?= site_url('careers') ?>">View all openings</a>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?= $this->endSection() ?>
|
|
|
|
<?php if (!empty($openPositions)): ?>
|
|
<?= $this->section('scripts') ?>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const modalEl = document.getElementById('volunteerOpeningsModal');
|
|
if (!modalEl || !window.bootstrap) {
|
|
return;
|
|
}
|
|
|
|
bootstrap.Modal.getOrCreateInstance(modalEl).show();
|
|
|
|
const checkbox = document.getElementById('hideJobOpeningsPopup');
|
|
const statusEl = document.getElementById('hideJobOpeningsPopupStatus');
|
|
if (!checkbox) {
|
|
return;
|
|
}
|
|
|
|
checkbox.addEventListener('change', async function () {
|
|
if (!checkbox.checked) {
|
|
return;
|
|
}
|
|
|
|
checkbox.disabled = true;
|
|
if (statusEl) {
|
|
statusEl.classList.remove('d-none', 'text-danger');
|
|
statusEl.classList.add('text-muted');
|
|
statusEl.textContent = 'Saving preference...';
|
|
}
|
|
|
|
const body = new FormData();
|
|
let csrfName = checkbox.dataset.csrfName || '';
|
|
let csrfValue = checkbox.dataset.csrfValue || '';
|
|
body.append('hide_job_openings_popup', '1');
|
|
if (csrfName && csrfValue) {
|
|
body.append(csrfName, csrfValue);
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(checkbox.dataset.saveUrl || '', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
...(csrfValue ? { 'X-CSRF-TOKEN': csrfValue } : {})
|
|
},
|
|
body
|
|
});
|
|
const data = await response.json().catch(function () {
|
|
return {};
|
|
});
|
|
|
|
if (data.csrf_token && data.csrf_hash) {
|
|
checkbox.dataset.csrfName = data.csrf_token;
|
|
checkbox.dataset.csrfValue = data.csrf_hash;
|
|
}
|
|
|
|
if (!response.ok || !data.ok) {
|
|
throw new Error(data.error || 'Unable to save preference.');
|
|
}
|
|
|
|
if (statusEl) {
|
|
statusEl.textContent = 'Saved.';
|
|
}
|
|
} catch (error) {
|
|
checkbox.checked = false;
|
|
checkbox.disabled = false;
|
|
if (statusEl) {
|
|
statusEl.classList.remove('d-none', 'text-muted');
|
|
statusEl.classList.add('text-danger');
|
|
statusEl.textContent = error.message || 'Unable to save preference.';
|
|
}
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?= $this->endSection() ?>
|
|
<?php endif; ?>
|