"use client" import * as React from "react" import { type DataTableRowAction } from "@/types/table" import { type ColumnDef } from "@tanstack/react-table" import { Ellipsis, FileText, Pencil, Edit, Trash2 } from "lucide-react" import { formatCurrency, formatDate, formatDateTime } 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, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" import Link from "next/link" import { ProcurementVendorQuotations } from "@/db/schema" import { useRouter } from "next/navigation" // 상태에 따른 배지 컴포넌트 function StatusBadge({ status }: { status: string }) { switch (status) { case "Draft": return 초안 case "Submitted": return 제출됨 case "Revised": return 수정됨 case "Rejected": return 반려됨 case "Accepted": return 승인됨 default: return {status} } } interface QuotationWithRfqCode extends ProcurementVendorQuotations { rfqCode?: string; rfq?: { id?: number; rfqCode?: string; status?: string; dueDate?: Date | string | null; rfqSendDate?: Date | string | null; item?: { id?: number; itemCode?: string; itemName?: string; } | null; } | null; vendor?: { id?: number; vendorName?: string; vendorCode?: string; } | null; } type NextRouter = ReturnType; interface GetColumnsProps { setRowAction: React.Dispatch< React.SetStateAction | null> > router: NextRouter } /** * tanstack table 컬럼 정의 (RfqsTable 스타일) */ export function getColumns({ setRowAction, router, }: 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 컬럼 // ---------------------------------------------------------------- const actionsColumn: ColumnDef = { id: "actions", enableHiding: false, cell: ({ row }) => { const id = row.original.id const code = row.getValue("quotationCode") as string const tooltipText = `${code} 작성하기` return (

{tooltipText}

) }, size: 50, } // ---------------------------------------------------------------- // 3) 컬럼 정의 배열 // ---------------------------------------------------------------- const columnDefinitions = [ { id: "quotationCode", label: "RFQ 번호", group: null, size: 150, minSize: 100, maxSize: 200, }, { id: "quotationVersion", label: "RFQ 버전", group: null, size: 100, minSize: 80, maxSize: 120, }, { id: "itemCode", label: "자재 그룹 코드", group: "RFQ 정보", size: 120, minSize: 100, maxSize: 150, }, { id: "itemName", label: "자재 이름", group: "RFQ 정보", // size를 제거하여 유연한 크기 조정 허용 minSize: 150, maxSize: 300, }, { id: "rfqSendDate", label: "RFQ 송부일", group: "날짜 정보", size: 150, minSize: 120, maxSize: 180, }, { id: "dueDate", label: "RFQ 마감일", group: "날짜 정보", size: 150, minSize: 120, maxSize: 180, }, { id: "status", label: "상태", group: null, size: 100, minSize: 80, maxSize: 120, }, { id: "totalPrice", label: "총액", group: null, size: 120, minSize: 100, maxSize: 150, }, { id: "submittedAt", label: "제출일", group: "날짜 정보", size: 120, minSize: 100, maxSize: 150, }, { id: "validUntil", label: "유효기간", group: "날짜 정보", size: 120, minSize: 100, maxSize: 150, }, ]; // ---------------------------------------------------------------- // 4) 그룹별로 컬럼 정리 (중첩 헤더 생성) // ---------------------------------------------------------------- const groupMap: Record[]> = {} columnDefinitions.forEach((cfg) => { const groupName = cfg.group || "_noGroup" if (!groupMap[groupName]) { groupMap[groupName] = [] } // 개별 컬럼 정의 const columnDef: ColumnDef = { accessorKey: cfg.id, enableResizing: true, header: ({ column }) => ( ), cell: ({ row, cell }) => { // 각 컬럼별 특별한 렌더링 처리 switch (cfg.id) { case "quotationCode": return row.original.quotationCode || "-" case "quotationVersion": return row.original.quotationVersion || "-" case "itemCode": const itemCode = row.original.rfq?.item?.itemCode; return itemCode ? itemCode : "-"; case "itemName": const itemName = row.original.rfq?.item?.itemName; return itemName ? itemName : "-"; case "rfqSendDate": const sendDate = row.original.rfq?.rfqSendDate; return sendDate ? formatDateTime(new Date(sendDate)) : "-"; case "dueDate": const dueDate = row.original.rfq?.dueDate; return dueDate ? formatDateTime(new Date(dueDate)) : "-"; case "status": return case "totalPrice": const price = parseFloat(row.getValue("totalPrice") as string || "0") const currency = row.original.currency return formatCurrency(price, currency) case "submittedAt": const submitDate = row.getValue("submittedAt") as string | null return submitDate ? formatDate(new Date(submitDate)) : "-" case "validUntil": const validDate = row.getValue("validUntil") as string | null return validDate ? formatDate(new Date(validDate)) : "-" default: return row.getValue(cfg.id) ?? "" } }, size: cfg.size, minSize: cfg.minSize, maxSize: cfg.maxSize, } groupMap[groupName].push(columnDef) }) // ---------------------------------------------------------------- // 5) 그룹별 중첩 컬럼 생성 // ---------------------------------------------------------------- const nestedColumns: ColumnDef[] = [] Object.entries(groupMap).forEach(([groupName, colDefs]) => { if (groupName === "_noGroup") { // 그룹이 없는 컬럼들은 직접 추가 nestedColumns.push(...colDefs) } else { // 그룹이 있는 컬럼들은 중첩 구조로 추가 nestedColumns.push({ id: groupName, header: groupName, columns: colDefs, }) } }) // ---------------------------------------------------------------- // 6) 최종 컬럼 배열 // ---------------------------------------------------------------- return [ selectColumn, ...nestedColumns, actionsColumn, ] }