import { useState, useEffect, type ReactElement } from "react"; import { PrimaryButton, StatusBadge, ActionDropdown, DataTable, Pagination, FilterDropdown, type Column, SupplierModal, ViewSupplierModal, SupplierContactsModal, SupplierScorecardsModal, } from "@/components/shared"; import { Plus, Building2 } from "lucide-react"; import { supplierService } from "@/services/supplier-service"; import type { Supplier } from "@/types/supplier"; import { formatDate } from "@/utils/format-date"; import { useAppTheme } from "@/hooks/useAppTheme"; interface SuppliersTableProps { tenantId?: string | null; showHeader?: boolean; compact?: boolean; } const getStatusVariant = ( status: string, ): "success" | "failure" | "process" | "info" => { switch (status?.toLowerCase()) { case "approved": case "qualified": return "success"; case "pending": case "conditional": return "process"; case "suspended": case "disqualified": return "failure"; default: return "success"; } }; const getCategoryColor = (category: string) => { switch (category?.toLowerCase()) { case "critical": return "bg-red-100 text-red-700"; case "major": return "bg-orange-100 text-orange-700"; case "minor": return "bg-blue-100 text-blue-700"; default: return "bg-gray-100 text-gray-700"; } }; export const SuppliersTable = ({ tenantId, showHeader = true, compact = false, }: SuppliersTableProps): ReactElement => { const { primaryColor } = useAppTheme(); const [suppliers, setSuppliers] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [currentPage, setCurrentPage] = useState(1); const [limit, setLimit] = useState(compact ? 5 : 10); const [total, setTotal] = useState(0); const [statusFilter, setStatusFilter] = useState(null); const [searchQuery, setSearchQuery] = useState(""); // Modal state const [modalOpen, setModalOpen] = useState(false); const [modalMode, setModalMode] = useState<"create" | "edit" | "view">( "create", ); const [selectedSupplierId, setSelectedSupplierId] = useState( null, ); const [selectedSupplierName, setSelectedSupplierName] = useState(""); const [viewModalOpen, setViewModalOpen] = useState(false); const [contactsModalOpen, setContactsModalOpen] = useState(false); const [scorecardsModalOpen, setScorecardsModalOpen] = useState(false); const fetchSuppliers = async () => { try { setIsLoading(true); setError(null); const response = await supplierService.list({ tenantId, status: statusFilter || undefined, search: searchQuery || undefined, limit, offset: (currentPage - 1) * limit, }); if (response.success) { setSuppliers(response.data); setTotal(response.pagination.total); } else { setError("Failed to load suppliers"); } } catch (err: any) { setError( err?.response?.data?.error?.message || "Failed to load suppliers", ); } finally { setIsLoading(false); } }; useEffect(() => { fetchSuppliers(); }, [tenantId, currentPage, limit, statusFilter, searchQuery]); const handleCreate = () => { setModalMode("create"); setSelectedSupplierId(null); setModalOpen(true); }; const handleView = (id: string) => { setSelectedSupplierId(id); setViewModalOpen(true); }; const handleEdit = (id: string) => { setModalMode("edit"); setSelectedSupplierId(id); setModalOpen(true); }; const handleContacts = (id: string, name: string) => { setSelectedSupplierId(id); setSelectedSupplierName(name); setContactsModalOpen(true); }; const handleScorecards = (id: string, name: string) => { setSelectedSupplierId(id); setSelectedSupplierName(name); setScorecardsModalOpen(true); }; const columns: Column[] = [ { key: "name", label: "Supplier", render: (supplier) => (
{supplier.name} {supplier.supplier_code && ( {supplier.supplier_code} )}
), }, { key: "supplier_type", label: "Type", render: (supplier) => ( {supplier.supplier_type.replace(/_/g, " ")} ), }, { key: "category", label: "Category", render: (supplier) => ( {supplier.category} ), }, { key: "status", label: "Status", render: (supplier) => ( {supplier.status} ), }, { key: "location", label: "Location", render: (supplier) => ( {supplier.address?.city ? `${supplier.address.city}, ${supplier.address.country}` : supplier.address?.country || "-"} ), }, { key: "created_at", label: "Dated", render: (supplier) => ( {formatDate(supplier.created_at)} ), }, { key: "actions", label: "Actions", align: "right", render: (supplier) => (
handleView(supplier.id)} onEdit={() => handleEdit(supplier.id)} // onContacts={() => handleContacts(supplier.id, supplier.name)} // onScorecards={() => handleScorecards(supplier.id, supplier.name)} />
), }, ]; const mobileCardRenderer = (supplier: Supplier) => (

{supplier.name}

{supplier.supplier_type}

handleView(supplier.id)} onEdit={() => handleEdit(supplier.id)} onContacts={() => handleContacts(supplier.id, supplier.name)} onScorecards={() => handleScorecards(supplier.id, supplier.name)} />
{supplier.status} {supplier.category}
); return (
{showHeader && (
{ e.currentTarget.style.borderColor = primaryColor; e.currentTarget.style.boxShadow = `0 0 0 2px ${primaryColor}1A`; }} onBlur={(e) => { e.currentTarget.style.borderColor = 'rgba(0,0,0,0.08)'; e.currentTarget.style.boxShadow = 'none'; }} value={searchQuery} onChange={(e) => { setSearchQuery(e.target.value); setCurrentPage(1); }} />
{ setStatusFilter(val as string); setCurrentPage(1); }} />
New Supplier
)}
s.id} isLoading={isLoading} error={error} mobileCardRenderer={mobileCardRenderer} emptyMessage="No suppliers found" /> {total > 0 && (
)}
setModalOpen(false)} mode={modalMode} supplierId={selectedSupplierId} tenantId={tenantId} onSuccess={fetchSuppliers} /> setViewModalOpen(false)} supplierId={selectedSupplierId} tenantId={tenantId} /> setContactsModalOpen(false)} supplierId={selectedSupplierId} supplierName={selectedSupplierName} tenantId={tenantId} /> setScorecardsModalOpen(false)} supplierId={selectedSupplierId} supplierName={selectedSupplierName} tenantId={tenantId} />
); };