203 lines
8.7 KiB
PHP
203 lines
8.7 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">
|
|
<table class="table app-table align-middle mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th><?= h(tr('المستخدم', 'User')) ?></th>
|
|
<th><?= h(tr('الدور', 'Role')) ?></th>
|
|
<th><?= h(tr('الفرع', 'Branch')) ?></th>
|
|
<th>POS</th>
|
|
<th><?= h(tr('تقارير', 'Reports')) ?></th>
|
|
<th><?= h(tr('مستخدمون', 'Users')) ?></th>
|
|
<th><?= h(tr('إجراءات', 'Actions')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?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-light text-primary border" onclick="mockEdit()" title="<?= h(tr('تعديل', 'Edit')) ?>">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-light text-danger border" 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'; ?>
|