60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
|
|
'use client';
|
||
|
|
|
||
|
|
import Link from 'next/link';
|
||
|
|
import { usePathname } from 'next/navigation';
|
||
|
|
import { ChevronRight, Home } from 'lucide-react';
|
||
|
|
import { Fragment } from 'react';
|
||
|
|
|
||
|
|
export function Breadcrumb() {
|
||
|
|
const pathname = usePathname();
|
||
|
|
|
||
|
|
// Generate breadcrumb items from pathname
|
||
|
|
const segments = pathname.split('/').filter(Boolean);
|
||
|
|
|
||
|
|
// Don't show breadcrumb on dashboard
|
||
|
|
if (segments.length === 0 || pathname === '/dashboard') {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const breadcrumbItems = segments.map((segment, index) => {
|
||
|
|
const href = '/' + segments.slice(0, index + 1).join('/');
|
||
|
|
const label = segment
|
||
|
|
.split('-')
|
||
|
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||
|
|
.join(' ');
|
||
|
|
|
||
|
|
return {
|
||
|
|
label,
|
||
|
|
href,
|
||
|
|
isLast: index === segments.length - 1,
|
||
|
|
};
|
||
|
|
});
|
||
|
|
|
||
|
|
return (
|
||
|
|
<nav className="mb-4 flex items-center space-x-2 text-sm text-muted-foreground">
|
||
|
|
<Link
|
||
|
|
href="/dashboard"
|
||
|
|
className="flex items-center transition-colors hover:text-foreground"
|
||
|
|
>
|
||
|
|
<Home className="h-4 w-4" />
|
||
|
|
</Link>
|
||
|
|
|
||
|
|
{breadcrumbItems.map((item) => (
|
||
|
|
<Fragment key={item.href}>
|
||
|
|
<ChevronRight className="h-4 w-4" />
|
||
|
|
{item.isLast ? (
|
||
|
|
<span className="font-medium text-foreground">{item.label}</span>
|
||
|
|
) : (
|
||
|
|
<Link
|
||
|
|
href={item.href}
|
||
|
|
className="transition-colors hover:text-foreground"
|
||
|
|
>
|
||
|
|
{item.label}
|
||
|
|
</Link>
|
||
|
|
)}
|
||
|
|
</Fragment>
|
||
|
|
))}
|
||
|
|
</nav>
|
||
|
|
);
|
||
|
|
}
|