-
@foreach($errors->all() as $erro)
- {{ $erro }} @endforeach
@livewireStyles {{-- ===================== Menu administrativo (ETAPA 2C) ===================== Fonte de dados ÚNICA e hierárquica (grupos com itens dentro), usada IDENTICAMENTE pelo dropdown desktop e pelo acordeão mobile logo abaixo — nunca duas listas divergentes (ver item 15 da Etapa 2C). 'tipo' => 'link' → item direto na barra, sem dropdown (Painel, Relatórios). 'tipo' => 'grupo' → dropdown (desktop) / acordeão (mobile) com sub-itens. Cada item folha: 'modulo' (chave de Permissao::MODULOS; null = livre pra qualquer operador autenticado), 'rota' (nome de rota existente, nada foi criado/alterado), 'icone' (Font Awesome já usado no projeto) e 'ativoQuando' (padrão(ões) de request()->routeIs()). Sessões Legislativas e Auditoria/Resumo da Sessão NÃO têm item de menu próprio de propósito (ver relatório da Etapa 2C): Sessões Legislativas já é gerenciada dentro da própria tela de Legislaturas (resources/views/admin/legislaturas/index.blade.php) e Auditoria/ Resumo já são alcançadas de dentro do contexto de uma sessão específica (central-sessao.blade.php e painel-operador.blade.php) — adicionar itens permanentes pra elas aqui só poluiria o menu. ETAPA 2C.1 (correção de bug): $config, $logoTopo, $haSessaoAtivaAgora, $menu e o cálculo de $menuVisivel/$grupoAtivoAtual abaixo foram unidos num ÚNICO bloco @php ... @endphp. Antes, cada um vinha num @php(...) curto separado — e o compilador do Blade extrai blocos @php como texto bruto da PRIMEIRA ocorrência de "@php" até o PRÓXIMO "@endphp" que encontrar (ver storePhpBlocks() em BladeCompiler.php), sem diferenciar a forma curta @php(...) da forma em bloco. Com vários @php(...) soltos antes de um bloco @php...@endphp real, tudo entre o primeiro @php(...) e aquele @endphp virava um único trecho bruto (comentários Blade e as outras diretivas inclusive), gerando PHP inválido e o 500 em /admin. Um único bloco elimina a ambiguidade. Nenhuma lógica foi alterada. --}} @php $config = \App\Models\Configuracao::atual(); // Logo "de marca" pro canto do painel gerencial: usa a logo da empresa // se tiver sido cadastrada, senão cai pra logo da câmara mesmo. $logoTopo = $config->logo_empresa_path ?? $config->logo_path; // Consulta única e leve (status já é indexado, ver migration de // sessoes) — só pra decidir se mostra o indicador "AO VIVO", nada // pesado. Calculada aqui (não dentro do @if de permissão) pra poder // ser reaproveitada tanto no menu desktop quanto no menu mobile sem // duplicar a consulta/lógica. $haSessaoAtivaAgora = \App\Models\Sessao::where('status', 'ativa')->exists(); $menu = [ ['tipo' => 'link', 'modulo' => null, 'rota' => 'admin.dashboard', 'label' => 'Painel', 'icone' => 'fa-house', 'ativoQuando' => ['admin.dashboard']], ['tipo' => 'grupo', 'grupo' => 'Sessão Plenária', 'icone' => 'fa-gauge-high', 'itens' => [ ['modulo' => 'sessoes', 'rota' => 'admin.central-sessao', 'label' => 'Central da Sessão', 'icone' => 'fa-gauge-high', 'ativoQuando' => ['admin.central-sessao'], 'aoVivo' => true], ['modulo' => 'sessoes', 'rota' => 'admin.sessoes.index', 'label' => 'Sessões', 'icone' => 'fa-calendar-days', 'ativoQuando' => ['admin.sessoes.*']], ['modulo' => 'audio', 'rota' => 'admin.audio.index', 'label' => 'Áudio', 'icone' => 'fa-microphone', 'ativoQuando' => ['admin.audio.*']], ]], ['tipo' => 'grupo', 'grupo' => 'Processo Legislativo', 'icone' => 'fa-file-lines', 'itens' => [ ['modulo' => 'materias', 'rota' => 'admin.materias.index', 'label' => 'Matérias', 'icone' => 'fa-file-lines', 'ativoQuando' => ['admin.materias.*']], ['modulo' => 'protocolo', 'rota' => 'admin.protocolos.index', 'label' => 'Protocolo', 'icone' => 'fa-inbox', 'ativoQuando' => ['admin.protocolos.*']], ['modulo' => 'leis', 'rota' => 'admin.leis.index', 'label' => 'Leis', 'icone' => 'fa-scroll', 'ativoQuando' => ['admin.leis.*']], ['modulo' => 'atas', 'rota' => 'admin.atas.index', 'label' => 'Atas', 'icone' => 'fa-book', 'ativoQuando' => ['admin.atas.*']], ]], ['tipo' => 'grupo', 'grupo' => 'Estrutura Legislativa', 'icone' => 'fa-landmark', 'itens' => [ // 'ativoQuando' também cobre admin.sessoes-legislativas* — autorizado // pelo módulo 'legislaturas' desde a Etapa 2B — pra "Legislaturas" // continuar marcado como módulo atual se alguém acessar aquela // rota diretamente, mesmo sem item de menu próprio pra ela. ['modulo' => 'legislaturas', 'rota' => 'admin.legislaturas.index', 'label' => 'Legislaturas', 'icone' => 'fa-landmark', 'ativoQuando' => ['admin.legislaturas*', 'admin.sessoes-legislativas*']], ['modulo' => 'comissoes', 'rota' => 'admin.comissoes.index', 'label' => 'Comissões', 'icone' => 'fa-people-group', 'ativoQuando' => ['admin.comissoes.*']], ['modulo' => 'configuracoes', 'rota' => 'admin.perfis-regimentais.index', 'label' => 'Perfis Regimentais', 'icone' => 'fa-sitemap', 'ativoQuando' => ['admin.perfis-regimentais.*']], // Autorização é o módulo 'configuracoes' (decisão da Etapa 2B, // não alterada aqui) — a posição visual dentro de "Estrutura // Legislativa" é só desta etapa. ['modulo' => 'configuracoes', 'rota' => 'admin.regras-deliberacao.index', 'label' => 'Regras de Deliberação', 'icone' => 'fa-gavel', 'ativoQuando' => ['admin.regras-deliberacao.*']], ]], ['tipo' => 'link', 'modulo' => 'relatorios', 'rota' => 'admin.relatorios.index', 'label' => 'Relatórios', 'icone' => 'fa-chart-line', 'ativoQuando' => ['admin.relatorios*']], ['tipo' => 'grupo', 'grupo' => 'Administração', 'icone' => 'fa-gear', 'alinhar' => 'direita', 'itens' => [ ['modulo' => 'usuarios', 'rota' => 'admin.usuarios.index', 'label' => 'Usuários', 'icone' => 'fa-users', 'ativoQuando' => ['admin.usuarios.*']], ['modulo' => 'cadastros', 'rota' => 'admin.cadastros.index', 'label' => 'Cadastros', 'icone' => 'fa-list-check', 'ativoQuando' => ['admin.cadastros.*']], ['modulo' => 'configuracoes', 'rota' => 'admin.configuracoes.edit', 'label' => 'Configurações', 'icone' => 'fa-gear', 'ativoQuando' => ['admin.configuracoes*']], ]], ]; // Filtra ITEM A ITEM por podeAcessarModulo() (nunca o grupo inteiro // de uma vez — ver item 7 da Etapa 2C) e remove grupos que ficaram // sem nenhum item visível. $menuVisivel é a única fonte usada tanto // pelo bloco desktop quanto pelo off-canvas mobile logo abaixo. $usuarioLogado = auth()->user(); $podeVerModulo = fn (?string $modulo) => is_null($modulo) || $usuarioLogado->podeAcessarModulo($modulo); $menuVisivel = collect($menu) ->map(function (array $entrada) use ($podeVerModulo) { if ($entrada['tipo'] === 'link') { return $podeVerModulo($entrada['modulo']) ? $entrada : null; } $itensVisiveis = array_values(array_filter( $entrada['itens'], fn (array $item) => $podeVerModulo($item['modulo']) )); return $itensVisiveis ? [...$entrada, 'itens' => $itensVisiveis] : null; }) ->filter() ->values() ->all(); // Nome do grupo que contém a rota atual (ou null) — usado pra // destacar o botão do grupo como "módulo atual" e pra já abrir o // acordeão certo no mobile quando o menu é aberto. $grupoComRotaAtual = collect($menuVisivel)->first( fn (array $entrada) => $entrada['tipo'] === 'grupo' && collect($entrada['itens'])->contains(fn (array $item) => request()->routeIs(...$item['ativoQuando'])) ); $grupoAtivoAtual = $grupoComRotaAtual['grupo'] ?? null; @endphp