summaryrefslogtreecommitdiff
path: root/lib/b-rfq/summary-table/summary-rfq-table.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/b-rfq/summary-table/summary-rfq-table.tsx')
-rw-r--r--lib/b-rfq/summary-table/summary-rfq-table.tsx285
1 files changed, 0 insertions, 285 deletions
diff --git a/lib/b-rfq/summary-table/summary-rfq-table.tsx b/lib/b-rfq/summary-table/summary-rfq-table.tsx
deleted file mode 100644
index 83d50685..00000000
--- a/lib/b-rfq/summary-table/summary-rfq-table.tsx
+++ /dev/null
@@ -1,285 +0,0 @@
-"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<ReturnType<typeof getRFQDashboard>>]>
- className?: string
-}
-
-export function RFQDashboardTable({ promises, className }: RFQDashboardTableProps) {
- const [rowAction, setRowAction] = React.useState<DataTableRowAction<RfqDashboardView> | null>(null)
- const [isFilterPanelOpen, setIsFilterPanelOpen] = React.useState(false)
-
- const router = useRouter()
- const searchParams = useSearchParams()
-
- const containerRef = React.useRef<HTMLDivElement>(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<RfqDashboardView>('rfq-dashboard-table', initialSettings)
-
- const columns = React.useMemo(
- () => getRFQColumns({ setRowAction, router }),
- [setRowAction, router]
- )
-
- const filterFields: DataTableFilterField<RfqDashboardView>[] = [
- { id: "rfqCode", label: "RFQ 코드" },
- { id: "projectName", label: "프로젝트" },
- { id: "status", label: "상태" },
- ]
-
- const advancedFilterFields: DataTableAdvancedFilterField<RfqDashboardView>[] = [
- { 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 */}
- <div
- className={cn(
- "fixed left-0 bg-background border-r z-50 flex flex-col transition-all duration-300 ease-in-out overflow-hidden",
- isFilterPanelOpen ? "border-r shadow-lg" : "border-r-0"
- )}
- style={{
- width: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px',
- top: `${containerTop}px`,
- height: `calc(100vh - ${containerTop}px)`
- }}
- >
- <div className="h-full">
- <RFQFilterSheet
- isOpen={isFilterPanelOpen}
- onClose={() => setIsFilterPanelOpen(false)}
- onSearch={handleSearch}
- isLoading={false}
- />
- </div>
- </div>
-
- {/* Main Content Container */}
- <div
- ref={containerRef}
- className={cn("relative w-full overflow-hidden", className)}
- >
- <div className="flex w-full h-full">
- <div
- className="flex flex-col min-w-0 overflow-hidden transition-all duration-300 ease-in-out"
- style={{
- width: isFilterPanelOpen ? `calc(100% - ${FILTER_PANEL_WIDTH}px)` : '100%',
- marginLeft: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px'
- }}
- >
- {/* Header Bar */}
- <div className="flex items-center justify-between p-4 bg-background shrink-0">
- <div className="flex items-center gap-3">
- <Button
- variant="outline"
- size="sm"
- type='button'
- onClick={() => setIsFilterPanelOpen(!isFilterPanelOpen)}
- className="flex items-center shadow-sm"
- >
- {isFilterPanelOpen ? <PanelLeftClose className="size-4"/> : <PanelLeftOpen className="size-4"/>}
- {getActiveBasicFilterCount() > 0 && (
- <span className="ml-2 bg-primary text-primary-foreground rounded-full px-2 py-0.5 text-xs">
- {getActiveBasicFilterCount()}
- </span>
- )}
- </Button>
- </div>
-
- <div className="text-sm text-muted-foreground">
- {tableData && (
- <span>총 {tableData.total || tableData.data.length}건</span>
- )}
- </div>
- </div>
-
- {/* Table Content Area */}
- <div className="flex-1 overflow-hidden" style={{ height: 'calc(100vh - 380px)' }}>
- <div className="h-full w-full">
- <DataTable table={table} className="h-full">
- <DataTableAdvancedToolbar
- table={table}
- filterFields={advancedFilterFields}
- shallow={false}
- >
- <div className="flex items-center gap-2">
- <TablePresetManager<RfqDashboardView>
- presets={presets}
- activePresetId={activePresetId}
- currentSettings={currentSettings}
- hasUnsavedChanges={hasUnsavedChanges}
- isLoading={presetsLoading}
- onCreatePreset={createPreset}
- onUpdatePreset={updatePreset}
- onDeletePreset={deletePreset}
- onApplyPreset={applyPreset}
- onSetDefaultPreset={setDefaultPreset}
- onRenamePreset={renamePreset}
- />
-
- <RFQTableToolbarActions table={table} />
- </div>
- </DataTableAdvancedToolbar>
- </DataTable>
- </div>
- </div>
- </div>
- </div>
- </div>
- </>
- )
-} \ No newline at end of file