feat(auth): add /login page, session middleware, role-based navigation and logout
This commit is contained in:
@@ -6,18 +6,30 @@ import {
|
||||
FolderGit2,
|
||||
Bot,
|
||||
ShieldCheck,
|
||||
Layers
|
||||
Layers,
|
||||
LogOut,
|
||||
UserCheck
|
||||
} from 'lucide-react';
|
||||
import { createClient } from '@/lib/supabase/server';
|
||||
import { logoutAction } from '@/app/auth/actions';
|
||||
|
||||
export default function DashboardLayout({
|
||||
export default async function DashboardLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const supabase = await createClient();
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
|
||||
const role = user?.user_metadata?.role || user?.app_metadata?.role || 'client';
|
||||
const company = user?.user_metadata?.company || '4Ventures Central';
|
||||
const email = user?.email || 'usuario@4ventures.es';
|
||||
const isAgency = role === 'admin' || role === 'team';
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen bg-[#0B0F19]">
|
||||
{/* Sidebar */}
|
||||
<aside className="w-64 border-r border-gray-800 bg-[#0D121F] flex flex-col justify-between p-4">
|
||||
<aside className="w-64 border-r border-gray-800 bg-[#0D121F] flex flex-col justify-between p-4 shrink-0">
|
||||
<div>
|
||||
<div className="flex items-center gap-3 px-2 py-4 border-b border-gray-800/80 mb-6">
|
||||
<div className="w-9 h-9 rounded-lg bg-gradient-to-br from-brand-500 to-amber-600 flex items-center justify-center font-bold text-white shadow-lg shadow-brand-500/20">
|
||||
@@ -58,27 +70,53 @@ export default function DashboardLayout({
|
||||
<Bot className="w-4 h-4 text-purple-400" />
|
||||
Asistente IA Financiero
|
||||
</Link>
|
||||
<div className="pt-4 mt-4 border-t border-gray-800/60">
|
||||
<span className="px-3 text-[10px] font-bold uppercase tracking-wider text-gray-400">Agencia OS</span>
|
||||
<Link
|
||||
href="/dashboard/agencia"
|
||||
className="flex items-center gap-3 px-3 py-2.5 mt-1 rounded-lg text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-800/60 transition-all"
|
||||
>
|
||||
<Layers className="w-4 h-4 text-amber-400" />
|
||||
Cartera Cross-Tenant
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{isAgency && (
|
||||
<div className="pt-4 mt-4 border-t border-gray-800/60">
|
||||
<span className="px-3 text-[10px] font-bold uppercase tracking-wider text-gray-400">Agencia OS</span>
|
||||
<Link
|
||||
href="/dashboard/agencia"
|
||||
className="flex items-center gap-3 px-3 py-2.5 mt-1 rounded-lg text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-800/60 transition-all"
|
||||
>
|
||||
<Layers className="w-4 h-4 text-amber-400" />
|
||||
Cartera Cross-Tenant
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div className="pt-4 border-t border-gray-800/80 text-xs text-gray-400 space-y-2">
|
||||
<div className="flex items-center justify-between px-2">
|
||||
<span className="flex items-center gap-1.5 text-emerald-400">
|
||||
<ShieldCheck className="w-3.5 h-3.5" /> Aislamiento RLS
|
||||
</span>
|
||||
<span className="bg-gray-800 px-1.5 py-0.5 rounded text-[10px] text-gray-300">VPS Hostinger</span>
|
||||
{/* Sidebar Footer with User Info & Logout */}
|
||||
<div className="pt-4 border-t border-gray-800/80 space-y-3">
|
||||
<div className="px-2 py-2 rounded-xl bg-gray-900/60 border border-gray-800/80">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<UserCheck className="w-3.5 h-3.5 text-brand-400 shrink-0" />
|
||||
<p className="text-xs font-medium text-white truncate">{email}</p>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[10px] text-gray-400 capitalize">{company}</span>
|
||||
<span className="text-[9px] uppercase tracking-wider font-semibold px-1.5 py-0.5 rounded bg-brand-500/20 text-brand-400">
|
||||
{role}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action={logoutAction}>
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-xs font-medium text-gray-400 hover:text-red-400 hover:bg-red-500/10 border border-transparent hover:border-red-500/20 transition-all cursor-pointer"
|
||||
>
|
||||
<LogOut className="w-3.5 h-3.5" />
|
||||
Cerrar Sesión
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="flex items-center justify-between px-2 pt-1 text-[11px] text-gray-500">
|
||||
<span className="flex items-center gap-1 text-emerald-400">
|
||||
<ShieldCheck className="w-3 h-3" /> RLS Activo
|
||||
</span>
|
||||
<span>VPS Hostinger</span>
|
||||
</div>
|
||||
<p className="px-2 text-[11px] text-gray-500">Hostinger VPS · Dokploy</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -86,9 +124,9 @@ export default function DashboardLayout({
|
||||
<div className="flex-1 flex flex-col min-w-0">
|
||||
<header className="h-16 border-b border-gray-800 bg-[#0D121F]/50 backdrop-blur px-8 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2 text-sm text-gray-400">
|
||||
<span>Tenant:</span>
|
||||
<span className="bg-brand-500/10 text-brand-500 font-semibold px-2 py-0.5 rounded border border-brand-500/20">
|
||||
4Ventures Central
|
||||
<span>Cliente / Portal:</span>
|
||||
<span className="bg-brand-500/10 text-brand-400 font-semibold px-2.5 py-1 rounded-md border border-brand-500/20">
|
||||
{company}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
|
||||
Reference in New Issue
Block a user