-
-
R
+
+
+
+
R
Reformix
-
/
-
Admin
+
/
+
Admin
-
+
{children}
diff --git a/mvp/b2c/src/app/panel/layout.tsx b/mvp/b2c/src/app/panel/layout.tsx
index e12474d..56e9cc5 100644
--- a/mvp/b2c/src/app/panel/layout.tsx
+++ b/mvp/b2c/src/app/panel/layout.tsx
@@ -4,6 +4,13 @@ import { requireUser } from '@/lib/auth/current-user';
import { db } from '@/db';
import { tenants } from '@/db/schema';
import { eq } from 'drizzle-orm';
+import AppNav from '@/components/AppNav';
+
+const PANEL_LINKS = [
+ { href: '/panel', label: 'Leads' },
+ { href: '/panel/precios', label: 'Precios' },
+ { href: '/panel/empresa', label: 'Empresa' },
+] as const;
export const metadata: Metadata = {
title: 'Panel · Reformix',
@@ -19,24 +26,19 @@ export default async function PanelLayout({ children }: { children: React.ReactN
return (
-
-
-
-
+
+
+
+
R
Reformix
-
/
-
{nombreEmpresa}
+
/
+
+ {nombreEmpresa}
+
-
+
{children}
diff --git a/mvp/b2c/src/components/AppNav.tsx b/mvp/b2c/src/components/AppNav.tsx
new file mode 100644
index 0000000..79cbc29
--- /dev/null
+++ b/mvp/b2c/src/components/AppNav.tsx
@@ -0,0 +1,105 @@
+'use client';
+
+import { useState } from 'react';
+import Link from 'next/link';
+import { usePathname } from 'next/navigation';
+
+export type AppNavLink = { href: string; label: string };
+
+// El enlace activo es el href más específico (más largo) que prefija el pathname.
+function activeHref(pathname: string, links: readonly AppNavLink[]): string {
+ let best = '';
+ for (const l of links) {
+ if ((pathname === l.href || pathname.startsWith(l.href + '/')) && l.href.length > best.length) {
+ best = l.href;
+ }
+ }
+ return best;
+}
+
+export default function AppNav({ links }: { links: readonly AppNavLink[] }) {
+ const pathname = usePathname();
+ const [open, setOpen] = useState(false);
+ const active = activeHref(pathname, links);
+
+ return (
+ <>
+ {/* Escritorio */}
+
+
+ {/* Móvil: botón hamburguesa */}
+
+
+ {/* Móvil: panel desplegable */}
+ {open && (
+ <>
+