"use client"; import { useState, useMemo } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { addDays, format, parseISO } from "date-fns"; import { de } from "date-fns/locale"; import { ArrowLeft, ArrowRight, CalendarCheck2, CalendarDays, ChevronDown, ChevronRight, Stethoscope, } from "lucide-react"; import { AbsenceReason } from "@prisma/client"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { AbsenceTable, type AbsenceTableItem } from "../absence-table"; import { reasonColor, reasonLabel } from "@/lib/absence-utils"; interface AbsencesClientProps { initialAbsences: AbsenceTableItem[]; childCount: number; upcomingAbsenceCount: number; closure: { title: string; type: string } | null; dateKey: string; selectedDateStr: string; isToday: boolean; isTooFarFuture: boolean; isClosedDay: boolean; todayStr: string; error: string | null; } export function AbsencesClient({ initialAbsences, childCount, upcomingAbsenceCount, closure, dateKey, selectedDateStr, isToday, isTooFarFuture, isClosedDay, todayStr, error, }: AbsencesClientProps) { const router = useRouter(); const selectedDate = parseISO(selectedDateStr); const today = parseISO(todayStr); // Filters State const [selectedReason, setSelectedReason] = useState<"all" | AbsenceReason>("all"); // Dropdown UI state const [isReasonOpen, setIsReasonOpen] = useState(false); // Date input state const [inputDate, setInputDate] = useState(dateKey); // Filter computation const filteredAbsences = useMemo(() => { return initialAbsences.filter((item) => { if (selectedReason !== "all" && item.reason !== selectedReason) { return false; } return true; }); }, [initialAbsences, selectedReason]); // Recalculate reasons count based on filtered absences const countsByReason = useMemo(() => { return filteredAbsences.reduce>>((acc, item) => { acc[item.reason] = (acc[item.reason] ?? 0) + 1; return acc; }, {}); }, [filteredAbsences]); const handleDateNavigate = (targetDate: Date) => { const formatted = format(targetDate, "yyyy-MM-dd"); setInputDate(formatted); router.push(`/dashboard/admin/abwesenheiten?date=${formatted}`); }; const handleDateFormSubmit = (e: React.FormEvent) => { e.preventDefault(); if (inputDate) { router.push(`/dashboard/admin/abwesenheiten?date=${inputDate}`); } }; return (

TAGESÜBERSICHT

{isToday ? "Heute" : "An diesem Tag"}{filteredAbsences.length === 1 ? " fehlt " : " fehlen "} {filteredAbsences.length} {filteredAbsences.length === 1 ? "Kind" : "Kinder"}

{format(selectedDate, "EEEE, d. MMMM yyyy", { locale: de })}

{Math.max(0, childCount - initialAbsences.length)} anwesend
setInputDate(e.target.value)} className="w-[140px]" />
{/* Reason Dropdown Filter */}
{isReasonOpen && ( <>
setIsReasonOpen(false)} />
)}
{filteredAbsences.length > 0 ? (
{reasonLabel(AbsenceReason.ILLNESS)} {countsByReason[AbsenceReason.ILLNESS] ?? 0} {reasonLabel(AbsenceReason.OTHER)} {countsByReason[AbsenceReason.OTHER] ?? 0} {reasonLabel(AbsenceReason.VACATION)} {countsByReason[AbsenceReason.VACATION] ?? 0} letzte Aktualisierung {format(new Date(), "HH:mm", { locale: de })}
) : null}
{error ? ( {error} ) : filteredAbsences.length > 0 ? (
{filteredAbsences.length} von {childCount} Kindern abwesend ·{" "} {upcomingAbsenceCount} anstehend {dateKey}
) : isTooFarFuture ? ( ) : isClosedDay ? ( ) : ( )}
); } function EmptyState({ tone, title, description, }: { tone: "good" | "accent"; title: string; description: string; }) { const isGood = tone === "good"; return (
{isGood ? ( ) : ( )}

{title}

{description}

Wochenübersicht öffnen
); }