Files
QrCode-Attendance-System/src/admin/attendance.php
2026-01-07 14:09:59 +08:00

132 lines
6.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require __DIR__ . '/../includes/bootstrap.php';
require_login();
require_admin();
$pdo = db();
$activities = $pdo->query(
'SELECT id, name, date, time_in, time_out
FROM activities
WHERE status = 1 AND date >= CURDATE() - INTERVAL 1 DAY
ORDER BY date DESC, time_in DESC'
)->fetchAll();
$hasActivities = !empty($activities);
$todayAttendance = $pdo->query(
'SELECT att.*, s.full_name, s.student_id, act.name AS activity_name
FROM attendance att
INNER JOIN students s ON att.student_id = s.id
INNER JOIN activities act ON att.activity_id = act.id
WHERE DATE(att.time_in) = CURDATE()
ORDER BY att.time_in DESC'
)->fetchAll();
render_header('Scan Center', ['active' => 'attendance']);
?>
<div class="row g-4">
<div class="col-lg-5">
<div class="scan-panel h-100">
<h2>Admin Scan Center</h2>
<p class="mb-4 text-white-50">Only signed-in administrators can scan QR codes. Use the camera or type the token below.</p>
<?php if (!$hasActivities): ?>
<div class="alert alert-warning bg-warning-subtle text-dark">
No active activities available. Create one first to start scanning.
</div>
<?php endif; ?>
<form data-scan-form data-endpoint="<?= url_for('api/scan.php') ?>" class="v-stack gap-3">
<div>
<label class="form-label text-white">Activity</label>
<select name="activity_id" class="form-select form-select-lg" <?= $hasActivities ? '' : 'disabled' ?> required>
<?php if ($hasActivities): ?>
<?php foreach ($activities as $activity): ?>
<option value="<?= $activity['id'] ?>">
<?= sanitize($activity['name']) ?> — <?= format_date($activity['date'], 'M d') ?>
</option>
<?php endforeach; ?>
<?php else: ?>
<option value="">No activities</option>
<?php endif; ?>
</select>
</div>
<div>
<label class="form-label text-white">QR Token / Student ID</label>
<input type="text" name="qr_token" class="form-control form-control-lg"
placeholder="Scan or type token" autocomplete="off" <?= $hasActivities ? '' : 'disabled' ?> required>
</div>
<div>
<label class="form-label text-white">Notes (optional)</label>
<textarea name="notes" class="form-control" rows="2" placeholder="Remarks for this scan"></textarea>
</div>
<div class="d-flex gap-2 flex-wrap">
<button type="submit" class="btn btn-light btn-lg flex-grow-1" <?= $hasActivities ? '' : 'disabled' ?>>Record Attendance</button>
<button type="button" class="btn btn-outline-light btn-lg flex-grow-1" data-scan-start <?= $hasActivities ? '' : 'disabled' ?>>
Start Camera Scan
</button>
</div>
<p class="text-white-50 small mb-0">
The scanner auto-selects the best camera mode and falls back to a built-in detector if needed.
</p>
</form>
<div class="mt-4">
<p id="scan-status" class="fw-semibold mb-3"></p>
<div id="camera-viewer" class="camera-viewer bg-white rounded shadow-sm">
<div class="text-center text-muted small">Camera idle</div>
</div>
</div>
</div>
</div>
<div class="col-lg-7">
<div class="card shadow-sm h-100">
<div class="card-header bg-white d-flex justify-content-between align-items-center">
<h5 class="mb-0">Todays Attendance</h5>
<span class="badge bg-primary-subtle text-primary"><?= count($todayAttendance) ?> captured</span>
</div>
<div class="card-body">
<div id="scan-result" class="mb-4"></div>
<?php if (!$todayAttendance): ?>
<p class="text-muted text-center mb-0">No scans recorded today.</p>
<?php else: ?>
<div class="table-responsive">
<table class="table align-middle">
<thead>
<tr>
<th>Student</th>
<th>Activity</th>
<th>Time In</th>
<th>Time Out</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($todayAttendance as $row): ?>
<tr>
<td>
<strong><?= sanitize($row['full_name']) ?></strong><br>
<span class="text-muted-sm"><?= sanitize($row['student_id']) ?></span>
</td>
<td><?= sanitize($row['activity_name']) ?></td>
<td><?= format_datetime($row['time_in'], 'h:i A') ?></td>
<td><?= format_datetime($row['time_out'], 'h:i A') ?></td>
<td>
<span class="badge bg-success-subtle text-success badge-status">
<?= strtoupper(sanitize($row['status'])) ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php
render_footer([
'extra_js' => [
'https://unpkg.com/html5-qrcode@2.3.10/html5-qrcode.min.js',
],
]);