<?php
// Include header
include_once 'includes/header.php';
// Check if instructor is logged in
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'instructor') {
header('Location: ../login.php');
exit;
}
$instructor_id = $_SESSION['user_id'];
$success_message = '';
$error_message = '';
// Initialize filters
$filter_course = isset($_GET['course_id']) ? $_GET['course_id'] : '';
$filter_month = isset($_GET['month']) ? $_GET['month'] : date('Y-m');
$filter_student = isset($_GET['student_id']) ? $_GET['student_id'] : '';
// Get courses for filter
$courses_query = "SELECT id, title FROM courses WHERE status = 'active' ORDER BY title";
$stmt = $conn->prepare($courses_query);
$stmt->execute();
$courses_result = $stmt->get_result();
$courses = [];
while ($row = $courses_result->fetch_assoc()) {
$courses[] = $row;
}
// Get students for filter
$students_query = "
SELECT DISTINCT u.id, CONCAT(u.first_name, ' ', u.last_name) as student_name
FROM users u
INNER JOIN enrollments e ON u.id = e.user_id
WHERE u.role = 'student' AND e.status = 'active'
ORDER BY u.first_name, u.last_name
";
$stmt = $conn->prepare($students_query);
$stmt->execute();
$students_result = $stmt->get_result();
$students = [];
while ($row = $students_result->fetch_assoc()) {
$students[] = $row;
}
// Build the attendance report query
$attendance_query = "
SELECT
a.id,
a.date,
a.status,
a.notes,
u.id as student_id,
CONCAT(u.first_name, ' ', u.last_name) as student_name,
u.email,
c.id as course_id,
c.title as course_title
FROM attendance a
INNER JOIN users u ON a.student_id = u.id
INNER JOIN courses c ON a.course_id = c.id
WHERE a.marked_by = ?
";
// Apply filters
$query_params = [$instructor_id];
if (!empty($filter_course)) {
$attendance_query .= " AND a.course_id = ?";
$query_params[] = $filter_course;
}
if (!empty($filter_month)) {
$attendance_query .= " AND DATE_FORMAT(a.date, '%Y-%m') = ?";
$query_params[] = $filter_month;
}
if (!empty($filter_student)) {
$attendance_query .= " AND a.student_id = ?";
$query_params[] = $filter_student;
}
$attendance_query .= " ORDER BY a.date DESC, c.title, u.first_name, u.last_name";
// Execute query
$stmt = $conn->prepare($attendance_query);
$stmt->bind_param(str_repeat('s', count($query_params)), ...$query_params);
$stmt->execute();
$attendance_result = $stmt->get_result();
// Format attendance data for reporting
$attendance_data = [];
$attendance_summary = [
'total_records' => 0,
'present' => 0,
'absent' => 0,
'late' => 0,
'excused' => 0
];
while ($row = $attendance_result->fetch_assoc()) {
$attendance_data[] = $row;
$attendance_summary['total_records']++;
$attendance_summary[$row['status']]++;
}
// Handle CSV download
if (isset($_GET['download']) && $_GET['download'] === 'csv') {
// Set headers for CSV download
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="attendance_report_' . $filter_month . '.csv"');
// Create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// Output the column headings
fputcsv($output, ['Date', 'Student Name', 'Student Email', 'Course', 'Status', 'Notes']);
// Output each row of data
foreach ($attendance_data as $row) {
fputcsv($output, [
date('Y-m-d', strtotime($row['date'])),
$row['student_name'],
$row['email'],
$row['course_title'],
ucfirst($row['status']),
$row['notes']
]);
}
// Close the file pointer
fclose($output);
exit;
}
?>
<div class="container-fluid">
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">Attendance Reports</h5>
<p class="text-muted">View and download attendance reports for your courses</p>
</div>
</div>
</div>
</div>
<?php if ($success_message): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="fas fa-check-circle me-2"></i> <?php echo $success_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="row">
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Filter Report</h5>
</div>
<div class="card-body">
<form method="get" action="" id="filterForm">
<div class="mb-3">
<label for="month" class="form-label">Month</label>
<input type="month" name="month" id="month" class="form-control" value="<?php echo $filter_month; ?>">
</div>
<div class="mb-3">
<label for="course_id" class="form-label">Course</label>
<select name="course_id" id="course_id" class="form-select">
<option value="">All Courses</option>
<?php foreach ($courses as $course): ?>
<option value="<?php echo $course['id']; ?>" <?php echo ($filter_course == $course['id']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($course['title']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="student_id" class="form-label">Student</label>
<select name="student_id" id="student_id" class="form-select">
<option value="">All Students</option>
<?php foreach ($students as $student): ?>
<option value="<?php echo $student['id']; ?>" <?php echo ($filter_student == $student['id']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($student['student_name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">
<i class="fas fa-filter me-2"></i> Apply Filter
</button>
<?php if (!empty($attendance_data)): ?>
<a href="<?php echo $_SERVER['REQUEST_URI'] . (strpos($_SERVER['REQUEST_URI'], '?') ? '&' : '?') . 'download=csv'; ?>" class="btn btn-success">
<i class="fas fa-download me-2"></i> Download CSV
</a>
<?php endif; ?>
</div>
</form>
</div>
</div>
<?php if (!empty($attendance_data)): ?>
<div class="card mt-4">
<div class="card-header">
<h5 class="mb-0">Summary</h5>
</div>
<div class="card-body">
<div class="mb-3">
<h6 class="text-muted">Total Records</h6>
<h3><?php echo $attendance_summary['total_records']; ?></h3>
</div>
<div class="progress mb-3" style="height: 24px;">
<?php if ($attendance_summary['total_records'] > 0): ?>
<div class="progress-bar bg-success" role="progressbar"
style="width: <?php echo ($attendance_summary['present'] / $attendance_summary['total_records']) * 100; ?>%"
aria-valuenow="<?php echo $attendance_summary['present']; ?>" aria-valuemin="0" aria-valuemax="<?php echo $attendance_summary['total_records']; ?>">
<?php echo $attendance_summary['present']; ?> Present
</div>
<?php endif; ?>
</div>
<div class="d-flex justify-content-between mb-2">
<div>
<span class="badge bg-success">Present</span>
</div>
<div><?php echo $attendance_summary['present']; ?></div>
</div>
<div class="d-flex justify-content-between mb-2">
<div>
<span class="badge bg-danger">Absent</span>
</div>
<div><?php echo $attendance_summary['absent']; ?></div>
</div>
<div class="d-flex justify-content-between mb-2">
<div>
<span class="badge bg-warning text-dark">Late</span>
</div>
<div><?php echo $attendance_summary['late']; ?></div>
</div>
<div class="d-flex justify-content-between">
<div>
<span class="badge bg-info">Excused</span>
</div>
<div><?php echo $attendance_summary['excused']; ?></div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<div class="col-md-8">
<?php if (empty($attendance_data)): ?>
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i> No attendance records found with the current filters. Please adjust your filters to see results.
</div>
<?php else: ?>
<div class="card">
<div class="card-header">
<h5 class="mb-0">Attendance Records</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover" id="attendanceTable">
<thead>
<tr>
<th>Date</th>
<th>Student</th>
<th>Course</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<?php foreach ($attendance_data as $record): ?>
<tr>
<td><?php echo date('d M Y', strtotime($record['date'])); ?></td>
<td><?php echo htmlspecialchars($record['student_name']); ?></td>
<td><?php echo htmlspecialchars($record['course_title']); ?></td>
<td>
<span class="badge bg-<?php
echo $record['status'] === 'present' ? 'success' :
($record['status'] === 'absent' ? 'danger' :
($record['status'] === 'late' ? 'warning' : 'info'));
?> <?php echo $record['status'] === 'late' ? 'text-dark' : ''; ?>">
<?php echo ucfirst($record['status']); ?>
</span>
</td>
<td><?php echo !empty($record['notes']) ? htmlspecialchars($record['notes']) : '-'; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize DataTable for better user experience
if (typeof $.fn.DataTable !== 'undefined') {
$('#attendanceTable').DataTable({
"paging": true,
"lengthChange": true,
"searching": true,
"ordering": true,
"info": true,
"autoWidth": false,
"responsive": true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
});
}
});
</script>
<?php
// Include footer
include_once 'includes/footer.php';
?>