Spaces:
Runtime error
Runtime error
File size: 2,705 Bytes
cd8bd0a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | "use client";
/**
* Breadcrumbs — FASE-07 UX
*
* Dashboard breadcrumb navigation component. Automatically generates
* breadcrumbs from the current path with friendly labels.
* Uses usePathname() internally — no props needed.
*
* Usage:
* <Breadcrumbs />
*/
import { usePathname } from "next/navigation";
import Link from "next/link";
const PATH_LABELS = {
dashboard: "Dashboard",
providers: "Providers",
combos: "Combos",
settings: "Settings",
logs: "Logs",
"audit-log": "Audit Log",
console: "Console",
logger: "Logger",
translator: "Translator",
playground: "Playground",
add: "Add",
edit: "Edit",
keys: "API Keys",
models: "Models",
};
/**
* Get a friendly label for a path segment.
* @param {string} segment
* @returns {string}
*/
function getLabel(segment) {
return PATH_LABELS[segment] || segment.charAt(0).toUpperCase() + segment.slice(1);
}
export default function Breadcrumbs() {
const pathname = usePathname();
if (!pathname || pathname === "/dashboard") return null;
const segments = pathname.split("/").filter(Boolean);
const crumbs = segments.map((seg, idx) => ({
label: getLabel(seg),
href: "/" + segments.slice(0, idx + 1).join("/"),
isLast: idx === segments.length - 1,
}));
return (
<nav
aria-label="Breadcrumb"
style={{
display: "flex",
alignItems: "center",
gap: "6px",
fontSize: "13px",
color: "var(--text-secondary, #888)",
padding: "8px 0",
marginBottom: "8px",
}}
>
{crumbs.map((crumb, i) => (
<span key={crumb.href} style={{ display: "flex", alignItems: "center", gap: "6px" }}>
{i > 0 && (
<span style={{ opacity: 0.4, fontSize: "11px" }} aria-hidden="true">
›
</span>
)}
{crumb.isLast ? (
<span
aria-current="page"
style={{ color: "var(--text-primary, #e0e0e0)", fontWeight: 500 }}
>
{crumb.label}
</span>
) : (
<Link
href={crumb.href}
style={{
color: "var(--text-secondary, #888)",
textDecoration: "none",
transition: "color 0.15s",
}}
onMouseEnter={(e) =>
((e.currentTarget as HTMLElement).style.color = "var(--accent, #818cf8)")
}
onMouseLeave={(e) =>
((e.currentTarget as HTMLElement).style.color = "var(--text-secondary, #888)")
}
>
{crumb.label}
</Link>
)}
</span>
))}
</nav>
);
}
|