"use client"; import { useMemo, useState } from "react"; import type { FormEvent } from "react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import type { Customer, CustomerPayload, CustomerStatus, CustomerType } from "@/types/customer"; const customerTypes: Array<{ value: CustomerType; label: string }> = [ { value: "company", label: "Unternehmen" }, { value: "private", label: "Privat" }, { value: "public_sector", label: "Öffentlicher Sektor" }, { value: "partner", label: "Partner" }, { value: "supplier", label: "Lieferant" }, ]; const statuses: Array<{ value: CustomerStatus; label: string }> = [ { value: "lead", label: "Lead" }, { value: "active", label: "Aktiv" }, { value: "inactive", label: "Inaktiv" }, { value: "blocked", label: "Gesperrt" }, { value: "archived", label: "Archiviert" }, ]; const emptyCustomer: CustomerPayload = { customer_number: "", company_name: "", legal_name: "", customer_type: "company", status: "lead", industry: "", website: "", email: "", phone: "", tax_number: "", vat_id: "", notes: "", addresses: [ { type: "primary", street: "", postal_code: "", city: "", state: "", country: "Deutschland", is_primary: true, }, ], }; type Props = { open: boolean; customer?: Customer | null; pending?: boolean; serverError?: string; onOpenChange: (open: boolean) => void; onSubmit: (payload: CustomerPayload) => Promise; }; export default function CustomerFormDialog({ open, customer, pending = false, serverError, onOpenChange, onSubmit, }: Props) { const initialForm = customer ? { customer_number: customer.customer_number, company_name: customer.company_name, legal_name: customer.legal_name, customer_type: customer.customer_type, status: customer.status, industry: customer.industry, website: customer.website, email: customer.email, phone: customer.phone, tax_number: customer.tax_number, vat_id: customer.vat_id, notes: customer.notes, addresses: customer.addresses.length > 0 ? customer.addresses.map((address) => ({ type: address.type, street: address.street, postal_code: address.postal_code, city: address.city, state: address.state, country: address.country, is_primary: address.is_primary, })) : emptyCustomer.addresses, } : emptyCustomer; return ( {open && ( onOpenChange(false)} onSubmit={onSubmit} /> )} ); } function CustomerForm({ initialForm, pending, serverError, onCancel, onSubmit, }: { initialForm: CustomerPayload; pending: boolean; serverError?: string; onCancel: () => void; onSubmit: (payload: CustomerPayload) => Promise; }) { const [form, setForm] = useState(initialForm); const errors = useMemo(() => ({ customer_number: form.customer_number.trim() ? "" : "Kundennummer erforderlich", company_name: form.company_name.trim() ? "" : "Firmenname erforderlich", email: !form.email || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email) ? "" : "Gültige E-Mail erforderlich", }), [form.company_name, form.customer_number, form.email]); const valid = Object.values(errors).every((error) => !error); function update(key: K, value: CustomerPayload[K]) { setForm((current) => ({ ...current, [key]: value })); } function updateAddress(index: number, key: keyof CustomerPayload["addresses"][number], value: string | boolean) { setForm((current) => ({ ...current, addresses: current.addresses.map((address, itemIndex) => ( itemIndex === index ? { ...address, [key]: value } : key === "is_primary" && value === true ? { ...address, is_primary: false } : address )), })); } async function handleSubmit(event: FormEvent) { event.preventDefault(); if (!valid) { return; } await onSubmit({ ...form, website: form.website?.trim() || null, email: form.email?.trim() || null, addresses: form.addresses.map((address, index) => ({ ...address, is_primary: address.is_primary || index === 0, })), }); } return (
Kunde {initialForm.customer_number ? "bearbeiten" : "erstellen"} Stammdaten und primäre Adresse des Kunden verwalten.
update("customer_number", event.target.value)} /> update("company_name", event.target.value)} /> update("legal_name", event.target.value)} /> update("industry", event.target.value)} /> update("email", event.target.value)} /> update("phone", event.target.value)} /> update("website", event.target.value)} /> update("vat_id", event.target.value)} />

Primäradresse

{form.addresses.slice(0, 1).map((address, index) => (
updateAddress(index, "street", event.target.value)} /> updateAddress(index, "postal_code", event.target.value)} /> updateAddress(index, "city", event.target.value)} /> updateAddress(index, "country", event.target.value)} />
))}
update("notes", event.target.value)} /> {serverError &&

{serverError}

}
); } function Field({ label, error, children, }: { label: string; error?: string; children: React.ReactNode; }) { return (
{children} {error &&

{error}

}
); }