8: Creando Cabecera y Menú
8: Creando Cabecera y Menú
1. Introducción
En este tutorial crearemos la cabecera (header) y el menú lateral (sidebar) de nuestro sistema utilizando AdminLTE. Estos componentes serán dinámicos y mostrarán diferentes opciones según el rol del usuario autenticado (secretaria, doctor, paciente o administrador).
2. Objetivos
✅ Crear cabecera personalizada con logo y usuario
✅ Implementar menú lateral dinámico por rol
✅ Incluir componentes mediante Blade partials
✅ Configurar redirecciones y protección de rutas
3. Proteger el Controlador de Inicio
Paso 1: Modificar InicioController.php
Para que solo usuarios autenticados puedan acceder al dashboard:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class InicioController extends Controller
{
/**
* Constructor: aplica middleware de autenticación
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('modulos.inicio');
}
// ... resto de métodos
}4. Crear la Cabecera (Header)
Paso 1: Crear el archivo header.blade.php
Crea resources/views/modulos/header.blade.php:
<!-- ========================================== -->
<!-- HEADER (Navbar) -->
<!-- ========================================== -->
<header class="main-header">
<!-- Logo -->
<a href="{{ route('inicio') }}" class="logo">
<!-- Logo versión mini (sidebar colapsado) -->
<span class="logo-mini"><b>C</b>L</span>
<!-- Logo versión completa -->
<span class="logo-lg"><b>Clínica</b> Médica</span>
</a>
<!-- Barra de navegación -->
<nav class="navbar navbar-static-top" role="navigation">
<!-- Botón toggle para colapsar sidebar -->
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<!-- Menú de la derecha -->
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<!-- ====================================== -->
<!-- MENÚ DE USUARIO (Dropdowon) -->
<!-- ====================================== -->
<li class="dropdown user user-menu">
<!-- Enlace del dropdown -->
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<!-- Avatar del usuario -->
<img src="{{ asset('dist/img/user2-160x160.jpg') }}"
class="user-image"
alt="User Image">
<!-- Nombre del usuario -->
<span class="hidden-xs">{{ Auth::user()->name }}</span>
</a>
<!-- Contenido del dropdown -->
<ul class="dropdown-menu">
<!-- Cabecera del usuario -->
<li class="user-header">
<img src="{{ asset('dist/img/user2-160x160.jpg') }}"
class="img-circle"
alt="User Image">
<p>
{{ Auth::user()->name }}
<small>{{ Auth::user()->rol }}</small>
</p>
</li>
<!-- Footer con acciones -->
<li class="user-footer">
<div class="pull-left">
<a href="#" class="btn btn-default btn-flat">
<i class="fa fa-user"></i> Perfil
</a>
</div>
<div class="pull-right">
<a href="#"
class="btn btn-default btn-flat"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
<i class="fa fa-sign-out"></i> Salir
</a>
<!-- Formulario oculto para logout -->
<form id="logout-form"
action="{{ route('logout') }}"
method="POST"
style="display: none;">
@csrf
</form>
</div>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</header>5. Crear los Menús por Rol
5.1 Menú de Secretaria
Crea resources/views/modulos/menu_secretaria.blade.php:
<!-- ========================================== -->
<!-- MENÚ SECRETARIA -->
<!-- ========================================== -->
<aside class="main-sidebar">
<section class="sidebar">
<!-- Panel del usuario -->
<div class="user-panel">
<div class="pull-left image">
<img src="{{ asset('dist/img/user2-160x160.jpg') }}"
class="img-circle"
alt="User Image">
</div>
<div class="pull-left info">
<p>{{ Auth::user()->name }}</p>
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- Formulario de búsqueda -->
<form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Buscar...">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
<!-- Menú principal -->
<ul class="sidebar-menu" data-widget="tree">
<li class="header">MENÚ PRINCIPAL</li>
<!-- Dashboard -->
<li class="{{ request()->routeIs('inicio') ? 'active' : '' }}">
<a href="{{ route('inicio') }}">
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
</a>
</li>
<!-- Consultorios -->
<li class="{{ request()->routeIs('consultorios*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-building"></i> <span>Consultorios</span>
</a>
</li>
<!-- Doctores -->
<li class="{{ request()->routeIs('doctores*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-user-md"></i> <span>Doctores</span>
</a>
</li>
<!-- Pacientes -->
<li class="{{ request()->routeIs('pacientes*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-users"></i> <span>Pacientes</span>
</a>
</li>
<!-- Citas -->
<li class="header">CITAS MÉDICAS</li>
<li class="{{ request()->routeIs('citas*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-calendar"></i> <span>Agenda de Citas</span>
</a>
</li>
</ul>
</section>
</aside>5.2 Menú de Doctor
Crea resources/views/modulos/menu_doctor.blade.php:
<!-- ========================================== -->
<!-- MENÚ DOCTOR -->
<!-- ========================================== -->
<aside class="main-sidebar">
<section class="sidebar">
<!-- Panel del usuario -->
<div class="user-panel">
<div class="pull-left image">
<img src="{{ asset('dist/img/user2-160x160.jpg') }}"
class="img-circle"
alt="User Image">
</div>
<div class="pull-left info">
<p>{{ Auth::user()->name }}</p>
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- Menú principal -->
<ul class="sidebar-menu" data-widget="tree">
<li class="header">MENÚ DOCTOR</li>
<!-- Dashboard -->
<li class="{{ request()->routeIs('inicio') ? 'active' : '' }}">
<a href="{{ route('inicio') }}">
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
</a>
</li>
<!-- Mis Pacientes -->
<li class="{{ request()->routeIs('mis-pacientes*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-users"></i> <span>Mis Pacientes</span>
</a>
</li>
<!-- Mi Agenda -->
<li class="header">AGENDA</li>
<li class="{{ request()->routeIs('mi-agenda*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-calendar"></i> <span>Mi Agenda</span>
</a>
</li>
<!-- Horarios -->
<li class="{{ request()->routeIs('horarios*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-clock-o"></i> <span>Horarios</span>
</a>
</li>
</ul>
</section>
</aside>5.3 Menú de Paciente
Crea resources/views/modulos/menu_paciente.blade.php:
<!-- ========================================== -->
<!-- MENÚ PACIENTE -->
<!-- ========================================== -->
<aside class="main-sidebar">
<section class="sidebar">
<!-- Panel del usuario -->
<div class="user-panel">
<div class="pull-left image">
<img src="{{ asset('dist/img/user2-160x160.jpg') }}"
class="img-circle"
alt="User Image">
</div>
<div class="pull-left info">
<p>{{ Auth::user()->name }}</p>
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- Menú principal -->
<ul class="sidebar-menu" data-widget="tree">
<li class="header">MENÚ PACIENTE</li>
<!-- Dashboard -->
<li class="{{ request()->routeIs('inicio') ? 'active' : '' }}">
<a href="{{ route('inicio') }}">
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
</a>
</li>
<!-- Buscar Doctor -->
<li class="{{ request()->routeIs('buscar-doctor*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-search"></i> <span>Buscar Doctor</span>
</a>
</li>
<!-- Mis Citas -->
<li class="header">MIS CITAS</li>
<li class="{{ request()->routeIs('mis-citas*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-calendar-check-o"></i> <span>Mis Citas</span>
</a>
</li>
<!-- Historial -->
<li class="{{ request()->routeIs('historial*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-history"></i> <span>Historial</span>
</a>
</li>
</ul>
</section>
</aside>5.4 Menú de Administrador
Crea resources/views/modulos/menu_admin.blade.php:
<!-- ========================================== -->
<!-- MENÚ ADMINISTRADOR -->
<!-- ========================================== -->
<aside class="main-sidebar">
<section class="sidebar">
<!-- Panel del usuario -->
<div class="user-panel">
<div class="pull-left image">
<img src="{{ asset('dist/img/user2-160x160.jpg') }}"
class="img-circle"
alt="User Image">
</div>
<div class="pull-left info">
<p>{{ Auth::user()->name }}</p>
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- Formulario de búsqueda -->
<form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Buscar...">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
<!-- Menú principal -->
<ul class="sidebar-menu" data-widget="tree">
<li class="header">MENÚ PRINCIPAL</li>
<!-- Dashboard -->
<li class="{{ request()->routeIs('inicio') ? 'active' : '' }}">
<a href="{{ route('inicio') }}">
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
</a>
</li>
<!-- Configuración -->
<li class="header">ADMINISTRACIÓN</li>
<li class="{{ request()->routeIs('configuracion*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-cogs"></i> <span>Configuración</span>
</a>
</li>
<!-- Gestión -->
<li class="header">GESTIÓN</li>
<li class="{{ request()->routeIs('consultorios*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-building"></i> <span>Consultorios</span>
</a>
</li>
<li class="{{ request()->routeIs('doctores*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-user-md"></i> <span>Doctores</span>
</a>
</li>
<li class="{{ request()->routeIs('pacientes*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-users"></i> <span>Pacientes</span>
</a>
</li>
<li class="{{ request()->routeIs('secretarias*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-user-plus"></i> <span>Secretarias</span>
</a>
</li>
<!-- Citas -->
<li class="header">CITAS MÉDICAS</li>
<li class="{{ request()->routeIs('citas*') ? 'active' : '' }}">
<a href="#">
<i class="fa fa-calendar"></i> <span>Agenda de Citas</span>
</a>
</li>
</ul>
</section>
</aside>6. Actualizar el Layout Principal
Paso 1: Modificar layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>@yield('title', 'Clínica L8') - Sistema de Citas Médicas</title>
<!-- Google Font: Source Sans Pro -->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
<!-- AdminLTE CSS -->
<link rel="stylesheet" href="{{ asset('bower_components/bootstrap/dist/css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ asset('bower_components/font-awesome/css/font-awesome.min.css') }}">
<link rel="stylesheet" href="{{ asset('bower_components/Ionicons/css/ionicons.min.css') }}">
<link rel="stylesheet" href="{{ asset('dist/css/AdminLTE.min.css') }}">
<link rel="stylesheet" href="{{ asset('dist/css/skins/_all-skins.min.css') }}">
@stack('styles')
</head>
<body class="hold-transition skin-blue {{ Auth::check() ? 'sidebar-mini' : '' }}">
@auth
<!-- ========================================== -->
<!-- LAYOUT CON AUTENTICACIÓN -->
<!-- ========================================== -->
<div class="wrapper">
<!-- ====================================== -->
<!-- INCLUIR CABECERA -->
<!-- ====================================== -->
@include('modulos.header')
<!-- ====================================== -->
<!-- MENÚ POR ROL -->
<!-- ====================================== -->
@if(Auth::user()->rol == 'admin')
@include('modulos.menu_admin')
@elseif(Auth::user()->rol == 'secretaria')
@include('modulos.menu_secretaria')
@elseif(Auth::user()->rol == 'doctor')
@include('modulos.menu_doctor')
@elseif(Auth::user()->rol == 'paciente')
@include('modulos.menu_paciente')
@else
@include('modulos.menu_secretaria') <!-- Menú por defecto -->
@endif
<!-- ====================================== -->
<!-- CONTENIDO PRINCIPAL -->
<!-- ====================================== -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
@yield('page-title', 'Dashboard')
<small>@yield('page-subtitle', 'Panel de control')</small>
</h1>
<ol class="breadcrumb">
<li>
<a href="{{ route('inicio') }}">
<i class="fa fa-dashboard"></i> Inicio
</a>
</li>
@yield('breadcrumb')
</ol>
</section>
<!-- Main content -->
<section class="content">
@yield('content')
</section>
</div>
<!-- ====================================== -->
<!-- FOOTER -->
<!-- ====================================== -->
<footer class="main-footer">
<div class="pull-right hidden-xs">
<b>Versión</b> 1.0.0
</div>
<strong>Copyright © 2024 <a href="#">Clínica L8</a>.</strong>
Todos los derechos reservados.
</footer>
</div>
@else
<!-- ========================================== -->
<!-- LAYOUT SIN AUTENTICACIÓN -->
<!-- ========================================== -->
@yield('content')
@endauth
<!-- Scripts -->
<script src="{{ asset('bower_components/jquery/dist/jquery.min.js') }}"></script>
<script src="{{ asset('bower_components/bootstrap/dist/js/bootstrap.min.js') }}"></script>
<script src="{{ asset('dist/js/adminlte.min.js') }}"></script>
@stack('scripts')
</body>
</html>7. Estructura de Archivos
📁 resources/
└── 📁 views/
├── 📁 layouts/
│ └── app.blade.php ← Modificado
├── 📁 modulos/
│ ├── header.blade.php ← NUEVO
│ ├── menu_admin.blade.php ← NUEVO
│ ├── menu_secretaria.blade.php ← NUEVO
│ ├── menu_doctor.blade.php ← NUEVO
│ ├── menu_paciente.blade.php ← NUEVO
│ ├── seleccionar.blade.php
│ ├── ingresar.blade.php
│ └── inicio.blade.php
└── 📁 auth/8. Verificar el Resultado
Paso 1: Iniciar sesión
Ve a
http://127.0.0.1:8000Haz clic en cualquier tarjeta de rol
Ingresa tus credenciales
Paso 2: Verificar el menú según el rol
Administrador verá:
Dashboard
Configuración
Consultorios, Doctores, Pacientes, Secretarias
Agenda de Citas
Secretaria verá:
Dashboard
Consultorios, Doctores, Pacientes
Agenda de Citas
Doctor verá:
Dashboard
Mis Pacientes
Mi Agenda, Horarios
Paciente verá:
Dashboard
Buscar Doctor
Mis Citas, Historial
9. Solución de Problemas
| Problema | Solución |
|---|---|
Error View [modulos.header] not found | Verifica que el archivo header.blade.php existe |
Error Undefined variable en el menú | Asegura Auth::user() antes de usarlo |
| El menú no se colapsa | Verifica que sidebar-toggle tenga los atributos correctos |
| No se ve el avatar del usuario | Verifica la ruta de la imagen en asset() |
| Error de logout | Asegura que route('logout') esté definido |
10. Comandos Útiles
# Verificar que las rutas están definidas
php artisan route:list
# Limpiar caché de vistas
php artisan view:clear
# Limpiar caché de configuración
php artisan config:clear
# Ver el usuario autenticado en Tinker
php artisan tinker
>>> auth()->user()11. Conclusión
🎉 ¡Excelente trabajo! Hemos creado:
✅ Cabecera personalizada con logo y usuario
✅ Menús dinámicos según el rol del usuario (admin, secretaria, doctor, paciente)
✅ Sistema de partials con
@includepara componentes reutilizables✅ Protección de rutas con middleware de autenticación
En el próximo tutorial comenzaremos a desarrollar el módulo de secretaria, empezando con la gestión de consultorios (CRUD)
Comentarios
Publicar un comentario