templates/admin/base_admin.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Panel de Administración - ImagingPro</title>
  7.     <link rel="icon" type="image/png" href="{{ asset('images/favicon-32-2.png') }}">
  8.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  9.     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  10.    <style>
  11.         :root {
  12.             --primary-color: #3498db;
  13.             --secondary-color: #2c3e50;
  14.             --accent-color: #e74c3c;
  15.             --success-color: #27ae60;
  16.             --warning-color: #f39c12;
  17.             --light-color: #ecf0f1;
  18.             --dark-color: #34495e;
  19.             --admin-bg: #f8f9fa;
  20.         }
  21.         
  22.         * {
  23.             margin: 0;
  24.             padding: 0;
  25.             box-sizing: border-box;
  26.             font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  27.         }
  28.         
  29.         body {
  30.             background-color: var(--admin-bg);
  31.             color: #333;
  32.             line-height: 1.6;
  33.             overflow-x: hidden; /* Previene scroll horizontal global */
  34.         }
  35.         
  36.         /* ===== LAYOUT PRINCIPAL ===== */
  37.         .admin-container {
  38.             display: flex;
  39.             min-height: 100vh;
  40.             overflow-x: hidden; /* Previene scroll horizontal */
  41.         }
  42.         
  43.         /* ===== SIDEBAR ===== */
  44.         .admin-sidebar {
  45.             width: 280px;
  46.             background: linear-gradient(135deg, var(--secondary-color) 0%, var(--dark-color) 100%);
  47.             color: white;
  48.             transition: all 0.3s ease;
  49.             box-shadow: 2px 0 10px rgba(0,0,0,0.1);
  50.             z-index: 1000;
  51.             position: fixed;
  52.             left: 0;
  53.             top: 0;
  54.             height: 100vh;
  55.             display: flex;
  56.             flex-direction: column;
  57.             overflow: hidden; /* Previene scroll horizontal en el sidebar */
  58.         }
  59.         
  60.         .admin-main-content {
  61.             margin-left: 280px;
  62.             transition: all 0.3s ease;
  63.             min-height: 100vh;
  64.             width: calc(100% - 280px);
  65.             overflow-x: hidden; /* Previene scroll horizontal en el contenido */
  66.         }
  67.         
  68.         /* Header del Sidebar */
  69.         .admin-sidebar-header {
  70.             padding: 1.5rem;
  71.             border-bottom: 1px solid rgba(255,255,255,0.1);
  72.             text-align: center;
  73.             flex-shrink: 0;
  74.         }
  75.         
  76.         .admin-sidebar-header h2 {
  77.             font-size: 1.5rem;
  78.             margin-bottom: 1rem;
  79.         }
  80.         
  81.         .admin-user-info {
  82.             text-align: center;
  83.         }
  84.         
  85.         .admin-avatar {
  86.             width: 70px;
  87.             height: 70px;
  88.             background: linear-gradient(135deg, var(--primary-color), #2980b9);
  89.             border-radius: 50%;
  90.             display: flex;
  91.             align-items: center;
  92.             justify-content: center;
  93.             color: white;
  94.             font-weight: bold;
  95.             font-size: 1.8rem;
  96.             margin: 0 auto 1rem;
  97.             border: 3px solid rgba(255,255,255,0.2);
  98.         }
  99.         
  100.         .admin-user-name {
  101.             font-weight: 600;
  102.             margin-bottom: 0.25rem;
  103.         }
  104.         
  105.         .admin-user-email {
  106.             font-size: 0.85rem;
  107.             color: rgba(255,255,255,0.7);
  108.         }
  109.         
  110.         /* Navegación del Sidebar - Área con scroll */
  111.         .admin-nav-container {
  112.             flex: 1;
  113.             display: flex;
  114.             flex-direction: column;
  115.             overflow: hidden;
  116.             width: 100%; /* Asegura que no se desborde */
  117.         }
  118.         
  119.         .admin-nav {
  120.             padding: 1.5rem 0;
  121.             flex: 1;
  122.             overflow-y: auto;
  123.             overflow-x: hidden; /* Elimina scroll horizontal */
  124.             max-height: calc(100vh - 280px);
  125.             width: 100%; /* Asegura que ocupe todo el ancho disponible */
  126.         }
  127.         
  128.         .admin-nav-section {
  129.             margin-bottom: 1.5rem;
  130.             width: 100%; /* Asegura que no cause desbordamiento */
  131.         }
  132.         
  133.         .admin-nav-title {
  134.             font-size: 0.8rem;
  135.             text-transform: uppercase;
  136.             padding: 0.5rem 1.5rem;
  137.             color: rgba(255,255,255,0.6);
  138.             letter-spacing: 1px;
  139.             margin-bottom: 0.5rem;
  140.             width: 100%;
  141.             overflow: hidden; /* Previene desbordamiento de texto */
  142.         }
  143.         
  144.         .admin-nav-item {
  145.             display: flex;
  146.             align-items: center;
  147.             padding: 0.75rem 1.5rem;
  148.             color: rgba(255,255,255,0.9);
  149.             text-decoration: none;
  150.             transition: all 0.3s ease;
  151.             border-left: 3px solid transparent;
  152.             position: relative;
  153.             width: 100%; /* Ocupa todo el ancho disponible */
  154.             white-space: nowrap; /* Evita que el texto se divida en varias líneas */
  155.             overflow: hidden; /* Oculta cualquier contenido que se desborde */
  156.         }
  157.         
  158.         .admin-nav-item:hover {
  159.             background: rgba(255,255,255,0.1);
  160.             color: white;
  161.             border-left-color: var(--primary-color);
  162.             transform: translateX(5px);
  163.         }
  164.         
  165.         .admin-nav-item.active {
  166.             background: rgba(52, 152, 219, 0.2);
  167.             color: white;
  168.             border-left-color: var(--primary-color);
  169.         }
  170.         
  171.         .admin-nav-icon {
  172.             width: 20px;
  173.             margin-right: 12px;
  174.             font-size: 1.1rem;
  175.             text-align: center;
  176.             flex-shrink: 0; /* Evita que el icono se reduzca */
  177.         }
  178.         
  179.         .admin-nav-badge {
  180.             background: var(--accent-color);
  181.             color: white;
  182.             border-radius: 10px;
  183.             padding: 2px 8px;
  184.             font-size: 0.7rem;
  185.             margin-left: auto;
  186.             flex-shrink: 0; /* Evita que la badge se reduzca */
  187.         }
  188.         /* Submenú para Agenda de Citas */
  189.         .admin-nav-item.has-submenu {
  190.             cursor: pointer;
  191.         }
  192.         .admin-submenu {
  193.             list-style: none;
  194.             max-height: 0;
  195.             overflow: hidden;
  196.             transition: max-height 0.3s ease;
  197.             background: rgba(0, 0, 0, 0.2);
  198.             width: 100%; /* Asegura que ocupe todo el ancho */
  199.         }
  200.         .admin-submenu.open {
  201.             max-height: 300px;
  202.         }
  203.         .admin-submenu-item {
  204.             padding: 0.6rem 1.5rem 0.6rem 3rem;
  205.             color: rgba(255, 255, 255, 0.8);
  206.             text-decoration: none;
  207.             display: block;
  208.             transition: all 0.2s ease;
  209.             border-left: 3px solid transparent;
  210.             font-size: 0.9rem;
  211.             width: 100%; /* Ocupa todo el ancho */
  212.             white-space: nowrap; /* Evita división de texto */
  213.             overflow: hidden; /* Oculta desbordamiento */
  214.         }
  215.         .admin-submenu-item:hover {
  216.             background: rgba(255, 255, 255, 0.05);
  217.             color: white;
  218.             border-left-color: rgba(255, 255, 255, 0.3);
  219.         }
  220.         .admin-submenu-item.active {
  221.             background: rgba(52, 152, 219, 0.15);
  222.             color: white;
  223.             border-left-color: var(--primary-color);
  224.         }
  225.         .admin-nav-arrow {
  226.             transition: transform 0.3s ease;
  227.             margin-left: auto;
  228.             font-size: 0.8rem;
  229.             flex-shrink: 0; /* Evita que la flecha se reduzca */
  230.         }
  231.         .admin-nav-arrow.rotated {
  232.             transform: rotate(180deg);
  233.         }
  234.         
  235.         /* Footer del Sidebar - Siempre visible en la parte inferior */
  236.         .admin-sidebar-footer {
  237.             padding: 1rem 1.5rem;
  238.             border-top: 1px solid rgba(255,255,255,0.1);
  239.             background: rgba(0,0,0,0.1);
  240.             flex-shrink: 0;
  241.             width: 100%; /* Asegura que ocupe todo el ancho */
  242.         }
  243.         
  244.         /* Scroll personalizado para el sidebar */
  245.         .admin-nav::-webkit-scrollbar {
  246.             width: 6px;
  247.         }
  248.         
  249.         .admin-nav::-webkit-scrollbar-track {
  250.             background: rgba(255,255,255,0.1);
  251.             border-radius: 3px;
  252.         }
  253.         
  254.         .admin-nav::-webkit-scrollbar-thumb {
  255.             background: rgba(255,255,255,0.3);
  256.             border-radius: 3px;
  257.         }
  258.         
  259.         .admin-nav::-webkit-scrollbar-thumb:hover {
  260.             background: rgba(255,255,255,0.5);
  261.         }
  262.         
  263.         /* ===== CONTENIDO PRINCIPAL ===== */
  264.         .admin-header {
  265.             background: white;
  266.             border-bottom: 1px solid #e9ecef;
  267.             padding: 1rem 1.5rem;
  268.             box-shadow: 0 2px 4px rgba(0,0,0,0.05);
  269.             display: flex;
  270.             align-items: center;
  271.             justify-content: space-between;
  272.             width: 100%; /* Asegura que no cause desbordamiento */
  273.             overflow: hidden; /* Previene desbordamiento */
  274.         }
  275.         
  276.         .admin-mobile-toggle {
  277.             display: none;
  278.             background: transparent;
  279.             border: 2px solid #e9ecef;
  280.             border-radius: 6px;
  281.             padding: 8px 12px;
  282.             color: var(--secondary-color);
  283.             transition: all 0.3s ease;
  284.             margin-right: 15px;
  285.             flex-shrink: 0; /* Evita que el botón se reduzca */
  286.         }
  287.         
  288.         .admin-mobile-toggle:hover {
  289.             background: var(--primary-color);
  290.             color: white;
  291.             border-color: var(--primary-color);
  292.         }
  293.         
  294.         .admin-content {
  295.             padding: 1.5rem;
  296.             width: 100%; /* Asegura que ocupe todo el ancho disponible */
  297.             overflow-x: hidden; /* Elimina scroll horizontal */
  298.         }
  299.         
  300.         /* ===== OVERLAY PARA MÓVIL ===== */
  301.         .admin-sidebar-overlay {
  302.             position: fixed;
  303.             top: 0;
  304.             left: 0;
  305.             width: 100%;
  306.             height: 100%;
  307.             background: rgba(0,0,0,0.5);
  308.             z-index: 999;
  309.             opacity: 0;
  310.             visibility: hidden;
  311.             transition: all 0.3s ease;
  312.         }
  313.         
  314.         .admin-sidebar-overlay.show {
  315.             opacity: 1;
  316.             visibility: visible;
  317.         }
  318.         
  319.         /* ===== RESPONSIVE ===== */
  320.         @media (max-width: 768px) {
  321.             .admin-sidebar {
  322.                 left: -280px;
  323.             }
  324.             
  325.             .admin-sidebar.mobile-open {
  326.                 left: 0;
  327.             }
  328.             
  329.             .admin-main-content {
  330.                 margin-left: 0;
  331.                 width: 100%;
  332.             }
  333.             
  334.             .admin-mobile-toggle {
  335.                 display: block;
  336.             }
  337.             
  338.             /* Ajustes adicionales para móviles */
  339.             .admin-nav-item,
  340.             .admin-submenu-item {
  341.                 white-space: normal; /* Permite que el texto se divida en móviles */
  342.                 padding: 0.75rem 1rem;
  343.             }
  344.             
  345.             .admin-submenu-item {
  346.                 padding-left: 2.5rem;
  347.             }
  348.         }
  349.         
  350.         @media (min-width: 769px) and (max-width: 1024px) {
  351.             .admin-sidebar {
  352.                 width: 240px;
  353.             }
  354.             
  355.             .admin-main-content {
  356.                 margin-left: 240px;
  357.                 width: calc(100% - 240px);
  358.             }
  359.         }
  360.         .admin-header {
  361.             background: #fff;
  362.             border-bottom: 1px solid #dee2e6;
  363.             padding: 1rem 1.5rem;
  364.             box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  365.         }
  366.         .admin-mobile-toggle {
  367.             background: none;
  368.             border: none;
  369.             color: #6c757d;
  370.             font-size: 1.2rem;
  371.             padding: 0.5rem;
  372.             border-radius: 0.375rem;
  373.             transition: all 0.2s ease;
  374.         }
  375.         .admin-mobile-toggle:hover {
  376.             background: #f8f9fa;
  377.             color: #495057;
  378.         }
  379.         .admin-page-title {
  380.             font-size: 1.1rem;
  381.             font-weight: 600;
  382.             white-space: nowrap;
  383.             overflow: hidden;
  384.             text-overflow: ellipsis;
  385.             max-width: 300px; /* Limita el ancho del título */
  386.         }
  387.         .admin-mobile-avatar {
  388.             width: 36px;
  389.             height: 36px;
  390.             border-radius: 50%;
  391.             background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  392.             color: white;
  393.             display: flex;
  394.             align-items: center;
  395.             justify-content: center;
  396.             font-weight: bold;
  397.             font-size: 0.8rem;
  398.             flex-shrink: 0;
  399.         }
  400.         /* Para móviles muy pequeños */
  401.         @media (max-width: 576px) {
  402.             .admin-header {
  403.                 padding: 0.75rem 1rem;
  404.             }
  405.             
  406.             .admin-page-title {
  407.                 font-size: 1rem;
  408.                 max-width: 200px;
  409.             }
  410.             
  411.             .admin-mobile-avatar {
  412.                 width: 32px;
  413.                 height: 32px;
  414.                 font-size: 0.7rem;
  415.             }
  416.             
  417.             .admin-nav-item,
  418.             .admin-submenu-item {
  419.                 padding: 0.6rem 1rem;
  420.             }
  421.         }
  422.     </style>
  423. </head>
  424. <body>
  425.     <div class="admin-container">
  426.         <!-- Overlay para móviles -->
  427.         <div class="admin-sidebar-overlay" id="adminSidebarOverlay"></div>
  428.         
  429.         <!-- Sidebar del Admin -->
  430.         <aside class="admin-sidebar" id="adminSidebar">
  431.             <div class="admin-sidebar-header">
  432.                 <h2>Panel Admin</h2>
  433.                 <div class="admin-user-info">
  434.                     <div class="admin-avatar">
  435.                        {{ app.user.name|first|upper }}{{ app.user.lastName|first|upper }}
  436.                     </div>
  437.                     <div class="admin-user-name">{{ app.user.name }} {{ app.user.lastName }}</div>
  438.                     <div class="admin-user-email">{{ app.user.email }}</div>
  439.                 </div>
  440.             </div>
  441.             
  442.             <!-- Contenedor para la navegación con scroll -->
  443.             <div class="admin-nav-container">
  444.                 <nav class="admin-nav">
  445.                     <div class="admin-nav-section">
  446.                         <a href="{{ path('admin_index') }}" class="admin-nav-item {% if app.request.attributes.get('_route') == 'admin_index' %}active{% endif %}">
  447.                             <i class="fas fa-tachometer-alt admin-nav-icon"></i>
  448.                             Dashboard
  449.                         </a>
  450.                         <a href="{{ path('admin_pacientes') }}" class="admin-nav-item {% if app.request.attributes.get('_route') == 'admin_pacientes' %}active{% endif %}">
  451.                             <i class="fas fa-user-injured admin-nav-icon"></i>
  452.                             Pacientes
  453.                         </a>
  454.                         <a href="{{ path('admin_proveedores') }}" class="admin-nav-item {% if app.request.attributes.get('_route') == 'admin_proveedores' %}active{% endif %}">
  455.                             <i class="fas fa-user-md admin-nav-icon"></i>
  456.                             Proveedores
  457.                         </a>
  458.                         
  459.                         <!-- Agenda de Citas con Submenú -->
  460.                         <div class="admin-nav-item has-submenu {% if 'admin_appointment' in app.request.attributes.get('_route') %}active{% endif %}" id="appointmentsMenu">
  461.                             <div class="d-flex align-items-center w-100">
  462.                                 <i class="fas fa-calendar-check admin-nav-icon"></i>
  463.                                 <span>Agenda de Citas</span>
  464.                                 <i class="fas fa-chevron-down admin-nav-arrow ms-auto" id="appointmentsArrow"></i>
  465.                             </div>
  466.                         </div>
  467.                         
  468.                         <ul class="admin-submenu" id="appointmentsSubmenu">
  469.                             <li>
  470.                                 <a href="{{ path('admin_appointment') }}" class="admin-submenu-item {% if app.request.attributes.get('_route') == 'admin_appointment' and not app.request.query.has('filter') %}active{% endif %}">
  471.                                     <i class="fas fa-list-ul me-2"></i>
  472.                                     Todas las Citas
  473.                                 </a>
  474.                             </li>
  475.                             <li>
  476.                                 <a href="{{ path('admin_appointment') }}?filter=confirmed" class="admin-submenu-item {% if app.request.query.get('filter') == 'confirmed' %}active{% endif %}">
  477.                                     <i class="fas fa-calendar-check me-2 text-success"></i>
  478.                                     Citas Confirmadas
  479.                                 </a>
  480.                             </li>
  481.                             <li>
  482.                                 <a href="{{ path('admin_appointment') }}?filter=completed" class="admin-submenu-item {% if app.request.query.get('filter') == 'completed' %}active{% endif %}">
  483.                                     <i class="fas fa-clipboard-check me-2 text-primary"></i>
  484.                                     Citas Finalizadas
  485.                                 </a>
  486.                             </li>
  487.                             <li>
  488.                                 <a href="{{ path('admin_appointment') }}?filter=cancelled" class="admin-submenu-item {% if app.request.query.get('filter') == 'cancelled' %}active{% endif %}">
  489.                                     <i class="fas fa-calendar-times me-2 text-danger"></i>
  490.                                     Citas Canceladas
  491.                                 </a>
  492.                             </li>
  493.                         </ul>
  494.                         
  495.                         <a href="{{ path('admin_horario') }}" class="admin-nav-item {% if app.request.attributes.get('_route') == 'admin_horario' %}active{% endif %}">
  496.                             <i class="fas fa-clock admin-nav-icon"></i>
  497.                             Horarios Médicos
  498.                         </a>
  499.                         <a href="{{ path('admin_profile') }}" class="admin-nav-item {% if app.request.attributes.get('_route') == 'admin_profile' %}active{% endif %}">
  500.                             <i class="fas fa-user-cog admin-nav-icon"></i>
  501.                             Perfil
  502.                         </a>
  503.                     </div>
  504.                 </nav>
  505.             </div>
  506.             
  507.             <!-- Footer fijo en la parte inferior -->
  508.             <div class="admin-sidebar-footer">
  509.                 <a href="{{ path('home_index') }}" class="admin-nav-item">
  510.                     <i class="fas fa-home admin-nav-icon"></i>
  511.                     Volver al Sitio
  512.                 </a>
  513.                 <a href="{{ path('app_logout') }}" class="admin-nav-item">
  514.                     <i class="fas fa-sign-out-alt admin-nav-icon"></i>
  515.                     Cerrar Sesión
  516.                 </a>
  517.             </div>
  518.         </aside>
  519.         
  520.         <!-- Contenido Principal -->
  521.         <main class="admin-main-content" id="adminMainContent">
  522.             <header class="admin-header">
  523.                 <div class="d-flex align-items-center justify-content-between w-100">
  524.                     <!-- Lado izquierdo: Toggle + Título -->
  525.                     <div class="d-flex align-items-center">
  526.                         <button class="admin-mobile-toggle me-2 me-md-3" id="adminMobileToggle">
  527.                             <i class="fas fa-bars"></i>
  528.                         </button>
  529.                         
  530.                         <!-- Título responsive sin truncar -->
  531.                         <h4 class="mb-0 text-dark admin-page-title">
  532.                             <span class="d-none d-md-inline">Panel de Administración</span>
  533.                             <span class="d-md-none">Panel de Admon</span>
  534.                         </h4>
  535.                     </div>
  536.                     
  537.                     <!-- Lado derecho: Información del usuario -->
  538.                     <div class="d-flex align-items-center">
  539.                         <!-- Versión móvil compacta -->
  540.                         <div class="d-md-none admin-mobile-user me-2">
  541.                             <div class="admin-mobile-avatar">
  542.                                 {{ app.user.name|first|upper }}{{ app.user.lastName|first|upper }}
  543.                             </div>
  544.                         </div>
  545.                         
  546.                         <!-- Versión desktop completa -->
  547.                         <div class="d-none d-md-block">
  548.                             <span class="text-muted">Bienvenido, {{ app.user.name }} {{ app.user.lastName }}</span>
  549.                         </div>
  550.                         
  551.                         <!-- Versión tablet intermedia -->
  552.                         <div class="d-none d-sm-block d-md-none">
  553.                             <span class="text-muted">Hola, {{ app.user.name }}</span>
  554.                         </div>
  555.                     </div>
  556.                 </div>
  557.             </header>
  558.             
  559.             <div class="admin-content">
  560.                {% block content %}{% endblock %}
  561.             </div>
  562.         </main>
  563.     </div>
  564.     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  565.     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
  566.     {% block javascripts %}
  567.     {% endblock %}
  568.     <script>
  569.         document.addEventListener('DOMContentLoaded', function() {
  570.             const adminMobileToggle = document.getElementById('adminMobileToggle');
  571.             const adminSidebar = document.getElementById('adminSidebar');
  572.             const adminSidebarOverlay = document.getElementById('adminSidebarOverlay');
  573.             
  574.             // Elementos del submenú de citas
  575.             const appointmentsMenu = document.getElementById('appointmentsMenu');
  576.             const appointmentsSubmenu = document.getElementById('appointmentsSubmenu');
  577.             const appointmentsArrow = document.getElementById('appointmentsArrow');
  578.             // Control del submenú de citas
  579.             if (appointmentsMenu && appointmentsSubmenu) {
  580.                 appointmentsMenu.addEventListener('click', function(e) {
  581.                     e.preventDefault();
  582.                     appointmentsSubmenu.classList.toggle('open');
  583.                     appointmentsArrow.classList.toggle('rotated');
  584.                 });
  585.             }
  586.             // Control del menú móvil
  587.             if (adminMobileToggle && adminSidebar) {
  588.                 function toggleAdminSidebar() {
  589.                     adminSidebar.classList.toggle('mobile-open');
  590.                     adminSidebarOverlay.classList.toggle('show');
  591.                     document.body.style.overflow = adminSidebar.classList.contains('mobile-open') ? 'hidden' : '';
  592.                 }
  593.                 adminMobileToggle.addEventListener('click', toggleAdminSidebar);
  594.                 adminSidebarOverlay.addEventListener('click', toggleAdminSidebar);
  595.                 // Cerrar menú al hacer clic en un enlace (en móviles)
  596.                 const adminNavLinks = adminSidebar.querySelectorAll('.admin-nav-item, .admin-submenu-item');
  597.                 adminNavLinks.forEach(link => {
  598.                     link.addEventListener('click', function() {
  599.                         if (window.innerWidth <= 768) {
  600.                             toggleAdminSidebar();
  601.                         }
  602.                     });
  603.                 });
  604.                 // Cerrar con tecla Escape
  605.                 document.addEventListener('keydown', function(e) {
  606.                     if (e.key === 'Escape' && adminSidebar.classList.contains('mobile-open')) {
  607.                         toggleAdminSidebar();
  608.                     }
  609.                 });
  610.                 // Ajustar el layout en resize
  611.                 window.addEventListener('resize', function() {
  612.                     if (window.innerWidth > 768) {
  613.                         adminSidebar.classList.remove('mobile-open');
  614.                         adminSidebarOverlay.classList.remove('show');
  615.                         document.body.style.overflow = '';
  616.                     }
  617.                 });
  618.             }
  619.         });
  620.     </script>
  621.     {# Notificaciones globales - se convierten automáticamente a SweetAlert2 #}
  622.     {% include 'partials/_flashes.html.twig' %}
  623. </body>
  624. </html>