"use client"; import { useEffect, useState, type ReactNode } from "react"; import { usePathname, useRouter } from "next/navigation"; import Link from "next/link"; import { logout, me } from "@/lib/api"; import { AuthContext, can } from "@/lib/abilities"; import { ROLE_LABEL } from "@/lib/labels"; import type { AuthUser, Ability } from "@/lib/types"; /** * Authenticated shell: gates on /auth/me, redirects to /login when the * session is missing, renders the brand header + logout, and wraps page * content. Provides the AuthContext so any page can read the user's * abilities. Used by every authenticated page. */ const NAV: { href: string; label: string; ability?: Ability }[] = [ { href: "/clientes", label: "Clientes" }, { href: "/servicios", label: "Propiedades" }, { href: "/polizas", label: "Pólizas" }, { href: "/estado-cuenta", label: "Estado de cuenta" }, { href: "/banco", label: "Chequera" }, { href: "/catalogos", label: "Catálogos", ability: "lookup:manage" }, { href: "/usuarios", label: "Usuarios", ability: "user:manage" }, { href: "/operaciones", label: "Operaciones", ability: "db:manage" }, ]; export function AppShell({ children }: { children: ReactNode }) { const router = useRouter(); const pathname = usePathname(); const [user, setUser] = useState(null); const [checking, setChecking] = useState(true); const [loggingOut, setLoggingOut] = useState(false); useEffect(() => { let alive = true; me() .then((u) => { if (alive) { setUser(u); setChecking(false); } }) .catch(() => { router.replace("/login"); }); return () => { alive = false; }; }, [router]); async function handleLogout() { setLoggingOut(true); try { await logout(); } catch { /* ignore — we redirect regardless */ } router.replace("/login"); } if (checking) { return (
); } return (
Jorge Cuadros & Asociados
{user && ( {user.name} {ROLE_LABEL[user.role]} )}
{children}
); }