| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- "use client";
- import React from "react";
- import Link from "next/link";
- import {
- Breadcrumb,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbList,
- BreadcrumbPage,
- BreadcrumbSeparator,
- } from "@/components/ui/breadcrumb";
- import { yearPath, monthPath } from "@/lib/frontend/routes";
- import { formatMonthLabel } from "@/lib/frontend/explorer/formatters";
- import {
- buildExplorerDropdownItems,
- buildBranchCrumbHref,
- } from "@/lib/frontend/explorer/breadcrumbDropdowns";
- import SegmentDropdown from "@/components/explorer/breadcrumbs/SegmentDropdown";
- /**
- * ExplorerBreadcrumbs
- *
- * Breadcrumb navigation for the Explorer drill-down using shadcn/ui Breadcrumb.
- * Optional dropdowns allow switching between existing years/months/days.
- *
- * UX rules:
- * - All user-facing strings must be German.
- * - Dropdowns are only rendered when options are available (non-empty lists).
- *
- * @param {{
- * branch: string,
- * year?: string|null,
- * month?: string|null,
- * day?: string|null,
- * yearOptions?: string[]|null,
- * monthOptions?: string[]|null,
- * dayOptions?: string[]|null
- * }} props
- */
- export default function ExplorerBreadcrumbs({
- branch,
- year = null,
- month = null,
- day = null,
- yearOptions = null,
- monthOptions = null,
- dayOptions = null,
- }) {
- const { yearItems, monthItems, dayItems } = buildExplorerDropdownItems({
- branch,
- year,
- month,
- day,
- yearOptions,
- monthOptions,
- dayOptions,
- });
- const showYear = Boolean(year);
- const showMonth = Boolean(year && month);
- const showDay = Boolean(year && month && day);
- const isBranchCurrent = !year;
- const isYearCurrent = Boolean(year && !month);
- const isMonthCurrent = Boolean(year && month && !day);
- return (
- <Breadcrumb>
- <BreadcrumbList>
- {/* Branch */}
- <BreadcrumbItem>
- {isBranchCurrent ? (
- <BreadcrumbPage>{branch}</BreadcrumbPage>
- ) : (
- <BreadcrumbLink asChild>
- <Link href={buildBranchCrumbHref(branch)}>{branch}</Link>
- </BreadcrumbLink>
- )}
- </BreadcrumbItem>
- {/* Year */}
- {showYear ? (
- <>
- <BreadcrumbSeparator />
- <BreadcrumbItem>
- <div className="flex items-center">
- {isYearCurrent ? (
- <BreadcrumbPage>{year}</BreadcrumbPage>
- ) : (
- <BreadcrumbLink asChild>
- <Link href={yearPath(branch, year)}>{year}</Link>
- </BreadcrumbLink>
- )}
- {yearItems ? (
- <SegmentDropdown
- items={yearItems}
- currentValue={year}
- menuLabel="Jahr wechseln"
- triggerAriaLabel="Jahr auswählen"
- />
- ) : null}
- </div>
- </BreadcrumbItem>
- </>
- ) : null}
- {/* Month */}
- {showMonth ? (
- <>
- <BreadcrumbSeparator />
- <BreadcrumbItem>
- <div className="flex items-center">
- {isMonthCurrent ? (
- <BreadcrumbPage>{formatMonthLabel(month)}</BreadcrumbPage>
- ) : (
- <BreadcrumbLink asChild>
- <Link href={monthPath(branch, year, month)}>
- {formatMonthLabel(month)}
- </Link>
- </BreadcrumbLink>
- )}
- {monthItems ? (
- <SegmentDropdown
- items={monthItems}
- currentValue={month}
- menuLabel="Monat wechseln"
- triggerAriaLabel="Monat auswählen"
- />
- ) : null}
- </div>
- </BreadcrumbItem>
- </>
- ) : null}
- {/* Day */}
- {showDay ? (
- <>
- <BreadcrumbSeparator />
- <BreadcrumbItem>
- <div className="flex items-center">
- {/* Day is always current on the leaf route */}
- <BreadcrumbPage>{day}</BreadcrumbPage>
- {dayItems ? (
- <SegmentDropdown
- items={dayItems}
- currentValue={day}
- menuLabel="Tag wechseln"
- triggerAriaLabel="Tag auswählen"
- />
- ) : null}
- </div>
- </BreadcrumbItem>
- </>
- ) : null}
- </BreadcrumbList>
- </Breadcrumb>
- );
- }
|