From f72142f6cc46c7be5bf90803d365c2ecd144c53d Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 1 Sep 2025 10:22:55 +0000
Subject: (김준회) MDG 자재마스터 정보 조회 기능 및 메뉴 추가, 회원가입시
 공급품목 선택 기능 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/material/table/material-table.tsx | 199 ++++++++++++++++++++++++++++++++++
 1 file changed, 199 insertions(+)
 create mode 100644 lib/material/table/material-table.tsx

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

diff --git a/lib/material/table/material-table.tsx b/lib/material/table/material-table.tsx
new file mode 100644
index 00000000..6870a030
--- /dev/null
+++ b/lib/material/table/material-table.tsx
@@ -0,0 +1,199 @@
+"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 { InfiniteDataTable } from "@/components/data-table/infinite-data-table"
+import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
+import { Button } from "@/components/ui/button"
+import { Alert, AlertDescription } from "@/components/ui/alert"
+
+import { getMaterials } from "../services"
+import { getColumns } from "./material-table-columns"
+import { MaterialDetailDialog } from "./material-detail-dialog"
+import { ViewModeToggle } from "@/components/data-table/view-mode-toggle"
+
+// Material 타입 정의 (서비스에서 반환되는 타입과 일치)
+type Material = {
+  id: number;
+  MATKL: string | null;    // 자재그룹(=자재그룹코드)
+  MATNR: string | null;    // 자재코드
+  ZZNAME: string | null;   // 자재명
+  ZZPJT: string | null;    // 프로젝트
+  createdAt: Date;
+  updatedAt: Date;
+}
+
+interface MaterialTableProps {
+  promises?: Promise<
+    [
+      Awaited<ReturnType<typeof getMaterials>>,
+    ]
+  >
+}
+
+export function MaterialTable({ promises }: MaterialTableProps) {
+  // 페이지네이션 모드 데이터
+  const paginationData = promises ? React.use(promises) : null
+  const [{ data = [], pageCount = 0 }] = paginationData || [{ data: [], pageCount: 0 }]
+
+  console.log('MaterialTable data:', data.length, 'materials')
+
+  const [rowAction, setRowAction] =
+    React.useState<DataTableRowAction<Material> | null>(null)
+
+  const columns = React.useMemo(
+    () => getColumns({ setRowAction }),
+    [setRowAction]
+  )
+
+  // 기존 필터 필드들
+  const filterFields: DataTableFilterField<Material>[] = [
+    {
+      id: "MATKL",
+      label: "자재그룹",
+    },
+    {
+      id: "MATNR",
+      label: "자재코드",
+    },
+  ]
+
+  const advancedFilterFields: DataTableAdvancedFilterField<Material>[] = [
+    {
+      id: "MATKL",
+      label: "자재그룹",
+      type: "text",
+    },
+    {
+      id: "MATNR",
+      label: "자재코드",
+      type: "text",
+    },
+    {
+      id: "ZZNAME",
+      label: "자재명",
+      type: "text",
+    },
+    {
+      id: "ZZPJT",
+      label: "프로젝트",
+      type: "text",
+    },
+  ]
+
+  // 확장된 useDataTable 훅 사용 (pageSize 기반 자동 전환)
+  const {
+    table,
+    infiniteScroll,
+    isInfiniteMode,
+    handlePageSizeChange,
+  } = useDataTable({
+    data,
+    columns,
+    pageCount,
+    filterFields,
+    enablePinning: true,
+    enableAdvancedFilter: true,
+          initialState: {
+        sorting: [{ id: "createdAt", desc: true }],
+        columnPinning: { left: ["select"], right: ["actions"] },
+      },
+    getRowId: (originalRow) => String(originalRow.id),
+    shallow: false,
+    clearOnDefault: true,
+    // 무한 스크롤 설정
+    infiniteScrollConfig: {
+      apiEndpoint: "/api/table/materials/infinite",
+      tableName: "materials",
+      maxPageSize: 100,
+    },
+  })
+
+  return (
+    <div className="w-full space-y-2.5 overflow-x-auto" style={{maxWidth:'100vw'}}>
+
+        {/* 모드 토글 */}
+        <div className="flex items-center justify-between">
+          <ViewModeToggle
+            isInfiniteMode={isInfiniteMode}
+            onSwitch={handlePageSizeChange}
+          />
+        </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}
+            />
+
+            {/* 테이블 렌더링 */}
+            {isInfiniteMode ? (
+              // 무한 스크롤 모드: InfiniteDataTable 사용
+              <InfiniteDataTable
+                table={table}
+                hasNextPage={infiniteScroll?.hasNextPage || false}
+                isLoadingMore={infiniteScroll?.isLoadingMore || false}
+                onLoadMore={infiniteScroll?.onLoadMore}
+                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>
+        )}
+
+        {/* 상세보기 다이얼로그 */}
+        <MaterialDetailDialog
+          open={rowAction?.type === "view"}
+          onOpenChange={() => setRowAction(null)}
+          matnr={rowAction?.row.original?.MATNR || null}
+        />
+      </div>
+      )
+}
-- 
cgit v1.2.3

