"use client"; import { useState, useTransition } from "react"; import { BellRing, Loader2 } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { checkAndSendDutyReminders, upsertDutyAssignment, } from "./actions"; const UNASSIGNED = "__unassigned__"; export type DutyPlanWeekDto = { key: string; label: string; startDate: string; endDate: string; }; export type DutyPlanDutyTypeDto = { id: string; name: string; description: string | null; }; export type DutyPlanFamilyDto = { id: string; name: string; }; export type DutyPlanAssignmentDto = { id: string; dutyTypeId: string; familyId: string; startDate: string; }; export function DutyPlanner({ weeks, dutyTypes, families, assignments, }: { weeks: DutyPlanWeekDto[]; dutyTypes: DutyPlanDutyTypeDto[]; families: DutyPlanFamilyDto[]; assignments: DutyPlanAssignmentDto[]; }) { const [isPending, startTransition] = useTransition(); const [pendingCell, setPendingCell] = useState(null); const assignmentByCell = new Map( assignments.map((assignment) => [ `${assignment.startDate}:${assignment.dutyTypeId}`, assignment, ]), ); function handleAssignmentChange( week: DutyPlanWeekDto, dutyTypeId: string, value: string, ) { const cellKey = `${week.startDate}:${dutyTypeId}`; setPendingCell(cellKey); startTransition(async () => { const result = await upsertDutyAssignment({ dutyTypeId, familyId: value === UNASSIGNED ? null : value, startDate: week.startDate, endDate: week.endDate, }); if (result.error) { toast.error(result.error); } else { toast.success( value === UNASSIGNED ? "Zuweisung entfernt" : "Dienstplan aktualisiert", ); } setPendingCell(null); }); } function sendReminders() { startTransition(async () => { const result = await checkAndSendDutyReminders(); if (result.error) { toast.error(result.error); return; } toast.success( `Erinnerungen versendet: ${result.sent ?? 0}. Ohne Empfaenger: ${ result.skipped ?? 0 }.`, ); if (result.errors?.length) { toast.warning(`${result.errors.length} Erinnerung(en) fehlgeschlagen.`); } }); } if (dutyTypes.length === 0) { return (

Noch keine Diensttypen

Lege zuerst einen Diensttyp an, danach erscheint hier das Planungsgrid.

); } return (
{dutyTypes.map((dutyType) => ( ))} {weeks.map((week) => ( {dutyTypes.map((dutyType) => { const cellKey = `${week.startDate}:${dutyType.id}`; const currentAssignment = assignmentByCell.get(cellKey); return ( ); })} ))}
Woche
{dutyType.name}
{dutyType.description && (
{dutyType.description}
)}
{week.label}
); }