diff options
Diffstat (limited to 'lib/po/vendor-table/vendor-po-table.tsx')
| -rw-r--r-- | lib/po/vendor-table/vendor-po-table.tsx | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/lib/po/vendor-table/vendor-po-table.tsx b/lib/po/vendor-table/vendor-po-table.tsx new file mode 100644 index 00000000..a3ad4949 --- /dev/null +++ b/lib/po/vendor-table/vendor-po-table.tsx @@ -0,0 +1,247 @@ +"use client" + +import * as React from "react" +import type { + DataTableAdvancedFilterField, + DataTableFilterField, + DataTableRowAction, +} from "@/types/table" + +import { useDataTable } from "@/hooks/use-data-table" +import { DataTable } from "@/components/data-table/data-table" +import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar" +import { toast } from "sonner" + +import { getVendorPOs, handleVendorPOAction } from "./service" +import { getVendorColumns } from "./vendor-po-columns" +import { VendorPO, VendorPOActionType } from "./types" +import { VendorPOItemsDialog } from "./vendor-po-items-dialog" +import { VendorPOToolbarActions } from "./vendor-po-toolbar-actions" + +interface VendorPoTableProps { + promises: Promise< + [ + Awaited<ReturnType<typeof getVendorPOs>>, + ] + > +} + +export function VendorPoTable({ promises }: VendorPoTableProps) { + const [data, setData] = React.useState<{ + data: VendorPO[]; + pageCount: number; + }>({ data: [], pageCount: 0 }); + + const [selectedRows, setSelectedRows] = React.useState<number[]>([]) + + // 데이터 로딩 + React.useEffect(() => { + promises.then(([result]) => { + console.log("Vendor PO data:", result.data) + setData(result); + }); + }, [promises]); + + const [rowAction, setRowAction] = + React.useState<DataTableRowAction<VendorPO> | null>(null) + + // 다이얼로그 상태 + const [itemsDialogOpen, setItemsDialogOpen] = React.useState(false) + const [selectedPO, setSelectedPO] = React.useState<VendorPO | null>(null) + + // 행 선택 처리 (1개만 선택 가능) + const handleRowSelect = (id: number, selected: boolean) => { + if (selected) { + setSelectedRows([id]) // 1개만 선택 + } else { + setSelectedRows([]) + } + } + + // 행 액션 처리 + React.useEffect(() => { + if (!rowAction) return + + const po = rowAction.row.original + setSelectedPO(po) + + switch (rowAction.type as VendorPOActionType) { + case "view-items": + setItemsDialogOpen(true) + break + case "pcr-create": + handleAction(po.id, "pcr-create") + break + case "approve": + handleAction(po.id, "approve") + break + case "cancel-approve": + handleAction(po.id, "cancel-approve") + break + case "reject-contract": + handleAction(po.id, "reject-contract") + break + case "print-contract": + handleAction(po.id, "print-contract") + break + case "item-status": + setItemsDialogOpen(true) + break + case "contract-detail": + toast.info("계약상세 기능은 개발 중입니다.") + break + case "po-note": + toast.info("PO Note 기능은 개발 중입니다.") + break + case "price-index": + toast.info("연동표입력 기능은 개발 중입니다.") + break + default: + toast.info("해당 기능은 개발 중입니다.") + } + + setRowAction(null) + }, [rowAction]) + + // 액션 처리 함수 + const handleAction = async (poId: number, action: string) => { + try { + const result = await handleVendorPOAction(poId, action) + if (result.success) { + toast.success(result.message) + // 필요시 데이터 새로고침 + } else { + toast.error(result.message) + } + } catch (error) { + console.error("Action error:", error) + toast.error("액션 처리 중 오류가 발생했습니다.") + } + } + + const columns = React.useMemo( + () => getVendorColumns({ + setRowAction, + selectedRows, + onRowSelect: handleRowSelect + }), + [selectedRows] + ) + + const filterFields: DataTableFilterField<VendorPO>[] = [ + { + id: "contractStatus", + label: "계약상태", + options: [ + { label: "승인대기", value: "승인대기" }, + { label: "계약완료", value: "계약완료" }, + { label: "진행중", value: "진행중" }, + { label: "수정요청", value: "수정요청" }, + { label: "거절됨", value: "거절됨" }, + ] + }, + { + id: "contractType", + label: "계약종류", + options: [ + { label: "구매계약", value: "구매계약" }, + { label: "서비스계약", value: "서비스계약" }, + { label: "임가공계약", value: "임가공계약" }, + ] + }, + { + id: "currency", + label: "계약통화", + options: [ + { label: "KRW", value: "KRW" }, + { label: "USD", value: "USD" }, + { label: "EUR", value: "EUR" }, + { label: "JPY", value: "JPY" }, + ] + } + ] + + const advancedFilterFields: DataTableAdvancedFilterField<VendorPO>[] = [ + { + id: "contractNo", + label: "PO/계약번호", + type: "text", + }, + { + id: "contractName", + label: "계약명/자재내역", + type: "text", + }, + { + id: "projectName", + label: "프로젝트", + type: "text", + }, + { + id: "purchaseManager", + label: "구매/계약담당", + type: "text", + }, + { + id: "poReceiveDate", + label: "PO/계약수신일", + type: "date", + }, + { + id: "contractDate", + label: "계약체결일", + type: "date", + }, + { + id: "lastModifiedDate", + label: "최종수정일", + type: "date", + }, + ] + + const { table } = useDataTable({ + data: data.data, + columns, + pageCount: data.pageCount, + filterFields, + enablePinning: true, + enableAdvancedFilter: true, + initialState: { + sorting: [{ id: "lastModifiedDate", desc: true }], + columnPinning: { right: ["actions"] }, + }, + getRowId: (originalRow) => String(originalRow.id), + shallow: false, + clearOnDefault: true, + }) + + return ( + <> + <DataTable + table={table} + > + <DataTableAdvancedToolbar + table={table} + filterFields={advancedFilterFields} + shallow={false} + > + <VendorPOToolbarActions + table={table} + selectedRows={selectedRows} + onAction={handleAction} + onViewItems={(po) => { + setSelectedPO(po) + setItemsDialogOpen(true) + }} + /> + </DataTableAdvancedToolbar> + </DataTable> + + <VendorPOItemsDialog + open={itemsDialogOpen} + onOpenChange={setItemsDialogOpen} + po={selectedPO} + /> + </> + ) +}
\ No newline at end of file |
