"use client"; import type { ComponentProps, FormEvent } from "react"; import { useEffect, useMemo, useState, useTransition } from "react"; import { TerminType } from "@prisma/client"; import { Plus } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { createTerminAdmin, updateTerminAdmin } from "../actions"; import { Textarea } from "@/components/ui/textarea"; type AdminTerminFormState = { title: string; description: string; type: TerminType; startDate: string; endDate: string; allDay: boolean; }; const initialFormState: AdminTerminFormState = { title: "", description: "", type: TerminType.KITA_FEST, startDate: "", endDate: "", allDay: false, }; type AdminTerminModalProps = { triggerLabel?: string; triggerVariant?: ComponentProps["variant"]; triggerClassName?: string; existingTermin?: { id: string; title: string; description: string | null; type: TerminType; startDate: Date; endDate: Date; allDay: boolean; }; }; export function AdminTerminModal({ triggerLabel = "Termin direkt anlegen", triggerVariant, triggerClassName = "gap-2", existingTermin, }: AdminTerminModalProps) { const [open, setOpen] = useState(false); const [formState, setFormState] = useState(initialFormState); const [isPending, startTransition] = useTransition(); const minDateTime = useMemo(() => getLocalDateTimeInputValue(new Date()), []); const minEndDateTime = formState.startDate || minDateTime; // Initialize and reset form fields when modal opens useEffect(() => { if (open) { if (existingTermin) { // eslint-disable-next-line react-hooks/set-state-in-effect setFormState({ title: existingTermin.title, description: existingTermin.description || "", type: existingTermin.type, startDate: getLocalDateTimeInputValue(existingTermin.startDate), endDate: getLocalDateTimeInputValue(existingTermin.endDate), allDay: existingTermin.allDay, }); } else { setFormState(initialFormState); } } }, [open, existingTermin]); const updateField = ( key: TKey, value: AdminTerminFormState[TKey], ) => { setFormState((current) => { const next = { ...current, [key]: value }; if (key === "startDate" && typeof value === "string" && next.endDate && next.endDate < value) { next.endDate = value; } return next; }); }; const handleSubmit = (event: FormEvent) => { event.preventDefault(); if (!formState.startDate || !formState.endDate) { toast.error("Bitte Start und Ende ausfüllen."); return; } // Only enforce future start date when creating a new event if (!existingTermin && formState.startDate < minDateTime) { toast.error("Der Startzeitpunkt darf nicht in der Vergangenheit liegen."); return; } if (formState.endDate < formState.startDate) { toast.error("Das Ende darf nicht vor dem Start liegen."); return; } const data = { title: formState.title, description: formState.description, type: formState.type, startDate: new Date(formState.startDate).toISOString(), endDate: new Date(formState.endDate).toISOString(), allDay: formState.allDay, }; startTransition(async () => { let res; if (existingTermin) { res = await updateTerminAdmin(existingTermin.id, data); } else { res = await createTerminAdmin(data); } if (res.error) { toast.error(res.error); } else { toast.success( existingTermin ? "Termin wurde erfolgreich aktualisiert!" : "Termin wurde direkt angelegt!" ); if (!existingTermin) { setFormState(initialFormState); } setOpen(false); } }); }; return (
{existingTermin ? "Termin bearbeiten (Admin)" : "Termin anlegen (Admin)"} {existingTermin ? "Nimm Änderungen an diesem Termin vor. Die Änderungen werden sofort wirksam." : "Dieser Termin wird sofort freigegeben und ist für alle sichtbar."}
updateField("title", event.target.value)} />