user(); $tenantId = request()->attributes->get('tenant_id'); $tenantRole = $user?->tenantRole($tenantId); if (! $user) { return $this->error('Unauthenticated', 401); } if ($user->isMasterAdmin() || $user->is_platform_staff) { $menus = MenuList::query() ->where('is_active', true) ->when($user->is_platform_staff && ! $user->isMasterAdmin(), fn ($q) => $q->whereIn('slug', ['role-applications', 'role-applications-tenants'])) ->orderBy('sort_order') ->orderBy('id') ->get() ->map(function (MenuList $menu) { return [ 'id' => $menu->id, 'parent_id' => $menu->parent_id, 'name' => $menu->name, 'slug' => $menu->slug, 'url' => $menu->url, 'icon' => $menu->icon, 'component' => $menu->component, 'sort_order' => $menu->sort_order, 'permissions' => [ 'can_view' => true, 'can_create' => true, 'can_update' => true, 'can_delete' => true, 'can_approve' => true, 'can_export' => true, ], ]; }); } else { $menuRows = DB::table('menu_lists as m') ->join('menu_group_menus as mgm', 'mgm.menu_id', '=', 'm.id') ->join('user_menu_groups as umg', 'umg.menu_group_id', '=', 'mgm.menu_group_id') ->join('menu_groups as mg', 'mg.id', '=', 'umg.menu_group_id') ->where('umg.user_id', $user->id) ->where('umg.tenant_id', $tenantId) ->where('mg.is_active', true) ->where('m.is_active', true) ->where('mgm.can_view', true) ->groupBy( 'm.id', 'm.parent_id', 'm.name', 'm.slug', 'm.url', 'm.icon', 'm.component', 'm.sort_order' ) ->select( 'm.id', 'm.parent_id', 'm.name', 'm.slug', 'm.url', 'm.icon', 'm.component', 'm.sort_order', DB::raw('MAX(CASE WHEN mgm.can_view THEN 1 ELSE 0 END) as can_view'), DB::raw('MAX(CASE WHEN mgm.can_create THEN 1 ELSE 0 END) as can_create'), DB::raw('MAX(CASE WHEN mgm.can_update THEN 1 ELSE 0 END) as can_update'), DB::raw('MAX(CASE WHEN mgm.can_delete THEN 1 ELSE 0 END) as can_delete'), DB::raw('MAX(CASE WHEN mgm.can_approve THEN 1 ELSE 0 END) as can_approve'), DB::raw('MAX(CASE WHEN mgm.can_export THEN 1 ELSE 0 END) as can_export') ) ->orderBy('m.sort_order') ->orderBy('m.id') ->get(); $menus = $menuRows->map(function ($row) { return [ 'id' => (int) $row->id, 'parent_id' => $row->parent_id ? (int) $row->parent_id : null, 'name' => $row->name, 'slug' => $row->slug, 'url' => $row->url, 'icon' => $row->icon, 'component' => $row->component, 'sort_order' => (int) $row->sort_order, 'permissions' => [ 'can_view' => (bool) $row->can_view, 'can_create' => (bool) $row->can_create, 'can_update' => (bool) $row->can_update, 'can_delete' => (bool) $row->can_delete, 'can_approve' => (bool) $row->can_approve, 'can_export' => (bool) $row->can_export, ], ]; }); } $tree = $this->buildMenuTree($menus); if (! $user->isMasterAdmin() && ! $user->is_platform_staff && ! in_array($tenantRole, ['staff', 'tenant_owner'], true)) { $restrictedSlugs = ['voucher-hotspot-agents', 'voucher-hotspot-login-page']; $tree = $this->removeRestrictedMenus($tree, $restrictedSlugs); } if (! $user->isMasterAdmin() && ! $user->is_platform_staff) { $tree = $this->removeRestrictedMenus($tree, ['role-applications-tenants']); } if (! $user->isTenantOwner($tenantId)) { $tree = $this->removeRestrictedMenus($tree, ['role-applications-staff']); } return $this->success( [ 'is_master' => (bool) $user->is_master, 'access_level' => $user->access_level->value, 'tenant_role' => $tenantRole, 'tenant_id' => $tenantId, 'menus' => $tree, ], 'Menu berhasil diambil' ); } private function buildMenuTree(Collection $menus, ?int $parentId = null): array { return $menus ->filter(fn ($menu) => $menu['parent_id'] === $parentId) ->sortBy('sort_order') ->values() ->map(function ($menu) use ($menus) { $children = $this->buildMenuTree($menus, $menu['id']); return [ 'id' => $menu['id'], 'parent_id' => $menu['parent_id'], 'name' => $menu['name'], 'slug' => $menu['slug'], 'url' => $menu['url'], 'icon' => $menu['icon'], 'component' => $menu['component'], 'sort_order' => $menu['sort_order'], 'permissions' => $menu['permissions'], 'children' => $children, ]; }) ->all(); } private function removeRestrictedMenus(array $menus, array $restrictedSlugs): array { return collect($menus) ->reject(fn ($menu) => in_array($menu['slug'], $restrictedSlugs, true)) ->map(function ($menu) use ($restrictedSlugs) { $menu['children'] = $this->removeRestrictedMenus($menu['children'] ?? [], $restrictedSlugs); return $menu; }) ->values()->all(); } }