Files
SKEEN-Proyecto/wacrm/src/components/layout/header.tsx
Consultoría Alcaraz Salazar a718592291 Initial commit: SKEEN Derma Experts - Sistema Integral de Gestión Clínica
- Frontend React (SKEEN Brand) con Vite, TypeScript, Tailwind
- Frontend Homenest (versión alternativa)
- Módulos Odoo 17 custom (citas, pacientes, monedero, pagos, ventas, inventario, whatsapp)
- WACRM fork (Next.js 16 + Supabase)
- Hermes + Bridge + Skills (Qwen3.6 via Nan Builders)
- Scripts de migración y operación
- Documentación extensiva en docs/
2026-07-20 07:44:23 +00:00

146 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useAuth } from "@/hooks/use-auth";
import { LogOut, Menu, Settings as SettingsIcon, User } from "lucide-react";
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/components/ui/avatar";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { ModeToggle } from "@/components/layout/mode-toggle";
const pageTitles: Record<string, string> = {
"/dashboard": "Dashboard",
"/inbox": "Inbox",
"/notifications": "Notifications",
"/contacts": "Contacts",
"/pipelines": "Pipelines",
"/broadcasts": "Broadcasts",
"/automations": "Automations",
"/settings": "Settings",
};
function getPageTitle(pathname: string): string {
if (pageTitles[pathname]) return pageTitles[pathname];
const match = Object.entries(pageTitles).find(([path]) =>
pathname.startsWith(path),
);
return match ? match[1] : "Dashboard";
}
interface HeaderProps {
/** Wired to the shell's drawer state. Used only on mobile — the
* hamburger button is hidden on lg+. */
onOpenSidebar?: () => void;
}
export function Header({ onOpenSidebar }: HeaderProps) {
const pathname = usePathname();
const { profile, signOut } = useAuth();
const title = getPageTitle(pathname);
const initial =
profile?.full_name?.charAt(0)?.toUpperCase() ??
profile?.email?.charAt(0)?.toUpperCase() ??
"U";
return (
<header className="flex h-14 shrink-0 items-center justify-between gap-3 border-b border-border bg-background px-4 lg:px-6">
<div className="flex min-w-0 items-center gap-2">
{/* Hamburger — mobile only. 44×44 hit target per Apple HIG. */}
<button
type="button"
onClick={onOpenSidebar}
aria-label="Open menu"
className="flex h-10 w-10 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground lg:hidden"
>
<Menu className="h-5 w-5" />
</button>
<h1 className="truncate text-base font-semibold text-foreground sm:text-lg">
{title}
</h1>
</div>
<div className="flex items-center gap-1 sm:gap-2">
<ModeToggle />
<DropdownMenu>
<DropdownMenuTrigger
className="flex items-center gap-2 rounded-md px-1 py-1 transition-colors hover:bg-muted/70 focus:bg-muted/70 focus:outline-none data-popup-open:bg-muted/70 sm:gap-3 sm:pl-1 sm:pr-3"
aria-label="Open account menu"
>
<Avatar className="size-8">
{profile?.avatar_url ? (
<AvatarImage
src={profile.avatar_url}
alt={profile.full_name ?? "Avatar"}
/>
) : null}
<AvatarFallback className="bg-primary/10 text-sm font-medium text-primary">
{initial}
</AvatarFallback>
</Avatar>
<span className="hidden text-sm font-medium text-foreground sm:inline">
{profile?.full_name ?? "User"}
</span>
</DropdownMenuTrigger>
<DropdownMenuContent
align="end"
sideOffset={6}
className="min-w-56 bg-popover text-popover-foreground ring-border"
>
<div className="px-2 py-1.5">
<p className="truncate text-sm font-medium text-foreground">
{profile?.full_name ?? "User"}
</p>
<p className="truncate text-xs text-muted-foreground">
{profile?.email ?? ""}
</p>
</div>
<DropdownMenuSeparator className="bg-border" />
<DropdownMenuItem
render={
<Link
href="/settings?tab=profile"
className="text-popover-foreground focus:bg-accent focus:text-accent-foreground"
/>
}
>
<User className="size-4" />
Profile
</DropdownMenuItem>
<DropdownMenuItem
render={
<Link
href="/settings?tab=whatsapp"
className="text-popover-foreground focus:bg-accent focus:text-accent-foreground"
/>
}
>
<SettingsIcon className="size-4" />
Settings
</DropdownMenuItem>
<DropdownMenuSeparator className="bg-border" />
<DropdownMenuItem
onClick={signOut}
className="text-popover-foreground focus:bg-accent focus:text-accent-foreground"
>
<LogOut className="size-4" />
Sign out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>
);
}