import { useState, useEffect, type ReactElement } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import { Modal, FormField, PrimaryButton, DataTable, type Column, } from "@/components/shared"; import { Plus, X } from "lucide-react"; import { supplierService } from "@/services/supplier-service"; import type { SupplierContact } from "@/types/supplier"; import { showToast } from "@/utils/toast"; const contactSchema = z.object({ name: z.string().min(2, "Name must be at least 2 characters"), title: z.string().optional().or(z.literal("")), email: z.string().email("Invalid email").optional().or(z.literal("")), phone: z.string().optional().or(z.literal("")), mobile: z.string().optional().or(z.literal("")), is_primary: z.boolean(), }); type ContactFormData = z.infer; interface SupplierContactsModalProps { isOpen: boolean; onClose: () => void; supplierId: string | null; supplierName?: string; tenantId?: string | null; } export const SupplierContactsModal = ({ isOpen, onClose, supplierId, supplierName, tenantId, }: SupplierContactsModalProps): ReactElement => { const [contacts, setContacts] = useState([]); const [isLoading, setIsLoading] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [showAddForm, setShowAddForm] = useState(false); const { register, handleSubmit, reset, formState: { errors }, } = useForm({ resolver: zodResolver(contactSchema), defaultValues: { name: "", title: "", email: "", phone: "", mobile: "", is_primary: false, }, }); const fetchContacts = async () => { if (!supplierId || !isOpen) return; try { setIsLoading(true); const response = await supplierService.getContacts(supplierId, tenantId); if (response.success) { setContacts(response.data); } } catch (error: any) { showToast.error("Failed to load contacts", error?.message); } finally { setIsLoading(false); } }; useEffect(() => { if (isOpen && supplierId) { fetchContacts(); setShowAddForm(false); reset(); } }, [isOpen, supplierId, tenantId]); const onSubmit = async (data: ContactFormData) => { if (!supplierId) return; try { setIsSubmitting(true); const response = await supplierService.addContact(supplierId, data, tenantId); if (response.success) { showToast.success("Contact added successfully"); setShowAddForm(false); reset(); fetchContacts(); } } catch (error: any) { showToast.error("Failed to add contact", error?.message); } finally { setIsSubmitting(false); } }; const columns: Column[] = [ { key: "name", label: "Name", render: (contact) => (
{contact.name} {contact.is_primary && ( Primary )}
), }, { key: "title", label: "Title/Role", render: (contact) => {contact.title || "-"}, }, { key: "email", label: "Email", render: (contact) => {contact.email || "-"}, }, { key: "phone", label: "Phone/Mobile", render: (contact) => (
{contact.phone || "-"} {contact.mobile && {contact.mobile} (M)}
), }, ]; return (
{/* Actions Bar */}

{showAddForm ? "Add New Contact" : "Supplier Contacts"}

{ if (showAddForm) { setShowAddForm(false); reset(); } else { setShowAddForm(true); } }} className="flex items-center gap-2" disabled={isSubmitting} > {showAddForm ? ( <> Cancel ) : ( <> Add Contact )}
{/* Add Form */} {showAddForm && (
{isSubmitting ? "Adding..." : "Save Contact"}
)} {/* List Table */}
c.id} isLoading={isLoading} emptyMessage="No contacts found for this supplier" />
); };