Revert "feat(ui): make dashboard responsive for iPhone and mobile devices"
This reverts commit d3b326e.
The deployment caused reports of blank screens and 400 errors. Reverting to restore stable state while investigating root cause.
This commit is contained in:
@@ -32,30 +32,24 @@ export function Header({ title, children }: HeaderProps) {
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-30 border-b bg-background/95 backdrop-blur">
|
||||
<div className="flex h-auto min-h-16 flex-col gap-3 px-4 py-3 md:flex-row md:items-center md:justify-between md:px-6 md:py-0">
|
||||
{/* Title section */}
|
||||
<div className="flex items-center gap-4 min-w-0">
|
||||
<h1 className="text-lg font-semibold truncate md:text-xl">{title}</h1>
|
||||
{children}
|
||||
</div>
|
||||
<header className="sticky top-0 z-30 flex h-16 items-center justify-between border-b bg-background/95 backdrop-blur px-6">
|
||||
<div className="flex items-center gap-4 min-w-0">
|
||||
<h1 className="text-xl font-semibold whitespace-nowrap">{title}</h1>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
{/* Actions section */}
|
||||
<div className="flex flex-wrap items-center gap-2 md:gap-3">
|
||||
<div className="flex flex-1 items-center gap-2 min-w-0 md:flex-initial md:gap-3">
|
||||
<ContribuyenteSelector />
|
||||
<MembershipSwitcher />
|
||||
<TenantSelector />
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={cycleTheme}
|
||||
title={`Tema: ${themes[theme].name}`}
|
||||
>
|
||||
{themeIcons[theme]}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<ContribuyenteSelector />
|
||||
<MembershipSwitcher />
|
||||
<TenantSelector />
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={cycleTheme}
|
||||
title={`Tema: ${themes[theme].name}`}
|
||||
>
|
||||
{themeIcons[theme]}
|
||||
</Button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { cn, Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@horux/shared-ui';
|
||||
import {
|
||||
LayoutDashboard,
|
||||
FileText,
|
||||
Calculator,
|
||||
Settings,
|
||||
LogOut,
|
||||
BarChart3,
|
||||
Calendar,
|
||||
Bell,
|
||||
Users,
|
||||
Building2,
|
||||
Scale,
|
||||
Send,
|
||||
ListChecks,
|
||||
FileCheck,
|
||||
ClipboardList,
|
||||
CreditCard,
|
||||
CheckSquare2,
|
||||
UserCog,
|
||||
Shield,
|
||||
FileWarning,
|
||||
Rocket,
|
||||
Menu,
|
||||
} from 'lucide-react';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
import { logout } from '@/lib/api/auth';
|
||||
import { useNavGate } from '@/lib/hooks/use-nav-gate';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { hasDespachoFeature, isGlobalAdminRfc, type DespachoPlan } from '@horux/shared';
|
||||
|
||||
interface NavItem {
|
||||
name: string;
|
||||
href: string;
|
||||
icon: typeof LayoutDashboard;
|
||||
feature?: string;
|
||||
roles?: string[];
|
||||
}
|
||||
|
||||
const navigation: NavItem[] = [
|
||||
{ name: 'Despacho', href: '/despachos', icon: ListChecks, roles: ['owner', 'cfo', 'contador', 'auxiliar', 'supervisor'] },
|
||||
{ name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard, roles: ['owner', 'cfo', 'contador', 'auxiliar', 'supervisor', 'cliente'] },
|
||||
{ name: 'CFDI', href: '/cfdi', icon: FileText },
|
||||
{ name: 'Impuestos', href: '/impuestos', icon: Calculator },
|
||||
{ name: 'Reportes', href: '/reportes', icon: BarChart3, feature: 'reportes', roles: ['owner', 'cfo', 'supervisor', 'cliente'] },
|
||||
{ name: 'Conciliacion', href: '/conciliacion', icon: Scale, feature: 'conciliacion' },
|
||||
{ name: 'Calendario', href: '/calendario', icon: Calendar, feature: 'calendario' },
|
||||
{ name: 'Alertas', href: '/alertas', icon: Bell, feature: 'alertas' },
|
||||
{ name: 'Facturación', href: '/facturacion', icon: Send, roles: ['owner', 'cfo', 'contador', 'auxiliar', 'supervisor'] },
|
||||
{ name: 'Documentos', href: '/documentos', icon: FileCheck, feature: 'documentos' },
|
||||
{ name: 'Carteras', href: '/carteras', icon: ClipboardList, roles: ['supervisor', 'auxiliar'] },
|
||||
{ name: 'Contribuyentes', href: '/contribuyentes', icon: Building2, roles: ['owner', 'cfo', 'supervisor', 'contador', 'auxiliar'] },
|
||||
{ name: 'Usuarios', href: '/usuarios', icon: Users, roles: ['owner', 'cfo', 'supervisor', 'auxiliar'] },
|
||||
{ name: 'Tareas', href: '/tareas', icon: CheckSquare2, roles: ['owner', 'cfo', 'contador', 'auxiliar', 'supervisor'] },
|
||||
{ name: 'Planes', href: '/configuracion/planes-despacho', icon: CreditCard, roles: ['owner', 'cfo'] },
|
||||
{ name: 'Configuracion', href: '/configuracion', icon: Settings, roles: ['owner', 'cfo', 'supervisor', 'auxiliar', 'cliente'] },
|
||||
];
|
||||
|
||||
const adminNavigation: NavItem[] = [
|
||||
{ name: 'Clientes', href: '/clientes', icon: Building2 },
|
||||
{ name: 'Admin Usuarios', href: '/admin/usuarios', icon: UserCog },
|
||||
{ name: 'Staff', href: '/admin/staff', icon: Shield },
|
||||
{ name: 'Audit Log', href: '/admin/audit-log', icon: FileWarning },
|
||||
];
|
||||
|
||||
export function MobileNav() {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
const { user, logout: clearAuth } = useAuthStore();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await logout();
|
||||
} catch {
|
||||
// Ignore errors
|
||||
} finally {
|
||||
clearAuth();
|
||||
router.push('/login');
|
||||
}
|
||||
};
|
||||
|
||||
const plan = (user?.plan || 'trial') as DespachoPlan;
|
||||
const role = user?.role || 'visor';
|
||||
const navGate = useNavGate();
|
||||
const filteredNav = navigation.filter((item) => {
|
||||
if (item.feature && !hasDespachoFeature(plan, item.feature)) return false;
|
||||
if (item.roles && !item.roles.includes(role)) return false;
|
||||
if (!navGate.isAllowed(item.href)) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
const isGlobalAdmin = isGlobalAdminRfc(user?.tenantRfc, role, user?.platformRoles);
|
||||
const allNavigation = isGlobalAdmin
|
||||
? [...filteredNav.slice(0, -1), ...adminNavigation, filteredNav[filteredNav.length - 1]]
|
||||
: filteredNav;
|
||||
|
||||
const handleLinkClick = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="md:hidden inline-flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium ring-offset-background transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
||||
aria-label="Abrir menú de navegación"
|
||||
>
|
||||
<Menu className="h-5 w-5" />
|
||||
</button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" className="flex w-[280px] flex-col p-0 sm:max-w-[280px]">
|
||||
{/* Logo */}
|
||||
<SheetHeader className="border-b px-4 py-4">
|
||||
<SheetTitle asChild>
|
||||
<Link href="/dashboard" onClick={handleLinkClick} className="flex items-center gap-2">
|
||||
<Image
|
||||
src="/logo.jpg"
|
||||
alt="Horux Despachos"
|
||||
width={32}
|
||||
height={32}
|
||||
className="rounded-full"
|
||||
/>
|
||||
<div className="flex flex-col leading-tight">
|
||||
<span className="font-bold text-xl">Horux</span>
|
||||
<span className="text-xs text-muted-foreground -mt-1">Despachos</span>
|
||||
</div>
|
||||
</Link>
|
||||
</SheetTitle>
|
||||
</SheetHeader>
|
||||
|
||||
{/* Navigation */}
|
||||
<nav className="flex-1 space-y-1 overflow-y-auto px-3 py-4">
|
||||
{allNavigation.map((item) => {
|
||||
const isActive = pathname === item.href || pathname.startsWith(`${item.href}/`);
|
||||
return (
|
||||
<Link
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
onClick={handleLinkClick}
|
||||
className={cn(
|
||||
'flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors',
|
||||
isActive
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'
|
||||
)}
|
||||
>
|
||||
<item.icon className="h-5 w-5 flex-shrink-0" />
|
||||
{item.name}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
{/* User & Logout */}
|
||||
<div className="border-t p-4">
|
||||
{!isGlobalAdmin && (
|
||||
<div className="mb-3 px-3">
|
||||
<p className="text-sm font-medium">{user?.nombre}</p>
|
||||
<p className="text-xs text-muted-foreground">{user?.email}</p>
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-destructive hover:text-destructive-foreground transition-colors"
|
||||
>
|
||||
<LogOut className="h-5 w-5" />
|
||||
Cerrar sesión
|
||||
</button>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user