|
|
@@ -33,18 +33,45 @@ $db = Database::getInstance();
|
|
|
|
|
|
switch ($action) {
|
|
|
case 'list':
|
|
|
- // Get all users with pagination
|
|
|
+ // Get filter parameters
|
|
|
+ $search = trim($_GET['search'] ?? '');
|
|
|
+ $role_filter = $_GET['role'] ?? 'all';
|
|
|
+ $status_filter = $_GET['status'] ?? 'all';
|
|
|
$page = max(1, (int)($_GET['page'] ?? 1));
|
|
|
$limit = 20;
|
|
|
$offset = ($page - 1) * $limit;
|
|
|
|
|
|
- // Get total users count
|
|
|
- $total_users = $db->fetch("SELECT COUNT(*) as count FROM users")['count'];
|
|
|
+ // Build WHERE clause for filtering
|
|
|
+ $where_conditions = [];
|
|
|
+ $params = [];
|
|
|
+
|
|
|
+ if (!empty($search)) {
|
|
|
+ $where_conditions[] = "(username LIKE ? OR email LIKE ?)";
|
|
|
+ $params[] = "%$search%";
|
|
|
+ $params[] = "%$search%";
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($role_filter !== 'all') {
|
|
|
+ $where_conditions[] = "role = ?";
|
|
|
+ $params[] = $role_filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($status_filter !== 'all') {
|
|
|
+ $where_conditions[] = "status = ?";
|
|
|
+ $params[] = $status_filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ $where_clause = !empty($where_conditions) ? "WHERE " . implode(" AND ", $where_conditions) : "";
|
|
|
+
|
|
|
+ // Get total users count with filters
|
|
|
+ $count_sql = "SELECT COUNT(*) as count FROM users $where_clause";
|
|
|
+ $total_users = $db->fetch($count_sql, $params)['count'];
|
|
|
$total_pages = ceil($total_users / $limit);
|
|
|
|
|
|
- // Get users for current page
|
|
|
- $sql = "SELECT id, username, email, auth_type, created_at, last_login FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?";
|
|
|
- $users = $db->fetchAll($sql, [$limit, $offset]);
|
|
|
+ // Get users for current page with filters
|
|
|
+ $sql = "SELECT id, username, email, auth_type, role, status, created_at, last_login FROM users $where_clause ORDER BY created_at DESC LIMIT ? OFFSET ?";
|
|
|
+ $query_params = array_merge($params, [$limit, $offset]);
|
|
|
+ $users = $db->fetchAll($sql, $query_params);
|
|
|
|
|
|
break;
|
|
|
|
|
|
@@ -54,6 +81,52 @@ switch ($action) {
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
+ // Handle form submission for user update
|
|
|
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
+ $username = trim($_POST['username'] ?? '');
|
|
|
+ $email = trim($_POST['email'] ?? '');
|
|
|
+ $auth_type = trim($_POST['auth_type'] ?? 'local');
|
|
|
+ $role = trim($_POST['role'] ?? 'user');
|
|
|
+ $status = trim($_POST['status'] ?? 'active');
|
|
|
+ $password = trim($_POST['password'] ?? '');
|
|
|
+
|
|
|
+ // Validation
|
|
|
+ if (empty($username)) $error = t('admin_username_required');
|
|
|
+ elseif (empty($email)) $error = t('admin_email_required');
|
|
|
+ elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) $error = t('admin_email_invalid');
|
|
|
+
|
|
|
+ if (!$error) {
|
|
|
+ try {
|
|
|
+ $update_data = [
|
|
|
+ 'username' => $username,
|
|
|
+ 'email' => $email,
|
|
|
+ 'auth_type' => $auth_type,
|
|
|
+ 'role' => $role,
|
|
|
+ 'status' => $status
|
|
|
+ ];
|
|
|
+
|
|
|
+ // Update password if provided
|
|
|
+ if (!empty($password)) {
|
|
|
+ $update_data['password'] = password_hash($password, PASSWORD_DEFAULT);
|
|
|
+ }
|
|
|
+
|
|
|
+ $db->update('users', $update_data, 'id = ?', [$user_id]);
|
|
|
+ $message = t('admin_user_updated_success');
|
|
|
+
|
|
|
+ // Redirect to avoid form resubmission
|
|
|
+ header('Location: users.php?message=' . urlencode($message));
|
|
|
+ exit;
|
|
|
+
|
|
|
+ } catch (Exception $e) {
|
|
|
+ if (strpos($e->getMessage(), 'Duplicate') !== false) {
|
|
|
+ $error = t('admin_username_exists');
|
|
|
+ } else {
|
|
|
+ $error = t('admin_user_update_error') . ' ' . $e->getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// Get user details
|
|
|
$user = $db->fetch("SELECT * FROM users WHERE id = ?", [$user_id]);
|
|
|
if (!$user) {
|
|
|
@@ -97,6 +170,10 @@ switch ($action) {
|
|
|
elseif (empty($password) && $auth_type === 'local') $error = t('admin_password_required_local');
|
|
|
elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) $error = t('admin_email_invalid');
|
|
|
|
|
|
+ // Get role and status from form
|
|
|
+ $role = trim($_POST['role'] ?? 'user');
|
|
|
+ $status = trim($_POST['status'] ?? 'active');
|
|
|
+
|
|
|
if (!$error) {
|
|
|
// Check if username already exists
|
|
|
$existing_user = $db->fetch("SELECT id FROM users WHERE username = ?", [$username]);
|
|
|
@@ -105,8 +182,8 @@ switch ($action) {
|
|
|
} else {
|
|
|
// Create new user
|
|
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
|
|
- $sql = "INSERT INTO users (username, email, password, auth_type, created_at) VALUES (?, ?, ?, ?, NOW())";
|
|
|
- $db->query($sql, [$username, $email, $hashed_password, $auth_type]);
|
|
|
+ $sql = "INSERT INTO users (username, email, password, auth_type, role, status, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())";
|
|
|
+ $db->query($sql, [$username, $email, $hashed_password, $auth_type, $role, $status]);
|
|
|
|
|
|
$message = t('admin_user_created_success');
|
|
|
|
|
|
@@ -132,6 +209,7 @@ switch ($action) {
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
<title><?php echo t('manage_users'); ?> - <?php echo SITE_TITLE; ?></title>
|
|
|
<link rel="stylesheet" href="../css/style.css">
|
|
|
+ <link rel="stylesheet" href="../css/admin-users.css">
|
|
|
</head>
|
|
|
<body>
|
|
|
<header class="admin-header">
|
|
|
@@ -174,6 +252,38 @@ switch ($action) {
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <div class="filters">
|
|
|
+ <form method="get" class="filter-form">
|
|
|
+ <div class="filter-group">
|
|
|
+ <label for="search"><?php echo t('search'); ?>:</label>
|
|
|
+ <input type="text" id="search" name="search" value="<?php echo htmlspecialchars($search); ?>" placeholder="<?php echo t('search_users_placeholder'); ?>">
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="filter-group">
|
|
|
+ <label for="role"><?php echo t('role'); ?>:</label>
|
|
|
+ <select id="role" name="role">
|
|
|
+ <option value="all" <?php echo $role_filter === 'all' ? 'selected' : ''; ?>><?php echo t('filter_all'); ?></option>
|
|
|
+ <option value="admin" <?php echo $role_filter === 'admin' ? 'selected' : ''; ?>><?php echo t('role_admin'); ?></option>
|
|
|
+ <option value="user" <?php echo $role_filter === 'user' ? 'selected' : ''; ?>><?php echo t('role_user'); ?></option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="filter-group">
|
|
|
+ <label for="status"><?php echo t('status'); ?>:</label>
|
|
|
+ <select id="status" name="status">
|
|
|
+ <option value="all" <?php echo $status_filter === 'all' ? 'selected' : ''; ?>><?php echo t('filter_all'); ?></option>
|
|
|
+ <option value="active" <?php echo $status_filter === 'active' ? 'selected' : ''; ?>><?php echo t('status_active'); ?></option>
|
|
|
+ <option value="inactive" <?php echo $status_filter === 'inactive' ? 'selected' : ''; ?>><?php echo t('status_inactive'); ?></option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <button type="submit" class="btn btn-sm"><?php echo t('filter'); ?></button>
|
|
|
+ <?php if ($search || $role_filter !== 'all' || $status_filter !== 'all'): ?>
|
|
|
+ <a href="users.php" class="btn btn-sm btn-secondary"><?php echo t('clear'); ?></a>
|
|
|
+ <?php endif; ?>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div class="users-table">
|
|
|
<table class="admin-table">
|
|
|
<thead>
|
|
|
@@ -181,6 +291,8 @@ switch ($action) {
|
|
|
<th><?php echo t('username'); ?></th>
|
|
|
<th><?php echo t('email'); ?></th>
|
|
|
<th><?php echo t('auth_type'); ?></th>
|
|
|
+ <th><?php echo t('role'); ?></th>
|
|
|
+ <th><?php echo t('status'); ?></th>
|
|
|
<th><?php echo t('created'); ?></th>
|
|
|
<th><?php echo t('last_login'); ?></th>
|
|
|
<th><?php echo t('actions'); ?></th>
|
|
|
@@ -196,6 +308,16 @@ switch ($action) {
|
|
|
<?php echo ucfirst($user['auth_type']); ?>
|
|
|
</span>
|
|
|
</td>
|
|
|
+ <td>
|
|
|
+ <span class="role-badge role-<?php echo $user['role']; ?>">
|
|
|
+ <?php echo t('role_' . $user['role']); ?>
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td>
|
|
|
+ <span class="status-badge status-<?php echo $user['status']; ?>">
|
|
|
+ <?php echo t('status_' . $user['status']); ?>
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
<td><?php echo date('Y-m-d H:i', strtotime($user['created_at'])); ?></td>
|
|
|
<td><?php echo $user['last_login'] ? date('Y-m-d H:i', strtotime($user['last_login'])) : 'Never'; ?></td>
|
|
|
<td>
|
|
|
@@ -252,6 +374,22 @@ switch ($action) {
|
|
|
</select>
|
|
|
</div>
|
|
|
|
|
|
+ <div class="form-group">
|
|
|
+ <label for="role"><?php echo t('role'); ?>:</label>
|
|
|
+ <select id="role" name="role">
|
|
|
+ <option value="user" <?php echo ($user['role'] ?? 'user') === 'user' ? 'selected' : ''; ?>><?php echo t('role_user'); ?></option>
|
|
|
+ <option value="admin" <?php echo ($user['role'] ?? 'user') === 'admin' ? 'selected' : ''; ?>><?php echo t('role_admin'); ?></option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <label for="status"><?php echo t('status'); ?>:</label>
|
|
|
+ <select id="status" name="status">
|
|
|
+ <option value="active" <?php echo ($user['status'] ?? 'active') === 'active' ? 'selected' : ''; ?>><?php echo t('status_active'); ?></option>
|
|
|
+ <option value="inactive" <?php echo ($user['status'] ?? 'active') === 'inactive' ? 'selected' : ''; ?>><?php echo t('status_inactive'); ?></option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div class="form-actions">
|
|
|
<button type="submit" class="btn btn-primary"><?php echo t('update'); ?></button>
|
|
|
<a href="users.php" class="btn"><?php echo t('cancel'); ?></a>
|
|
|
@@ -291,6 +429,22 @@ switch ($action) {
|
|
|
</select>
|
|
|
</div>
|
|
|
|
|
|
+ <div class="form-group">
|
|
|
+ <label for="role"><?php echo t('role'); ?>:</label>
|
|
|
+ <select id="role" name="role">
|
|
|
+ <option value="user"><?php echo t('role_user'); ?></option>
|
|
|
+ <option value="admin"><?php echo t('role_admin'); ?></option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <label for="status"><?php echo t('status'); ?>:</label>
|
|
|
+ <select id="status" name="status">
|
|
|
+ <option value="active"><?php echo t('status_active'); ?></option>
|
|
|
+ <option value="inactive"><?php echo t('status_inactive'); ?></option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div class="form-actions">
|
|
|
<button type="submit" class="btn btn-primary"><?php echo t('create'); ?></button>
|
|
|
<a href="users.php" class="btn"><?php echo t('cancel'); ?></a>
|