From 14f61e24947fb92dd71ec0a7196a6e815f8e66da Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 21 Jul 2025 07:54:26 +0000
Subject: (최겸)기술영업 RFQ 담당자 초대, 요구사항 반영
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../possible-items/possible-items-table.tsx        | 171 +++++++++++++++++++++
 1 file changed, 171 insertions(+)
 create mode 100644 lib/tech-vendors/possible-items/possible-items-table.tsx

(limited to 'lib/tech-vendors/possible-items/possible-items-table.tsx')

diff --git a/lib/tech-vendors/possible-items/possible-items-table.tsx b/lib/tech-vendors/possible-items/possible-items-table.tsx
new file mode 100644
index 00000000..9c024a93
--- /dev/null
+++ b/lib/tech-vendors/possible-items/possible-items-table.tsx
@@ -0,0 +1,171 @@
+"use client"
+
+import * as React from "react"
+import type {
+  DataTableAdvancedFilterField,
+  DataTableFilterField,
+  DataTableRowAction,
+} from "@/types/table"
+import { toast } from "sonner"
+
+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 {
+  AlertDialog,
+  AlertDialogAction,
+  AlertDialogCancel,
+  AlertDialogContent,
+  AlertDialogDescription,
+  AlertDialogFooter,
+  AlertDialogHeader,
+  AlertDialogTitle,
+} from "@/components/ui/alert-dialog"
+
+import { getColumns } from "./possible-items-columns"
+import {
+  getTechVendorPossibleItems,
+  deleteTechVendorPossibleItem,
+} from "../service"
+import type { TechVendorPossibleItem } from "../validations"
+import { PossibleItemsTableToolbarActions } from "./possible-items-toolbar-actions"
+import { AddItemDialog } from "./add-item-dialog"
+
+interface TechVendorPossibleItemsTableProps {
+  promises: Promise<
+    [
+      Awaited<ReturnType<typeof getTechVendorPossibleItems>>,
+    ]
+  >
+  vendorId: number
+}
+
+export function TechVendorPossibleItemsTable({ 
+  promises, 
+  vendorId,
+}: TechVendorPossibleItemsTableProps) {
+  // Suspense로 받아온 데이터
+  const [{ data, pageCount }] = React.use(promises)
+  const [rowAction, setRowAction] = React.useState<DataTableRowAction<TechVendorPossibleItem> | null>(null)
+  const [showAddDialog, setShowAddDialog] = React.useState(false)
+  const [showDeleteAlert, setShowDeleteAlert] = React.useState(false)
+  const [isDeleting, setIsDeleting] = React.useState(false)
+
+  // getColumns() 호출 시, setRowAction을 주입
+  const columns = React.useMemo(
+    () => getColumns({ setRowAction }),
+    [setRowAction]
+  )
+
+  // 단일 아이템 삭제 핸들러
+  async function handleDeleteItem() {
+    if (!rowAction || rowAction.type !== "delete") return
+
+    setIsDeleting(true)
+    try {
+      const { success, error } = await deleteTechVendorPossibleItem(
+        rowAction.row.original.id, 
+        vendorId
+      )
+      
+      if (!success) {
+        throw new Error(error)
+      }
+
+      toast.success("아이템이 삭제되었습니다")
+      setShowDeleteAlert(false)
+      setRowAction(null)
+    } catch (err) {
+      toast.error(err instanceof Error ? err.message : "아이템 삭제 중 오류가 발생했습니다")
+    } finally {
+      setIsDeleting(false)
+    }
+  }
+
+  const filterFields: DataTableFilterField<TechVendorPossibleItem>[] = [
+    { id: "itemCode", label: "아이템 코드" },
+    { id: "workType", label: "공종" },
+  ]
+
+  const advancedFilterFields: DataTableAdvancedFilterField<TechVendorPossibleItem>[] = [
+    { id: "itemCode", label: "아이템 코드", type: "text" },
+    { id: "workType", label: "공종", type: "text" },
+    { id: "itemList", label: "아이템명", type: "text" },
+    { id: "shipTypes", label: "선종", type: "text" },
+    { id: "subItemList", label: "서브아이템", type: "text" },
+    { id: "createdAt", label: "등록일", type: "date" },
+    { id: "updatedAt", label: "수정일", type: "date" },
+  ]
+
+  const { table } = useDataTable({
+    data,
+    columns,
+    pageCount,
+    filterFields,
+    enablePinning: true,
+    enableAdvancedFilter: true,
+    initialState: {
+      sorting: [{ id: "createdAt", desc: true }],
+      columnPinning: { right: ["actions"] },
+    },
+    getRowId: (originalRow) => String(originalRow.id),
+    shallow: false,
+    clearOnDefault: true,
+  })
+
+  // rowAction 상태 변경 감지
+  React.useEffect(() => {
+    if (rowAction?.type === "delete") {
+      setShowDeleteAlert(true)
+    }
+  }, [rowAction])
+
+  return (
+    <>
+      <DataTable table={table}>
+        <DataTableAdvancedToolbar
+          table={table}
+          filterFields={advancedFilterFields}
+          shallow={false}
+        >
+          <PossibleItemsTableToolbarActions 
+            table={table} 
+            vendorId={vendorId}
+            onAdd={() => setShowAddDialog(true)}
+          />
+        </DataTableAdvancedToolbar>
+      </DataTable>
+
+      {/* Add Item Dialog */}
+      <AddItemDialog
+        open={showAddDialog}
+        onOpenChange={setShowAddDialog}
+        vendorId={vendorId}
+      />
+
+      {/* Delete Confirmation Dialog */}
+      <AlertDialog open={showDeleteAlert} onOpenChange={setShowDeleteAlert}>
+        <AlertDialogContent>
+          <AlertDialogHeader>
+            <AlertDialogTitle>아이템 삭제</AlertDialogTitle>
+            <AlertDialogDescription>
+              이 아이템을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.
+            </AlertDialogDescription>
+          </AlertDialogHeader>
+          <AlertDialogFooter>
+            <AlertDialogCancel onClick={() => setRowAction(null)}>
+              취소
+            </AlertDialogCancel>
+            <AlertDialogAction 
+              onClick={handleDeleteItem}
+              disabled={isDeleting}
+              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
+            >
+              {isDeleting ? "삭제 중..." : "삭제"}
+            </AlertDialogAction>
+          </AlertDialogFooter>
+        </AlertDialogContent>
+      </AlertDialog>
+    </>
+  )
+} 
\ No newline at end of file
-- 
cgit v1.2.3

