"use client"; import * as React from "react"; import { type DataTableRowAction } from "@/types/table"; import { type ColumnDef } from "@tanstack/react-table"; import { Ellipsis } from "lucide-react"; import { formatDate } from "@/lib/utils"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { BidHistoryRow } from "./bid-history-table"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"; import { bidHistoryColumnsConfig } from "@/config/bidHistoryColumnsConfig"; interface GetColumnsProps { setRowAction: React.Dispatch | null>>; onViewDetails: (biddingId: number) => void; } /** * tanstack table 컬럼 정의 (중첩 헤더 버전) */ export function getColumns({ setRowAction, onViewDetails }: GetColumnsProps): ColumnDef[] { // ---------------------------------------------------------------- // 1) select 컬럼 (체크박스) // ---------------------------------------------------------------- const selectColumn: ColumnDef = { id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label="Select all" className="translate-y-0.5" /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label="Select row" className="translate-y-0.5" /> ), size: 40, enableSorting: false, enableHiding: false, }; // ---------------------------------------------------------------- // 2) actions 컬럼 (Dropdown 메뉴) // ---------------------------------------------------------------- const actionsColumn: ColumnDef = { id: "actions", enableHiding: false, cell: function Cell({ row }) { return ( onViewDetails(row.original.biddingId)} > 입찰상세 ); }, size: 40, }; // ---------------------------------------------------------------- // 3) 일반 컬럼들 // ---------------------------------------------------------------- const basicColumns: ColumnDef[] = bidHistoryColumnsConfig.map((cfg) => { const column: ColumnDef = { accessorKey: cfg.id, header: ({ column }) => ( ), size: cfg.size, }; // 계약구분 표시 if (cfg.id === "contractType") { column.cell = ({ row }) => { const contractType = row.original.contractType; if (!contractType) return null; const contractTypeLabels = { unit_price: "단가", general: "일반", sale: "매각" }; return ( {contractTypeLabels[contractType] || contractType} ); }; } // 입찰유형 표시 if (cfg.id === "biddingType") { column.cell = ({ row }) => { const biddingType = row.original.biddingType; if (!biddingType) return null; const biddingTypeLabels = { equipment: "기자재", construction: "공사", service: "용역", lease: "임차", steel_stock: "형강스톡", piping: "배관", transport: "운송", waste: "폐기물", sale: "매각" }; return ( {biddingTypeLabels[biddingType] || biddingType} ); }; } // 입찰상태 표시 if (cfg.id === "biddingStatus") { column.cell = ({ row }) => { const biddingStatus = row.original.biddingStatus; if (!biddingStatus) return null; const statusLabels = { bidding_generated: "입찰생성", request_for_quotation: "사전견적요청", received_quotation: "사전견적접수", set_target_price: "내정가산정", bidding_opened: "입찰공고", bidding_closed: "입찰마감", evaluation_of_bidding: "입찰평가중", bidding_disposal: "유찰", vendor_selected: "업체선정" }; const statusColors = { bidding_generated: "secondary", request_for_quotation: "outline", received_quotation: "outline", set_target_price: "outline", bidding_opened: "default", bidding_closed: "destructive", evaluation_of_bidding: "secondary", bidding_disposal: "destructive", vendor_selected: "default" }; return ( {statusLabels[biddingStatus] || biddingStatus} ); }; } // 입찰번호 표시 (Rev. 포함) if (cfg.id === "biddingNumber") { column.cell = ({ row }) => { const biddingNumber = row.original.biddingNumber; const revision = row.original.revision; if (!biddingNumber) return null; return (
{biddingNumber}
); }; } // 품목명 표시 (자재그룹 포함) if (cfg.id === "itemName") { column.cell = ({ row }) => { const itemName = row.original.itemName; const materialGroup = row.original.materialGroup; const materialGroupName = row.original.materialGroupName; if (!itemName) return null; const displayText = materialGroup && materialGroupName ? `${itemName} (${materialGroup}/${materialGroupName})` : itemName; return (
{displayText}
{displayText}
); }; } // 입찰명 표시 if (cfg.id === "biddingTitle") { column.cell = ({ row }) => { const title = row.original.biddingTitle; if (!title) return null; return (
{title}
{title}
); }; } // 계약정보 표시 (PO/계약정보) if (cfg.id === "contractNumber") { column.cell = ({ row }) => { const poNumber = row.original.poNumber; const contractNumber = row.original.contractNumber; if (!poNumber && !contractNumber) return null; const displayText = poNumber && contractNumber ? `${poNumber}/${contractNumber}` : poNumber || contractNumber; return (
{displayText}
); }; } // 날짜 필드들 표시 if (cfg.id === "biddingRequestDate" || cfg.id === "biddingDeadline") { column.cell = ({ row }) => (
{formatDate(row.getValue(cfg.id), "KR")}
); } // 금액 필드들 표시 if (cfg.id === "finalBidPrice" || cfg.id === "expectedAmount" || cfg.id === "preQuotePrice") { column.cell = ({ row }) => { const amount = row.getValue(cfg.id) as string; const currency = row.original.currency; if (!amount || !currency) return null; const numericAmount = parseFloat(amount); if (isNaN(numericAmount)) return null; return (
{`${currency} ${numericAmount.toLocaleString()}`}
); }; } // 발주비율 표시 if (cfg.id === "awardRatio") { column.cell = ({ row }) => { const ratio = row.original.awardRatio; if (!ratio) return null; const numericRatio = parseFloat(ratio); if (isNaN(numericRatio)) return null; return (
{`${numericRatio}%`}
); }; } return column; }); // ---------------------------------------------------------------- // 4) 최종 컬럼 배열 // ---------------------------------------------------------------- return [ selectColumn, ...basicColumns, actionsColumn, ]; }