"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useMemo, useState } from "react"; import { useForm, useWatch } from "react-hook-form"; import { z } from "zod/v4"; import { campaignFormDefaults, campaignFormSchema, mapCampaignFormToPayload, } from "@/lib/campaign-form"; import { Button } from "@/components/ui/button"; import { Dialog, DialogCloseButton, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; type CampaignFormValues = z.infer; type CampaignFormSeed = Partial & { _id?: string; }; type CampaignFormDialogProps = { open: boolean; onOpenChange: (open: boolean) => void; campaign?: CampaignFormSeed | null; onSubmit: ( payload: Omit & Required> & { countryCode: "DE"; country: "Deutschland"; }, ) => Promise; }; const categoryOptions = [ "Anwalt", "Bauunternehmen", "Friseur", "Gastronomie", "Handwerk", "Immobilien", "Kfz-Werkstatt", "Marketing", "Restaurant", "Zahnarzt", "Anderes", ] as const; const recurrenceOptions: Record = { manual: "manuell", daily: "täglich", weekly: "wöchentlich", monthly: "monatlich", }; const statusLabel: Record = { active: "Aktiv", paused: "Pausiert", }; const customCategoryValue = "Anderes"; export function CampaignFormDialog({ open, onOpenChange, campaign, onSubmit, }: CampaignFormDialogProps) { const [pending, setPending] = useState(false); const [error, setError] = useState(null); const methods = useForm({ resolver: zodResolver(campaignFormSchema), defaultValues: campaignFormDefaults, }); const { control, reset, setValue, formState: { isSubmitting }, } = methods; const selectedCategory = useWatch({ control, name: "category", defaultValue: campaignFormDefaults.category, }); const selectedStatus = useWatch({ control, name: "status", defaultValue: campaignFormDefaults.status, }); const showCustomSearch = selectedCategory === customCategoryValue; useEffect(() => { const defaults = campaign ? { status: campaign.status ?? campaignFormDefaults.status, categoryMode: campaign.categoryMode ?? campaignFormDefaults.categoryMode, recurrence: campaign.recurrence ?? campaignFormDefaults.recurrence, radiusKm: campaign.radiusKm ?? campaignFormDefaults.radiusKm, maxNewLeadsPerRun: campaign.maxNewLeadsPerRun ?? campaignFormDefaults.maxNewLeadsPerRun, maxAuditsPerRun: campaign.maxAuditsPerRun ?? campaignFormDefaults.maxAuditsPerRun, name: campaign.name ?? "", category: campaign.category ?? "", customSearchTerm: campaign.customSearchTerm ?? "", postalCode: campaign.postalCode ?? campaignFormDefaults.postalCode, } : campaignFormDefaults; reset(defaults); }, [campaign, reset]); useEffect(() => { if (showCustomSearch) { setValue("categoryMode", "custom"); return; } setValue("categoryMode", "preset"); setValue("customSearchTerm", ""); }, [showCustomSearch, setValue]); const dialogTitle = useMemo( () => (campaign ? "Kampagne bearbeiten" : "Kampagne anlegen"), [campaign], ); const submitLabel = useMemo( () => (campaign ? "Speichern" : "Erstellen"), [campaign], ); const submitForm = async (values: CampaignFormValues) => { setPending(true); setError(null); try { const payload = mapCampaignFormToPayload(values as Record); await onSubmit({ ...payload, status: values.status, categoryMode: values.categoryMode, category: values.category, customSearchTerm: values.customSearchTerm || undefined, postalCode: values.postalCode, radiusKm: values.radiusKm, recurrence: values.recurrence, maxNewLeadsPerRun: values.maxNewLeadsPerRun, maxAuditsPerRun: values.maxAuditsPerRun, name: values.name, }); onOpenChange(false); } catch { setError("Speichern fehlgeschlagen."); } finally { setPending(false); } }; return ( {dialogTitle} Wähle Kategorie, PLZ, Radius und Lead-Limit je Kampagne.
( Name )} /> ( Kategorie )} /> {showCustomSearch && ( ( Eigene Nische )} /> )}
( PLZ )} /> ( Radius (km) { const value = Number(event.target.value); field.onChange(Number.isFinite(value) ? value : 0); }} /> )} />
( Wiederholung )} /> ( Max. neue Leads { const value = Number(event.target.value); field.onChange(Number.isFinite(value) ? value : 0); }} /> )} /> ( Status
field.onChange(checked ? "active" : "paused") } /> {statusLabel[selectedStatus ?? "paused"]}
)} /> {error ?

{error}

: null}
); }