Initial commit
This commit is contained in:
84
resources/js/components/AppBreadcrumbs.tsx
Normal file
84
resources/js/components/AppBreadcrumbs.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user