"use client" import * as React from "react" import { useRouter, useSearchParams } from "next/navigation" import { Button } from "@/components/ui/button" import { PanelLeftClose, PanelLeftOpen } from "lucide-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 { getRFQDashboard } from "../service" import { cn } from "@/lib/utils" import { useTablePresets } from "@/components/data-table/use-table-presets" import { TablePresetManager } from "@/components/data-table/data-table-preset" import { useMemo } from "react" import { getRFQColumns } from "./summary-rfq-columns" import { RfqDashboardView } from "@/db/schema" import { RFQTableToolbarActions } from "./summary-rfq-table-toolbar-actions" import { RFQFilterSheet } from "./summary-rfq-filter-sheet" interface RFQDashboardTableProps { promises: Promise<[Awaited>]> className?: string } export function RFQDashboardTable({ promises, className }: RFQDashboardTableProps) { const [rowAction, setRowAction] = React.useState | null>(null) const [isFilterPanelOpen, setIsFilterPanelOpen] = React.useState(false) const router = useRouter() const searchParams = useSearchParams() const containerRef = React.useRef(null) const [containerTop, setContainerTop] = React.useState(0) const updateContainerBounds = React.useCallback(() => { if (containerRef.current) { const rect = containerRef.current.getBoundingClientRect() setContainerTop(rect.top) } }, []) React.useEffect(() => { updateContainerBounds() const handleResize = () => { updateContainerBounds() } window.addEventListener('resize', handleResize) window.addEventListener('scroll', updateContainerBounds) return () => { window.removeEventListener('resize', handleResize) window.removeEventListener('scroll', updateContainerBounds) } }, [updateContainerBounds]) const [promiseData] = React.use(promises) const tableData = promiseData console.log("RFQ Dashboard Table Data:", { dataLength: tableData.data?.length, pageCount: tableData.pageCount, total: tableData.total, sampleData: tableData.data?.[0] }) const initialSettings = React.useMemo(() => ({ page: parseInt(searchParams.get('page') || '1'), perPage: parseInt(searchParams.get('perPage') || '10'), sort: searchParams.get('sort') ? JSON.parse(searchParams.get('sort')!) : [{ id: "createdAt", desc: true }], filters: searchParams.get('filters') ? JSON.parse(searchParams.get('filters')!) : [], joinOperator: (searchParams.get('joinOperator') as "and" | "or") || "and", basicFilters: searchParams.get('basicFilters') || searchParams.get('rfqBasicFilters') ? JSON.parse(searchParams.get('basicFilters') || searchParams.get('rfqBasicFilters')!) : [], basicJoinOperator: (searchParams.get('basicJoinOperator') as "and" | "or") || "and", search: searchParams.get('search') || '', columnVisibility: {}, columnOrder: [], pinnedColumns: { left: [], right: ["actions"] }, groupBy: [], expandedRows: [] }), [searchParams]) const { presets, activePresetId, hasUnsavedChanges, isLoading: presetsLoading, createPreset, applyPreset, updatePreset, deletePreset, setDefaultPreset, renamePreset, updateClientState, getCurrentSettings, } = useTablePresets('rfq-dashboard-table', initialSettings) const columns = React.useMemo( () => getRFQColumns({ setRowAction, router }), [setRowAction, router] ) const filterFields: DataTableFilterField[] = [ { id: "rfqCode", label: "RFQ 코드" }, { id: "projectName", label: "프로젝트" }, { id: "status", label: "상태" }, ] const advancedFilterFields: DataTableAdvancedFilterField[] = [ { id: "rfqCode", label: "RFQ 코드", type: "text" }, { id: "description", label: "설명", type: "text" }, { id: "projectName", label: "프로젝트명", type: "text" }, { id: "projectCode", label: "프로젝트 코드", type: "text" }, { id: "packageNo", label: "패키지 번호", type: "text" }, { id: "packageName", label: "패키지명", type: "text" }, { id: "picName", label: "담당자", type: "text" }, { id: "status", label: "상태", type: "select", options: [ { label: "초안", value: "DRAFT" }, { label: "문서접수", value: "Doc. Received" }, { label: "담당자배정", value: "PIC Assigned" }, { label: "문서확인", value: "Doc. Confirmed" }, { label: "초기RFQ발송", value: "Init. RFQ Sent" }, { label: "초기RFQ회신", value: "Init. RFQ Answered" }, { label: "TBE시작", value: "TBE started" }, { label: "TBE완료", value: "TBE finished" }, { label: "최종RFQ발송", value: "Final RFQ Sent" }, { label: "견적접수", value: "Quotation Received" }, { label: "업체선정", value: "Vendor Selected" }, ]}, { id: "overallProgress", label: "진행률", type: "number" }, { id: "dueDate", label: "마감일", type: "date" }, { id: "createdAt", label: "생성일", type: "date" }, ] const currentSettings = useMemo(() => { return getCurrentSettings() }, [getCurrentSettings]) const initialState = useMemo(() => { return { sorting: initialSettings.sort.filter(sortItem => { const columnExists = columns.some(col => col.accessorKey === sortItem.id) return columnExists }) as any, columnVisibility: currentSettings.columnVisibility, columnPinning: currentSettings.pinnedColumns, } }, [currentSettings, initialSettings.sort, columns]) const { table } = useDataTable({ data: tableData.data, columns, pageCount: tableData.pageCount, rowCount: tableData.total || tableData.data.length, filterFields, enablePinning: true, enableAdvancedFilter: true, initialState, getRowId: (originalRow) => String(originalRow.rfqId), shallow: false, clearOnDefault: true, }) const handleSearch = () => { setIsFilterPanelOpen(false) } const getActiveBasicFilterCount = () => { try { const basicFilters = searchParams.get('basicFilters') || searchParams.get('rfqBasicFilters') return basicFilters ? JSON.parse(basicFilters).length : 0 } catch (e) { return 0 } } const FILTER_PANEL_WIDTH = 400; return ( <> {/* Filter Panel */}
setIsFilterPanelOpen(false)} onSearch={handleSearch} isLoading={false} />
{/* Main Content Container */}
{/* Header Bar */}
{tableData && ( 총 {tableData.total || tableData.data.length}건 )}
{/* Table Content Area */}
presets={presets} activePresetId={activePresetId} currentSettings={currentSettings} hasUnsavedChanges={hasUnsavedChanges} isLoading={presetsLoading} onCreatePreset={createPreset} onUpdatePreset={updatePreset} onDeletePreset={deletePreset} onApplyPreset={applyPreset} onSetDefaultPreset={setDefaultPreset} onRenamePreset={renamePreset} />
) }