85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
import React from "react";
|
|
import { Breadcrumbs, BreadcrumbItem } from "@heroui/react";
|
|
import { useContestStore } from "@/stores/contestStore";
|
|
import { useLanguageStore } from "@/stores/languageStore";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
type AppBreadcrumbsProps = {
|
|
extra?: { label: string; href?: string }[];
|
|
};
|
|
|
|
export default function AppBreadcrumbs({ extra = [] }: AppBreadcrumbsProps) {
|
|
const selectedContest = useContestStore((s) => s.selectedContest);
|
|
const selectedRound = useContestStore((s) => s.selectedRound);
|
|
const setSelectedRound = useContestStore((s) => s.setSelectedRound);
|
|
const clearSelection = useContestStore((s) => s.clearSelection);
|
|
const setSelectedContest = useContestStore((s) => s.setSelectedContest);
|
|
const locale = useLanguageStore((s) => s.locale);
|
|
const navigate = useNavigate();
|
|
|
|
const resolveLabel = (value: any): string => {
|
|
if (!value) return "";
|
|
if (typeof value === "string") return value;
|
|
if (typeof value === "object") {
|
|
if (value[locale]) return value[locale];
|
|
if (value["en"]) return value["en"];
|
|
const first = Object.values(value)[0];
|
|
return typeof first === "string" ? first : "";
|
|
}
|
|
return String(value);
|
|
};
|
|
|
|
const crumbs = [
|
|
{ label: "Home", href: "/", level: "home" as const },
|
|
{ label: "Závody", href: "/contests", level: "contests" as const },
|
|
...(selectedContest
|
|
? [{
|
|
label: resolveLabel(selectedContest.name),
|
|
href: `/contests/${selectedContest.id}`,
|
|
level: "contest" as const,
|
|
contest: selectedContest,
|
|
}]
|
|
: []),
|
|
...(selectedRound
|
|
? [{
|
|
label: resolveLabel(selectedRound.name),
|
|
href: `/contests/${selectedContest?.id ?? ""}/rounds/${selectedRound.id}`,
|
|
level: "round" as const,
|
|
}]
|
|
: []),
|
|
...extra,
|
|
];
|
|
|
|
const handleNavigate = (href?: string, level?: "home" | "contests" | "contest" | "round", contest?: any) => {
|
|
if (!href) return;
|
|
|
|
// při kliknutí na vyšší úroveň vyčisti nižší selekce
|
|
if (level === "home") {
|
|
clearSelection();
|
|
} else if (level === "contests") {
|
|
setSelectedRound(null);
|
|
} else if (level === "contest") {
|
|
setSelectedRound(null);
|
|
if (contest) {
|
|
setSelectedContest(contest);
|
|
}
|
|
}
|
|
|
|
navigate(href);
|
|
};
|
|
|
|
return (
|
|
<Breadcrumbs aria-label="Breadcrumb" variant="solid" className="mb-2">
|
|
{crumbs.map((c, idx) => (
|
|
<BreadcrumbItem
|
|
key={`${c.label}-${idx}`}
|
|
href={c.href}
|
|
onPress={() => handleNavigate(c.href, c.level as any, (c as any).contest)}
|
|
>
|
|
{c.label}
|
|
</BreadcrumbItem>
|
|
))}
|
|
</Breadcrumbs>
|
|
);
|
|
}
|