39414-vm/admin_users.php
2026-04-01 03:59:27 +00:00

250 lines
12 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/queue_bootstrap.php';
qh_boot();
qh_admin_handle_request(); // To handle language swaps etc. if needed
$pdo = db();
$error = '';
$success = '';
// Handle actions
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'create_user') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
if ($username === '' || $password === '') {
$error = qh_t('Username and password are required.', 'اسم المستخدم وكلمة المرور مطلوبان.');
} else {
try {
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users (username, password) VALUES (:username, :password)");
$stmt->execute(['username' => $username, 'password' => $hash]);
$success = qh_t('User created successfully.', 'تم إنشاء المستخدم بنجاح.');
} catch (PDOException $e) {
if ($e->getCode() == 23000) {
$error = qh_t('Username already exists.', 'اسم المستخدم موجود مسبقاً.');
} else {
$error = qh_t('Failed to create user.', 'فشل في إنشاء المستخدم.');
}
}
}
} elseif ($action === 'update_user') {
$id = (int)($_POST['id'] ?? 0);
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
if ($id <= 0 || $username === '') {
$error = qh_t('Invalid user data.', 'بيانات المستخدم غير صالحة.');
} else {
try {
if ($password !== '') {
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET username = :username, password = :password WHERE id = :id");
$stmt->execute(['username' => $username, 'password' => $hash, 'id' => $id]);
} else {
$stmt = $pdo->prepare("UPDATE users SET username = :username WHERE id = :id");
$stmt->execute(['username' => $username, 'id' => $id]);
}
$success = qh_t('User updated successfully.', 'تم تحديث المستخدم بنجاح.');
} catch (PDOException $e) {
if ($e->getCode() == 23000) {
$error = qh_t('Username already exists.', 'اسم المستخدم موجود مسبقاً.');
} else {
$error = qh_t('Failed to update user.', 'فشل في تحديث المستخدم.');
}
}
}
} elseif ($action === 'delete_user') {
$id = (int)($_POST['id'] ?? 0);
// Prevent deleting the last user
$count = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
if ($count <= 1) {
$error = qh_t('Cannot delete the last user in the system.', 'لا يمكن حذف آخر مستخدم في النظام.');
} elseif ($id > 0) {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
$success = qh_t('User deleted successfully.', 'تم حذف المستخدم بنجاح.');
}
}
}
try {
$users = $pdo->query("SELECT id, username, created_at FROM users ORDER BY id ASC")->fetchAll();
} catch (PDOException $e) {
if ($e->getCode() == '42S02') {
$pdo->exec("CREATE TABLE IF NOT EXISTS users (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
$users = [];
$error = qh_t('Users table was missing and has been created.', 'كان جدول المستخدمين مفقوداً وتم إنشاؤه.');
} else {
throw $e;
}
}
$stats = qh_admin_stats();
qh_page_start(
'admin',
qh_t('System Users', 'مستخدمو النظام'),
qh_t('Manage system users and access.', 'إدارة مستخدمي النظام وصلاحيات الوصول.')
);
?>
<div class="container-fluid container-xxl px-3 px-lg-4">
<div class="admin-layout">
<aside class="admin-sidebar-column">
<?php qh_render_admin_sidebar('admin_users.php', $stats); ?>
</aside>
<div class="admin-content-stack">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h3 mb-0 text-gray-800 fw-bold"><?= qh_h(qh_t('System Users', 'مستخدمو النظام')) ?></h1>
<p class="text-muted mb-0 mt-1"><?= qh_h(qh_t('Manage system administrators and staff access.', 'إدارة مديري النظام وصلاحيات وصول الموظفين.')) ?></p>
</div>
<button type="button" class="btn btn-primary d-flex align-items-center gap-2" data-bs-toggle="modal" data-bs-target="#createUserModal">
<svg viewBox="0 0 24 24" width="18" height="18" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
<?= qh_h(qh_t('Add User', 'إضافة مستخدم')) ?>
</button>
</div>
<?php if ($error !== ''): ?>
<div class="alert alert-danger" role="alert"><?= qh_h($error) ?></div>
<?php endif; ?>
<?php if ($success !== ''): ?>
<div class="alert alert-success" role="alert"><?= qh_h($success) ?></div>
<?php endif; ?>
<div class="card shadow-sm border-0 mb-4">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light">
<tr>
<th scope="col" class="px-4 py-3">ID</th>
<th scope="col" class="px-4 py-3"><?= qh_h(qh_t('Username', 'اسم المستخدم')) ?></th>
<th scope="col" class="px-4 py-3"><?= qh_h(qh_t('Created At', 'تاريخ الإنشاء')) ?></th>
<th scope="col" class="px-4 py-3 text-end"><?= qh_h(qh_t('Actions', 'الإجراءات')) ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td class="px-4 py-3 text-muted">#<?= qh_h((string)$user['id']) ?></td>
<td class="px-4 py-3 fw-medium text-gray-900"><?= qh_h($user['username']) ?></td>
<td class="px-4 py-3 text-muted"><?= qh_h($user['created_at']) ?></td>
<td class="px-4 py-3 text-end">
<button type="button" class="btn btn-sm btn-outline-secondary me-2"
data-bs-toggle="modal"
data-bs-target="#editUserModal"
data-id="<?= qh_h((string)$user['id']) ?>"
data-username="<?= qh_h($user['username']) ?>">
<?= qh_h(qh_t('Edit', 'تعديل')) ?>
</button>
<?php if (count($users) > 1): ?>
<form action="" method="POST" class="d-inline-block" onsubmit="return confirm('<?= qh_h(qh_t('Are you sure you want to delete this user?', 'هل أنت متأكد أنك تريد حذف هذا المستخدم؟')) ?>');">
<input type="hidden" name="action" value="delete_user">
<input type="hidden" name="id" value="<?= qh_h((string)$user['id']) ?>">
<button type="submit" class="btn btn-sm btn-outline-danger">
<?= qh_h(qh_t('Delete', 'حذف')) ?>
</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($users)): ?>
<tr>
<td colspan="4" class="px-4 py-4 text-center text-muted">
<?= qh_h(qh_t('No users found.', 'لا يوجد مستخدمين.')) ?>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Create User Modal -->
<div class="modal fade" id="createUserModal" tabindex="-1" aria-labelledby="createUserModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<form action="" method="POST">
<input type="hidden" name="action" value="create_user">
<div class="modal-header border-bottom-0 pb-0">
<h5 class="modal-title fw-bold" id="createUserModalLabel"><?= qh_h(qh_t('Add New User', 'إضافة مستخدم جديد')) ?></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label text-muted small fw-bold text-uppercase"><?= qh_h(qh_t('Username', 'اسم المستخدم')) ?></label>
<input type="text" name="username" class="form-control form-control-lg bg-light" required>
</div>
<div class="mb-3">
<label class="form-label text-muted small fw-bold text-uppercase"><?= qh_h(qh_t('Password', 'كلمة المرور')) ?></label>
<input type="password" name="password" class="form-control form-control-lg bg-light" required>
</div>
</div>
<div class="modal-footer border-top-0 pt-0">
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><?= qh_h(qh_t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary px-4"><?= qh_h(qh_t('Create 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">
<div class="modal-content border-0 shadow">
<form action="" method="POST">
<input type="hidden" name="action" value="update_user">
<input type="hidden" name="id" id="editUserId" value="">
<div class="modal-header border-bottom-0 pb-0">
<h5 class="modal-title fw-bold" id="editUserModalLabel"><?= qh_h(qh_t('Edit User', 'تعديل المستخدم')) ?></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label text-muted small fw-bold text-uppercase"><?= qh_h(qh_t('Username', 'اسم المستخدم')) ?></label>
<input type="text" name="username" id="editUserUsername" class="form-control form-control-lg bg-light" required>
</div>
<div class="mb-3">
<label class="form-label text-muted small fw-bold text-uppercase"><?= qh_h(qh_t('New Password (Optional)', 'كلمة مرور جديدة (اختياري)')) ?></label>
<input type="password" name="password" class="form-control form-control-lg bg-light" placeholder="<?= qh_h(qh_t('Leave blank to keep current password', 'اتركه فارغاً للاحتفاظ بكلمة المرور الحالية')) ?>">
</div>
</div>
<div class="modal-footer border-top-0 pt-0">
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><?= qh_h(qh_t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary px-4"><?= qh_h(qh_t('Save Changes', 'حفظ التغييرات')) ?></button>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const editModal = document.getElementById('editUserModal');
if (editModal) {
editModal.addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const id = button.getAttribute('data-id');
const username = button.getAttribute('data-username');
editModal.querySelector('#editUserId').value = id;
editModal.querySelector('#editUserUsername').value = username;
});
}
});
</script>
<?php
qh_page_end();