Files
bot_palmas/admin/Layout.php
T
Lizandro GuarnizoandClaude Sonnet 4.6 ef6e9c1f70 feat: UI/UX overhaul — shared layout, SSE live feed, responsive nav, approval drawer
- admin/Layout.php: nueva clase compartida con topbar, nav agrupado y hamburger móvil
- assets/app.css: CSS centralizado (~130 líneas), elimina ~2000 líneas duplicadas
- DashboardController: 11 vistas refactorizadas con Layout; tarjetas de stats clicables;
  drawer de aprobación rápida desde el dashboard; Live Feed reemplaza polling 3s por SSE;
  bot-config con preview WhatsApp en tiempo real; chat con back-button móvil y textarea auto-resize
- public/index.php: rutas SSE (/admin/webhook/stream/sse) y pending-list (/admin/pending-list)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 21:21:32 -05:00

82 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
class Layout
{
private static function h(string $v): string
{
return htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
}
public static function open(
string $title,
string $active,
string $userName,
int $pending = 0
): string {
$t = self::h($title);
$u = self::h($userName);
$groups = [
[
['dashboard', '/admin/dashboard', '📊', 'Dashboard'],
['live', '/admin/live', '🔴', 'Live'],
['chat', '/admin/chat', '💬', 'Chat'],
],
[
['pending', '/admin/pending', '⏳', 'Pendientes', $pending],
['companies', '/admin/companies', '🏢', 'Empresas'],
],
[
['bot-config', '/admin/bot-config', '🤖', 'Bot'],
['conv-flow', '/admin/conversation-flow', '🔗', 'Flujos'],
['settings', '/admin/settings', '⚙️', 'Ajustes'],
],
];
$navHtml = '';
foreach ($groups as $gi => $group) {
if ($gi > 0) {
$navHtml .= '<span class="nav-sep"></span>';
}
foreach ($group as $item) {
[$key, $href, $icon, $label] = $item;
$badge = isset($item[4]) && $item[4] > 0
? '<span class="nav-badge">' . (int)$item[4] . '</span>'
: '';
$cls = $active === $key ? ' active' : '';
$navHtml .= "<a href=\"{$href}\" class=\"nav-link{$cls}\">{$icon} {$label}{$badge}</a>";
}
}
$navHtml .= '<span class="nav-sep"></span>';
$navHtml .= '<a href="/admin/sync-companies" class="nav-link nav-action" title="Sincronizar desde ERP" onclick="return confirm(\'¿Sincronizar empresas desde el ERP?\')">🔄</a>';
$navHtml .= '<a href="/admin/process-queue" class="nav-link nav-action" title="Procesar cola de mensajes" onclick="return confirm(\'¿Procesar cola de mensajes?\')">📨</a>';
return <<<HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$t} &mdash; Palmas360</title>
<link rel="stylesheet" href="/assets/app.css">
</head>
<body>
<div class="topbar">
<div style="display:flex;align-items:center;gap:10px">
<button class="nav-hamburger" id="navToggle" onclick="document.getElementById('navBar').classList.toggle('open')" aria-label="Menu">&#9776;</button>
<h1><img src="https://app.palmas360.com/Test/imgLogin/logo.png" alt="Palmas360" style="height:32px;vertical-align:middle;margin-right:8px;filter:brightness(0) invert(1)"> {$t}</h1>
</div>
<div class="topbar-r">
<span class="ubadge">&#128100; {$u}</span>
<a href="/logout" class="btn-out">Salir</a>
</div>
</div>
<nav class="nav-bar" id="navBar">
{$navHtml}
</nav>
HTML;
}
}