"use client"; import { CalendarClock } from "lucide-react"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; import { Button } from "@/components/ui/Button"; import { FILTER_SELECT_CLASS, istMeldbaresDatum } from "@/components/ui/Field"; import { fmtDate } from "@/lib/format"; type AsOfPickerProps = { asOf: string; today: string; /** Placements projected from effective-dated changes not yet applied. */ projectedCount: number; /** Earliest date the assignment history covers; before that it is today's placement. */ historyStartsAt: string | null; }; export function AsOfPicker({ asOf, today, projectedCount, historyStartsAt }: AsOfPickerProps) { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); function setAsOf(value: string | undefined) { const sp = new URLSearchParams(searchParams.toString()); if (value && value !== today) sp.set("asOf", value); else sp.delete("asOf"); router.push(sp.size > 0 ? `${pathname}?${sp}` : pathname, { scroll: false }); } // Angeglichen während des Renderns, nicht in einem Effekt — siehe DateField. const [entwurf, setEntwurf] = useState(asOf); const [zuletzt, setZuletzt] = useState(asOf); if (asOf !== zuletzt) { setZuletzt(asOf); setEntwurf(asOf); } const isToday = asOf === today; const isFuture = asOf > today; // Assignments only started being recorded when the history table was // introduced; asking for a date before that yields today's placement for // everyone, which is worth saying out loud rather than quietly implying. const beforeHistory = historyStartsAt !== null && asOf < historyStartsAt; return (
{/* Der Tippstand bleibt hier, gemeldet wird nur ein vollständiges Datum: jede Änderung ist eine Navigation, und beim Tippen der Jahreszahl entstehen unterwegs 0002, 0020 und 0202 — jede davon lud die Seite neu und setzte das Feld mitten im Tippen zurück. Dieselbe Regel wie in DateField, dort steht auch der lange Grund. */} { const wert = e.target.value; setEntwurf(wert); if (istMeldbaresDatum(wert) && wert !== asOf) setAsOf(wert || undefined); }} onBlur={() => { if (entwurf !== asOf && istMeldbaresDatum(entwurf)) setAsOf(entwurf || undefined); }} className={FILTER_SELECT_CLASS} /> {!isToday && ( )} {isToday ? "Aktuelle Organisationsstruktur." : `Struktur zum ${fmtDate(asOf)}.`}
{isFuture && (

Vorschau: {projectedCount > 0 ? `${projectedCount} geplante Versetzung(en)/Reorganisation(en) sind eingerechnet.` : "Für diesen Zeitraum sind keine Versetzungen vorgemerkt."}{" "} Ein-/Austritte und Karenzen sind berücksichtigt.

)} {beforeHistory && (

Vor dem {fmtDate(historyStartsAt)} wurde die Zuordnungshistorie noch nicht aufgezeichnet. Wer beschäftigt war, stimmt; Team und Vorgesetzte zeigen für diesen Stichtag die heutige Zuordnung.

)}
); }