import React from 'react'; import { Menu, ChevronRight, User, LogOut, Settings as SettingsIcon } from 'lucide-react'; import { Button } from '../../ui/button'; import { ThemeToggle } from '../../brand/theme-toggle'; import { LanguageSelector } from '../../brand/language-selector'; import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbLink, } from '../../ui/breadcrumb'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '../../ui/dropdown-menu'; import { Avatar, AvatarFallback, AvatarImage } from '../../ui/avatar'; import { useOptionalLayout } from '../../../contexts/LayoutContext'; /** * Breadcrumb entry for the header navigation. */ export interface BreadcrumbType { /** Text label to display */ label: string; /** * URL to navigate to. * When `renderLink` is provided on the Header, this value is passed to your * custom link component (e.g., React Router's ``). * Otherwise it's used as a standard ``. */ href?: string; /** Optional leading icon */ icon?: React.ReactNode; } /** * Action button configuration for the header. */ export interface HeaderAction { /** Unique identifier for the action */ id: string; /** Optional text label (hidden on mobile) */ label?: string; /** Icon element to display */ icon: React.ReactNode; /** Click handler */ onClick?: () => void; /** Additional CSS classes */ className?: string; } /** * Props for the Header component. */ export interface HeaderProps { /** * Page title — used only when the page has no navigation hierarchy. * Renders as a plain text label without breadcrumb separators. * This is the **exception** pattern; prefer `breadcrumbs` for all navigable pages. */ title?: string; /** * Navigation breadcrumb trail — the **primary** and recommended pattern. * Supports unlimited levels. The last item (without `href`) is treated as the current page. */ breadcrumbs?: BreadcrumbType[]; /** Whether to show the language selector */ showLanguageSelector?: boolean; /** Whether to show the theme toggle button */ showThemeToggle?: boolean; /** Additional CSS classes */ className?: string; /** Logged-in user information and menu */ user?: { name?: string; email?: string; avatar?: string; menuItems?: HeaderAction[]; }; /** Custom action buttons to display */ actions?: HeaderAction[]; /** Whether to show a quick settings button */ showSettings?: boolean; /** Click handler for settings */ onSettingsClick?: () => void; /** Whether to show a quick logout button */ showLogout?: boolean; /** Click handler for logout */ onLogoutClick?: () => void; /** * Custom element rendered immediately after the breadcrumb / title area. * Accepts any React node — badges, buttons, status chips, etc. * * @example * ```tsx *
Beta} * /> * ``` */ breadcrumbSlot?: React.ReactNode; /** * Custom link renderer for breadcrumb navigation. * Use this to integrate with client-side routers (e.g., React Router, Next.js Link) * to prevent full-page reloads on navigation. * * When omitted, breadcrumbs render standard `` tags. * * @example * ```tsx * import { Link } from 'react-router-dom'; * *
} * /> * ``` */ renderLink?: ( href: string, props: { className?: string; children: React.ReactNode } ) => React.ReactNode; } /** * Main application Header component. * * @description * Provides a sticky top navigation bar with breadcrumbs, responsive mobile menu trigger, * theme/language selectors, and user profile management. * * The Header supports two navigation modes: * - **Breadcrumbs (default)**: Pass the `breadcrumbs` array for pages with navigation hierarchy. * Supports unlimited depth levels. * - **Title-only (exception)**: Pass `title` for pages without any navigation (e.g., standalone pages). * This renders a simple text label without separators. * * @ai-rules * 1. **Always prefer `breadcrumbs`** for any page that has a parent or navigation context. * 2. Use `title` **only** when the page is a top-level standalone page with no navigation hierarchy. * 3. Use `actions` for page-specific global actions (e.g., Save, Edit). * 4. The `user` prop is mandatory for authenticated states to show the profile dropdown. * 5. Breadcrumbs support unlimited levels — do not limit to 2 or 3 items. */ export function Header({ title, breadcrumbs, showLanguageSelector = true, showThemeToggle = true, className, user, actions, showSettings, onSettingsClick, showLogout, onLogoutClick, renderLink, breadcrumbSlot, }: HeaderProps) { const layout = useOptionalLayout(); const toggleSidebar = layout?.toggleSidebar ?? (() => {}); return (
{/* Mobile menu trigger */} {/* Breadcrumbs or Title */} {breadcrumbs && breadcrumbs.length > 0 ? ( {breadcrumbs.map((item, index) => ( {item.href ? ( renderLink ? ( {renderLink(item.href, { className: 'flex items-center gap-1.5', children: ( <> {item.icon} {item.label} ), })} ) : ( {item.icon} {item.label} ) ) : ( {item.icon} {item.label} )} {index < breadcrumbs.length - 1 && } ))} ) : title ? ( {title} ) : ( Xertica.ai )} {/* Breadcrumb slot */} {breadcrumbSlot &&
{breadcrumbSlot}
}
{/* User controls */}
{/* Language selector */} {showLanguageSelector && ( )} {/* Theme toggle */} {showThemeToggle && } {/* Custom actions */} {actions?.map(action => ( ))} {/* Quick settings button */} {showSettings && ( )} {/* User profile dropdown */} {user && (

{user.name || 'User'}

{user.email || 'user@example.com'}

{user.menuItems?.map(item => ( {item.icon && {item.icon}} {item.label} ))} {!user.menuItems && ( <> Settings Logout )}
)} {/* Quick logout button - always last */} {showLogout && ( )}
); }