"use client" import * as React from "react" import { ColumnDef } from "@tanstack/react-table" import { Checkbox } from "@/components/ui/checkbox" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Edit, Ellipsis } from "lucide-react" import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" import { formatDate } from "@/lib/utils" // Import types import { type DataTableRowAction } from "@/types/table" import { vendorInvestigationsColumnsConfig, VendorInvestigationsViewWithContacts } from "@/config/vendorInvestigationsColumnsConfig" // Props for the column generator function interface GetVendorInvestigationsColumnsProps { setRowAction?: React.Dispatch< React.SetStateAction< DataTableRowAction | null > > openVendorDetailsModal?: (vendorId: number) => void } // Helper function for investigation method variants function getMethodVariant(method: string): "default" | "secondary" | "outline" | "destructive" { switch (method) { case "PURCHASE_SELF_EVAL": return "secondary" case "DOCUMENT_EVAL": return "outline" case "PRODUCT_INSPECTION": return "default" case "SITE_VISIT_EVAL": return "destructive" default: return "outline" } } export function getColumns({ setRowAction, openVendorDetailsModal, }: GetVendorInvestigationsColumnsProps): ColumnDef< VendorInvestigationsViewWithContacts >[] { // -------------------------------------------- // 1) Select (checkbox) column // -------------------------------------------- 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 column // -------------------------------------------- const actionsColumn: ColumnDef = { id: "actions", enableHiding: false, cell: ({ row }) => { const isCanceled = row.original.investigationStatus === "CANCELED" const isCompleted = row.original.investigationStatus === "COMPLETED" return ( ) }, size: 40, } // -------------------------------------------- // 3) Vendor Name with click handler // -------------------------------------------- const vendorNameColumn: ColumnDef = { accessorKey: "vendorName", header: ({ column }) => ( ), cell: ({ row }) => { const vendorId = row.original.vendorId const vendorName = row.getValue("vendorName") as string return ( ) }, meta: { excelHeader: "협력사명", group: "협력업체", }, } // -------------------------------------------- // 4) Build grouped columns from config // -------------------------------------------- const groupMap: Record[]> = {} vendorInvestigationsColumnsConfig.forEach((cfg) => { // Skip vendorName as we have a custom column for it if (cfg.id === "vendorName") { return } const groupName = cfg.group || "_noGroup" if (!groupMap[groupName]) { groupMap[groupName] = [] } const childCol: ColumnDef = { accessorKey: cfg.id, header: ({ column }) => ( ), meta: { excelHeader: cfg.excelHeader, group: cfg.group, type: cfg.type, }, cell: ({ row, column }) => { const value = row.getValue(column.id) // Handle date fields if ( column.id === "scheduledStartAt" || column.id === "scheduledEndAt" || column.id === "forecastedAt" || column.id === "requestedAt" || column.id === "confirmedAt" || column.id === "completedAt" || column.id === "createdAt" || column.id === "updatedAt" ) { if (!value) return "" return formatDate(new Date(value as string), "KR") } // Handle status fields with badges if (column.id === "investigationStatus") { if (!value) return "" return ( {formatStatus(value as string)} ) } // Handle investigation method if (column.id === "investigationMethod") { if (!value) return "" return ( {formatEnumValue(value as string)} ) } // Handle evaluation result if (column.id === "evaluationResult") { if (!value) return "" return ( {formatEnumValue(value as string)} ) } // Handle pqItems if (column.id === "pqItems") { if (!value) return - const items = typeof value === 'string' ? JSON.parse(value as string) : value; if (Array.isArray(items) && items.length > 0) { const firstItem = items[0]; return (
{firstItem.itemCode} - {firstItem.itemName} {items.length > 1 && ( 외 {items.length - 1}건 )}
); } } // Handle IDs for pqSubmissionId (keeping for reference) if (column.id === "pqSubmissionId") { return value ? `#${value}` : "" } // Handle file attachment status if (column.id === "hasAttachments") { return (
{value ? ( 📎 첨부 ) : ( - )}
) } if (column.id === "requesterName") { if (!value && !row.original.requesterEmail) { return 미배정 } return (
{value || "미배정"} {row.original.requesterEmail && ( {row.original.requesterEmail} )}
) } if (column.id === "qmManagerName") { if (!value && !row.original.qmManagerEmail) { return 미배정 } return (
{value || "미배정"} {row.original.qmManagerEmail && ( {row.original.qmManagerEmail} )}
) } return value ?? "" }, } groupMap[groupName].push(childCol) }) // Insert custom vendorNameColumn in the 협력업체 group if (groupMap["협력업체"]) { groupMap["협력업체"].unshift(vendorNameColumn) } // Convert the groupMap into nested columns const nestedColumns: ColumnDef[] = [] for (const [groupName, colDefs] of Object.entries(groupMap)) { if (groupName === "_noGroup") { nestedColumns.push(...colDefs) } else { nestedColumns.push({ id: groupName, header: groupName, columns: colDefs, }) } } // -------------------------------------------- // 5) Return final columns array (simplified) // -------------------------------------------- return [ selectColumn, ...nestedColumns, actionsColumn, ] } // Helper functions for formatting function formatStatus(status: string): string { switch (status) { case "PLANNED": return "계획됨" case "IN_PROGRESS": return "진행 중" case "COMPLETED": return "완료됨" case "CANCELED": return "취소됨" case "RESULT_SENT": return "실사결과발송" default: return status } } function formatEnumValue(value: string): string { switch (value) { // Evaluation types case "PURCHASE_SELF_EVAL": return "구매자체평가" case "DOCUMENT_EVAL": return "서류평가" case "PRODUCT_INSPECTION": return "제품검사평가" case "SITE_VISIT_EVAL": return "방문실사평가" // Evaluation results case "APPROVED": return "승인" case "SUPPLEMENT": return "보완" case "REJECTED": return "불가" default: return value.replace(/_/g, " ").toLowerCase() } } function getStatusVariant(status: string): "default" | "secondary" | "outline" | "destructive" { switch (status) { case "PLANNED": return "secondary" case "IN_PROGRESS": return "default" case "COMPLETED": return "outline" case "CANCELED": return "destructive" default: return "default" } } function getResultVariant(result: string): "default" | "secondary" | "outline" | "destructive" { switch (result) { case "APPROVED": return "default" case "SUPPLEMENT": return "secondary" case "REJECTED": return "destructive" default: return "outline" } }