From bbee9c0a5c8c506e11fad4934628137695268c88 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Wed, 24 Jun 2026 08:35:42 -0500 Subject: [PATCH] =?UTF-8?q?feat(sidebar):=20sub-acorde=C3=B3n=20para=20rec?= =?UTF-8?q?epci=C3=B3n=20y=20estaciones=20de=20muestras=20en=20turnero?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- modules/turnero/module.php | 97 ++++++++++++++++++----------------- shared/components/sidebar.php | 85 ++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 51 deletions(-) diff --git a/modules/turnero/module.php b/modules/turnero/module.php index 5273f7c..74f064d 100644 --- a/modules/turnero/module.php +++ b/modules/turnero/module.php @@ -1,22 +1,18 @@ getConnection(); - $_trDesks = $_trPdo->query( "SELECT id, nombre FROM turnero_lugares WHERE activo=1 AND tipo='recepcion' ORDER BY sort_order" )->fetchAll(PDO::FETCH_ASSOC); - $_trMuestras = $_trPdo->query( "SELECT id, nombre FROM turnero_lugares WHERE activo=1 AND tipo='muestras' ORDER BY sort_order" )->fetchAll(PDO::FETCH_ASSOC); @@ -25,60 +21,67 @@ try { $_trMuestras = []; } +// Sub-links de recepción +$_trRecepChildren = []; +foreach ($_trDesks as $_d) { + $_trRecepChildren[] = [ + 'name' => $_d['nombre'], + 'icon' => 'fas fa-chair', + 'route' => '/erp.php?m=turnero&v=recepcion&desk_id=' . (int)$_d['id'], + ]; +} +if (empty($_trRecepChildren)) { + $_trRecepChildren[] = ['name' => 'Recepción', 'icon' => 'fas fa-chair', 'route' => '/erp.php?m=turnero&v=recepcion']; +} + +// Sub-links de muestras +$_trMuestrasChildren = []; +foreach ($_trMuestras as $_m) { + $_trMuestrasChildren[] = [ + 'name' => $_m['nombre'], + 'icon' => 'fas fa-flask', + 'route' => '/erp.php?m=turnero&v=lugar&lugar_id=' . (int)$_m['id'], + ]; +} + $_trLinks = []; -// ── Recepcionista: solo sus escritorios + pantalla TV ───────── +// ── Recepcionista ───────────────────────────────────────────── if ($_trIsRecep) { $_trLinks[] = ['name' => 'Pantalla TV', 'icon' => 'fas fa-tv', 'route' => '/erp.php?m=turnero&v=display_global']; - if (!empty($_trDesks)) { - foreach ($_trDesks as $_d) { - $_trLinks[] = [ - 'name' => $_d['nombre'], - 'icon' => 'fas fa-concierge-bell', - 'route' => '/erp.php?m=turnero&v=recepcion&desk_id=' . (int)$_d['id'], - ]; - } + if (count($_trRecepChildren) > 1) { + $_trLinks[] = ['name' => 'Recepción', 'icon' => 'fas fa-concierge-bell', 'route' => null, 'children' => $_trRecepChildren]; } else { - $_trLinks[] = ['name' => 'Recepción', 'icon' => 'fas fa-concierge-bell', 'route' => '/erp.php?m=turnero&v=recepcion']; + $_trLinks[] = array_merge($_trRecepChildren[0], ['icon' => 'fas fa-concierge-bell']); } -// ── Bacteriólogo: dashboard, historial, TV + sus estaciones ── +// ── Bacteriólogo ────────────────────────────────────────────── } elseif ($_trIsBacte) { $_trLinks[] = ['name' => 'Dashboard', 'icon' => 'fas fa-tachometer-alt', 'route' => '/erp.php?m=turnero&v=dashboard']; $_trLinks[] = ['name' => 'Historial', 'icon' => 'fas fa-history', 'route' => '/erp.php?m=turnero&v=historial']; $_trLinks[] = ['name' => 'Pantalla TV', 'icon' => 'fas fa-tv', 'route' => '/erp.php?m=turnero&v=display_global']; - foreach ($_trMuestras as $_m) { - $_trLinks[] = [ - 'name' => $_m['nombre'], - 'icon' => 'fas fa-flask', - 'route' => '/erp.php?m=turnero&v=lugar&lugar_id=' . (int)$_m['id'], - ]; + if (count($_trMuestrasChildren) > 1) { + $_trLinks[] = ['name' => 'Estaciones', 'icon' => 'fas fa-flask', 'route' => null, 'children' => $_trMuestrasChildren]; + } elseif (!empty($_trMuestrasChildren)) { + $_trLinks[] = $_trMuestrasChildren[0]; } -// ── Admin / Supervisor / otros: acceso completo ─────────────── +// ── Admin / Supervisor / otros ──────────────────────────────── } else { - $_trLinks[] = ['name' => 'Dashboard', 'icon' => 'fas fa-tachometer-alt', 'route' => '/erp.php?m=turnero&v=dashboard']; - $_trLinks[] = ['name' => 'Historial', 'icon' => 'fas fa-history', 'route' => '/erp.php?m=turnero&v=historial']; - $_trLinks[] = ['name' => 'Configuración', 'icon' => 'fas fa-sliders-h', 'route' => '/erp.php?m=turnero&v=configuracion']; - $_trLinks[] = ['name' => 'Kiosko', 'icon' => 'fas fa-desktop', 'route' => '/erp.php?m=turnero&v=kiosko']; - $_trLinks[] = ['name' => 'Pantalla TV Global', 'icon' => 'fas fa-th-large', 'route' => '/erp.php?m=turnero&v=display_global']; - if (!empty($_trDesks)) { - foreach ($_trDesks as $_d) { - $_trLinks[] = [ - 'name' => $_d['nombre'], - 'icon' => 'fas fa-concierge-bell', - 'route' => '/erp.php?m=turnero&v=recepcion&desk_id=' . (int)$_d['id'], - ]; - } - } else { - $_trLinks[] = ['name' => 'Recepción', 'icon' => 'fas fa-concierge-bell', 'route' => '/erp.php?m=turnero&v=recepcion']; + $_trLinks[] = ['name' => 'Dashboard', 'icon' => 'fas fa-tachometer-alt', 'route' => '/erp.php?m=turnero&v=dashboard']; + $_trLinks[] = ['name' => 'Historial', 'icon' => 'fas fa-history', 'route' => '/erp.php?m=turnero&v=historial']; + $_trLinks[] = ['name' => 'Configuración', 'icon' => 'fas fa-sliders-h', 'route' => '/erp.php?m=turnero&v=configuracion']; + $_trLinks[] = ['name' => 'Kiosko', 'icon' => 'fas fa-desktop', 'route' => '/erp.php?m=turnero&v=kiosko']; + $_trLinks[] = ['name' => 'Pantalla TV', 'icon' => 'fas fa-tv', 'route' => '/erp.php?m=turnero&v=display_global']; + if (count($_trRecepChildren) > 1) { + $_trLinks[] = ['name' => 'Recepción', 'icon' => 'fas fa-concierge-bell', 'route' => null, 'children' => $_trRecepChildren]; + } elseif (!empty($_trRecepChildren)) { + $_trLinks[] = array_merge($_trRecepChildren[0], ['icon' => 'fas fa-concierge-bell']); } - foreach ($_trMuestras as $_m) { - $_trLinks[] = [ - 'name' => $_m['nombre'], - 'icon' => 'fas fa-flask', - 'route' => '/erp.php?m=turnero&v=lugar&lugar_id=' . (int)$_m['id'], - ]; + if (count($_trMuestrasChildren) > 1) { + $_trLinks[] = ['name' => 'Estaciones', 'icon' => 'fas fa-flask', 'route' => null, 'children' => $_trMuestrasChildren]; + } elseif (!empty($_trMuestrasChildren)) { + $_trLinks[] = $_trMuestrasChildren[0]; } } diff --git a/shared/components/sidebar.php b/shared/components/sidebar.php index 564b60c..f6e8816 100644 --- a/shared/components/sidebar.php +++ b/shared/components/sidebar.php @@ -171,15 +171,43 @@ if (class_exists('ModuleRegistry', false)) { $mod): $links = $mod['links'] ?? []; if (!empty($links)): - foreach ($links as $lnk): - $href = $_base . $lnk['route']; - $active = $_isActive($lnk['route']); + foreach ($links as $lnkIdx => $lnk): + $children = $lnk['children'] ?? []; + if (!empty($children)): + // Sub-acordeón para links con hijos + $subId = $catId . '-sub-' . $slug . '-' . $lnkIdx; + $hasActive = false; + foreach ($children as $ch) { if ($_isActive($ch['route']) !== '') { $hasActive = true; break; } } +?> +
  • + + + +
  • +
  • + +
  • +
  • - ul { list-style: none; padding: 0 0 4px; margin: 0; } .sb-group.collapsed { max-height: 0 !important; opacity: 0; pointer-events: none; } + +/* Sub-acordeón dentro de un módulo */ +.sb-sub-header { + display: flex; align-items: center; gap: 8px; + padding: 7px 16px 7px 20px; + cursor: pointer; user-select: none; + color: rgba(255,255,255,.75); + font-size: .84rem; + border-radius: 6px; margin: 1px 6px; + transition: background .15s, color .15s; +} +.sb-sub-header:hover, .sb-sub-header.has-active { color: #fff; background: rgba(255,255,255,.1); } +.sb-sub-header span { flex: 1; } +.sb-sub-chev { font-size: .6rem; opacity: .7; transition: transform .22s ease; flex-shrink: 0; } +.sb-sub-header.collapsed .sb-sub-chev { transform: rotate(-90deg); } +.sb-sub-group { overflow: hidden; transition: max-height .25s ease, opacity .2s ease; } +.sb-sub-group > ul { list-style: none; padding: 0; margin: 0; } +.sb-sub-group.collapsed { max-height: 0 !important; opacity: 0; pointer-events: none; } +.nav-link-sub { padding-left: 36px !important; font-size: .82rem !important; }