diff options
Diffstat (limited to 'lib/rfqs/tbe-table/vendor-contact')
| -rw-r--r-- | lib/rfqs/tbe-table/vendor-contact/vendor-contact-table-column.tsx | 70 | ||||
| -rw-r--r-- | lib/rfqs/tbe-table/vendor-contact/vendor-contact-table.tsx | 89 |
2 files changed, 159 insertions, 0 deletions
diff --git a/lib/rfqs/tbe-table/vendor-contact/vendor-contact-table-column.tsx b/lib/rfqs/tbe-table/vendor-contact/vendor-contact-table-column.tsx new file mode 100644 index 00000000..fcd0c3fb --- /dev/null +++ b/lib/rfqs/tbe-table/vendor-contact/vendor-contact-table-column.tsx @@ -0,0 +1,70 @@ +"use client" +// Because columns rely on React state/hooks for row actions + +import * as React from "react" +import { ColumnDef, Row } from "@tanstack/react-table" +import { ClientDataTableColumnHeaderSimple } from "@/components/client-data-table/data-table-column-simple-header" +import { formatDate } from "@/lib/utils" +import { Checkbox } from "@/components/ui/checkbox" +import { VendorData } from "./vendor-contact-table" + + +/** getColumns: return array of ColumnDef for 'vendors' data */ +export function getColumns(): ColumnDef<VendorData>[] { + return [ + + // Vendor Name + { + accessorKey: "contactName", + header: ({ column }) => ( + <ClientDataTableColumnHeaderSimple column={column} title="Contact Name" /> + ), + cell: ({ row }) => row.getValue("contactName"), + }, + + // Vendor Code + { + accessorKey: "contactPosition", + header: ({ column }) => ( + <ClientDataTableColumnHeaderSimple column={column} title="Position" /> + ), + cell: ({ row }) => row.getValue("contactPosition"), + }, + + // Status + { + accessorKey: "contactEmail", + header: ({ column }) => ( + <ClientDataTableColumnHeaderSimple column={column} title="Email" /> + ), + cell: ({ row }) => row.getValue("contactEmail"), + }, + + // Country + { + accessorKey: "contactPhone", + header: ({ column }) => ( + <ClientDataTableColumnHeaderSimple column={column} title="Phone" /> + ), + cell: ({ row }) => row.getValue("contactPhone"), + }, + + // Created At + { + accessorKey: "createdAt", + header: ({ column }) => ( + <ClientDataTableColumnHeaderSimple column={column} title="Created At" /> + ), + cell: ({ cell }) => formatDate(cell.getValue() as Date), + }, + + // Updated At + { + accessorKey: "updatedAt", + header: ({ column }) => ( + <ClientDataTableColumnHeaderSimple column={column} title="Updated At" /> + ), + cell: ({ cell }) => formatDate(cell.getValue() as Date), + }, + ] +}
\ No newline at end of file diff --git a/lib/rfqs/tbe-table/vendor-contact/vendor-contact-table.tsx b/lib/rfqs/tbe-table/vendor-contact/vendor-contact-table.tsx new file mode 100644 index 00000000..c079da02 --- /dev/null +++ b/lib/rfqs/tbe-table/vendor-contact/vendor-contact-table.tsx @@ -0,0 +1,89 @@ +'use client' + +import * as React from "react" +import { ClientDataTable } from "@/components/client-data-table/data-table" +import { getColumns } from "./vendor-contact-table-column" +import { DataTableAdvancedFilterField } from "@/types/table" +import { Loader2 } from "lucide-react" +import { useToast } from "@/hooks/use-toast" +import { getVendorContactsByVendorId } from "../../service" + +export interface VendorData { + id: number + contactName: string + contactPosition: string | null + contactEmail: string + contactPhone: string | null + isPrimary: boolean | null + createdAt: Date + updatedAt: Date +} + +interface VendorContactsTableProps { + vendorId: number +} + +export function VendorContactsTable({ vendorId }: VendorContactsTableProps) { + const { toast } = useToast() + + const columns = React.useMemo( + () => getColumns(), + [] + ) + + const [vendorContacts, setVendorContacts] = React.useState<VendorData[]>([]) + const [isLoading, setIsLoading] = React.useState(false) + + React.useEffect(() => { + async function loadVendorContacts() { + setIsLoading(true) + try { + const result = await getVendorContactsByVendorId(vendorId) + if (result.success && result.data) { + // undefined 체크 추가 및 타입 캐스팅 + setVendorContacts(result.data as VendorData[]) + } else { + throw new Error(result.error || "Unknown error occurred") + } + } catch (error) { + console.error("협력업체 연락처 로드 오류:", error) + toast({ + title: "Error", + description: "Failed to load vendor contacts", + variant: "destructive", + }) + } finally { + setIsLoading(false) + } + } + loadVendorContacts() + }, [toast, vendorId]) + + const advancedFilterFields: DataTableAdvancedFilterField<VendorData>[] = [ + { id: "contactName", label: "Contact Name", type: "text" }, + { id: "contactPosition", label: "Posiotion", type: "text" }, + { id: "contactEmail", label: "Email", type: "text" }, + { id: "contactPhone", label: "Phone", type: "text" }, + + + ] + + // If loading, show a flex container that fills the parent and centers the spinner + if (isLoading) { + return ( + <div className="flex h-full w-full items-center justify-center"> + <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" /> + </div> + ) + } + + // Otherwise, show the table + return ( + <ClientDataTable + data={vendorContacts} + columns={columns} + advancedFilterFields={advancedFilterFields} + > + </ClientDataTable> + ) +}
\ No newline at end of file |
