Desenvolvendo um Sistema em Laravel — Parte 4C: Sidebar, Dashboards e Controle de Acesso

Introdução

Dando continuidade no nosso projeto em Laravel, e após consolidar a arquitetura de interface (Parte 4A) e estabelecer identidade visual, tema e internacionalização (Parte 4B), entramos agora no terceiro pilar da experiência do usuário: estrutura de navegação, organização por perfil e aplicação prática do sistema de permissões na interface.

Nesta etapa, o foco é transformar a base visual em um painel de controle real, adaptável ao papel do usuário, com navegação lateral inteligente, dashboards distintos por função e controle de acesso aplicado diretamente nos componentes de interface.


Etapa 1 — Dashboards por perfil

Estrutura de telas

Criamos dois dashboards distintos, separados por responsabilidade e função:

resources/views/dashboards/admin.blade.php
resources/views/dashboards/user.blade.php

Para ilustrar, vejamos um exemplo de código base (para teste) do painel administrativo:

<x-system-layout>

    <h1 class="text-2xl font-semibold mb-6">
        {{ __('messages.dashboard_admin') }}
    </h1>

    <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">

        <div class="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
            <p class="text-sm text-gray-500">{{ __('messages.total_users') }}</p>
            <p class="text-3xl font-bold mt-2">128</p>
        </div>

        <div class="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
            <p class="text-sm text-gray-500">{{ __('messages.active_companies') }}</p>
            <p class="text-3xl font-bold mt-2">5</p>
        </div>

        <div class="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
            <p class="text-sm text-gray-500">{{ __('messages.pending_tasks') }}</p>
            <p class="text-3xl font-bold mt-2">12</p>
        </div>

        <div class="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
            <p class="text-sm text-gray-500">{{ __('messages.system_health') }}</p>
            <p class="text-3xl font-bold mt-2 text-green-500">OK</p>
        </div>

    </div>

</x-system-layout>

A decisão de separar dashboards por perfil evita sobrecarga de lógica nas views e mantém cada painel limpo, coeso e focado na função do usuário.

Redirecionamento automático por role

routes/web.php
    Route::middleware('auth')->get('/dashboard', function () {
        return dashboardType() === 'admin'
            ? redirect()->route('dashboard.admin')
            : redirect()->route('dashboard.user');
    })->name('dashboard');


    Route::get('/dashboard/admin', function () {
        return view('dashboards.admin');
    })->name('dashboard.admin');

    Route::get('/dashboard/user', function () {
        return view('dashboards.user');
    })->name('dashboard.user');

Com isso, o usuário acessa sempre /dashboard, e o sistema, utilizando o helper dashboardType(), resolve dinamicamente qual painel deve ser exibido, redirecionando de forma segura e transparente para o dashboard correspondente ao seu perfil.


Etapa 2 — Sidebar como núcleo da navegação

A sidebar passa a ser o elemento central de navegação do sistema.

resources/views/components/sidebar.blade.php

Principais características:

  • Expansão e recolhimento persistidos no navegador
  • Ícones gráficos com Heroicons
  • Itens exibidos conforme permissões do usuário
  • Integração direta com o sistema de idiomas

Exemplo de item controlado por permissão:

{{-- Usuários --}}
@if (can('manage_users'))
    <a href="{{ route('users.index') }}" class="group relative flex items-center px-4 py-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition rounded-md overflow-hidden">
        <x-heroicon-o-users class="w-5 h-5 flex-shrink-0" />
        <span x-show="sidebarOpen"
            class="absolute left-12 ml-1 font-medium whitespace-nowrap transition-opacity duration-400 ease-in-out"
            :class="sidebarOpen ? 'opacity-100' : 'opacity-0'" style="top: 50%; transform: translateY(-50%);">
            {{ __('messages.users') }}
        </span>
    </a>
@endif

A função can() conecta diretamente a regra de negócio à interface, sem espalhar lógica por controllers ou views.


Etapa 3 — Controle de acesso aplicado à interface

O sistema de permissões definido em config/permissions.php deixa de ser apenas teórico e passa a governar o que o usuário vê e pode interagir.

Exemplo de controle de funcionalidade

{{-- Usuários --}}
@if (can('manage_users'))...

Isso garante:

  • Interface limpa para cada perfil
  • Redução de erros operacionais
  • Alinhamento entre backend e UX

Etapa 4 — Layout definitivo do sistema

O layout principal do sistema, criado na Parte 4A e evoluído na 4B, agora se consolida como base de toda a aplicação interna.

resources/views/components/system-layout.blade.php

Responsabilidades:

  • Orquestrar header + sidebar + área de conteúdo
  • Controlar tema, idioma e estado da navegação
  • Servir como casca de todas as telas internas

Os dashboards agora se tornam simples:

<x-system-layout>
    <h1 class="text-2xl font-semibold mb-4">
        {{ __('messages.admin_panel') }}
    </h1>
</x-system-layout>

Etapa 5 — Fallback do dashboard genérico

O arquivo resources/views/dashboard.blade.php é mantido como fallback técnico:

<x-system-layout>

    <h1 class="text-2xl font-semibold mb-2">
        {{ __('messages.dashboard') }}
    </h1>

    <p class="text-gray-500 mb-6">
        {{ __('messages.dashboard_redirect_info') }}
    </p>

    <div class="bg-white dark:bg-gray-800 rounded-lg p-6 shadow text-sm space-y-3">

        <p>
            {{ __('messages.dashboard_fallback_notice') }}
        </p>

        <p class="text-gray-500">
            {{ __('messages.dashboard_fallback_tip') }}
        </p>

        <div class="pt-4">
            <a href="{{ route('dashboard') }}"
               class="inline-block bg-primary text-white px-4 py-2 rounded hover:opacity-90 transition">
                {{ __('messages.go_to_panel') }}
            </a>
        </div>

    </div>

</x-system-layout>

Ele não é mais usado diretamente, mas permanece útil como proteção estrutural e ponto de depuração.


Conclusão

Ao final da Parte 4C, o sistema passa a operar como uma plataforma real:

✔ Dashboards separados por perfil
✔ Navegação lateral inteligente e persistente
✔ Controle de acesso aplicado à interface
✔ UX coerente com regras de negócio
✔ Arquitetura pronta para crescimento funcional

A base de experiência do usuário está concluída.
A partir da próxima etapa, o foco passa a ser construção das funcionalidades operacionais do sistema.

Leia também Desenvolvendo um Sistema em Laravel — Parte 4B: Header, Tema e Internacionalização.