= {
accessorKey: cfg.id,
enableResizing: true,
header: ({ column }) => (
),
cell: ({ row, cell }) => {
// 각 컬럼별 특별한 렌더링 처리
switch (cfg.id) {
case "rfqCode":
return row.original.rfq?.rfqCode || "-"
case "rfqDueDate":
const dueDate = row.original.rfq?.dueDate;
return dueDate ? formatDate(new Date(dueDate)) : "-";
case "overallStatus":
return
case "totalAttachments":
return (
{row.original.totalAttachments}
)
case "respondedCount":
return (
{row.original.respondedCount}
)
case "pendingCount":
return (
{row.original.pendingCount}
)
case "responseRate":
const responseRate = row.original.responseRate;
return (
= 80 ? 'text-green-600' : responseRate >= 50 ? 'text-yellow-600' : 'text-red-600'}`}>
{responseRate}%
)
case "completionRate":
const completionRate = row.original.completionRate;
return (
= 80 ? 'text-green-600' : completionRate >= 50 ? 'text-yellow-600' : 'text-red-600'}`}>
{completionRate}%
)
case "requestedAt":
return formatDateTime(new Date(row.original.requestedAt))
case "lastRespondedAt":
const lastRespondedAt = row.original.lastRespondedAt;
return lastRespondedAt ? formatDateTime(new Date(lastRespondedAt)) : "-";
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,
]
}