From 37f55540833c2d5894513eca9fc8f7c6233fc2d2 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 29 May 2025 05:17:13 +0000
Subject: (대표님) 0529 14시 16분 변경사항 저장 (Vendor Data, Docu)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/items/table/items-table.tsx | 161 +++++++++++++++++++++++++++++-----------
 1 file changed, 116 insertions(+), 45 deletions(-)

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

diff --git a/lib/items/table/items-table.tsx b/lib/items/table/items-table.tsx
index 2bc1c913..c05b4348 100644
--- a/lib/items/table/items-table.tsx
+++ b/lib/items/table/items-table.tsx
@@ -9,8 +9,12 @@ import type {
 
 import { useDataTable } from "@/hooks/use-data-table"
 import { DataTable } from "@/components/data-table/data-table"
+import { InfiniteDataTable } from "@/components/data-table/infinite-data-table"
 import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
 import { useFeatureFlags } from "./feature-flags-provider"
+import { Button } from "@/components/ui/button"
+import { RotateCcw, Info } from "lucide-react"
+import { Alert, AlertDescription } from "@/components/ui/alert"
 
 import { getItems } from "../service"
 import { Item } from "@/db/schema/items"
@@ -20,7 +24,7 @@ import { UpdateItemSheet } from "./update-item-sheet"
 import { DeleteItemsDialog } from "./delete-items-dialog"
 
 interface ItemsTableProps {
-  promises: Promise<
+  promises?: Promise<
     [
       Awaited<ReturnType<typeof getItems>>,
     ]
@@ -30,11 +34,11 @@ interface ItemsTableProps {
 export function ItemsTable({ promises }: ItemsTableProps) {
   const { featureFlags } = useFeatureFlags()
 
-  const [{ data, pageCount }] =
-    React.use(promises)
-
-    console.log(data)
+  // 페이지네이션 모드 데이터
+  const paginationData = promises ? React.use(promises) : null
+  const [{ data = [], pageCount = 0 }] = paginationData || [{ data: [], pageCount: 0 }]
 
+  console.log('ItemsTable data:', data.length, 'items')
 
   const [rowAction, setRowAction] =
     React.useState<DataTableRowAction<Item> | null>(null)
@@ -44,17 +48,7 @@ export function ItemsTable({ promises }: ItemsTableProps) {
     [setRowAction]
   )
 
-  /**
-   * This component can render either a faceted filter or a search filter based on the `options` prop.
-   *
-   * @prop options - An array of objects, each representing a filter option. If provided, a faceted filter is rendered. If not, a search filter is rendered.
-   *
-   * Each `option` object has the following properties:
-   * @prop {string} label - The label for the filter option.
-   * @prop {string} value - The value for the filter option.
-   * @prop {React.ReactNode} [icon] - An optional icon to display next to the label.
-   * @prop {boolean} [withCount] - An optional boolean to display the count of the filter option.
-   */
+  // 기존 필터 필드들
   const filterFields: DataTableFilterField<Item>[] = [
     {
       id: "itemCode",
@@ -62,16 +56,6 @@ export function ItemsTable({ promises }: ItemsTableProps) {
     },
   ]
 
-  /**
-   * Advanced filter fields for the data table.
-   * These fields provide more complex filtering options compared to the regular filterFields.
-   *
-   * Key differences from regular filterFields:
-   * 1. More field types: Includes 'text', 'multi-select', 'date', and 'boolean'.
-   * 2. Enhanced flexibility: Allows for more precise and varied filtering options.
-   * 3. Used with DataTableAdvancedToolbar: Enables a more sophisticated filtering UI.
-   * 4. Date and boolean types: Adds support for filtering by date ranges and boolean values.
-   */
   const advancedFilterFields: DataTableAdvancedFilterField<Item>[] = [
     {
       id: "itemLevel",
@@ -130,8 +114,15 @@ export function ItemsTable({ promises }: ItemsTableProps) {
     },
   ]
 
-
-  const { table } = useDataTable({
+  // 확장된 useDataTable 훅 사용 (pageSize 기반 자동 전환)
+  const { 
+    table, 
+    infiniteScroll, 
+    isInfiniteMode, 
+    effectivePageSize,
+    handlePageSizeChange,
+    urlState 
+  } = useDataTable({
     data,
     columns,
     pageCount,
@@ -145,24 +136,104 @@ export function ItemsTable({ promises }: ItemsTableProps) {
     getRowId: (originalRow) => String(originalRow.id),
     shallow: false,
     clearOnDefault: true,
+    // 무한 스크롤 설정
+    infiniteScrollConfig: {
+      apiEndpoint: "/api/table/items/infinite",
+      tableName: "items",
+      maxPageSize: 100,
+    },
   })
 
-  return (
-    <>
-      <DataTable
-        table={table}
-
-      >
-
-        <DataTableAdvancedToolbar
-          table={table}
-          filterFields={advancedFilterFields}
-          shallow={false}
-        >
-          <ItemsTableToolbarActions table={table} />
-        </DataTableAdvancedToolbar>
+  // 새로고침 핸들러
+  const handleRefresh = () => {
+    if (isInfiniteMode && infiniteScroll) {
+      infiniteScroll.refresh()
+    } else {
+      window.location.reload()
+    }
+  }
 
-      </DataTable>
+  return (
+    <div className="w-full space-y-2.5">
+    
+      {/* <div className="flex items-center justify-between">
+        <div className="flex items-center gap-2">
+          <Button
+            variant="outline"
+            size="sm"
+            onClick={handleRefresh}
+            disabled={isInfiniteMode && infiniteScroll?.isLoading}
+          >
+            <RotateCcw className="h-4 w-4 mr-2" />
+            새로고침
+          </Button>
+        </div>
+      </div> */}
+
+      {/* 에러 상태 (무한 스크롤 모드) */}
+      {isInfiniteMode && infiniteScroll?.error && (
+        <Alert variant="destructive">
+          <AlertDescription>
+            데이터를 불러오는 중 오류가 발생했습니다.
+            <Button
+              variant="link"
+              size="sm"
+              onClick={() => infiniteScroll.reset()}
+              className="ml-2 p-0 h-auto"
+            >
+              다시 시도
+            </Button>
+          </AlertDescription>
+        </Alert>
+      )}
+
+      {/* 로딩 상태가 아닐 때만 테이블 렌더링 */}
+      {!(isInfiniteMode && infiniteScroll?.isLoading && infiniteScroll?.isEmpty) ? (
+        <>
+          {/* 도구 모음 */}
+          <DataTableAdvancedToolbar
+            table={table}
+            filterFields={advancedFilterFields}
+            shallow={false}
+          >
+            <ItemsTableToolbarActions table={table} />
+          </DataTableAdvancedToolbar>
+
+          {/* 테이블 렌더링 */}
+          {isInfiniteMode ? (
+            // 무한 스크롤 모드: InfiniteDataTable 사용 (자체 페이지네이션 없음)
+            <InfiniteDataTable
+              table={table}
+              hasNextPage={infiniteScroll?.hasNextPage || false}
+              isLoadingMore={infiniteScroll?.isLoadingMore || false}
+              onLoadMore={infiniteScroll?.loadMore}
+              totalCount={infiniteScroll?.totalCount}
+              isEmpty={infiniteScroll?.isEmpty || false}
+              compact={false}
+              autoSizeColumns={true}
+            />
+          ) : (
+            // 페이지네이션 모드: DataTable 사용 (내장 페이지네이션 활용)
+            <DataTable 
+              table={table}
+              compact={false}
+              autoSizeColumns={true}
+            />
+          )}
+        </>
+      ) : (
+        /* 로딩 스켈레톤 (무한 스크롤 초기 로딩) */
+        <div className="space-y-3">
+          <div className="text-sm text-muted-foreground mb-4">
+            무한 스크롤 모드로 데이터를 로드하고 있습니다...
+          </div>
+          {Array.from({ length: 10 }).map((_, i) => (
+            <div key={i} className="h-12 w-full bg-muted animate-pulse rounded" />
+          ))}
+        </div>
+      )}
+
+      {/* 기존 다이얼로그들 */}
       <UpdateItemSheet
         open={rowAction?.type === "update"}
         onOpenChange={() => setRowAction(null)}
@@ -175,6 +246,6 @@ export function ItemsTable({ promises }: ItemsTableProps) {
         showTrigger={false}
         onSuccess={() => rowAction?.row.toggleSelected(false)}
       />
-    </>
+    </div>
   )
-}
+}
\ No newline at end of file
-- 
cgit v1.2.3

