217 lines
9.3 KiB
PHP
217 lines
9.3 KiB
PHP
<?php
|
|
require_once __DIR__ . '/db/config.php';
|
|
|
|
$db = db();
|
|
$date = date('Y-m-d');
|
|
$message = '';
|
|
|
|
// Handle Attendance Submission
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['attendance'])) {
|
|
try {
|
|
$db->beginTransaction();
|
|
$stmt = $db->prepare("INSERT INTO attendance (learner_id, status, date)
|
|
VALUES (:learner_id, :status, :date)
|
|
ON DUPLICATE KEY UPDATE status = VALUES(status)");
|
|
|
|
foreach ($_POST['attendance'] as $learner_id => $status) {
|
|
$stmt->execute([
|
|
'learner_id' => $learner_id,
|
|
'status' => $status,
|
|
'date' => $date
|
|
]);
|
|
}
|
|
$db->commit();
|
|
$message = "Attendance saved successfully for $date.";
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
$message = "Error: " . $e->getMessage();
|
|
}
|
|
}
|
|
|
|
// Fetch Learners and their current attendance for today
|
|
$query = "SELECT l.*, a.status as today_status
|
|
FROM learners l
|
|
LEFT JOIN attendance a ON l.id = a.learner_id AND a.date = :date
|
|
ORDER BY l.full_name ASC";
|
|
$stmt = $db->prepare($query);
|
|
$stmt->execute(['date' => $date]);
|
|
$learners = $stmt->fetchAll();
|
|
|
|
// Stats
|
|
$total_learners = count($learners);
|
|
$present_count = 0;
|
|
foreach ($learners as $l) {
|
|
if ($l['today_status'] === 'present') $present_count++;
|
|
}
|
|
$presence_rate = $total_learners > 0 ? round(($present_count / $total_learners) * 100) : 0;
|
|
|
|
// Project Info
|
|
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Education Ecosystem Platform for South African Schools';
|
|
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Teacher Dashboard | Township Schools Platform</title>
|
|
<?php if ($projectDescription): ?>
|
|
<meta name="description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<?php endif; ?>
|
|
<?php if ($projectImageUrl): ?>
|
|
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
<?php endif; ?>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="navbar navbar-dark mb-4">
|
|
<div class="container">
|
|
<a class="navbar-brand" href="#">
|
|
<i class="bi bi-book-half me-2"></i>
|
|
Township Schools Platform
|
|
</a>
|
|
<div class="d-flex align-items-center">
|
|
<span class="text-white me-3 d-none d-md-inline">Role: <strong>Teacher</strong></span>
|
|
<div class="dropdown">
|
|
<button class="btn btn-outline-light btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
Switch Role
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li><a class="dropdown-item active" href="#">Teacher</a></li>
|
|
<li><a class="dropdown-item" href="#">Admin (Soon)</a></li>
|
|
<li><a class="dropdown-item" href="#">Parent (Soon)</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container pb-5">
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h2 class="h4 mb-1">Teacher Dashboard</h2>
|
|
<p class="text-muted small">Daily attendance for <strong><?= date('l, d F Y') ?></strong></p>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="alert alert-info alert-dismissible fade show" role="alert">
|
|
<?= htmlspecialchars($message) ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Stats Row -->
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-4">
|
|
<div class="card p-3 stats-card">
|
|
<p>Total Learners</p>
|
|
<h3><?= $total_learners ?></h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card p-3 stats-card" style="border-left-color: #2E7D32;">
|
|
<p>Presence Rate</p>
|
|
<h3><?= $presence_rate ?>%</h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card p-3 stats-card" style="border-left-color: var(--secondary-color);">
|
|
<p>Pending Reports</p>
|
|
<h3>0</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Attendance Table -->
|
|
<div class="card">
|
|
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Class Register</h5>
|
|
<div class="input-group input-group-sm w-auto">
|
|
<span class="input-group-text bg-white border-end-0"><i class="bi bi-search"></i></span>
|
|
<input type="text" id="learnerSearch" class="form-control border-start-0" placeholder="Search learner...">
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<form method="POST">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0" id="learnersTable">
|
|
<thead>
|
|
<tr>
|
|
<th class="ps-4">Learner Name</th>
|
|
<th>Grade</th>
|
|
<th>Student ID</th>
|
|
<th class="text-end pe-4">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($learners as $learner): ?>
|
|
<tr>
|
|
<td class="ps-4">
|
|
<strong><?= htmlspecialchars($learner['full_name']) ?></strong>
|
|
</td>
|
|
<td><?= htmlspecialchars($learner['grade']) ?></td>
|
|
<td><span class="badge bg-light text-dark"><?= htmlspecialchars($learner['student_id']) ?></span></td>
|
|
<td class="text-end pe-4">
|
|
<div class="btn-group btn-group-sm" role="group">
|
|
<input type="radio" class="btn-check" name="attendance[<?= $learner['id'] ?>]"
|
|
id="pres_<?= $learner['id'] ?>" value="present"
|
|
<?= $learner['today_status'] === 'present' ? 'checked' : '' ?> required>
|
|
<label class="btn btn-outline-success" for="pres_<?= $learner['id'] ?>">Present</label>
|
|
|
|
<input type="radio" class="btn-check" name="attendance[<?= $learner['id'] ?>]"
|
|
id="abs_<?= $learner['id'] ?>" value="absent"
|
|
<?= $learner['today_status'] === 'absent' ? 'checked' : '' ?>>
|
|
<label class="btn btn-outline-danger" for="abs_<?= $learner['id'] ?>">Absent</label>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="p-3 text-end border-top">
|
|
<button type="submit" class="btn btn-primary px-4">
|
|
<i class="bi bi-cloud-upload me-2"></i> Save & Sync Register
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="bg-white border-top py-4 mt-5">
|
|
<div class="container text-center">
|
|
<p class="text-muted small mb-0">© <?= date('Y') ?> Township Schools Platform. Optimized for low-bandwidth.</p>
|
|
<div class="mt-2">
|
|
<span class="badge rounded-pill bg-light text-dark border"><i class="bi bi-wifi-off me-1"></i> Offline Capable</span>
|
|
<span class="badge rounded-pill bg-light text-dark border ms-2"><i class="bi bi-shield-check me-1"></i> POPIA Compliant</span>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="assets/js/main.js?v=<?= time() ?>"></script>
|
|
<script>
|
|
// Simple Search Filter
|
|
document.getElementById('learnerSearch').addEventListener('keyup', function() {
|
|
let filter = this.value.toUpperCase();
|
|
let rows = document.querySelector("#learnersTable tbody").rows;
|
|
for (let i = 0; i < rows.length; i++) {
|
|
let nameCol = rows[i].cells[0].textContent.toUpperCase();
|
|
let idCol = rows[i].cells[2].textContent.toUpperCase();
|
|
if (nameCol.indexOf(filter) > -1 || idCol.indexOf(filter) > -1) {
|
|
rows[i].style.display = "";
|
|
} else {
|
|
rows[i].style.display = "none";
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|