feat(web): add bgm viewer navigation

This commit is contained in:
2026-08-09 20:02:03 +08:00
parent 64c8bb60b3
commit 4e18ab5bc8
12 changed files with 403 additions and 66 deletions
+33
View File
@@ -0,0 +1,33 @@
import { Link } from 'react-router-dom';
export interface Crumb {
label: string;
/** Where the crumb links; omit for the current (last) crumb. */
to?: string;
}
/**
* A breadcrumb navigation trail. The last crumb is the current page and is
* rendered as plain text; earlier crumbs link to their routes.
*/
export default function Breadcrumbs({ crumbs }: { crumbs: Crumb[] }) {
return (
<nav aria-label="Breadcrumb" className="flex flex-wrap items-center gap-1 text-sm text-zinc-400">
{crumbs.map((crumb, i) => {
const last = i === crumbs.length - 1;
return (
<span key={i} className="flex items-center gap-1">
{i > 0 && <span className="text-zinc-600">/</span>}
{crumb.to && !last ? (
<Link to={crumb.to} className="hover:text-zinc-100">
{crumb.label}
</Link>
) : (
<span className={last ? 'text-zinc-100' : ''}>{crumb.label}</span>
)}
</span>
);
})}
</nav>
);
}
@@ -0,0 +1,15 @@
import { Link } from 'react-router-dom';
import Breadcrumbs from './Breadcrumbs';
/** Shown when a bgm package id doesn't resolve to a known package. */
export default function PackageMissing({ id }: { id: string }) {
return (
<div className="space-y-4">
<Breadcrumbs crumbs={[{ label: 'Board games', to: '/bgm' }, { label: id }]} />
<p className="text-sm text-zinc-400">No package {id}.</p>
<Link to="/bgm" className="text-sm text-zinc-300 underline">
Back to all packages
</Link>
</div>
);
}