Commit a83fd794 authored by Administrator's avatar Administrator

Update 1 files via Son of Anton

parent cbd6fc0a
<?php
use App\Core\Registries\MenuRegistry;
/**
* Sidebar component — reads menu items from MenuRegistry.
*/
use App\Core\App;
use App\Core\Registries\MenuRegistry;
$currentPath = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$employee = App::getInstance()->currentEmployee();
$permissions = ['*'];
// Get all permissions for current employee
$employeePermissions = [];
if ($employee && method_exists($employee, 'getAllPermissions')) {
$permissions = $employee->getAllPermissions();
$employeePermissions = $employee->getAllPermissions();
} elseif ($employee) {
// Fallback: load permissions directly
try {
$db = App::getInstance()->db();
$empId = $employee->id ?? 0;
$perms = $db->select(
"SELECT DISTINCT rp.permission_key
FROM employee_roles er
JOIN role_permissions rp ON rp.role_id = er.role_id
WHERE er.employee_id = ? AND er.is_active = 1",
[(int) $empId]
);
$employeePermissions = array_column($perms, 'permission_key');
// Check if super_admin — gets all permissions
$isSuperAdmin = $db->selectOne(
"SELECT 1 FROM employee_roles er
JOIN roles r ON r.id = er.role_id
WHERE er.employee_id = ? AND r.role_code = 'super_admin' AND er.is_active = 1
LIMIT 1",
[(int) $empId]
);
if ($isSuperAdmin) {
$employeePermissions = ['*']; // Wildcard — has all permissions
}
} catch (\Throwable $e) {
$employeePermissions = [];
}
}
$hasPerm = function(string $perm) use ($employeePermissions): bool {
if (empty($perm)) return true;
if (in_array('*', $employeePermissions)) return true;
return in_array($perm, $employeePermissions);
};
$isActive = function(string $route) use ($currentPath): bool {
if ($route === '/') return $currentPath === '/';
return str_starts_with($currentPath, $route);
};
// Get menu items from registry
$menuItems = MenuRegistry::getAll();
// Sort by order
usort($menuItems, fn($a, $b) => ($a['order'] ?? 999) <=> ($b['order'] ?? 999));
// If MenuRegistry is empty, build default menu from known modules
if (empty($menuItems)) {
$menuItems = [
[
'key' => 'dashboard',
'label_ar' => 'لوحة التحكم',
'icon' => '📊',
'route' => '/dashboard',
'permission' => '',
'order' => 10,
'children' => [],
],
[
'key' => 'members',
'label_ar' => 'إدارة الأعضاء',
'icon' => '👥',
'route' => '/members',
'permission' => 'member.view',
'order' => 100,
'children' => [
['label_ar' => 'كل الأعضاء', 'route' => '/members', 'permission' => 'member.view', 'order' => 1],
['label_ar' => 'عضو جديد', 'route' => '/members/create', 'permission' => 'member.create', 'order' => 2],
['label_ar' => 'بحث', 'route' => '/members/search', 'permission' => 'member.view', 'order' => 3],
],
],
[
'key' => 'forms',
'label_ar' => 'النماذج',
'icon' => '📋',
'route' => '/forms',
'permission' => 'form.view',
'order' => 150,
'children' => [
['label_ar' => 'النماذج المقدمة', 'route' => '/forms/submissions', 'permission' => 'form.view', 'order' => 1],
['label_ar' => 'منشئ النماذج', 'route' => '/forms/builder', 'permission' => 'form.manage', 'order' => 2],
],
],
[
'key' => 'interviews',
'label_ar' => 'المقابلات',
'icon' => '🗓️',
'route' => '/interviews',
'permission' => 'interview.view',
'order' => 200,
'children' => [],
],
[
'key' => 'payments',
'label_ar' => 'المدفوعات',
'icon' => '💰',
'route' => '/payments',
'permission' => 'payment.view',
'order' => 300,
'children' => [
['label_ar' => 'كل المدفوعات', 'route' => '/payments', 'permission' => 'payment.view', 'order' => 1],
['label_ar' => 'الإيصالات', 'route' => '/receipts', 'permission' => 'receipt.view', 'order' => 2],
['label_ar' => 'التقرير اليومي', 'route' => '/payments/daily-report', 'permission' => 'payment.view', 'order' => 3],
],
],
[
'key' => 'installments',
'label_ar' => 'الأقساط',
'icon' => '📅',
'route' => '/installments',
'permission' => 'installment.view',
'order' => 350,
'children' => [],
],
[
'key' => 'subscriptions',
'label_ar' => 'الاشتراكات',
'icon' => '🔄',
'route' => '/subscriptions',
'permission' => 'subscription.view',
'order' => 400,
'children' => [],
],
[
'key' => 'violations',
'label_ar' => 'المخالفات والغرامات',
'icon' => '⚠️',
'route' => '/violations',
'permission' => 'violation.view',
'order' => 450,
'children' => [
['label_ar' => 'المخالفات', 'route' => '/violations', 'permission' => 'violation.view', 'order' => 1],
['label_ar' => 'الغرامات', 'route' => '/fines', 'permission' => 'fine.view', 'order' => 2],
],
],
[
'key' => 'transfers',
'label_ar' => 'التحويلات',
'icon' => '🔀',
'route' => '/transfers',
'permission' => 'transfer.view',
'order' => 500,
'children' => [
['label_ar' => 'طلبات التحويل', 'route' => '/transfers', 'permission' => 'transfer.view', 'order' => 1],
['label_ar' => 'حالات الطلاق', 'route' => '/divorce', 'permission' => 'divorce.view', 'order' => 2],
['label_ar' => 'حالات الوفاة', 'route' => '/death', 'permission' => 'death.view', 'order' => 3],
['label_ar' => 'التنازلات', 'route' => '/waiver', 'permission' => 'waiver.view', 'order' => 4],
],
],
[
'key' => 'memberships',
'label_ar' => 'أنواع العضوية',
'icon' => '🏅',
'route' => '#',
'permission' => '',
'order' => 550,
'children' => [
['label_ar' => 'الموسمية', 'route' => '/seasonal', 'permission' => 'seasonal.view', 'order' => 1],
['label_ar' => 'الرياضية', 'route' => '/sports', 'permission' => 'sports.view', 'order' => 2],
['label_ar' => 'الشرفية', 'route' => '/honorary', 'permission' => 'honorary.view', 'order' => 3],
['label_ar' => 'الأجنبية', 'route' => '/foreign', 'permission' => 'foreign.view', 'order' => 4],
],
],
[
'key' => 'carnets',
'label_ar' => 'الكارنيهات',
'icon' => '🪪',
'route' => '/carnets',
'permission' => 'carnet.view',
'order' => 600,
'children' => [],
],
[
'key' => 'documents',
'label_ar' => 'المستندات',
'icon' => '📁',
'route' => '/documents',
'permission' => 'document.view',
'order' => 650,
'children' => [],
],
[
'key' => 'notifications',
'label_ar' => 'الرسائل النصية',
'icon' => '📱',
'route' => '/notifications',
'permission' => 'notification.view',
'order' => 700,
'children' => [
['label_ar' => 'إرسال رسالة', 'route' => '/notifications/send', 'permission' => 'notification.send', 'order' => 1],
['label_ar' => 'سجل الرسائل', 'route' => '/notifications/log', 'permission' => 'notification.view', 'order' => 2],
['label_ar' => 'القوالب', 'route' => '/notifications/templates', 'permission' => 'notification.manage', 'order' => 3],
],
],
[
'key' => 'reports',
'label_ar' => 'التقارير',
'icon' => '📈',
'route' => '/reports',
'permission' => 'report.view',
'order' => 800,
'children' => [],
],
[
'key' => 'separator_admin',
'label_ar' => '── الإدارة ──',
'icon' => '',
'route' => '',
'permission' => '',
'order' => 900,
'children' => [],
'is_separator' => true,
],
[
'key' => 'users',
'label_ar' => 'الموظفون',
'icon' => '👤',
'route' => '/users',
'permission' => 'user.view',
'order' => 910,
'children' => [
['label_ar' => 'كل الموظفين', 'route' => '/users', 'permission' => 'user.view', 'order' => 1],
['label_ar' => 'موظف جديد', 'route' => '/users/create', 'permission' => 'user.create', 'order' => 2],
],
],
[
'key' => 'roles',
'label_ar' => 'الأدوار والصلاحيات',
'icon' => '🔐',
'route' => '/roles',
'permission' => 'role.view',
'order' => 920,
'children' => [],
],
[
'key' => 'branches',
'label_ar' => 'الفروع',
'icon' => '🏢',
'route' => '/branches',
'permission' => 'branch.view',
'order' => 930,
'children' => [],
],
[
'key' => 'rules',
'label_ar' => 'محرك القواعد',
'icon' => '⚙️',
'route' => '/rules',
'permission' => 'rule.view',
'order' => 940,
'children' => [],
],
[
'key' => 'pricing',
'label_ar' => 'التسعير',
'icon' => '💲',
'route' => '/pricing',
'permission' => 'pricing.view',
'order' => 950,
'children' => [
['label_ar' => 'أسعار العضوية', 'route' => '/pricing', 'permission' => 'pricing.view', 'order' => 1],
['label_ar' => 'كتالوج الخدمات', 'route' => '/catalog', 'permission' => 'catalog.view', 'order' => 2],
],
],
[
'key' => 'settings',
'label_ar' => 'الإعدادات',
'icon' => '🔧',
'route' => '/settings',
'permission' => 'settings.view',
'order' => 960,
'children' => [],
],
[
'key' => 'audit',
'label_ar' => 'سجل المراجعة',
'icon' => '📜',
'route' => '/audit',
'permission' => 'audit.view',
'order' => 970,
'children' => [],
],
[
'key' => 'archive',
'label_ar' => 'الأرشيف',
'icon' => '🗄️',
'route' => '/archive',
'permission' => 'archive.view',
'order' => 980,
'children' => [],
],
[
'key' => 'workflow',
'label_ar' => 'سير العمل',
'icon' => '🔄',
'route' => '/workflow',
'permission' => 'workflow.view',
'order' => 990,
'children' => [],
],
];
}
$menuItems = MenuRegistry::getVisible($permissions);
$currentPath = $_SERVER['REQUEST_URI'] ?? '/';
$currentPath = parse_url($currentPath, PHP_URL_PATH);
?>
<div class="sidebar-header">
<div class="sidebar-logo">
<span class="sidebar-brand">THE CLUB</span>
</div>
<button class="sidebar-toggle" id="sidebar-toggle" onclick="toggleSidebar()"></button>
<div class="sidebar-brand">THE CLUB</div>
</div>
<nav class="sidebar-nav">
<ul class="sidebar-menu">
<li class="sidebar-item">
<a href="/" class="sidebar-link <?= $currentPath === '/' ? 'active' : '' ?>">
<span class="sidebar-icon">🏠</span>
<span class="sidebar-text">الرئيسية</span>
</a>
</li>
<?php foreach ($menuItems as $key => $item): ?>
<?php foreach ($menuItems as $item): ?>
<?php
$hasChildren = !empty($item['children']);
$isActive = str_starts_with($currentPath, $item['route'] ?? '###');
if ($hasChildren) {
foreach ($item['children'] as $child) {
if (str_starts_with($currentPath, $child['route'] ?? '###')) {
$isActive = true;
break;
}
}
// Check permission
if (!empty($item['permission']) && !$hasPerm($item['permission'])) {
continue;
}
// Separator
if (!empty($item['is_separator'])) {
echo '<li style="padding:15px 20px 5px;font-size:11px;color:#6B7280;text-transform:uppercase;letter-spacing:1px;">' . e($item['label_ar']) . '</li>';
continue;
}
$children = $item['children'] ?? [];
// Filter children by permission
$visibleChildren = [];
foreach ($children as $child) {
if (empty($child['permission']) || $hasPerm($child['permission'])) {
$visibleChildren[] = $child;
}
}
$hasChildren = !empty($visibleChildren);
$itemRoute = $item['route'] ?? '#';
$itemActive = $isActive($itemRoute);
// Check if any child is active
$childActive = false;
foreach ($visibleChildren as $child) {
if ($isActive($child['route'] ?? '')) {
$childActive = true;
break;
}
}
$isOpen = $itemActive || $childActive;
?>
<li class="sidebar-item <?= $hasChildren ? 'has-children' : '' ?> <?= $isActive ? 'open' : '' ?>">
<li class="sidebar-item<?= $isOpen && $hasChildren ? ' open' : '' ?>">
<?php if ($hasChildren): ?>
<a href="#" class="sidebar-link <?= $isActive ? 'active' : '' ?>" onclick="toggleSubmenu(this);return false;">
<span class="sidebar-icon"><?= $item['icon'] ?? '📁' ?></span>
<span class="sidebar-text"><?= e($item['label_ar'] ?? '') ?></span>
<a href="javascript:void(0)" class="sidebar-link<?= $itemActive ? ' active' : '' ?>" onclick="toggleSubmenu(this)">
<span class="sidebar-icon"><?= $item['icon'] ?? '' ?></span>
<span class="sidebar-text"><?= e($item['label_ar']) ?></span>
<span class="sidebar-arrow"></span>
</a>
<ul class="sidebar-submenu" style="<?= $isActive ? 'display:block;' : 'display:none;' ?>">
<?php foreach ($item['children'] as $child): ?>
<ul class="sidebar-submenu" style="display:<?= $isOpen ? 'block' : 'none' ?>;">
<?php foreach ($visibleChildren as $child): ?>
<?php $childRoute = $child['route'] ?? '#'; ?>
<li>
<a href="<?= e($child['route'] ?? '#') ?>" class="sidebar-sublink <?= $currentPath === ($child['route'] ?? '') ? 'active' : '' ?>">
<?= e($child['label_ar'] ?? '') ?>
<a href="<?= e($childRoute) ?>" class="sidebar-sublink<?= $isActive($childRoute) ? ' active' : '' ?>">
<?= e($child['label_ar']) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<a href="<?= e($item['route'] ?? '#') ?>" class="sidebar-link <?= $isActive ? 'active' : '' ?>">
<span class="sidebar-icon"><?= $item['icon'] ?? '📄' ?></span>
<span class="sidebar-text"><?= e($item['label_ar'] ?? '') ?></span>
<a href="<?= e($itemRoute) ?>" class="sidebar-link<?= $itemActive ? ' active' : '' ?>">
<span class="sidebar-icon"><?= $item['icon'] ?? '' ?></span>
<span class="sidebar-text"><?= e($item['label_ar']) ?></span>
</a>
<?php endif; ?>
</li>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment