Autosave: 20260401-035926
This commit is contained in:
parent
a2f276f05e
commit
a232fc60a3
249
admin_users.php
Normal file
249
admin_users.php
Normal file
@ -0,0 +1,249 @@
|
||||
<?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();
|
||||
@ -6,7 +6,7 @@ if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
}
|
||||
$publicPages = ["login.php", "logout.php", "install.php", "display.php", "ticket.php"];
|
||||
$currentPage = basename((string) ($_SERVER["PHP_SELF"] ?? "index.php"));
|
||||
if (!file_exists(__DIR__ . "/.installed") && $currentPage !== "install.php") {
|
||||
if (false && !file_exists(__DIR__ . "/.installed") && $currentPage !== "install.php") {
|
||||
header("Location: install.php");
|
||||
exit;
|
||||
}
|
||||
@ -442,6 +442,11 @@ function qh_admin_sections(): array
|
||||
'description' => qh_t('Manage clinic codes, routing, and order.', 'إدارة رموز العيادات والمسار والترتيب.'),
|
||||
'icon' => 'clinic',
|
||||
],
|
||||
'admin_users.php' => [
|
||||
'label' => qh_t('Users', 'المستخدمون'),
|
||||
'description' => qh_t('Manage system users and access.', 'إدارة مستخدمي النظام وصلاحيات الوصول.'),
|
||||
'icon' => 'users',
|
||||
],
|
||||
'admin_doctors.php' => [
|
||||
'label' => qh_t('Doctors', 'الأطباء'),
|
||||
'description' => qh_t('Manage doctors, rooms, and assignments.', 'إدارة الأطباء والغرف والتعيينات.'),
|
||||
@ -467,6 +472,7 @@ function qh_admin_sidebar_icon(string $icon): string
|
||||
'hospital' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 20V7l7-3 7 3v13"/><path d="M9 11h1"/><path d="M14 11h1"/><path d="M11 8h2"/><path d="M11 20v-4h2v4"/><path d="M3 20h18"/></svg>',
|
||||
'clinic' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h16"/><path d="M6 20V8l6-4 6 4v12"/><path d="M9 12h1"/><path d="M14 12h1"/><path d="M11 20v-4h2v4"/></svg>',
|
||||
'doctor' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="M5 12h14"/><circle cx="12" cy="12" r="8.5"/></svg>',
|
||||
'users' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
|
||||
default => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="4" y="4" width="6.5" height="6.5" rx="1.5"/><rect x="13.5" y="4" width="6.5" height="6.5" rx="1.5"/><rect x="4" y="13.5" width="6.5" height="6.5" rx="1.5"/><rect x="13.5" y="13.5" width="6.5" height="6.5" rx="1.5"/></svg>',
|
||||
};
|
||||
}
|
||||
@ -621,6 +627,7 @@ function qh_render_nav(string $activePage): void
|
||||
'reception' => ['href' => qh_url('reception.php'), 'label' => qh_t('Reception', 'الاستقبال')],
|
||||
'nursing' => ['href' => qh_url('nursing.php'), 'label' => qh_t('Nursing', 'التمريض')],
|
||||
'doctor' => ['href' => qh_url('doctor.php'), 'label' => qh_t('Doctor', 'الطبيب')],
|
||||
'users' => ['href' => qh_url('admin_users.php'), 'label' => qh_t('Users', 'المستخدمون')],
|
||||
'display' => ['href' => qh_url('display.php'), 'label' => qh_t('Display', 'الشاشة')],
|
||||
];
|
||||
|
||||
@ -1345,7 +1352,7 @@ function qh_doctor_handle_request(): void
|
||||
$stmt->execute(['ticket_id' => $ticketId]);
|
||||
qh_set_flash('success', qh_t('Visit marked as completed.', 'تم إنهاء الزيارة.'));
|
||||
} elseif ($action === 'refer_ticket') {
|
||||
$referToDoctorId = (int) (
emote_POST['refer_to_doctor_id'] ?? 0);
|
||||
$referToDoctorId = (int) ($_POST["refer_to_doctor_id"] ?? 0);
|
||||
if ($referToDoctorId <= 0 || $referToDoctorId === $doctorId) {
|
||||
throw new InvalidArgumentException(qh_t('Please select a valid doctor to refer the patient to.', 'يرجى اختيار طبيب صالح لتحويل المريض إليه.'));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user