"use client" import * as React from "react" import { type ColumnDef } from "@tanstack/react-table" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Eye, Calendar, FileX, DollarSign, AlertTriangle, RefreshCw } from "lucide-react" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" import { biddingStatusLabels, contractTypeLabels, } from "@/db/schema" import { formatDate } from "@/lib/utils" import { DataTableRowAction } from "@/types/table" type BiddingFailureItem = { id: number biddingNumber: string originalBiddingNumber: string | null title: string status: string contractType: string prNumber: string | null // 가격 정보 targetPrice: number | null currency: string | null // 일정 정보 biddingRegistrationDate: Date | null submissionStartDate: Date | null submissionEndDate: Date | null // 담당자 정보 bidPicName: string | null supplyPicName: string | null // 유찰 정보 disposalDate: Date | null // 유찰일 disposalUpdatedAt: Date | null // 폐찰수정일 disposalUpdatedBy: string | null // 폐찰수정자 // 기타 정보 createdBy: string | null createdAt: Date | null updatedAt: Date | null updatedBy: string | null } interface GetColumnsProps { setRowAction: React.Dispatch | null>> } // 상태별 배지 색상 const getStatusBadgeVariant = (status: string) => { switch (status) { case 'bidding_disposal': return 'destructive' default: return 'outline' } } // 금액 포맷팅 const formatCurrency = (amount: string | number | null, currency = 'KRW') => { if (!amount) return '-' const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount if (isNaN(numAmount)) return '-' return new Intl.NumberFormat('ko-KR', { style: 'currency', currency: currency, minimumFractionDigits: 0, maximumFractionDigits: 0, }).format(numAmount) } export function getBiddingsFailureColumns({ setRowAction }: GetColumnsProps): ColumnDef[] { return [ // ░░░ 입찰번호 ░░░ { accessorKey: "biddingNumber", header: ({ column }) => , cell: ({ row }) => (
{row.original.biddingNumber}
), size: 120, meta: { excelHeader: "입찰번호" }, }, // ░░░ 입찰명 ░░░ { accessorKey: "title", header: ({ column }) => , cell: ({ row }) => (
), size: 200, meta: { excelHeader: "입찰명" }, }, // ░░░ 진행상태 ░░░ { accessorKey: "status", header: ({ column }) => , cell: ({ row }) => ( {biddingStatusLabels[row.original.status]} ), size: 120, meta: { excelHeader: "진행상태" }, }, // ░░░ 계약구분 ░░░ { accessorKey: "contractType", header: ({ column }) => , cell: ({ row }) => ( {contractTypeLabels[row.original.contractType]} ), size: 100, meta: { excelHeader: "계약구분" }, }, // ░░░ 내정가 ░░░ { accessorKey: "targetPrice", header: ({ column }) => , cell: ({ row }) => { const price = row.original.targetPrice const currency = row.original.currency || 'KRW' return (
{price ? formatCurrency(price, currency) : '-'}
) }, size: 120, meta: { excelHeader: "내정가" }, }, // ░░░ 통화 ░░░ { accessorKey: "currency", header: ({ column }) => , cell: ({ row }) => ( {row.original.currency || 'KRW'} ), size: 60, meta: { excelHeader: "통화" }, }, // ░░░ 입찰등록일 ░░░ { accessorKey: "biddingRegistrationDate", header: ({ column }) => , cell: ({ row }) => ( {formatDate(row.original.biddingRegistrationDate, "KR")} ), size: 100, meta: { excelHeader: "입찰등록일" }, }, // ░░░ 입찰담당자 ░░░ { accessorKey: "bidPicName", header: ({ column }) => , cell: ({ row }) => { const bidPic = row.original.bidPicName const supplyPic = row.original.supplyPicName const displayName = bidPic || supplyPic || "-" return {displayName} }, size: 100, meta: { excelHeader: "입찰담당자" }, }, // ░░░ 유찰일 ░░░ { id: "disposalDate", header: ({ column }) => , cell: ({ row }) => (
{formatDate(row.original.disposalDate, "KR")}
), size: 100, meta: { excelHeader: "유찰일" }, }, // ░░░ 폐찰일 ░░░ { id: "disposalUpdatedAt", header: ({ column }) => , cell: ({ row }) => (
{formatDate(row.original.disposalUpdatedAt, "KR")}
), size: 100, meta: { excelHeader: "폐찰일" }, }, // ░░░ 폐찰수정자 ░░░ { id: "disposalUpdatedBy", header: ({ column }) => , cell: ({ row }) => ( {row.original.disposalUpdatedBy || '-'} ), size: 100, meta: { excelHeader: "폐찰수정자" }, }, // ░░░ P/R번호 ░░░ { accessorKey: "prNumber", header: ({ column }) => , cell: ({ row }) => ( {row.original.prNumber || '-'} ), size: 100, meta: { excelHeader: "P/R번호" }, }, // ░░░ 등록자 ░░░ { accessorKey: "createdBy", header: ({ column }) => , cell: ({ row }) => ( {row.original.createdBy || '-'} ), size: 100, meta: { excelHeader: "등록자" }, }, // ░░░ 등록일시 ░░░ { accessorKey: "createdAt", header: ({ column }) => , cell: ({ row }) => ( {formatDate(row.original.createdAt, "KR")} ), size: 100, meta: { excelHeader: "등록일시" }, }, // ═══════════════════════════════════════════════════════════════ // 액션 // ═══════════════════════════════════════════════════════════════ { id: "actions", header: "액션", cell: ({ row }) => ( setRowAction({ row, type: "view" })}> 상세보기 setRowAction({ row, type: "history" })}> 이력보기 setRowAction({ row, type: "rebid" })}> 재입찰 ), size: 50, enableSorting: false, enableHiding: false, }, ] }