1207 lines
57 KiB
PHP
1207 lines
57 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 = "Manage Students";
|
|
|
|
// Initialize variables
|
|
$action = $_GET['action'] ?? '';
|
|
$student_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
|
$message = '';
|
|
$message_type = '';
|
|
|
|
// CSRF token for POST actions
|
|
$csrf_token = bin2hex(random_bytes(32));
|
|
$_SESSION['csrf_token'] = $csrf_token;
|
|
|
|
// ==================== HELPER FUNCTIONS ====================
|
|
function sanitizeInput($input) {
|
|
return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
|
|
}
|
|
|
|
function exportToExcel($conn) {
|
|
$filename = "students_" . date('Y-m-d') . ".csv";
|
|
|
|
header('Content-Type: text/csv');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
|
header('Pragma: no-cache');
|
|
header('Expires: 0');
|
|
|
|
$output = fopen('php://output', 'w');
|
|
|
|
// Add BOM for UTF-8
|
|
fputs($output, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
|
|
|
// Header row
|
|
fputcsv($output, [
|
|
'Student ID', 'Full Name', 'Gender', 'Year Level', 'Course',
|
|
'Department', 'School', 'Email', 'Contact', 'Status'
|
|
]);
|
|
|
|
// Get all students
|
|
$sql = "SELECT s.*, g.name as gender, c.code as course_code, c.name as course_name,
|
|
d.code as department_code, d.name as department_name,
|
|
sc.code as school_code, sc.name as school_name
|
|
FROM students s
|
|
LEFT JOIN genders g ON s.gender_id = g.id
|
|
LEFT JOIN courses c ON s.course_id = c.id
|
|
LEFT JOIN departments d ON s.department_id = d.id
|
|
LEFT JOIN schools sc ON s.school_id = sc.id
|
|
ORDER BY s.created_at DESC";
|
|
|
|
$result = mysqli_query($conn, $sql);
|
|
|
|
if ($result) {
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
fputcsv($output, [
|
|
$row['student_id'],
|
|
$row['full_name'],
|
|
$row['gender'],
|
|
'Year ' . $row['year_level'],
|
|
$row['course_code'] . ' - ' . $row['course_name'],
|
|
$row['department_name'],
|
|
$row['school_name'],
|
|
$row['email'],
|
|
$row['contact_number'],
|
|
$row['status'] == 1 ? 'Active' : 'Inactive'
|
|
]);
|
|
}
|
|
}
|
|
|
|
fclose($output);
|
|
exit();
|
|
}
|
|
|
|
// ==================== HANDLE FORM SUBMISSIONS ====================
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
|
// --- Add Student (Modal) ---
|
|
if (isset($_POST['modal_add_student'])) {
|
|
$sid = trim($_POST['student_id'] ?? '');
|
|
$full = trim($_POST['full_name'] ?? '');
|
|
$gender_id = intval($_POST['gender_id'] ?? 0);
|
|
$year_level = intval($_POST['year_level'] ?? 0);
|
|
$course_id = intval($_POST['course_id'] ?? 0);
|
|
$department_id = intval($_POST['department_id'] ?? 0);
|
|
$school_id = intval($_POST['school_id'] ?? 0);
|
|
$birth_date = ($_POST['birth_date'] ?? '') ?: null;
|
|
if ($birth_date === '0000-00-00') { $birth_date = null; }
|
|
$contact = trim($_POST['contact_number'] ?? '');
|
|
$email = trim($_POST['email'] ?? '');
|
|
$address = trim($_POST['address'] ?? '');
|
|
$status = isset($_POST['status']) ? 1 : 1; // default active
|
|
|
|
// basic required validation
|
|
if ($sid === '' || $full === '' || $gender_id === 0 || $year_level === 0 || $course_id === 0 || $department_id === 0 || $school_id === 0) {
|
|
$message = 'Please fill in all required fields.';
|
|
$message_type = 'danger';
|
|
} else {
|
|
// duplicate check
|
|
$dup = mysqli_prepare($conn, "SELECT id FROM students WHERE student_id = ?");
|
|
mysqli_stmt_bind_param($dup, 's', $sid);
|
|
mysqli_stmt_execute($dup);
|
|
mysqli_stmt_store_result($dup);
|
|
if (mysqli_stmt_num_rows($dup) > 0) {
|
|
$message = 'Student ID already exists.';
|
|
$message_type = 'danger';
|
|
} else {
|
|
$qr = 'STU_' . $sid . '_' . uniqid();
|
|
$sql = "INSERT INTO students (student_id, qr_code, full_name, gender_id, year_level, course_id, department_id, school_id, birth_date, contact_number, email, address, created_at, updated_at, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW(), ?)";
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
// null-safe birth_date
|
|
$bd = $birth_date ?: null;
|
|
mysqli_stmt_bind_param($stmt, 'sssiiiiissssi', $sid, $qr, $full, $gender_id, $year_level, $course_id, $department_id, $school_id, $bd, $contact, $email, $address, $status);
|
|
if (mysqli_stmt_execute($stmt)) {
|
|
$_SESSION['flash_message'] = 'Student added successfully!';
|
|
$_SESSION['flash_type'] = 'success';
|
|
header('Location: manage_students.php');
|
|
exit();
|
|
} else {
|
|
$message = 'Error adding student: ' . mysqli_error($conn);
|
|
$message_type = 'danger';
|
|
}
|
|
mysqli_stmt_close($stmt);
|
|
}
|
|
mysqli_stmt_close($dup);
|
|
}
|
|
}
|
|
|
|
// --- Update Student (Modal) ---
|
|
elseif (isset($_POST['modal_update_student'])) {
|
|
$id = intval($_POST['id'] ?? 0);
|
|
$sid = trim($_POST['student_id'] ?? '');
|
|
$full = trim($_POST['full_name'] ?? '');
|
|
$gender_id = intval($_POST['gender_id'] ?? 0);
|
|
$year_level = intval($_POST['year_level'] ?? 0);
|
|
$course_id = intval($_POST['course_id'] ?? 0);
|
|
$department_id = intval($_POST['department_id'] ?? 0);
|
|
$school_id = intval($_POST['school_id'] ?? 0);
|
|
$birth_date = ($_POST['birth_date'] ?? '') ?: null;
|
|
if ($birth_date === '0000-00-00') { $birth_date = null; }
|
|
$contact = trim($_POST['contact_number'] ?? '');
|
|
$email = trim($_POST['email'] ?? '');
|
|
$address = trim($_POST['address'] ?? '');
|
|
$status = isset($_POST['status']) ? 1 : 0;
|
|
|
|
if ($id <= 0) {
|
|
$message = 'Invalid student id.';
|
|
$message_type = 'danger';
|
|
} elseif ($sid === '' || $full === '' || $gender_id === 0 || $year_level === 0 || $course_id === 0 || $department_id === 0 || $school_id === 0) {
|
|
$message = 'Please fill in all required fields.';
|
|
$message_type = 'danger';
|
|
} else {
|
|
// duplicate student_id check excluding current id
|
|
$dup = mysqli_prepare($conn, "SELECT id FROM students WHERE student_id = ? AND id != ?");
|
|
mysqli_stmt_bind_param($dup, 'si', $sid, $id);
|
|
mysqli_stmt_execute($dup);
|
|
mysqli_stmt_store_result($dup);
|
|
if (mysqli_stmt_num_rows($dup) > 0) {
|
|
$message = 'Student ID already exists.';
|
|
$message_type = 'danger';
|
|
} else {
|
|
// Build dynamic update allowing NULLs
|
|
$set = 'student_id = ?, full_name = ?, gender_id = ?, year_level = ?, course_id = ?, department_id = ?, school_id = ?, status = ?, updated_at = NOW()';
|
|
$types = 'ssiiiiii';
|
|
$params = [$sid, $full, $gender_id, $year_level, $course_id, $department_id, $school_id, $status];
|
|
if ($birth_date) { $set .= ', birth_date = ?'; $types .= 's'; $params[] = $birth_date; } else { $set .= ', birth_date = NULL'; }
|
|
if ($contact !== '') { $set .= ', contact_number = ?'; $types .= 's'; $params[] = $contact; } else { $set .= ', contact_number = NULL'; }
|
|
if ($email !== '') { $set .= ', email = ?'; $types .= 's'; $params[] = $email; } else { $set .= ', email = NULL'; }
|
|
if ($address !== '') { $set .= ', address = ?'; $types .= 's'; $params[] = $address; } else { $set .= ', address = NULL'; }
|
|
$sql = "UPDATE students SET $set WHERE id = ?";
|
|
$types .= 'i';
|
|
$params[] = $id;
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
if ($stmt && mysqli_stmt_bind_param($stmt, $types, ...$params) && mysqli_stmt_execute($stmt)) {
|
|
$_SESSION['flash_message'] = 'Student updated successfully!';
|
|
$_SESSION['flash_type'] = 'success';
|
|
header('Location: manage_students.php');
|
|
exit();
|
|
} else {
|
|
$message = 'Error updating student: ' . mysqli_error($conn);
|
|
$message_type = 'danger';
|
|
}
|
|
if ($stmt) { mysqli_stmt_close($stmt); }
|
|
}
|
|
mysqli_stmt_close($dup);
|
|
}
|
|
}
|
|
|
|
// --- Delete Student ---
|
|
if (isset($_POST['delete_student'])) {
|
|
$student_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
|
if ($student_id > 0) {
|
|
// Check if student exists
|
|
$check_sql = "SELECT id, full_name FROM students WHERE id = ?";
|
|
$stmt = mysqli_prepare($conn, $check_sql);
|
|
mysqli_stmt_bind_param($stmt, 'i', $student_id);
|
|
mysqli_stmt_execute($stmt);
|
|
$result = mysqli_stmt_get_result($stmt);
|
|
|
|
if ($row = mysqli_fetch_assoc($result)) {
|
|
$student_name = $row['full_name'];
|
|
|
|
// Remove associated files before deletion
|
|
$fetch_sql = "SELECT picture_path, qr_code_image, full_name FROM students WHERE id = ?";
|
|
$stmtf = mysqli_prepare($conn, $fetch_sql);
|
|
mysqli_stmt_bind_param($stmtf, 'i', $student_id);
|
|
mysqli_stmt_execute($stmtf);
|
|
$resf = mysqli_stmt_get_result($stmtf);
|
|
if ($fileRow = mysqli_fetch_assoc($resf)) {
|
|
if (!empty($fileRow['picture_path']) && file_exists('../' . $fileRow['picture_path'])) {
|
|
@unlink('../' . $fileRow['picture_path']);
|
|
}
|
|
if (!empty($fileRow['qr_code_image']) && file_exists('../' . $fileRow['qr_code_image'])) {
|
|
@unlink('../' . $fileRow['qr_code_image']);
|
|
}
|
|
// Ensure we have name
|
|
$student_name = $fileRow['full_name'];
|
|
}
|
|
mysqli_stmt_close($stmtf);
|
|
|
|
// Delete the student; related attendance/logs cascade via FK constraints
|
|
$sql = "DELETE FROM students WHERE id = ?";
|
|
$stmt3 = mysqli_prepare($conn, $sql);
|
|
mysqli_stmt_bind_param($stmt3, 'i', $student_id);
|
|
|
|
if (mysqli_stmt_execute($stmt3)) {
|
|
$affected_rows = mysqli_stmt_affected_rows($stmt3);
|
|
|
|
if ($affected_rows > 0) {
|
|
$_SESSION['flash_message'] = "Student '$student_name' deleted successfully!";
|
|
$_SESSION['flash_type'] = 'success';
|
|
header("Location: manage_students.php?msg=deleted");
|
|
exit();
|
|
} else {
|
|
$message = 'No student was deleted. Student might not exist or there was an error.';
|
|
$message_type = 'warning';
|
|
error_log("No rows affected when deleting student ID: $student_id");
|
|
}
|
|
} else {
|
|
$error = mysqli_error($conn);
|
|
$message = 'Error deleting student: ' . $error;
|
|
$message_type = 'danger';
|
|
error_log("SQL Error deleting student: $error");
|
|
}
|
|
mysqli_stmt_close($stmt3);
|
|
|
|
} else {
|
|
$message = 'Student not found!';
|
|
$message_type = 'danger';
|
|
error_log("Student ID $student_id not found");
|
|
}
|
|
mysqli_stmt_close($stmt);
|
|
}
|
|
}
|
|
|
|
// --- Export to Excel ---
|
|
elseif (isset($_POST['export_excel'])) {
|
|
exportToExcel($conn);
|
|
exit();
|
|
}
|
|
|
|
// --- Bulk Actions ---
|
|
elseif (isset($_POST['bulk_action']) && isset($_POST['selected_students'])) {
|
|
$bulk_action = sanitizeInput($_POST['bulk_action']);
|
|
$selected_students = $_POST['selected_students'];
|
|
|
|
// Validate selected students
|
|
if (empty($selected_students) || !is_array($selected_students)) {
|
|
$message = 'No students selected.';
|
|
$message_type = 'warning';
|
|
} else {
|
|
// Sanitize all IDs
|
|
$sanitized_ids = array_map('intval', $selected_students);
|
|
$ids = implode(',', $sanitized_ids);
|
|
$count = count($sanitized_ids);
|
|
|
|
// Check if force delete is requested
|
|
$force_delete = isset($_POST['force_bulk_delete']) && $_POST['force_bulk_delete'] == 1;
|
|
|
|
// Prepare SQL based on action
|
|
if ($bulk_action === 'activate') {
|
|
$sql = "UPDATE students SET status = 1, updated_at = NOW() WHERE id IN ($ids)";
|
|
$success_msg = "$count student(s) activated successfully!";
|
|
} elseif ($bulk_action === 'deactivate') {
|
|
$sql = "UPDATE students SET status = 0, updated_at = NOW() WHERE id IN ($ids)";
|
|
$success_msg = "$count student(s) deactivated successfully!";
|
|
} elseif ($bulk_action === 'delete') {
|
|
// Direct bulk delete; related attendance and logs cascade via FK constraints
|
|
$sql = "DELETE FROM students WHERE id IN ($ids)";
|
|
$success_msg = "$count student(s) deleted successfully!";
|
|
}
|
|
|
|
if (isset($sql) && empty($message)) {
|
|
// If deleting, clean up files first
|
|
if ($bulk_action === 'delete') {
|
|
$files_sql = "SELECT id, picture_path, qr_code_image FROM students WHERE id IN ($ids)";
|
|
$files_result = mysqli_query($conn, $files_sql);
|
|
if ($files_result) {
|
|
while ($f = mysqli_fetch_assoc($files_result)) {
|
|
if (!empty($f['picture_path']) && file_exists('../' . $f['picture_path'])) {
|
|
@unlink('../' . $f['picture_path']);
|
|
}
|
|
if (!empty($f['qr_code_image']) && file_exists('../' . $f['qr_code_image'])) {
|
|
@unlink('../' . $f['qr_code_image']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
error_log("Executing SQL: $sql");
|
|
if (mysqli_query($conn, $sql)) {
|
|
$affected_rows = mysqli_affected_rows($conn);
|
|
error_log("Bulk action affected $affected_rows row(s)");
|
|
|
|
$_SESSION['flash_message'] = $success_msg;
|
|
$_SESSION['flash_type'] = 'success';
|
|
header("Location: manage_students.php?msg=bulk");
|
|
exit();
|
|
} else {
|
|
$error = mysqli_error($conn);
|
|
$message = 'Error performing bulk action: ' . $error;
|
|
$message_type = 'danger';
|
|
error_log("SQL Error in bulk action: $error");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for flash messages from session
|
|
if (isset($_SESSION['flash_message'])) {
|
|
$message = $_SESSION['flash_message'];
|
|
$message_type = $_SESSION['flash_type'];
|
|
unset($_SESSION['flash_message']);
|
|
unset($_SESSION['flash_type']);
|
|
}
|
|
|
|
// ==================== GET STUDENTS DATA ====================
|
|
$students = [];
|
|
$sql = "SELECT s.*, g.name as gender, c.code as course_code, c.name as course_name,
|
|
d.code as department_code, d.name as department_name,
|
|
sc.code as school_code, sc.name as school_name
|
|
FROM students s
|
|
LEFT JOIN genders g ON s.gender_id = g.id
|
|
LEFT JOIN courses c ON s.course_id = c.id
|
|
LEFT JOIN departments d ON s.department_id = d.id
|
|
LEFT JOIN schools sc ON s.school_id = sc.id
|
|
ORDER BY s.created_at DESC";
|
|
|
|
$result = mysqli_query($conn, $sql);
|
|
if ($result) {
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$students[] = $row;
|
|
}
|
|
} else {
|
|
error_log("Error fetching students: " . mysqli_error($conn));
|
|
}
|
|
|
|
// Dropdown data for modals
|
|
$genders = [];
|
|
$courses = [];
|
|
$departments = [];
|
|
$schools = [];
|
|
$r = mysqli_query($conn, "SELECT * FROM genders ORDER BY id");
|
|
if ($r) { while ($row = mysqli_fetch_assoc($r)) { $genders[] = $row; } }
|
|
$r = mysqli_query($conn, "SELECT * FROM courses WHERE status = 1 ORDER BY code");
|
|
if ($r) { while ($row = mysqli_fetch_assoc($r)) { $courses[] = $row; } }
|
|
$r = mysqli_query($conn, "SELECT * FROM departments WHERE status = 1 ORDER BY code");
|
|
if ($r) { while ($row = mysqli_fetch_assoc($r)) { $departments[] = $row; } }
|
|
$r = mysqli_query($conn, "SELECT * FROM schools WHERE status = 1 ORDER BY code");
|
|
if ($r) { while ($row = mysqli_fetch_assoc($r)) { $schools[] = $row; } }
|
|
|
|
// ==================== INCLUDE HEADER ====================
|
|
include '../includes/header.php';
|
|
?>
|
|
|
|
<style>
|
|
/* Compact Styles */
|
|
body { font-size: 0.9rem; }
|
|
.table-sm th { padding: 6px 8px; font-size: 0.8rem; }
|
|
.table-sm td { padding: 4px 8px; font-size: 0.85rem; }
|
|
.btn-xs { padding: 0.15rem 0.5rem; font-size: 0.75rem; }
|
|
.badge-sm { font-size: 0.7rem; padding: 2px 5px; }
|
|
.search-box input { font-size: 0.85rem; height: 32px; }
|
|
.stat-card { padding: 10px; }
|
|
.stat-card h3 { font-size: 1.3rem; margin-bottom: 0.2rem; }
|
|
.stat-card h6 { font-size: 0.75rem; margin-bottom: 0.3rem; }
|
|
.avatar { width: 30px !important; height: 30px !important; font-size: 0.8rem; }
|
|
.avatar i { font-size: 0.8rem; }
|
|
.dropdown-menu { font-size: 0.85rem; min-width: 180px; }
|
|
.alert form { display: inline; }
|
|
.debug-info { font-size: 0.7rem; color: #666; margin-top: 5px; }
|
|
</style>
|
|
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<div>
|
|
<h1 class="h4 mb-1">Manage Students</h1>
|
|
<small class="text-muted">Manage student records</small>
|
|
<?php if (isset($_GET['debug'])): ?>
|
|
<div class="debug-info">
|
|
PHP Version: <?php echo phpversion(); ?> |
|
|
DB Connected: <?php echo mysqli_ping($conn) ? 'Yes' : 'No'; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div>
|
|
<button type="button" class="btn btn-primary btn-sm" id="openAddModal">
|
|
<i class="bi bi-person-plus me-1"></i> Add
|
|
</button>
|
|
<a href="?debug=1" class="btn btn-outline-info btn-sm ms-1" title="Debug Info">
|
|
<i class="bi bi-bug"></i>
|
|
</a>
|
|
<form method="POST" action="" class="d-inline">
|
|
<button type="submit" name="export_excel" class="btn btn-outline-success btn-sm ms-1">
|
|
<i class="bi bi-file-excel me-1"></i> Export
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Message Alert -->
|
|
<?php
|
|
// Check for URL messages
|
|
if (isset($_GET['msg'])) {
|
|
switch ($_GET['msg']) {
|
|
case 'added':
|
|
$message = 'Student added successfully!';
|
|
$message_type = 'success';
|
|
break;
|
|
case 'updated':
|
|
$message = 'Student updated successfully!';
|
|
$message_type = 'success';
|
|
break;
|
|
case 'deleted':
|
|
$message = 'Student deleted successfully!';
|
|
$message_type = 'success';
|
|
break;
|
|
case 'bulk':
|
|
$message = 'Bulk action completed!';
|
|
$message_type = 'success';
|
|
break;
|
|
case 'notfound':
|
|
$message = 'Student not found!';
|
|
$message_type = 'danger';
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($message): ?>
|
|
<div class="alert alert-<?php echo $message_type; ?> alert-dismissible fade show py-2 mb-3" role="alert" style="font-size: 0.85rem;">
|
|
<i class="bi bi-<?php echo $message_type == 'success' ? 'check-circle' : 'exclamation-triangle'; ?> me-1"></i>
|
|
<?php echo $message; ?>
|
|
<?php if ($message_type != 'danger' && $message_type != 'warning'): ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close" style="font-size: 0.7rem;"></button>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Statistics Cards - Compact -->
|
|
<div class="row g-2 mb-3">
|
|
<div class="col-md-3">
|
|
<div class="card stat-card border-start-primary py-2">
|
|
<div class="card-body p-2">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-0" style="font-size: 0.75rem;">Total</h6>
|
|
<h4 class="mb-0" style="font-size: 1.2rem;"><?php echo number_format(count($students)); ?></h4>
|
|
</div>
|
|
<i class="bi bi-people text-primary" style="font-size: 1.8rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card stat-card border-start-success py-2">
|
|
<div class="card-body p-2">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-0" style="font-size: 0.75rem;">Active</h6>
|
|
<h4 class="mb-0" style="font-size: 1.2rem;">
|
|
<?php
|
|
$active_count = 0;
|
|
foreach ($students as $student) {
|
|
$active_count += $student['status'];
|
|
}
|
|
echo number_format($active_count);
|
|
?>
|
|
</h4>
|
|
</div>
|
|
<i class="bi bi-person-check text-success" style="font-size: 1.8rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card stat-card border-start-info py-2">
|
|
<div class="card-body p-2">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-0" style="font-size: 0.75rem;">Inactive</h6>
|
|
<h4 class="mb-0" style="font-size: 1.2rem;">
|
|
<?php
|
|
$inactive_count = count($students) - $active_count;
|
|
echo number_format($inactive_count);
|
|
?>
|
|
</h4>
|
|
</div>
|
|
<i class="bi bi-person-x text-info" style="font-size: 1.8rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card stat-card border-start-warning py-2">
|
|
<div class="card-body p-2">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-0" style="font-size: 0.75rem;">Departments</h6>
|
|
<h4 class="mb-0" style="font-size: 1.2rem;">
|
|
<?php
|
|
$sql = "SELECT COUNT(*) as count FROM departments WHERE status = 1";
|
|
$result = mysqli_query($conn, $sql);
|
|
echo $result ? mysqli_fetch_assoc($result)['count'] : 0;
|
|
?>
|
|
</h4>
|
|
</div>
|
|
<i class="bi bi-building text-warning" style="font-size: 1.8rem; opacity: 0.7;"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Students Table -->
|
|
<form method="POST" action="" id="bulkForm">
|
|
<input type="hidden" name="csrf_token" value="<?php echo $csrf_token; ?>">
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header py-2">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0" style="font-size: 0.9rem;">
|
|
<i class="bi bi-people me-1"></i> Student List
|
|
</h6>
|
|
<div class="d-flex">
|
|
<input type="text" id="searchInput" class="form-control form-control-sm me-2"
|
|
placeholder="Search..." style="width: 180px; height: 28px; font-size: 0.8rem;">
|
|
<div class="btn-group btn-group-sm">
|
|
<button class="btn btn-outline-secondary btn-xs" type="button" onclick="printReport()" title="Print">
|
|
<i class="bi bi-printer"></i>
|
|
</button>
|
|
<button type="submit" name="export_excel" class="btn btn-outline-primary btn-xs" title="Export">
|
|
<i class="bi bi-download"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<!-- Bulk Actions Bar -->
|
|
<div class="bulk-actions-bar p-2 bg-light border-bottom" style="display: none; font-size: 0.8rem;">
|
|
<div class="d-flex align-items-center">
|
|
<div class="form-check me-2">
|
|
<input class="form-check-input" type="checkbox" id="selectAll" style="transform: scale(0.8);">
|
|
<label class="form-check-label" for="selectAll">
|
|
<span id="selectedCount">0</span> selected
|
|
</label>
|
|
</div>
|
|
<select class="form-select form-select-sm me-2" name="bulk_action" style="width: 130px; height: 26px; font-size: 0.8rem;">
|
|
<option value="">Bulk Actions</option>
|
|
<option value="activate">Activate</option>
|
|
<option value="deactivate">Deactivate</option>
|
|
<option value="delete">Delete</option>
|
|
</select>
|
|
<button type="submit" class="btn btn-primary btn-sm py-0 px-2" style="font-size: 0.8rem;">Apply</button>
|
|
<button type="button" class="btn btn-outline-secondary btn-sm py-0 px-2 ms-1" style="font-size: 0.8rem;" onclick="clearBulkSelection()">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0" id="studentsTable">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th width="20">
|
|
<input type="checkbox" id="toggleAll" style="transform: scale(0.8);">
|
|
</th>
|
|
<th width="30">#</th>
|
|
<th width="90">Student ID</th>
|
|
<th>Student</th>
|
|
<th width="150">Course</th>
|
|
<th width="60">Year</th>
|
|
<th width="80">Status</th>
|
|
<th width="120" class="text-center">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($students)): ?>
|
|
<tr>
|
|
<td colspan="8" class="text-center py-3">
|
|
<i class="bi bi-people text-muted" style="font-size: 2rem;"></i>
|
|
<p class="mt-1 mb-0" style="font-size: 0.85rem;">No students found.</p>
|
|
<a href="add_student.php" class="btn btn-primary btn-sm mt-2">
|
|
<i class="bi bi-person-plus me-1"></i> Add First Student
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php $counter = 1; ?>
|
|
<?php foreach ($students as $student): ?>
|
|
<tr>
|
|
<td>
|
|
<input type="checkbox" class="student-check" name="selected_students[]"
|
|
value="<?php echo $student['id']; ?>" style="transform: scale(0.8);">
|
|
</td>
|
|
<td class="text-muted"><?php echo $counter++; ?></td>
|
|
<td>
|
|
<small class="text-primary fw-bold"><?php echo htmlspecialchars($student['student_id']); ?></small>
|
|
</td>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<div class="avatar me-2">
|
|
<?php if (!empty($student['picture_path']) && file_exists('../' . $student['picture_path'])): ?>
|
|
<img src="../<?php echo htmlspecialchars($student['picture_path']); ?>"
|
|
alt="<?php echo htmlspecialchars($student['full_name']); ?>"
|
|
class="rounded-circle"
|
|
style="width: 30px; height: 30px; object-fit: cover;">
|
|
<?php else: ?>
|
|
<div class="bg-primary rounded-circle d-flex align-items-center justify-content-center"
|
|
style="width: 30px; height: 30px;">
|
|
<i class="bi bi-person text-white" style="font-size: 0.8rem;"></i>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div style="font-size: 0.85rem;">
|
|
<div class="fw-bold mb-0" style="font-size: 0.85rem;"><?php echo htmlspecialchars($student['full_name']); ?></div>
|
|
<small class="text-muted"><?php echo htmlspecialchars($student['gender']); ?></small>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td style="font-size: 0.8rem;">
|
|
<div class="fw-bold"><?php echo htmlspecialchars($student['course_code']); ?></div>
|
|
<small class="text-muted"><?php echo htmlspecialchars($student['department_name']); ?></small>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-info badge-sm">Yr <?php echo $student['year_level']; ?></span>
|
|
</td>
|
|
<td>
|
|
<?php if ($student['status'] == 1): ?>
|
|
<span class="badge bg-success badge-sm">
|
|
<i class="bi bi-check-circle me-1"></i> Active
|
|
</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-danger badge-sm">
|
|
<i class="bi bi-x-circle me-1"></i> Inactive
|
|
</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-center">
|
|
<div class="btn-group btn-group-sm">
|
|
<a href="view_student.php?id=<?php echo $student['id']; ?>"
|
|
class="btn btn-info btn-xs" title="View">
|
|
<i class="bi bi-eye"></i>
|
|
</a>
|
|
<button type="button"
|
|
class="btn btn-warning btn-xs edit-student" title="Edit"
|
|
data-id="<?php echo $student['id']; ?>"
|
|
data-student_id="<?php echo htmlspecialchars($student['student_id']); ?>"
|
|
data-full_name="<?php echo htmlspecialchars($student['full_name']); ?>"
|
|
data-gender_id="<?php echo $student['gender_id']; ?>"
|
|
data-year_level="<?php echo $student['year_level']; ?>"
|
|
data-course_id="<?php echo $student['course_id']; ?>"
|
|
data-department_id="<?php echo $student['department_id']; ?>"
|
|
data-school_id="<?php echo $student['school_id']; ?>"
|
|
data-birth_date="<?php echo $student['birth_date']; ?>"
|
|
data-contact_number="<?php echo htmlspecialchars($student['contact_number']); ?>"
|
|
data-email="<?php echo htmlspecialchars($student['email']); ?>"
|
|
data-address="<?php echo htmlspecialchars($student['address']); ?>"
|
|
data-status="<?php echo $student['status']; ?>">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<div class="btn-group">
|
|
<a href="../qr/generate.php?id=<?php echo $student['id']; ?>"
|
|
class="btn btn-primary btn-xs" title="QR Code" target="_blank">
|
|
<i class="bi bi-qr-code"></i>
|
|
</a>
|
|
<button type="button" class="btn btn-primary btn-xs dropdown-toggle dropdown-toggle-split"
|
|
data-bs-toggle="dropdown" style="padding: 0 4px;">
|
|
<span class="visually-hidden">Toggle Dropdown</span>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li>
|
|
<a class="dropdown-item py-1" href="../qr/generate.php?id=<?php echo $student['id']; ?>&print=1" target="_blank">
|
|
<i class="bi bi-printer me-2"></i> Print QR
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a class="dropdown-item py-1" href="../qr/generate.php?id=<?php echo $student['id']; ?>&download=1">
|
|
<i class="bi bi-download me-2"></i> Download QR
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a class="dropdown-item py-1" href="../qr/generate.php?id=<?php echo $student['id']; ?>&autoPrint=1" target="_blank">
|
|
<i class="bi bi-printer-fill me-2"></i> Auto Print
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<button type="button" class="btn btn-danger btn-xs delete-student"
|
|
data-id="<?php echo $student['id']; ?>"
|
|
data-name="<?php echo htmlspecialchars($student['full_name']); ?>"
|
|
title="Delete">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer py-1">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<small class="text-muted" style="font-size: 0.75rem;">
|
|
<i class="bi bi-info-circle me-1"></i> Showing <?php echo count($students); ?> student(s)
|
|
</small>
|
|
</div>
|
|
<div class="col-md-6 text-md-end">
|
|
<small class="text-muted" style="font-size: 0.75rem;">
|
|
<i class="bi bi-clock me-1"></i> Updated: <?php echo date('h:i A'); ?>
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Add Student Modal -->
|
|
<div class="modal fade" id="addStudentModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-primary text-white py-2">
|
|
<h6 class="modal-title mb-0"><i class="bi bi-person-plus me-1"></i> Add Student</h6>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<form method="POST" action="">
|
|
<div class="modal-body">
|
|
<div class="row g-2">
|
|
<div class="col-md-6">
|
|
<label class="form-label">Student ID *</label>
|
|
<input class="form-control" name="student_id" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Full Name *</label>
|
|
<input class="form-control" name="full_name" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Gender *</label>
|
|
<select class="form-select" name="gender_id" required>
|
|
<option value="">Select Gender</option>
|
|
<?php foreach ($genders as $g): ?>
|
|
<option value="<?php echo $g['id']; ?>"><?php echo htmlspecialchars($g['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Year Level *</label>
|
|
<select class="form-select" name="year_level" required>
|
|
<option value="">Select</option>
|
|
<?php for ($i=1;$i<=4;$i++): ?>
|
|
<option value="<?php echo $i; ?>">Year <?php echo $i; ?></option>
|
|
<?php endfor; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">School *</label>
|
|
<select class="form-select" name="school_id" required>
|
|
<option value="">Select School</option>
|
|
<?php foreach ($schools as $s): ?>
|
|
<option value="<?php echo $s['id']; ?>"><?php echo htmlspecialchars($s['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Department *</label>
|
|
<select class="form-select" name="department_id" required>
|
|
<option value="">Select Department</option>
|
|
<?php foreach ($departments as $d): ?>
|
|
<option value="<?php echo $d['id']; ?>"><?php echo htmlspecialchars($d['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Course *</label>
|
|
<select class="form-select" name="course_id" required>
|
|
<option value="">Select Course</option>
|
|
<?php foreach ($courses as $c): ?>
|
|
<option value="<?php echo $c['id']; ?>"><?php echo htmlspecialchars($c['code']); ?> - <?php echo htmlspecialchars($c['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Birth Date</label>
|
|
<input type="date" class="form-control" name="birth_date" max="<?php echo date('Y-m-d'); ?>">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Email</label>
|
|
<input class="form-control" name="email">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Contact</label>
|
|
<input class="form-control" name="contact_number">
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label">Address</label>
|
|
<textarea class="form-control" name="address" rows="2"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer py-2">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary btn-sm" name="modal_add_student">Save</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Student Modal -->
|
|
<div class="modal fade" id="editStudentModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-warning py-2">
|
|
<h6 class="modal-title mb-0"><i class="bi bi-pencil me-1"></i> Edit Student</h6>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<form method="POST" action="">
|
|
<div class="modal-body">
|
|
<input type="hidden" name="id" id="edit_id">
|
|
<div class="row g-2">
|
|
<div class="col-md-6">
|
|
<label class="form-label">Student ID *</label>
|
|
<input class="form-control" name="student_id" id="edit_student_id" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Full Name *</label>
|
|
<input class="form-control" name="full_name" id="edit_full_name" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Gender *</label>
|
|
<select class="form-select" name="gender_id" id="edit_gender_id" required>
|
|
<option value="">Select Gender</option>
|
|
<?php foreach ($genders as $g): ?>
|
|
<option value="<?php echo $g['id']; ?>"><?php echo htmlspecialchars($g['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Year Level *</label>
|
|
<select class="form-select" name="year_level" id="edit_year_level" required>
|
|
<option value="">Select</option>
|
|
<?php for ($i=1;$i<=4;$i++): ?>
|
|
<option value="<?php echo $i; ?>">Year <?php echo $i; ?></option>
|
|
<?php endfor; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">School *</label>
|
|
<select class="form-select" name="school_id" id="edit_school_id" required>
|
|
<option value="">Select School</option>
|
|
<?php foreach ($schools as $s): ?>
|
|
<option value="<?php echo $s['id']; ?>"><?php echo htmlspecialchars($s['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Department *</label>
|
|
<select class="form-select" name="department_id" id="edit_department_id" required>
|
|
<option value="">Select Department</option>
|
|
<?php foreach ($departments as $d): ?>
|
|
<option value="<?php echo $d['id']; ?>"><?php echo htmlspecialchars($d['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Course *</label>
|
|
<select class="form-select" name="course_id" id="edit_course_id" required>
|
|
<option value="">Select Course</option>
|
|
<?php foreach ($courses as $c): ?>
|
|
<option value="<?php echo $c['id']; ?>"><?php echo htmlspecialchars($c['code']); ?> - <?php echo htmlspecialchars($c['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Birth Date</label>
|
|
<input type="date" class="form-control" name="birth_date" id="edit_birth_date" max="<?php echo date('Y-m-d'); ?>">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Email</label>
|
|
<input class="form-control" name="email" id="edit_email">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Contact</label>
|
|
<input class="form-control" name="contact_number" id="edit_contact_number">
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label">Address</label>
|
|
<textarea class="form-control" name="address" id="edit_address" rows="2"></textarea>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" name="status" id="edit_status" value="1">
|
|
<label class="form-check-label" for="edit_status">Active</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer py-2">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-warning btn-sm" name="modal_update_student">Update</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Delete Confirmation Modal -->
|
|
<div class="modal fade" id="deleteStudentModal" tabindex="-1" aria-labelledby="deleteStudentModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-danger text-white py-2">
|
|
<h6 class="modal-title mb-0" id="deleteStudentModalLabel"><i class="bi bi-exclamation-triangle me-1"></i>Confirm Delete</h6>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form method="POST" action="">
|
|
<div class="modal-body p-3" style="font-size: 0.9rem;">
|
|
<p class="mb-2">Delete student: <strong id="modalStudentName"></strong>?</p>
|
|
<p class="text-danger mb-0"><small>This action cannot be undone.</small></p>
|
|
<input type="hidden" name="delete_student" value="1">
|
|
<input type="hidden" name="id" id="modalStudentId" value="">
|
|
</div>
|
|
<div class="modal-footer py-2">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-danger btn-sm" id="modalConfirmDelete">Delete</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php
|
|
$page_scripts = '
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize DataTable
|
|
const table = $("#studentsTable").DataTable({
|
|
pageLength: 25,
|
|
lengthMenu: [[15, 25, 50, 100, -1], [15, 25, 50, 100, "All"]],
|
|
order: [[2, "asc"]], // Sort by Student ID
|
|
responsive: true,
|
|
columnDefs: [
|
|
{ orderable: false, targets: [0, 1, 7] },
|
|
{ searchable: false, targets: [0, 1, 5, 6, 7] },
|
|
{ visible: false, targets: [0] }
|
|
],
|
|
language: {
|
|
search: "_INPUT_",
|
|
searchPlaceholder: "Search...",
|
|
lengthMenu: "Show _MENU_",
|
|
info: "Showing _START_ to _END_ of _TOTAL_",
|
|
infoEmpty: "No students",
|
|
infoFiltered: "(filtered from _MAX_ total)"
|
|
}
|
|
});
|
|
|
|
// Open Add modal
|
|
document.getElementById('openAddModal').addEventListener('click', function(){
|
|
const form = document.querySelector('#addStudentModal form');
|
|
form.reset();
|
|
const addModal = new bootstrap.Modal(document.getElementById('addStudentModal'));
|
|
addModal.show();
|
|
});
|
|
|
|
// Open Edit modal and populate
|
|
$(document).on('click', '.edit-student', function(){
|
|
const d = $(this).data();
|
|
$('#edit_id').val(d.id);
|
|
$('#edit_student_id').val(d.student_id);
|
|
$('#edit_full_name').val(d.full_name);
|
|
$('#edit_gender_id').val(String(d.gender_id));
|
|
$('#edit_year_level').val(String(d.year_level));
|
|
$('#edit_course_id').val(String(d.course_id));
|
|
$('#edit_department_id').val(String(d.department_id));
|
|
$('#edit_school_id').val(String(d.school_id));
|
|
$('#edit_birth_date').val(d.birth_date && d.birth_date !== '0000-00-00' ? d.birth_date : '');
|
|
$('#edit_contact_number').val(d.contact_number || '');
|
|
$('#edit_email').val(d.email || '');
|
|
$('#edit_address').val(d.address || '');
|
|
$('#edit_status').prop('checked', Number(d.status) === 1);
|
|
const editModal = new bootstrap.Modal(document.getElementById('editStudentModal'));
|
|
editModal.show();
|
|
});
|
|
|
|
// Custom search
|
|
$("#searchInput").on("keyup", function() {
|
|
table.search($(this).val()).draw();
|
|
});
|
|
|
|
// Bulk selection functionality
|
|
$("#toggleAll").change(function() {
|
|
$(".student-check").prop("checked", this.checked);
|
|
updateBulkSelection();
|
|
});
|
|
|
|
$(document).on("change", ".student-check", function() {
|
|
if (!this.checked) {
|
|
$("#toggleAll").prop("checked", false);
|
|
}
|
|
updateBulkSelection();
|
|
});
|
|
|
|
// Delete confirmation
|
|
$(document).on("click", ".delete-student", function(e) {
|
|
e.preventDefault();
|
|
const studentId = $(this).data("id");
|
|
const studentName = $(this).data("name");
|
|
|
|
// Create confirmation dialog
|
|
const confirmed = confirm(`Are you sure you want to delete student "${studentName}"?\\nThis action cannot be undone.`);
|
|
|
|
if (confirmed) {
|
|
// Create and submit form
|
|
const form = document.createElement("form");
|
|
form.method = "POST";
|
|
form.action = "";
|
|
|
|
const deleteInput = document.createElement("input");
|
|
deleteInput.type = "hidden";
|
|
deleteInput.name = "delete_student";
|
|
deleteInput.value = "1";
|
|
form.appendChild(deleteInput);
|
|
|
|
const idInput = document.createElement("input");
|
|
idInput.type = "hidden";
|
|
idInput.name = "id";
|
|
idInput.value = studentId;
|
|
form.appendChild(idInput);
|
|
|
|
const csrfInput = document.createElement("input");
|
|
csrfInput.type = "hidden";
|
|
csrfInput.name = "csrf_token";
|
|
csrfInput.value = "<?php echo $csrf_token; ?>";
|
|
form.appendChild(csrfInput);
|
|
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
});
|
|
|
|
// Bulk form validation
|
|
$("#bulkForm").submit(function(e) {
|
|
const selectedCount = $(".student-check:checked").length;
|
|
const action = $("select[name=\'bulk_action\']").val();
|
|
|
|
if (selectedCount === 0) {
|
|
e.preventDefault();
|
|
alert("Please select at least one student.");
|
|
return false;
|
|
}
|
|
|
|
if (!action) {
|
|
e.preventDefault();
|
|
alert("Please select a bulk action.");
|
|
return false;
|
|
}
|
|
|
|
if (action === "delete") {
|
|
e.preventDefault();
|
|
if (confirm(`Delete ${selectedCount} student(s)?\\nThis action cannot be undone.`)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
});
|
|
|
|
// Bulk selection functions
|
|
function updateBulkSelection() {
|
|
const selectedCount = $(".student-check:checked").length;
|
|
$("#selectedCount").text(selectedCount);
|
|
|
|
if (selectedCount > 0) {
|
|
$(".bulk-actions-bar").show();
|
|
$("#studentsTable_wrapper .col-sm-12:first").css("margin-top", "50px");
|
|
} else {
|
|
$(".bulk-actions-bar").hide();
|
|
$("#studentsTable_wrapper .col-sm-12:first").css("margin-top", "0");
|
|
}
|
|
|
|
const totalCheckboxes = $(".student-check").length;
|
|
$("#toggleAll").prop("checked", selectedCount === totalCheckboxes && totalCheckboxes > 0);
|
|
}
|
|
|
|
function clearBulkSelection() {
|
|
$(".student-check").prop("checked", false);
|
|
$("#toggleAll").prop("checked", false);
|
|
updateBulkSelection();
|
|
}
|
|
|
|
// Print Report
|
|
function printReport() {
|
|
const table = $("#studentsTable").DataTable();
|
|
const data = table.rows({ search: \'applied\' }).data().toArray();
|
|
|
|
if (data.length === 0) {
|
|
alert("No data to print.");
|
|
return;
|
|
}
|
|
|
|
const printWindow = window.open("", "_blank");
|
|
printWindow.document.write(`
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Student List - <?php echo date("Y-m-d"); ?></title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 15px; font-size: 12px; }
|
|
h1 { text-align: center; margin-bottom: 20px; font-size: 16px; }
|
|
.report-info { margin-bottom: 15px; font-size: 11px; }
|
|
table { width: 100%; border-collapse: collapse; margin-bottom: 15px; font-size: 11px; }
|
|
th, td { border: 1px solid #ddd; padding: 5px; text-align: left; }
|
|
th { background-color: #f2f2f2; }
|
|
.footer { text-align: center; margin-top: 20px; font-size: 10px; color: #666; }
|
|
@media print { .no-print { display: none; } button { display: none; } }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Student List</h1>
|
|
<div class="report-info">
|
|
<p><strong>Date:</strong> <?php echo date("m/d/Y h:i A"); ?></p>
|
|
<p><strong>Total:</strong> ${data.length} students</p>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>Student ID</th>
|
|
<th>Name</th>
|
|
<th>Course</th>
|
|
<th>Year</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
${data.map((row, index) => {
|
|
const studentId = $(row[2]).find(".text-primary").text() || row[2];
|
|
const studentName = $(row[3]).find(".fw-bold").text() || row[3];
|
|
const course = $(row[4]).text();
|
|
const year = $(row[5]).text();
|
|
const status = $(row[6]).text();
|
|
|
|
return `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td>${studentId}</td>
|
|
<td>${studentName}</td>
|
|
<td>${course}</td>
|
|
<td>${year}</td>
|
|
<td>${status}</td>
|
|
</tr>
|
|
`;
|
|
}).join("")}
|
|
</tbody>
|
|
</table>
|
|
<div class="footer">
|
|
Student Management System
|
|
</div>
|
|
<div class="no-print" style="text-align: center; margin-top: 15px;">
|
|
<button onclick="window.print()">Print</button>
|
|
<button onclick="window.close()" style="margin-left: 10px;">Close</button>
|
|
</div>
|
|
<script>window.onload = function() { window.print(); };<\/script>
|
|
</body>
|
|
</html>
|
|
`);
|
|
printWindow.document.close();
|
|
}
|
|
</script>
|
|
';
|
|
|
|
$page_scripts .= '\n<script>\n$(document).off("click", ".delete-student").on("click", ".delete-student", function(e){ e.preventDefault(); const studentId = $(this).data("id"); const studentName = $(this).data("name"); document.getElementById("modalStudentId").value = studentId; document.getElementById("modalStudentName").textContent = studentName; const modalEl = document.getElementById("deleteStudentModal"); const deleteModal = new bootstrap.Modal(modalEl); deleteModal.show(); });\n<\/script>\n';
|
|
|
|
include '../includes/footer.php';
|
|
?>
|