Files
mypage/components/layout/Breadcrumbs.tsx
2025-11-10 09:49:07 +02:00

146 lines
3.8 KiB
TypeScript

'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Fragment } from 'react';
import { BreadcrumbsSchema } from './BreadcrumbsSchema';
interface BreadcrumbItem {
label: string;
href: string;
current?: boolean;
}
function HomeIcon({ className }: { className?: string }) {
return (
<svg
className={className}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
/>
</svg>
);
}
function ChevronIcon({ className }: { className?: string }) {
return (
<svg
className={className}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5l7 7-7 7"
/>
</svg>
);
}
function formatSegmentLabel(segment: string): string {
const specialCases: { [key: string]: string } = {
blog: 'Blog',
tags: 'Tag-uri',
about: 'Despre',
};
if (specialCases[segment]) {
return specialCases[segment];
}
return segment
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
}
export function Breadcrumbs({ items }: { items?: BreadcrumbItem[] }) {
const pathname = usePathname();
let breadcrumbs: BreadcrumbItem[] = items || [];
if (!items) {
const segments = pathname.split('/').filter(Boolean);
breadcrumbs = segments.map((segment, index) => {
const href = '/' + segments.slice(0, index + 1).join('/');
const label = formatSegmentLabel(segment);
const current = index === segments.length - 1;
return { label, href, current };
});
}
if (pathname === '/') {
return null;
}
const schemaItems = [
{ position: 1, name: 'Acasă', item: '/' },
...breadcrumbs.map((item, index) => ({
position: index + 2,
name: item.label,
item: item.href,
})),
];
return (
<>
<nav
aria-label="Breadcrumb"
className="bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700"
>
<div className="container mx-auto px-4 py-3">
<ol className="flex items-center space-x-2 text-sm overflow-x-auto scrollbar-hide">
<li className="flex-shrink-0">
<Link
href="/"
className="flex items-center text-gray-500 hover:text-primary-600 transition"
aria-label="Acasă"
>
<HomeIcon className="w-4 h-4" />
</Link>
</li>
{breadcrumbs.map((item) => (
<Fragment key={item.href}>
<li className="text-gray-400 flex-shrink-0">
<ChevronIcon className="w-4 h-4" />
</li>
<li className="flex-shrink-0">
{item.current ? (
<span
className="font-medium text-gray-700 dark:text-gray-300 truncate max-w-[150px] sm:max-w-none block"
aria-current="page"
>
{item.label}
</span>
) : (
<Link
href={item.href}
className="text-gray-500 hover:text-primary-600 transition truncate max-w-[150px] sm:max-w-none block"
>
{item.label}
</Link>
)}
</li>
</Fragment>
))}
</ol>
</div>
</nav>
<BreadcrumbsSchema items={schemaItems} />
</>
);
}