203 lines
9.5 KiB
PHP
203 lines
9.5 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/app.php';
|
|
$user = require_roles(['owner']);
|
|
$pageTitle = tr('المستخدمون والأدوار', 'Users & Roles');
|
|
$activeNav = 'users';
|
|
|
|
$allAccounts = demo_users();
|
|
|
|
// Search logic
|
|
$search = $_GET['q'] ?? '';
|
|
$filteredAccounts = [];
|
|
if ($search) {
|
|
$lowerSearch = strtolower($search);
|
|
foreach ($allAccounts as $key => $acc) {
|
|
if (
|
|
str_contains(strtolower((string)$acc['name_ar']), $lowerSearch) ||
|
|
str_contains(strtolower((string)$acc['name_en']), $lowerSearch) ||
|
|
str_contains(strtolower((string)$acc['username']), $lowerSearch)
|
|
) {
|
|
$filteredAccounts[$key] = $acc;
|
|
}
|
|
}
|
|
} else {
|
|
$filteredAccounts = $allAccounts;
|
|
}
|
|
|
|
// Pagination logic
|
|
$page = max(1, (int)($_GET['p'] ?? 1));
|
|
$limit = 10;
|
|
$total = count($filteredAccounts);
|
|
$totalPages = max(1, ceil($total / $limit));
|
|
$offset = ($page - 1) * $limit;
|
|
$accounts = array_slice($filteredAccounts, $offset, $limit, true);
|
|
|
|
require __DIR__ . '/includes/header.php';
|
|
?>
|
|
<section class="surface-card mb-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<div>
|
|
<h3 class="h5 mb-2"><i class="bi bi-people me-2"></i><?= h(tr('الوصول حسب الدور', 'Role-based access')) ?></h3>
|
|
<p class="text-muted mb-0"><?= h(tr('الإصدار الأول يستخدم حسابات تجريبية منفصلة لإثبات هيكل الصلاحيات قبل ربط المستخدمين بقاعدة البيانات.', 'This first version uses separate demo accounts to prove the permissions model before wiring users into the database.')) ?></p>
|
|
</div>
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addUserModal">
|
|
<i class="bi bi-person-plus"></i> <?= h(tr('إضافة مستخدم', 'Add User')) ?>
|
|
</button>
|
|
</div>
|
|
|
|
<form class="d-flex mb-3" method="GET" action="users.php">
|
|
<div class="input-group" style="max-width: 400px;">
|
|
<input type="text" name="q" class="form-control" placeholder="<?= h(tr('بحث...', 'Search...')) ?>" value="<?= h($search) ?>">
|
|
<button class="btn btn-outline-secondary" type="submit"><i class="bi bi-search"></i></button>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="surface-card">
|
|
<div class="table-responsive shadow-sm" style="border-radius: 12px; overflow: hidden; border: 1px solid rgba(0,0,0,0.05);">
|
|
<table class="table table-hover align-middle mb-0 text-center" style="background-color: #fff;">
|
|
<thead style="background: linear-gradient(90deg, #0d6efd, #0dcaf0);">
|
|
<tr>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('المستخدم', 'User')) ?></th>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('الدور', 'Role')) ?></th>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('الفرع', 'Branch')) ?></th>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent">POS</th>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('تقارير', 'Reports')) ?></th>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('مستخدمون', 'Users')) ?></th>
|
|
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('إجراءات', 'Actions')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="border-top-0">
|
|
<?php if(empty($accounts)): ?>
|
|
<tr><td colspan="7" class="text-center text-muted py-4"><?= h(tr('لا توجد بيانات', 'No data found')) ?></td></tr>
|
|
<?php endif; ?>
|
|
<?php foreach ($accounts as $key => $account): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-semibold"><?= h(current_lang() === 'ar' ? $account['name_ar'] : $account['name_en']) ?></div>
|
|
<div class="small text-muted"><?= h($account['username']) ?></div>
|
|
</td>
|
|
<td><?= h(role_label($account['role'])) ?></td>
|
|
<td><?= h(branch_label($account['branch_code'])) ?></td>
|
|
<td><span class="badge text-bg-light border"><?= h(tr('نعم', 'Yes')) ?></span></td>
|
|
<td><span class="badge <?= in_array($account['role'], ['owner', 'manager'], true) ? 'text-bg-light border' : 'text-bg-secondary' ?>"><?= h(in_array($account['role'], ['owner', 'manager'], true) ? tr('نعم', 'Yes') : tr('لا', 'No')) ?></span></td>
|
|
<td><span class="badge <?= $account['role'] === 'owner' ? 'text-bg-light border' : 'text-bg-secondary' ?>"><?= h($account['role'] === 'owner' ? tr('نعم', 'Yes') : tr('لا', 'No')) ?></span></td>
|
|
<td>
|
|
<button class="btn btn-sm btn-outline-primary rounded-circle shadow-sm" style="width: 34px; height: 34px; padding: 0;" onclick="mockEdit()" title="<?= h(tr('تعديل', 'Edit')) ?>">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-outline-danger rounded-circle shadow-sm ms-1" style="width: 34px; height: 34px; padding: 0;" onclick="mockDelete()" title="<?= h(tr('حذف', 'Delete')) ?>">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<?php if ($totalPages > 1): ?>
|
|
<nav class="mt-4">
|
|
<ul class="pagination justify-content-center mb-0">
|
|
<?php for($i=1; $i<=$totalPages; $i++): ?>
|
|
<li class="page-item <?= $i === $page ? 'active' : '' ?>">
|
|
<a class="page-link" href="<?= h(url_for('users.php', ['p' => $i, 'q' => $search])) ?>"><?= $i ?></a>
|
|
</li>
|
|
<?php endfor; ?>
|
|
</ul>
|
|
</nav>
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
<!-- Add User Modal -->
|
|
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form id="addUserForm" onsubmit="handleUserSubmit(event)">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="addUserModalLabel"><?= h(tr('إضافة مستخدم جديد', '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 for="userName" class="form-label"><?= h(tr('اسم المستخدم', 'Name')) ?></label>
|
|
<input type="text" class="form-control" id="userName" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="userRole" class="form-label"><?= h(tr('الدور', 'Role')) ?></label>
|
|
<select class="form-select" id="userRole" required>
|
|
<option value="cashier"><?= h(tr('كاشير', 'Cashier')) ?></option>
|
|
<option value="manager"><?= h(tr('مدير فرع', 'Branch Manager')) ?></option>
|
|
<option value="owner"><?= h(tr('مالك', 'Owner')) ?></option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="userBranch" class="form-label"><?= h(tr('الفرع', 'Branch')) ?></label>
|
|
<select class="form-select" id="userBranch" required>
|
|
<option value="main"><?= h(tr('الرئيسي', 'Main')) ?></option>
|
|
<option value="north"><?= h(tr('الشمالي', 'North')) ?></option>
|
|
<option value="south"><?= h(tr('الجنوبي', 'South')) ?></option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?= h(tr('إلغاء', 'Cancel')) ?></button>
|
|
<button type="submit" class="btn btn-primary"><?= h(tr('حفظ', 'Save')) ?></button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function handleUserSubmit(e) {
|
|
e.preventDefault();
|
|
// Close the modal
|
|
var myModalEl = document.getElementById('addUserModal');
|
|
var modal = bootstrap.Modal.getInstance(myModalEl);
|
|
modal.hide();
|
|
|
|
// Show SweetAlert2 Success Message
|
|
Swal.fire({
|
|
title: '<?= h(tr('تم الحفظ!', 'Saved!')) ?>',
|
|
text: '<?= h(tr('تمت إضافة المستخدم بنجاح. (تجريبي)', 'User has been added successfully. (Demo)')) ?>',
|
|
icon: 'success',
|
|
confirmButtonText: '<?= h(tr('حسناً', 'OK')) ?>'
|
|
});
|
|
|
|
// Reset form
|
|
e.target.reset();
|
|
}
|
|
|
|
function mockEdit() {
|
|
Swal.fire({
|
|
title: '<?= h(tr('تعديل (تجريبي)', 'Edit (Demo)')) ?>',
|
|
text: '<?= h(tr('هذه الميزة غير مفعلة للبيانات التجريبية.', 'This feature is mock data and not active yet.')) ?>',
|
|
icon: 'info',
|
|
confirmButtonText: '<?= h(tr('حسناً', 'OK')) ?>'
|
|
});
|
|
}
|
|
|
|
function mockDelete() {
|
|
Swal.fire({
|
|
title: '<?= h(tr('هل أنت متأكد؟', 'Are you sure?')) ?>',
|
|
text: '<?= h(tr('لن تتمكن من التراجع عن هذا!', "You won't be able to revert this!")) ?>',
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#dc3545',
|
|
cancelButtonColor: '#6c757d',
|
|
confirmButtonText: '<?= h(tr('نعم، احذف', 'Yes, delete it!')) ?>',
|
|
cancelButtonText: '<?= h(tr('إلغاء', 'Cancel')) ?>'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
Swal.fire(
|
|
'<?= h(tr('محذوف!', 'Deleted!')) ?>',
|
|
'<?= h(tr('حساب تجريبي لا يمكن حذفه.', 'Demo account cannot be deleted.')) ?>',
|
|
'success'
|
|
);
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<?php require __DIR__ . '/includes/footer.php'; ?>
|