"use client"; // components/EditEntityModal.tsx // Pre-filled edit form for existing director or company records. // Opens from the Edit button on a table row or from the detail page. // PUT/PATCH via /api/pb/records/:id, invalidates list + detail cache. import { useState, useEffect, useRef } from "react"; import { useQueryClient } from "@tanstack/react-query"; import { pbPatch } from "@/lib/api"; interface Director { id: string; surname?: string | null; first_names?: string | null; id_no?: string | null; telephone?: string | null; email?: string | null; postal_address?: string | null; director_type?: string | null; notes?: string | null; } interface Company { id: string; enterprise_no?: string | null; enterprise_name?: string | null; enterprise_type?: string | null; registration_date?: string | null; physical_address?: string | null; postal_address?: string | null; director?: string | null; notes?: string | null; } interface Props { entity: "director" | "company"; /** Original record data for pre-filling the form */ record: Director | Company; open: boolean; onClose: () => void; /** Called after a successful save */ onAfterSave?: () => void; } export default function EditEntityModal({ entity, record, open, onClose, onAfterSave }: Props) { const qc = useQueryClient(); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const overlayRef = useRef(null); // Director fields const [surname, setSurname] = useState(""); const [firstNames, setFirstNames] = useState(""); const [idNo, setIdNo] = useState(""); const [telephone, setTelephone] = useState(""); const [email, setEmail] = useState(""); const [postalAddress, setPostalAddress] = useState(""); const [directorType, setDirectorType] = useState(""); const [notes, setNotes] = useState(""); // Company fields const [enterpriseNo, setEnterpriseNo] = useState(""); const [enterpriseName, setEnterpriseName] = useState(""); const [enterpriseType, setEnterpriseType] = useState(""); const [registrationDate, setRegistrationDate] = useState(""); const [physicalAddress, setPhysicalAddress] = useState(""); const [postalAddressCo, setPostalAddressCo] = useState(""); const [notesCo, setNotesCo] = useState(""); // Populate form when modal opens or record changes useEffect(() => { if (!open) return; setError(null); if (entity === "director") { const d = record as Director; setSurname(d.surname ?? ""); setFirstNames(d.first_names ?? ""); setIdNo(d.id_no ?? ""); setTelephone(d.telephone ?? ""); setEmail(d.email ?? ""); setPostalAddress(d.postal_address ?? ""); setDirectorType(d.director_type ?? ""); setNotes(d.notes ?? ""); } else { const c = record as Company; setEnterpriseNo(c.enterprise_no ?? ""); setEnterpriseName(c.enterprise_name ?? ""); setEnterpriseType(c.enterprise_type ?? ""); setRegistrationDate(c.registration_date ?? ""); setPhysicalAddress(c.physical_address ?? ""); setPostalAddressCo(c.postal_address ?? ""); setNotesCo(c.notes ?? ""); } }, [open, entity, record]); if (!open) return null; const isDirector = entity === "director"; const title = isDirector ? `Edit director — ${(record as Director).surname}, ${(record as Director).first_names}` : `Edit company — ${(record as Company).enterprise_name}`; const collection = isDirector ? "ysterbaard_directors" : "ysterbaard_companies"; const handleOverlayClick = (e: React.MouseEvent) => { if (e.target === overlayRef.current) onClose(); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setLoading(true); try { const fields: Record = {}; if (isDirector) { if (!surname.trim() || !firstNames.trim()) { setError("Surname and first names are required."); setLoading(false); return; } fields.surname = surname.trim(); fields.first_names = firstNames.trim(); if (idNo.trim()) fields.id_no = idNo.trim(); if (telephone.trim()) fields.telephone = telephone.trim(); if (email.trim()) fields.email = email.trim(); if (postalAddress.trim()) fields.postal_address = postalAddress.trim(); if (directorType.trim()) fields.director_type = directorType.trim(); if (notes.trim()) fields.notes = notes.trim(); } else { if (!enterpriseNo.trim() || !enterpriseName.trim()) { setError("Enterprise number and name are required."); setLoading(false); return; } fields.enterprise_no = enterpriseNo.trim().toUpperCase(); fields.enterprise_name = enterpriseName.trim().toUpperCase(); 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 (postalAddressCo.trim()) fields.postal_address = postalAddressCo.trim(); if (notesCo.trim()) fields.notes = notesCo.trim(); } await pbPatch({ collection, id: record.id, fields }); // Invalidate both list and detail caches await qc.invalidateQueries({ queryKey: ["pb-list", collection] }); await qc.invalidateQueries({ queryKey: ["director", record.id] }); await qc.invalidateQueries({ queryKey: ["company", record.id] }); onAfterSave?.(); onClose(); } catch (err) { setError(err instanceof Error ? err.message : "Something went wrong. Please try again."); } finally { setLoading(false); } }; return (
{/* Header */}

Edit {isDirector ? "director" : "company"}

{title}

{/* Form */}
{error && (
{error}
)} {isDirector ? ( <>
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 focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" required />
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 focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" required />
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 font-mono focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent" maxLength={13} />
setTelephone(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" />
setEmail(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" />