{{-- GIGAX ARENA • Painel Admin completo Exibe todos os módulos administrativos conhecidos e, ao final, descobre automaticamente novas telas GET /admin sem parâmetros. --}} @php use Illuminate\Support\Facades\Route; $adminMenu = [ ['route' => 'admin.index', 'icon' => '◆', 'label' => 'Dashboard Admin'], ['route' => 'admin.matches', 'icon' => '▦', 'label' => 'Administração de Partidas'], ['route' => 'admin.matches.active', 'icon' => '⚔', 'label' => 'Partidas Ativas'], ['route' => 'admin.matches.history', 'icon' => '◉', 'label' => 'Histórico de Partidas'], ['route' => 'admin.users', 'icon' => '♟', 'label' => 'Usuários / Cargos'], ['route' => 'admin.queues.overview', 'icon' => '≋', 'label' => 'Filas / Visão Geral'], ['route' => 'admin.permissions', 'href_route' => 'admin.users', 'fragment' => 'permissions', 'icon' => '🔐', 'label' => 'Permissões'], ['route' => 'admin.anti-cheat', 'icon' => '🛡', 'label' => 'Anti-Cheat / Visão Geral'], ['route' => 'admin.ac-monitor', 'icon' => '◉', 'label' => 'Monitor do AC'], ['route' => 'admin.macros.index', 'icon' => '⚠', 'label' => 'Macros / Evidências'], ['route' => 'admin.voice-settings', 'icon' => '🎧', 'label' => 'Comunicação das Partidas'], ['route' => 'admin.teamspeak', 'icon' => '🎙', 'label' => 'TeamSpeak 3'], ['route' => 'admin.youtubers.index', 'icon' => '▶', 'label' => 'Youtubers / Lives'], // Rotas carregadas por arquivos auxiliares: só aparecem quando existirem ['route' => 'admin.discord', 'icon' => '◉', 'label' => 'Discord'], ['route' => 'admin.discord.index', 'icon' => '◉', 'label' => 'Discord'], ['route' => 'admin.discord.settings', 'icon' => '◉', 'label' => 'Discord'], ['route' => 'admin.clans.index', 'icon' => '♛', 'label' => 'Clãs / Times'], ['route' => 'admin.clan-settings', 'icon' => '⚙', 'label' => 'Configurações de Clãs'], ['route' => 'admin.support-tickets.index','icon'=> '✉', 'label' => 'Chamados / Tickets'], ['route' => 'admin.support.index', 'icon' => '✉', 'label' => 'Chamados / Tickets'], ['route' => 'admin.tickets.index', 'icon' => '✉', 'label' => 'Chamados / Tickets'], ['route' => 'admin.ac-online', 'icon' => '●', 'label' => 'AC Online'], ['route' => 'admin.ac.index', 'icon' => '●', 'label' => 'AC Online'], ['route' => 'admin.notifications.index','icon' => '🔔', 'label' => 'Notificações'], ['route' => 'admin.streams.index', 'icon' => '▶', 'label' => 'Transmissões'], ['route' => 'admin.system.index', 'icon' => '⚙', 'label' => 'Sistema'], ['route' => 'admin.settings', 'icon' => '⚙', 'label' => 'Configurações'], ['route' => 'admin.logs', 'icon' => '📝', 'label' => 'Logs Administrativos'], ]; // Remove duplicados por destino real. Ex.: diferentes aliases de Discord/Tickets. $knownNames = []; $resolvedItems = []; $resolvedUrls = []; foreach ($adminMenu as $item) { if (!Route::has($item['route'])) { continue; } try { $hrefRoute = $item['href_route'] ?? $item['route']; if (!Route::has($hrefRoute)) { continue; } $url = route($hrefRoute) . (!empty($item['fragment']) ? '#' . $item['fragment'] : ''); } catch (\Throwable $e) { continue; } if (in_array($url, $resolvedUrls, true)) { continue; } $resolvedUrls[] = $url; $knownNames[] = $item['route']; $resolvedItems[] = $item; } /* * AUTO-DESCOBERTA: * Qualquer nova tela administrativa GET/HEAD, nomeada como admin.*, * sem {parâmetros}, entra automaticamente em "Outros módulos". * Endpoints técnicos/data/actions são ignorados. */ $autoItems = []; $ignoredTokens = [ '.data', '.status', '.summary', '.details', '.result', '.show', '.test', '.full-test', '.cleanup-test', '.create', '.edit', '.resend', '.update', '.store', '.destroy', '.delete', '.ban', '.unban', '.move', '.cleanup', '.provision', '.permission', '.permissions.update', '.role', '.professional' ]; foreach (Route::getRoutes() as $routeObject) { $name = (string) $routeObject->getName(); if ($name === '' || !substr($name, 0, 6) === 'admin.') { continue; } $methods = $routeObject->methods(); if (!in_array('GET', $methods, true) && !in_array('HEAD', $methods, true)) { continue; } $uri = (string) $routeObject->uri(); if (strpos($uri, '{') !== false) { continue; } if (in_array($name, $knownNames, true)) { continue; } $ignore = false; foreach ($ignoredTokens as $token) { if (strpos($name, $token) !== false) { $ignore = true; break; } } if ($ignore) { continue; } try { $url = route($name); } catch (\Throwable $e) { continue; } if (in_array($url, $resolvedUrls, true)) { continue; } $resolvedUrls[] = $url; $tail = preg_replace('/^admin\./', '', $name); $label = collect(explode('.', $tail)) ->map(fn ($part) => mb_convert_case(str_replace(['-', '_'], ' ', $part), MB_CASE_TITLE, 'UTF-8')) ->implode(' / '); $autoItems[] = [ 'route' => $name, 'icon' => '◇', 'label' => $label, ]; } usort($autoItems, fn ($a, $b) => strcmp($a['label'], $b['label'])); $isActiveAdminRoute = function (string $routeName): bool { if (request()->routeIs($routeName)) return true; // Mantém módulo pai ativo em páginas filhas. if ($routeName === 'admin.matches' && request()->routeIs('admin.matches.*')) return true; if ($routeName === 'admin.macros.index' && request()->routeIs('admin.macros.*')) return true; if ($routeName === 'admin.clans.index' && request()->routeIs('admin.clans.*')) return true; if (strpos($routeName, 'support') !== false && request()->routeIs('admin.support*')) return true; if (strpos($routeName, 'ticket') !== false && request()->routeIs('admin.*ticket*')) return true; return false; }; @endphp