summaryrefslogtreecommitdiff
path: root/lib/po/vendor-table/vendor-po-table.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/po/vendor-table/vendor-po-table.tsx')
-rw-r--r--lib/po/vendor-table/vendor-po-table.tsx247
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