"use client"; // components/AddEntityModal.tsx // Shared modal for adding a new client director or company. // Opens on "Add Director" / "Add Company" button click. // On submit: POSTs to /api/pb/records/create, invalidates the // relevant list query, shows success toast, closes modal. import { useState, useEffect, useRef } from "react"; import { useQueryClient } from "@tanstack/react-query"; import { pbCreateClient } from "@/lib/api"; import { pbList } from "@/lib/api"; interface Props { /** "director" | "company" */ entity: "director" | "company"; /** Controlled open state (passed from parent) */ open: boolean; /** Called when modal requests to close (user dismissed or success) */ onClose: () => void; } interface Director { id: string; surname: string; first_names: string; id_no: string; } export default function AddEntityModal({ entity, open, onClose }: Props) { const qc = useQueryClient(); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const overlayRef = useRef(null); // Director form state const [surname, setSurname] = useState(""); const [firstNames, setFirstNames] = useState(""); const [idNo, setIdNo] = useState(""); const [telephone, setTelephone] = useState(""); const [email, setEmail] = useState(""); // Company form state const [enterpriseNo, setEnterpriseNo] = useState(""); const [enterpriseName, setEnterpriseName] = useState(""); const [enterpriseType, setEnterpriseType] = useState(""); const [registrationDate, setRegistrationDate] = useState(""); const [physicalAddress, setPhysicalAddress] = useState(""); const [postalAddress, setPostalAddress] = useState(""); const [selectedDirectorId, setSelectedDirectorId] = useState(""); // Directors list for company form dropdown const [directors, setDirectors] = useState([]); // Reset form whenever modal opens useEffect(() => { if (open) { setSurname(""); setFirstNames(""); setIdNo(""); setTelephone(""); setEmail(""); setEnterpriseNo(""); setEnterpriseName(""); setEnterpriseType(""); setRegistrationDate(""); setPhysicalAddress(""); setPostalAddress(""); setSelectedDirectorId(""); setError(null); } }, [open]); // Load directors list when opening the company form useEffect(() => { if (open && entity === "company") { pbList({ collection: "ysterbaard_directors", perPage: 500, sort: "surname", fields: "id,surname,first_names,id_no", }).then((r) => setDirectors(r.items)).catch(() => {}); } }, [open, entity]); if (!open) return null; const handleOverlayClick = (e: React.MouseEvent) => { if (e.target === overlayRef.current) onClose(); }; const isDirector = entity === "director"; const title = isDirector ? "Add new client director" : "Add new client company"; const subtitle = isDirector ? "Fill in the details. The director will be saved with is_client=true." : "Fill in the details. The company will be saved with is_client=true."; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setLoading(true); try { if (isDirector) { if (!surname.trim() || !firstNames.trim()) { setError("Surname and first names are required."); setLoading(false); return; } const fields: Record = { surname: surname.trim(), first_names: firstNames.trim(), source: "app", }; if (idNo.trim()) fields.id_no = idNo.trim(); if (telephone.trim()) fields.telephone = telephone.trim(); if (email.trim()) fields.email = email.trim(); await pbCreateClient({ collection: "ysterbaard_directors", fields }); await qc.invalidateQueries({ queryKey: ["pb-list", "ysterbaard_directors"] }); } else { if (!enterpriseNo.trim() || !enterpriseName.trim()) { setError("Enterprise number and name are required."); setLoading(false); return; } const fields: Record = { enterprise_no: enterpriseNo.trim().toUpperCase(), enterprise_name: enterpriseName.trim().toUpperCase(), source: "app", }; if (enterpriseType.trim()) fields.enterprise_type = enterpriseType.trim(); if (registrationDate.trim()) fields.registration_date = registrationDate.trim(); if (physicalAddress.trim()) fields.physical_address = physicalAddress.trim(); if (postalAddress.trim()) fields.postal_address = postalAddress.trim(); if (selectedDirectorId) fields.director = selectedDirectorId; await pbCreateClient({ collection: "ysterbaard_companies", fields }); await qc.invalidateQueries({ queryKey: ["pb-list", "ysterbaard_companies"] }); } onClose(); } catch (err) { setError(err instanceof Error ? err.message : "Something went wrong. Please try again."); } finally { setLoading(false); } }; return (
{/* Header */}

{title}

{subtitle}

{/* Form */}
{error && (
{error}
)} {isDirector ? ( <> {/* Surname */}
setSurname(e.target.value.toUpperCase())} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="e.g. JONES" required />
{/* First names */}
setFirstNames(e.target.value.toUpperCase())} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="e.g. PETER JOHANNES" required />
{/* ID number */}
setIdNo(e.target.value.replace(/\D/g, "").slice(0, 13))} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent font-mono" placeholder="13 digits" maxLength={13} />
{/* Telephone */}
setTelephone(e.target.value)} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="0821234567" />
{/* Email */}
setEmail(e.target.value)} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="director@example.com" />
) : ( <> {/* Enterprise number */}
setEnterpriseNo(e.target.value.toUpperCase())} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg font-mono placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="K2022808158" required />
{/* Enterprise name */}
setEnterpriseName(e.target.value.toUpperCase())} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="ABC TRADING PTY LTD" required />
{/* Enterprise type */}
setEnterpriseType(e.target.value)} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" placeholder="Private Company" />
{/* Registration date */}
setRegistrationDate(e.target.value)} className="w-full rounded-lg border border-border bg-surface-warm px-3 py-2.5 text-sm text-fg focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" />
{/* Physical address */}