Initial commit
This commit is contained in:
767
src-backup/admin/users.php
Normal file
767
src-backup/admin/users.php
Normal file
@@ -0,0 +1,767 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
// Check if user is logged in and is admin
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
|
||||
header("Location: ../auth/login.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
// Use absolute path with error checking
|
||||
$db_path = __DIR__ . '/../includes/database.php';
|
||||
if (!file_exists($db_path)) {
|
||||
die("Database configuration file not found at: $db_path");
|
||||
}
|
||||
|
||||
require_once $db_path;
|
||||
|
||||
// Check if $pdo is set
|
||||
if (!isset($pdo)) {
|
||||
die("Database connection failed. \$pdo variable not set.");
|
||||
}
|
||||
|
||||
$title = "User Management";
|
||||
|
||||
// Try different paths for header.php
|
||||
$header_paths = [
|
||||
'header.php', // Same directory
|
||||
__DIR__ . '/header.php', // Absolute path in admin
|
||||
__DIR__ . '/../header.php', // Parent directory (attendance_system)
|
||||
__DIR__ . '/../includes/header.php', // Includes directory
|
||||
__DIR__ . '/../templates/header.php', // Templates directory
|
||||
'C:/xampp/htdocs/attendance_system/header.php',
|
||||
'C:/xampp/htdocs/attendance_system/admin/header.php'
|
||||
];
|
||||
|
||||
$header_found = false;
|
||||
foreach ($header_paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
$header_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$header_found) {
|
||||
// If header not found, create basic HTML structure
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo $title; ?></title>
|
||||
|
||||
<!-- Bootstrap 5 -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Bootstrap Icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
|
||||
<!-- DataTables -->
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/dataTables.bootstrap5.min.css">
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f7fb;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.navbar {
|
||||
background: #37502c;
|
||||
}
|
||||
.card {
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.08);
|
||||
margin-bottom: 15px;
|
||||
border: none;
|
||||
}
|
||||
.card-header {
|
||||
background: linear-gradient(135deg, #205e03 0%, #9bdb34 100%);
|
||||
color: white;
|
||||
border-radius: 10px 10px 0 0;
|
||||
border: none;
|
||||
padding: 12px 15px;
|
||||
}
|
||||
.table {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||||
margin-bottom: 0;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.table th {
|
||||
font-size: 0.8rem;
|
||||
padding: 8px 12px;
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
}
|
||||
.table td {
|
||||
padding: 6px 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.table tbody tr:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.status-active {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.status-inactive {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.badge {
|
||||
font-size: 0.75rem;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
.action-buttons .btn {
|
||||
padding: 3px 6px;
|
||||
font-size: 0.8rem;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.search-box {
|
||||
position: relative;
|
||||
}
|
||||
.search-box i {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #6c757d;
|
||||
}
|
||||
.search-box input {
|
||||
padding-left: 35px;
|
||||
font-size: 0.85rem;
|
||||
height: 36px;
|
||||
}
|
||||
.form-control, .form-select {
|
||||
font-size: 0.85rem;
|
||||
padding: 6px 10px;
|
||||
height: 36px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 12px;
|
||||
}
|
||||
.stat-card h3 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.stat-card h6 {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.stat-card i {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Simple Navigation -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">
|
||||
<i class="bi bi-qr-code-scan me-2"></i>AMS - User Management
|
||||
</a>
|
||||
<div class="d-flex align-items-center text-white">
|
||||
<span class="me-3" style="font-size: 0.9rem;">
|
||||
<i class="bi bi-person-circle me-1"></i>
|
||||
<?php echo htmlspecialchars($_SESSION['full_name'] ?? 'User'); ?>
|
||||
</span>
|
||||
<a href="../auth/logout.php" class="btn btn-outline-light btn-sm" style="font-size: 0.8rem;">
|
||||
<i class="bi bi-box-arrow-right"></i> Logout
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<!-- ================ START OF YOUR USER MANAGEMENT CONTENT ================ -->
|
||||
|
||||
<!-- Display messages -->
|
||||
<?php if (isset($_SESSION['message'])): ?>
|
||||
<?php $message_type = $_SESSION['message_type'] ?? 'success'; ?>
|
||||
<div class="alert alert-<?php echo $message_type; ?> alert-dismissible fade show py-2" role="alert" style="font-size: 0.85rem;">
|
||||
<?php echo $_SESSION['message']; ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php
|
||||
unset($_SESSION['message']);
|
||||
unset($_SESSION['message_type']);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center py-2">
|
||||
<h6 class="mb-0" style="font-size: 0.9rem;"><i class="bi bi-people-fill me-1"></i>User Management</h6>
|
||||
<button class="btn btn-primary btn-sm py-1 px-2" data-bs-toggle="modal" data-bs-target="#addUserModal" style="font-size: 0.8rem;">
|
||||
<i class="bi bi-person-plus me-1"></i> Add User
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body p-3">
|
||||
<!-- Search and Filter -->
|
||||
<div class="row mb-2 g-2">
|
||||
<div class="col-md-6">
|
||||
<div class="search-box">
|
||||
<i class="bi bi-search"></i>
|
||||
<input type="text" class="form-control" id="searchInput" placeholder="Search users...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select" id="roleFilter">
|
||||
<option value="">All Roles</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="teacher">Teacher</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select" id="statusFilter">
|
||||
<option value="">All Status</option>
|
||||
<option value="1">Active</option>
|
||||
<option value="0">Inactive</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Users Table - COMPACT VERSION -->
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm" id="usersTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="3%">#</th>
|
||||
<th width="20%">Full Name</th>
|
||||
<th width="18%">Email</th>
|
||||
<th width="12%">Username</th>
|
||||
<th width="10%">Role</th>
|
||||
<th width="10%">Status</th>
|
||||
<th width="12%">Created</th>
|
||||
<th width="15%">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
try {
|
||||
$query = "SELECT * FROM users ORDER BY created_at DESC";
|
||||
$stmt = $pdo->query($query);
|
||||
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$count = 1;
|
||||
|
||||
if (count($users) > 0):
|
||||
foreach ($users as $user):
|
||||
$status_class = $user['status'] ? 'status-active' : 'status-inactive';
|
||||
$status_text = $user['status'] ? 'Active' : 'Inactive';
|
||||
|
||||
$role_badge = '';
|
||||
switch($user['role']) {
|
||||
case 'admin': $role_badge = 'danger'; break;
|
||||
case 'teacher': $role_badge = 'success'; break;
|
||||
default: $role_badge = 'secondary';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-muted"><?php echo $count++; ?></td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="rounded-circle bg-light p-1 me-2">
|
||||
<i class="bi bi-person text-dark" style="font-size: 0.8rem;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size: 0.85rem; font-weight: 500;"><?php echo htmlspecialchars($user['full_name']); ?></div>
|
||||
<?php if ($user['id'] == $_SESSION['user_id']): ?>
|
||||
<span class="badge bg-warning" style="font-size: 0.65rem;">You</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<small class="text-truncate d-inline-block" style="max-width: 150px;" title="<?php echo htmlspecialchars($user['email'] ?? 'N/A'); ?>">
|
||||
<?php echo htmlspecialchars($user['email'] ?? 'N/A'); ?>
|
||||
</small>
|
||||
</td>
|
||||
<td><code style="font-size: 0.8rem;"><?php echo htmlspecialchars($user['username']); ?></code></td>
|
||||
<td>
|
||||
<span class="badge bg-<?php echo $role_badge; ?>">
|
||||
<?php echo ucfirst($user['role']); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="<?php echo $status_class; ?>">
|
||||
<?php echo $status_text; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><small><?php echo date('m/d/Y', strtotime($user['created_at'])); ?></small></td>
|
||||
<td>
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-sm btn-outline-primary py-0 px-1"
|
||||
onclick="editUser(<?php echo $user['id']; ?>)"
|
||||
title="Edit User">
|
||||
<i class="bi bi-pencil" style="font-size: 0.8rem;"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-<?php echo $user['status'] ? 'warning' : 'success'; ?> py-0 px-1 mx-1"
|
||||
onclick="toggleStatus(<?php echo $user['id']; ?>, <?php echo $user['status']; ?>)"
|
||||
title="<?php echo $user['status'] ? 'Deactivate' : 'Activate'; ?>">
|
||||
<i class="bi bi-<?php echo $user['status'] ? 'x-circle' : 'check-circle'; ?>" style="font-size: 0.8rem;"></i>
|
||||
</button>
|
||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
||||
<button class="btn btn-sm btn-outline-danger py-0 px-1"
|
||||
onclick="deleteUser(<?php echo $user['id']; ?>, '<?php echo htmlspecialchars($user['full_name']); ?>')"
|
||||
title="Delete User">
|
||||
<i class="bi bi-trash" style="font-size: 0.8rem;"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach;
|
||||
else:
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="8" class="text-center text-muted py-2">
|
||||
<i class="bi bi-people me-1"></i> No users found.
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endif;
|
||||
} catch (PDOException $e) {
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="8" class="text-center text-danger py-2">
|
||||
<i class="bi bi-exclamation-triangle me-1"></i> Error loading users
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Stats - Compact Version -->
|
||||
<div class="row g-2">
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card py-2">
|
||||
<div class="card-body p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1" style="font-size: 0.75rem;">Total Users</h6>
|
||||
<h4 class="mb-0" style="font-size: 1.2rem;">
|
||||
<?php
|
||||
$query = "SELECT COUNT(*) as total FROM users";
|
||||
$stmt = $pdo->query($query);
|
||||
echo $stmt->fetch()['total'] ?? 0;
|
||||
?>
|
||||
</h4>
|
||||
</div>
|
||||
<i class="bi bi-people text-primary" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card py-2">
|
||||
<div class="card-body p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1" style="font-size: 0.75rem;">Active Users</h6>
|
||||
<h4 class="mb-0" style="font-size: 1.2rem;">
|
||||
<?php
|
||||
$query = "SELECT COUNT(*) as active FROM users WHERE status = 1";
|
||||
$stmt = $pdo->query($query);
|
||||
echo $stmt->fetch()['active'] ?? 0;
|
||||
?>
|
||||
</h4>
|
||||
</div>
|
||||
<i class="bi bi-check-circle text-success" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card py-2">
|
||||
<div class="card-body p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1" style="font-size: 0.75rem;">Admins</h6>
|
||||
<h4 class="mb-0" style="font-size: 1.2rem;">
|
||||
<?php
|
||||
$query = "SELECT COUNT(*) as admins FROM users WHERE role = 'admin'";
|
||||
$stmt = $pdo->query($query);
|
||||
echo $stmt->fetch()['admins'] ?? 0;
|
||||
?>
|
||||
</h4>
|
||||
</div>
|
||||
<i class="bi bi-shield-check text-danger" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card py-2">
|
||||
<div class="card-body p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1" style="font-size: 0.75rem;">Teachers</h6>
|
||||
<h4 class="mb-0" style="font-size: 1.2rem;">
|
||||
<?php
|
||||
$query = "SELECT COUNT(*) as teachers FROM users WHERE role = 'teacher'";
|
||||
$stmt = $pdo->query($query);
|
||||
echo $stmt->fetch()['teachers'] ?? 0;
|
||||
?>
|
||||
</h4>
|
||||
</div>
|
||||
<i class="bi bi-person-badge text-info" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ================ MODALS SECTION ================ -->
|
||||
|
||||
<!-- Add User Modal -->
|
||||
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-md">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header py-2">
|
||||
<h6 class="modal-title mb-0" id="addUserModalLabel"><i class="bi bi-person-plus me-1"></i>Add New User</h6>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="process_user.php" method="POST" id="addUserForm">
|
||||
<div class="modal-body p-3">
|
||||
<input type="hidden" name="action" value="add">
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="full_name" class="form-label" style="font-size: 0.85rem;">Full Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control form-control-sm" id="full_name" name="full_name" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="username" class="form-label" style="font-size: 0.85rem;">Username <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control form-control-sm" id="username" name="username" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label for="email" class="form-label" style="font-size: 0.85rem;">Email Address</label>
|
||||
<input type="email" class="form-control form-control-sm" id="email" name="email">
|
||||
</div>
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="password" class="form-label" style="font-size: 0.85rem;">Password <span class="text-danger">*</span></label>
|
||||
<input type="password" class="form-control form-control-sm" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="confirm_password" class="form-label" style="font-size: 0.85rem;">Confirm Password <span class="text-danger">*</span></label>
|
||||
<input type="password" class="form-control form-control-sm" id="confirm_password" name="confirm_password" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="role" class="form-label" style="font-size: 0.85rem;">Role <span class="text-danger">*</span></label>
|
||||
<select class="form-select form-select-sm" id="role" name="role" required>
|
||||
<option value="">Select Role</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="teacher">Teacher</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="status" class="form-label" style="font-size: 0.85rem;">Status</label>
|
||||
<select class="form-select form-select-sm" id="status" name="status">
|
||||
<option value="1">Active</option>
|
||||
<option value="0">Inactive</option>
|
||||
</select>
|
||||
</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">Add User</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit User Modal -->
|
||||
<div class="modal fade" id="editUserModal" tabindex="-1" aria-labelledby="editUserModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-md">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header py-2">
|
||||
<h6 class="modal-title mb-0" id="editUserModalLabel"><i class="bi bi-pencil me-1"></i>Edit User</h6>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="process_user.php" method="POST" id="editUserForm">
|
||||
<div class="modal-body p-3">
|
||||
<input type="hidden" name="action" value="edit">
|
||||
<input type="hidden" id="edit_user_id" name="user_id">
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="edit_full_name" class="form-label" style="font-size: 0.85rem;">Full Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control form-control-sm" id="edit_full_name" name="full_name" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="edit_username" class="form-label" style="font-size: 0.85rem;">Username <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control form-control-sm" id="edit_username" name="username" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label for="edit_email" class="form-label" style="font-size: 0.85rem;">Email Address</label>
|
||||
<input type="email" class="form-control form-control-sm" id="edit_email" name="email">
|
||||
</div>
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="edit_password" class="form-label" style="font-size: 0.85rem;">New Password (leave blank)</label>
|
||||
<input type="password" class="form-control form-control-sm" id="edit_password" name="password">
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="edit_confirm_password" class="form-label" style="font-size: 0.85rem;">Confirm New Password</label>
|
||||
<input type="password" class="form-control form-control-sm" id="edit_confirm_password" name="confirm_password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="edit_role" class="form-label" style="font-size: 0.85rem;">Role <span class="text-danger">*</span></label>
|
||||
<select class="form-select form-select-sm" id="edit_role" name="role" required>
|
||||
<option value="">Select Role</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="teacher">Teacher</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label for="edit_status" class="form-label" style="font-size: 0.85rem;">Status</label>
|
||||
<select class="form-select form-select-sm" id="edit_status" name="status">
|
||||
<option value="1">Active</option>
|
||||
<option value="0">Inactive</option>
|
||||
</select>
|
||||
</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">Update User</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" 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="deleteModalLabel"><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>
|
||||
<div class="modal-body p-3">
|
||||
<p class="mb-2" style="font-size: 0.85rem;">Delete user: <strong id="deleteUserName"></strong>?</p>
|
||||
<p class="text-danger mb-0" style="font-size: 0.8rem;"><i class="bi bi-exclamation-circle me-1"></i>Cannot be undone.</p>
|
||||
</div>
|
||||
<div class="modal-footer py-2">
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="confirmDelete">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ================ JAVASCRIPT SECTION ================ -->
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.11.5/js/dataTables.bootstrap5.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Table filtering and search - COMPACT VERSION
|
||||
$(document).ready(function() {
|
||||
const table = $('#usersTable').DataTable({
|
||||
pageLength: 15, // More rows per page
|
||||
lengthMenu: [[10, 15, 25, 50, -1], [10, 15, 25, 50, "All"]],
|
||||
responsive: true,
|
||||
dom: '<"row"<"col-sm-12"fr>>rt<"row"<"col-sm-6"i><"col-sm-6"p>>',
|
||||
language: {
|
||||
search: "_INPUT_",
|
||||
searchPlaceholder: "Search...",
|
||||
lengthMenu: "Show _MENU_ entries",
|
||||
info: "Showing _START_ to _END_ of _TOTAL_ users",
|
||||
paginate: {
|
||||
first: "First",
|
||||
last: "Last",
|
||||
next: "→",
|
||||
previous: "←"
|
||||
}
|
||||
},
|
||||
columnDefs: [
|
||||
{ orderable: false, targets: [7] } // Make actions column not sortable
|
||||
]
|
||||
});
|
||||
|
||||
$('#searchInput').on('keyup', function() {
|
||||
table.search(this.value).draw();
|
||||
});
|
||||
|
||||
$('#roleFilter').on('change', function() {
|
||||
table.column(4).search(this.value).draw();
|
||||
});
|
||||
|
||||
$('#statusFilter').on('change', function() {
|
||||
table.column(5).search(this.value).draw();
|
||||
});
|
||||
});
|
||||
|
||||
// Edit User Function
|
||||
function editUser(userId) {
|
||||
fetch(`get_user.php?id=${userId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const user = data.user;
|
||||
document.getElementById('edit_user_id').value = user.id;
|
||||
document.getElementById('edit_full_name').value = user.full_name;
|
||||
document.getElementById('edit_username').value = user.username;
|
||||
document.getElementById('edit_email').value = user.email || '';
|
||||
document.getElementById('edit_role').value = user.role;
|
||||
document.getElementById('edit_status').value = user.status;
|
||||
|
||||
const editModal = new bootstrap.Modal(document.getElementById('editUserModal'));
|
||||
editModal.show();
|
||||
} else {
|
||||
alert('Error loading user data: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error loading user data');
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle User Status
|
||||
function toggleStatus(userId, currentStatus) {
|
||||
if (confirm(`Are you sure you want to ${currentStatus ? 'deactivate' : 'activate'} this user?`)) {
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'toggle_status');
|
||||
formData.append('user_id', userId);
|
||||
|
||||
fetch('process_user.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Error: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error updating user status');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Delete User Function
|
||||
let userToDelete = null;
|
||||
let userNameToDelete = '';
|
||||
|
||||
function deleteUser(userId, userName) {
|
||||
userToDelete = userId;
|
||||
userNameToDelete = userName;
|
||||
document.getElementById('deleteUserName').textContent = userName;
|
||||
const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
|
||||
deleteModal.show();
|
||||
}
|
||||
|
||||
// Confirm Delete
|
||||
document.getElementById('confirmDelete').addEventListener('click', function() {
|
||||
if (userToDelete) {
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'delete');
|
||||
formData.append('user_id', userToDelete);
|
||||
|
||||
fetch('process_user.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Error: ' + data.message);
|
||||
bootstrap.Modal.getInstance(document.getElementById('deleteModal')).hide();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error deleting user');
|
||||
bootstrap.Modal.getInstance(document.getElementById('deleteModal')).hide();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Form Validation
|
||||
document.getElementById('addUserForm').addEventListener('submit', function(e) {
|
||||
const password = document.getElementById('password').value;
|
||||
const confirmPassword = document.getElementById('confirm_password').value;
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
e.preventDefault();
|
||||
alert('Passwords do not match!');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
e.preventDefault();
|
||||
alert('Password must be at least 6 characters long!');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('editUserForm').addEventListener('submit', function(e) {
|
||||
const password = document.getElementById('edit_password').value;
|
||||
const confirmPassword = document.getElementById('edit_confirm_password').value;
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
e.preventDefault();
|
||||
alert('Passwords do not match!');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password && password.length < 6) {
|
||||
e.preventDefault();
|
||||
alert('Password must be at least 6 characters long!');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
// Check if we need to close HTML tags (if no header was found)
|
||||
if (!$header_found) {
|
||||
echo '</div></body></html>';
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user