391 lines
18 KiB
PHP
391 lines
18 KiB
PHP
<?php
|
|
require_once '../includes/config.php';
|
|
|
|
// Check if user is logged in and is admin
|
|
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true || $_SESSION['role'] !== 'admin') {
|
|
header('Location: ../auth/login.php');
|
|
exit();
|
|
}
|
|
|
|
$title = "Admin Dashboard";
|
|
|
|
// Get statistics
|
|
$stats = [];
|
|
|
|
// Total Students
|
|
$sql = "SELECT COUNT(*) as total FROM students WHERE status = 1";
|
|
$result = query($conn, $sql);
|
|
$stats['total_students'] = mysqli_fetch_assoc($result)['total'];
|
|
|
|
// Total Users
|
|
$sql = "SELECT COUNT(*) as total FROM users WHERE status = 1";
|
|
$result = query($conn, $sql);
|
|
$stats['total_users'] = mysqli_fetch_assoc($result)['total'];
|
|
|
|
// Upcoming Activities
|
|
$sql = "SELECT COUNT(*) as total FROM activities WHERE status = 1 AND date >= CURDATE()";
|
|
$result = query($conn, $sql);
|
|
$stats['upcoming_activities'] = mysqli_fetch_assoc($result)['total'];
|
|
|
|
// Today's Attendance
|
|
$sql = "SELECT COUNT(*) as total FROM attendance WHERE DATE(created_at) = CURDATE()";
|
|
$result = query($conn, $sql);
|
|
$stats['today_attendance'] = mysqli_fetch_assoc($result)['total'];
|
|
|
|
// Get recent attendance
|
|
$recent_attendance = [];
|
|
$sql = "
|
|
SELECT a.*, s.full_name, s.student_id, ac.name as activity_name
|
|
FROM attendance a
|
|
JOIN students s ON a.student_id = s.id
|
|
JOIN activities ac ON a.activity_id = ac.id
|
|
ORDER BY a.created_at DESC
|
|
LIMIT 10
|
|
";
|
|
$result = query($conn, $sql);
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$recent_attendance[] = $row;
|
|
}
|
|
|
|
// Get upcoming activities
|
|
$upcoming_activities = [];
|
|
$sql = "
|
|
SELECT * FROM activities
|
|
WHERE date >= CURDATE() AND status = 1
|
|
ORDER BY date ASC, time_in ASC
|
|
LIMIT 5
|
|
";
|
|
$result = query($conn, $sql);
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$upcoming_activities[] = $row;
|
|
}
|
|
|
|
include '../includes/header.php';
|
|
?>
|
|
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-2">Dashboard Overview</h1>
|
|
<p class="text-muted">Welcome back, <?php echo $_SESSION['full_name']; ?>! Here's what's happening today.</p>
|
|
</div>
|
|
<div class="btn-group">
|
|
<button class="btn btn-primary" onclick="window.print()">
|
|
<i class="bi bi-printer me-2"></i> Print Report
|
|
</button>
|
|
<a href="attendance.php" class="btn btn-success">
|
|
<i class="bi bi-qr-code-scan me-2"></i> Scan QR
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics Cards -->
|
|
<div class="row mb-4">
|
|
<div class="col-xl-3 col-md-6 mb-4">
|
|
<div class="card stat-card border-left-primary">
|
|
<div class="card-body">
|
|
<div class="row align-items-center">
|
|
<div class="col-8">
|
|
<div class="text-uppercase text-primary mb-1">Total Students</div>
|
|
<div class="h2 font-weight-bold"><?php echo $stats['total_students']; ?></div>
|
|
<div class="text-muted">Active enrolled</div>
|
|
</div>
|
|
<div class="col-4 text-end">
|
|
<i class="bi bi-people-fill text-primary" style="font-size: 3rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-3 col-md-6 mb-4">
|
|
<div class="card stat-card border-left-success">
|
|
<div class="card-body">
|
|
<div class="row align-items-center">
|
|
<div class="col-8">
|
|
<div class="text-uppercase text-success mb-1">System Users</div>
|
|
<div class="h2 font-weight-bold"><?php echo $stats['total_users']; ?></div>
|
|
<div class="text-muted">Admin & Teachers</div>
|
|
</div>
|
|
<div class="col-4 text-end">
|
|
<i class="bi bi-person-badge-fill text-success" style="font-size: 3rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-3 col-md-6 mb-4">
|
|
<div class="card stat-card border-left-info">
|
|
<div class="card-body">
|
|
<div class="row align-items-center">
|
|
<div class="col-8">
|
|
<div class="text-uppercase text-info mb-1">Upcoming Activities</div>
|
|
<div class="h2 font-weight-bold"><?php echo $stats['upcoming_activities']; ?></div>
|
|
<div class="text-muted">Scheduled events</div>
|
|
</div>
|
|
<div class="col-4 text-end">
|
|
<i class="bi bi-calendar-event-fill text-info" style="font-size: 3rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-3 col-md-6 mb-4">
|
|
<div class="card stat-card border-left-warning">
|
|
<div class="card-body">
|
|
<div class="row align-items-center">
|
|
<div class="col-8">
|
|
<div class="text-uppercase text-warning mb-1">Today's Attendance</div>
|
|
<div class="h2 font-weight-bold"><?php echo $stats['today_attendance']; ?></div>
|
|
<div class="text-muted">Records today</div>
|
|
</div>
|
|
<div class="col-4 text-end">
|
|
<i class="bi bi-clock-history text-warning" style="font-size: 3rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Content Row -->
|
|
<div class="row">
|
|
<!-- Recent Attendance -->
|
|
<div class="col-lg-8">
|
|
<div class="card shadow mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h6 class="m-0 font-weight-bold">
|
|
<i class="bi bi-clock-history me-2"></i> Recent Attendance
|
|
</h6>
|
|
<a href="reports.php" class="btn btn-sm btn-primary">View All</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0" id="recentAttendance">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Student</th>
|
|
<th>Activity</th>
|
|
<th>Time In</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($recent_attendance)): ?>
|
|
<tr>
|
|
<td colspan="4" class="text-center py-4">
|
|
<i class="bi bi-inbox text-muted" style="font-size: 3rem;"></i>
|
|
<p class="mt-2">No attendance records yet</p>
|
|
</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($recent_attendance as $attendance): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<div class="avatar me-3">
|
|
<div class="bg-primary rounded-circle p-2 text-white">
|
|
<i class="bi bi-person"></i>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<strong><?php echo $attendance['full_name']; ?></strong><br>
|
|
<small class="text-muted"><?php echo $attendance['student_id']; ?></small>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="fw-bold"><?php echo $attendance['activity_name']; ?></div>
|
|
<small class="text-muted"><?php echo date('M d, Y', strtotime($attendance['created_at'])); ?></small>
|
|
</td>
|
|
<td>
|
|
<?php
|
|
if ($attendance['time_in']) {
|
|
echo '<span class="badge bg-light text-dark">';
|
|
echo '<i class="bi bi-clock me-1"></i>';
|
|
echo date('h:i A', strtotime($attendance['time_in']));
|
|
echo '</span>';
|
|
} else {
|
|
echo '<span class="badge bg-secondary">Pending</span>';
|
|
}
|
|
?>
|
|
</td>
|
|
<td>
|
|
<?php
|
|
$status = $attendance['status'] ?? 'pending';
|
|
$badge_class = 'secondary';
|
|
$icon = 'clock';
|
|
|
|
switch($status) {
|
|
case 'present':
|
|
$badge_class = 'success';
|
|
$icon = 'check-circle';
|
|
break;
|
|
case 'late':
|
|
$badge_class = 'warning';
|
|
$icon = 'clock-history';
|
|
break;
|
|
case 'absent':
|
|
$badge_class = 'danger';
|
|
$icon = 'x-circle';
|
|
break;
|
|
case 'excused':
|
|
$badge_class = 'info';
|
|
$icon = 'calendar-check';
|
|
break;
|
|
default:
|
|
$badge_class = 'secondary';
|
|
$icon = 'clock';
|
|
}
|
|
?>
|
|
<span class="badge bg-<?php echo $badge_class; ?>">
|
|
<i class="bi bi-<?php echo $icon; ?> me-1"></i>
|
|
<?php echo ucfirst($status); ?>
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Upcoming Activities -->
|
|
<div class="col-lg-4">
|
|
<div class="card shadow mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h6 class="m-0 font-weight-bold">
|
|
<i class="bi bi-calendar-event me-2"></i> Upcoming Activities
|
|
</h6>
|
|
<a href="manage_activities.php" class="btn btn-sm btn-primary">View All</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="list-group list-group-flush">
|
|
<?php if (empty($upcoming_activities)): ?>
|
|
<div class="text-center py-4">
|
|
<i class="bi bi-calendar-x text-muted" style="font-size: 3rem;"></i>
|
|
<p class="mt-2">No upcoming activities</p>
|
|
</div>
|
|
<?php else: ?>
|
|
<?php foreach ($upcoming_activities as $activity): ?>
|
|
<div class="list-group-item border-0 px-4 py-3">
|
|
<div class="d-flex align-items-start">
|
|
<div class="flex-shrink-0">
|
|
<div class="calendar-icon bg-primary text-white rounded text-center p-2" style="width: 60px;">
|
|
<div class="fw-bold" style="font-size: 1.5rem;"><?php echo date('d', strtotime($activity['date'])); ?></div>
|
|
<div class="small"><?php echo date('M', strtotime($activity['date'])); ?></div>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1 ms-3">
|
|
<h6 class="mb-1 fw-bold"><?php echo $activity['name']; ?></h6>
|
|
<small class="text-muted d-block">
|
|
<i class="bi bi-clock"></i>
|
|
<?php echo date('h:i A', strtotime($activity['time_in'])) . ' - ' . date('h:i A', strtotime($activity['time_out'])); ?>
|
|
</small>
|
|
<small class="text-muted d-block">
|
|
<i class="bi bi-geo-alt"></i> <?php echo $activity['location']; ?>
|
|
</small>
|
|
<div class="mt-2">
|
|
<?php
|
|
$activity_date = strtotime($activity['date'] . ' ' . $activity['time_in']);
|
|
$current_time = time();
|
|
|
|
if ($current_time >= $activity_date) {
|
|
echo '<span class="badge bg-success">Active Now</span>';
|
|
} else {
|
|
$days_diff = floor(($activity_date - $current_time) / (60 * 60 * 24));
|
|
if ($days_diff == 0) {
|
|
echo '<span class="badge bg-warning">Today</span>';
|
|
} elseif ($days_diff == 1) {
|
|
echo '<span class="badge bg-info">Tomorrow</span>';
|
|
} else {
|
|
echo '<span class="badge bg-secondary">In ' . $days_diff . ' days</span>';
|
|
}
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Stats -->
|
|
<div class="card shadow">
|
|
<div class="card-header">
|
|
<h6 class="m-0 font-weight-bold">
|
|
<i class="bi bi-bar-chart me-2"></i> Quick Stats
|
|
</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<?php
|
|
// Calculate attendance percentage
|
|
$percentage = $stats['total_students'] > 0 ?
|
|
round(($stats['today_attendance'] / $stats['total_students']) * 100, 1) : 0;
|
|
|
|
// Get today's date for display
|
|
$today = date('l, F j, Y');
|
|
?>
|
|
<h5 class="text-center mb-3"><?php echo $today; ?></h5>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex justify-content-between mb-1">
|
|
<span>Attendance Rate</span>
|
|
<strong><?php echo $percentage; ?>%</strong>
|
|
</div>
|
|
<div class="progress" style="height: 10px;">
|
|
<div class="progress-bar progress-bar-striped progress-bar-animated"
|
|
role="progressbar"
|
|
style="width: <?php echo $percentage; ?>%"
|
|
aria-valuenow="<?php echo $percentage; ?>"
|
|
aria-valuemin="0"
|
|
aria-valuemax="100">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row text-center">
|
|
<div class="col-6">
|
|
<div class="p-3 border rounded">
|
|
<div class="h4 mb-1"><?php echo $stats['today_attendance']; ?></div>
|
|
<small class="text-muted">Scanned Today</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="p-3 border rounded">
|
|
<div class="h4 mb-1"><?php echo $stats['total_students'] - $stats['today_attendance']; ?></div>
|
|
<small class="text-muted">Remaining</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php
|
|
$page_scripts = '
|
|
<script>
|
|
$(document).ready(function() {
|
|
$("#recentAttendance").DataTable({
|
|
pageLength: 5,
|
|
lengthMenu: [[5, 10, 25, -1], [5, 10, 25, "All"]],
|
|
order: [[2, "desc"]],
|
|
language: {
|
|
search: "_INPUT_",
|
|
searchPlaceholder: "Search attendance..."
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
';
|
|
include '../includes/footer.php';
|
|
?>
|