"use client"; import Image from "next/image"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useId, useRef, useState, type ReactNode } from "react"; import { ROL_ETIQUETA, type Rol } from "@/lib/crm/constantes"; import { AVISO_DEMO } from "@/data/empresa"; import { accionCerrarSesion } from "@/lib/crm/acciones"; /** * Cascarón del panel: barra lateral fija en escritorio, cajón deslizable en * móvil. Es lo único de cliente del layout —necesita `usePathname` para marcar * la sección activa y estado para el cajón—; el contenido llega ya renderizado * desde el servidor. * * El panel no monta el widget de WhatsApp del sitio público: aquí adentro el * usuario ya es de la casa. */ type Enlace = { href: string; label: string; soloAdmin?: boolean }; const ENLACES: Enlace[] = [ { href: "/admin", label: "Tablero" }, { href: "/admin/oportunidades", label: "Oportunidades" }, { href: "/admin/contactos", label: "Contactos" }, { href: "/admin/pedidos", label: "Pedidos" }, { href: "/admin/analitica", label: "Analítica" }, { href: "/admin/equipo", label: "Equipo", soloAdmin: true }, { href: "/admin/reglas", label: "Reglas", soloAdmin: true }, ]; function esActivo(pathname: string, href: string): boolean { if (href === "/admin") return pathname === "/admin"; return pathname === href || pathname.startsWith(`${href}/`); } export function Cascaron({ nombre, rol, children, }: { nombre: string; rol: Rol; children: ReactNode; }) { const pathname = usePathname(); const [abierto, setAbierto] = useState(false); const cajonId = useId(); const botonRef = useRef(null); const enlaces = ENLACES.filter((e) => !e.soloAdmin || rol === "ADMIN"); // El cajón se cierra al navegar: en móvil nadie quiere cerrarlo a mano. useEffect(() => { setAbierto(false); }, [pathname]); useEffect(() => { if (!abierto) return; function alTecla(e: KeyboardEvent) { if (e.key === "Escape") { setAbierto(false); botonRef.current?.focus(); } } document.addEventListener("keydown", alTecla); return () => document.removeEventListener("keydown", alTecla); }, [abierto]); return (
Ir al contenido del panel {/* ---------- barra lateral, escritorio ---------- */} {/* ---------- cajón, móvil ---------- */}
{/* ---------- columna de contenido ---------- */}

Panel comercial

{nombre} {ROL_ETIQUETA[rol]}
{children}
); } function Marca() { return (
Fire Service Plus México CRM
); } function Navegacion({ enlaces, pathname, tabbable = true, }: { enlaces: Enlace[]; pathname: string; tabbable?: boolean; }) { return ( ); } function PieLateral({ rol }: { rol: Rol }) { return (

{rol === "ADMIN" ? "Alcance: toda la operación" : "Alcance: solo lo asignado a ti"}

); } function FranjaDemo() { return (
); } function BotonSalir() { const [saliendo, setSaliendo] = useState(false); async function salir() { setSaliendo(true); try { await accionCerrarSesion(); } finally { setSaliendo(false); } } return (
); }