2026-02-22 21:35:53 +01:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import * as React from 'react';
|
|
|
|
|
import Link from 'next/link';
|
|
|
|
|
import { usePathname } from 'next/navigation';
|
|
|
|
|
import { Menu, Search, Bell, ChevronRight, Moon, Sun, X } from 'lucide-react';
|
|
|
|
|
import { Button } from '@/components/ui/Button';
|
|
|
|
|
import { useTheme } from '@/components/providers/ThemeProvider';
|
|
|
|
|
import { cn } from '@/lib/utils/cn';
|
|
|
|
|
import { useSidebar } from './SidebarProvider';
|
|
|
|
|
|
|
|
|
|
export function AppHeader() {
|
|
|
|
|
const pathname = usePathname();
|
|
|
|
|
const { toggle, isOpen } = useSidebar();
|
|
|
|
|
|
|
|
|
|
// Custom breadcrumb logic
|
|
|
|
|
const pathSegments = pathname.split('/').filter(Boolean);
|
|
|
|
|
|
|
|
|
|
return (
|
2026-02-23 02:04:46 +01:00
|
|
|
<header className="h-16 border-b border-border bg-background/10 backdrop-blur-xl sticky top-0 z-40 flex items-center justify-between px-4 lg:px-8">
|
2026-02-22 21:35:53 +01:00
|
|
|
<div className="flex items-center gap-4">
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
className="lg:hidden text-muted-foreground hover:text-foreground"
|
|
|
|
|
onClick={toggle}
|
|
|
|
|
>
|
|
|
|
|
{isOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<nav className="hidden sm:flex items-center text-sm font-medium text-muted-foreground">
|
|
|
|
|
<Link href="/" className="hover:text-foreground transition-colors flex items-center gap-2">
|
|
|
|
|
<span>Kit</span>
|
|
|
|
|
</Link>
|
|
|
|
|
{pathSegments.map((segment, index) => {
|
|
|
|
|
const href = `/${pathSegments.slice(0, index + 1).join('/')}`;
|
|
|
|
|
const isLast = index === pathSegments.length - 1;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<React.Fragment key={href}>
|
|
|
|
|
<ChevronRight className="h-4 w-4 mx-1 text-muted-foreground/30" />
|
|
|
|
|
<Link
|
|
|
|
|
href={href}
|
|
|
|
|
className={cn(
|
|
|
|
|
"capitalize transition-colors",
|
|
|
|
|
isLast ? "text-foreground font-semibold" : "hover:text-foreground"
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
{segment.replace(/-/g, ' ')}
|
|
|
|
|
</Link>
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center gap-2 sm:gap-4">
|
|
|
|
|
<ThemeToggleComponent />
|
|
|
|
|
</div>
|
|
|
|
|
</header>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ThemeToggleComponent() {
|
|
|
|
|
const { resolvedTheme, setTheme } = useTheme();
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}
|
2026-02-23 02:04:46 +01:00
|
|
|
className="text-muted-foreground hover:text-foreground hover:bg-accent/50"
|
2026-02-22 21:35:53 +01:00
|
|
|
title={`Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`}
|
|
|
|
|
>
|
|
|
|
|
{resolvedTheme === 'dark' ? (
|
|
|
|
|
<Sun className="h-5 w-5" />
|
|
|
|
|
) : (
|
|
|
|
|
<Moon className="h-5 w-5" />
|
|
|
|
|
)}
|
|
|
|
|
</Button>
|
|
|
|
|
);
|
|
|
|
|
}
|