"use client" import * as React from "react" import { useRouter } from "next/navigation" import type { DataTableAdvancedFilterField, DataTableFilterField, DataTableRowAction, } from "@/types/table" import { cn } from "@/lib/utils" import { PanelLeftClose, PanelLeftOpen } from "lucide-react" 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 { Button } from "@/components/ui/button" import { getColumns } from "./tech-vendors-table-columns" import { getTechVendors, getTechVendorStatusCounts } from "../service" import { TechVendor, techVendors, TechVendorWithAttachments } from "@/db/schema/techVendors" import { TechVendorsTableToolbarActions } from "./tech-vendors-table-toolbar-actions" import { UpdateVendorSheet } from "./update-vendor-sheet" import { getVendorStatusIcon } from "../utils" import { TechVendorsFilterSheet } from "./tech-vendors-filter-sheet" // import { ViewTechVendorLogsDialog } from "./view-tech-vendors-logs-dialog" // 필터 패널 관련 상수 const FILTER_PANEL_WIDTH = 400; const LAYOUT_HEADER_HEIGHT = 60; const LOCAL_HEADER_HEIGHT = 60; const FIXED_FILTER_HEIGHT = "calc(100vh - 120px)"; interface TechVendorsTableProps { promises: Promise< [ Awaited>, Awaited> ] > className?: string; calculatedHeight?: string; } export function TechVendorsTable({ promises, className, calculatedHeight }: TechVendorsTableProps) { // Suspense로 받아온 데이터 const [{ data, pageCount }, statusCounts] = React.use(promises) const [isCompact, setIsCompact] = React.useState(false) const [rowAction, setRowAction] = React.useState | null>(null) // 필터 패널 상태 const [isFilterPanelOpen, setIsFilterPanelOpen] = React.useState(false) // **router** 획득 const router = useRouter() // getColumns() 호출 시, router를 주입 // 임시 삭제 버튼 추가 const columns = React.useMemo( () => getColumns({ setRowAction, router, onVendorDeleted: () => router.refresh() }), [setRowAction, router] ) // 상태 한글 변환 유틸리티 함수 const getStatusDisplay = (status: string): string => { const statusMap: Record = { "ACTIVE": "활성 상태", "INACTIVE": "비활성 상태", "BLACKLISTED": "거래 금지", "PENDING_INVITE": "초대 대기", "INVITED": "초대 완료", "QUOTE_COMPARISON": "견적 비교", }; return statusMap[status] || status; }; const filterFields: DataTableFilterField[] = [ { id: "status", label: "상태", options: techVendors.status.enumValues.map((status) => ({ label: getStatusDisplay(status), value: status, count: statusCounts[status], })), }, { id: "vendorCode", label: "업체 코드" }, ] const advancedFilterFields: DataTableAdvancedFilterField[] = [ { id: "vendorName", label: "업체명", type: "text" }, { id: "vendorCode", label: "업체코드", type: "text" }, { id: "email", label: "이메일", type: "text" }, { id: "country", label: "국가", type: "text" }, { id: "status", label: "업체승인상태", type: "multi-select", options: techVendors.status.enumValues.map((status) => ({ label: getStatusDisplay(status), value: status, count: statusCounts[status], icon: getVendorStatusIcon(status), })), }, { id: "techVendorType", label: "벤더 타입", type: "multi-select", options: [ { label: "조선", value: "조선" }, { label: "해양TOP", value: "해양TOP" }, { label: "해양HULL", value: "해양HULL" }, ], }, { id: "workTypes", label: "Work Type", type: "multi-select", options: [ // 조선 workTypes { label: "기장", value: "기장" }, { label: "전장", value: "전장" }, { label: "선실", value: "선실" }, { label: "배관", value: "배관" }, { label: "철의", value: "철의" }, { label: "선체", value: "선체" }, // 해양TOP workTypes { label: "TM", value: "TM" }, { label: "TS", value: "TS" }, { label: "TE", value: "TE" }, { label: "TP", value: "TP" }, { label: "TA", value: "TA" }, // 해양HULL workTypes { label: "HA", value: "HA" }, { label: "HE", value: "HE" }, { label: "HH", value: "HH" }, { label: "HM", value: "HM" }, { label: "NC", value: "NC" }, { label: "HP", value: "HP" }, { label: "HO", value: "HO" }, ], }, { 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, }) const handleCompactChange = React.useCallback((compact: boolean) => { setIsCompact(compact) }, []) // 테이블 새로고침 핸들러 const handleRefresh = React.useCallback(() => { router.refresh() }, [router]) // 필터 패널 검색 핸들러 const handleSearch = React.useCallback(() => { router.refresh() }, [router]) return (
{/* Filter Panel */}
{/* Filter Content */}
setIsFilterPanelOpen(false)} onSearch={handleSearch} isLoading={false} />
{/* Main Content */}
{/* Header Bar - 고정 높이 */}
{/* Right side info
{data && ( 총 {data.length || 0}건 )}
*/}
{/* DataTable */}
} >
setRowAction(null)} vendor={rowAction?.row.original ?? null} />
) }