"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,
]
}