"use client"; import * as React from "react"; import { type ColumnDef } from "@tanstack/react-table"; import { Checkbox } from "@/components/ui/checkbox"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Eye, FileText, Send, Package, Users, ChevronRight } from "lucide-react"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"; import { RfqsLastView } from "@/db/schema"; import { DataTableRowAction } from "@/types/table"; import { format } from "date-fns"; import { ko } from "date-fns/locale"; interface GetColumnsProps { setRowAction: React.Dispatch | null>>; rfqCategory?: "all" | "general" | "itb" | "rfq"; } // RFQ 상태별 색상 const getStatusBadgeVariant = (status: string) => { switch (status) { case "RFQ 생성": return "outline"; case "구매담당지정": return "secondary"; case "견적요청문서 확정": return "default"; case "Short List 확정": return "default"; case "TBE 완료": return "default"; case "RFQ 발송": return "default"; case "견적접수": return "default"; case "최종업체선정": return "default"; default: return "outline"; } }; // 시리즈 배지 const getSeriesBadge = (series: string | null) => { if (!series) return null; const label = series === "SS" ? "시리즈 통합" : series === "II" ? "품목 통합" : series; const variant = series === "SS" ? "default" : series === "II" ? "secondary" : "outline"; return {label}; }; export function getRfqColumns({ setRowAction, rfqCategory = "all" }: GetColumnsProps): ColumnDef[] { const baseColumns: ColumnDef[] = [ // ═══════════════════════════════════════════════════════════════ // 선택 및 기본 정보 // ═══════════════════════════════════════════════════════════════ // Checkbox { id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!v)} aria-label="select all" className="translate-y-0.5" /> ), cell: ({ row }) => ( row.toggleSelected(!!v)} aria-label="select row" className="translate-y-0.5" /> ), size: 40, enableSorting: false, enableHiding: false, }, // RFQ 코드 { accessorKey: "rfqCode", header: ({ column }) => , cell: ({ row }) => { const rfqSealed = row.original.rfqSealedYn; return (
{row.original.rfqCode} {rfqSealed && ( 봉인 )}
); }, size: 140, }, // 상태 { accessorKey: "status", header: ({ column }) => , cell: ({ row }) => ( {row.original.status} ), size: 120, }, // ═══════════════════════════════════════════════════════════════ // 일반견적 필드 (rfqCategory가 'general' 또는 'all'일 때만) // ═══════════════════════════════════════════════════════════════ ...(rfqCategory === "general" || rfqCategory === "all" ? [ { id: "rfqType", accessorKey: "rfqType", header: ({ column }) => , cell: ({ row }) => row.original.rfqType || "-", size: 100, }, { id: "rfqTitle", accessorKey: "rfqTitle", header: ({ column }) => , cell: ({ row }) => (
{row.original.rfqTitle || "-"}
), size: 200, }, ] as ColumnDef[] : []), // ═══════════════════════════════════════════════════════════════ // ITB 필드 (rfqCategory가 'itb' 또는 'all'일 때만) // ═══════════════════════════════════════════════════════════════ ...(rfqCategory === "itb" || rfqCategory === "all" ? [ { id: "projectCompany", accessorKey: "projectCompany", header: ({ column }) => , cell: ({ row }) => row.original.projectCompany || "-", size: 120, }, { id: "projectFlag", accessorKey: "projectFlag", header: ({ column }) => , cell: ({ row }) => row.original.projectFlag || "-", size: 100, }, { id: "projectSite", accessorKey: "projectSite", header: ({ column }) => , cell: ({ row }) => row.original.projectSite || "-", size: 120, }, { id: "smCode", accessorKey: "smCode", header: ({ column }) => , cell: ({ row }) => row.original.smCode || "-", size: 80, }, ] as ColumnDef[] : []), // ═══════════════════════════════════════════════════════════════ // RFQ(PR) 필드 (rfqCategory가 'rfq' 또는 'all'일 때만) // ═══════════════════════════════════════════════════════════════ ...(rfqCategory === "rfq" || rfqCategory === "all" ? [ { id: "prNumber", accessorKey: "prNumber", header: ({ column }) => , cell: ({ row }) => ( {row.original.prNumber || "-"} ), size: 120, }, { id: "prIssueDate", accessorKey: "prIssueDate", header: ({ column }) => , cell: ({ row }) => { const date = row.original.prIssueDate; return date ? format(new Date(date), "yyyy-MM-dd") : "-"; }, size: 100, }, { id: "series", accessorKey: "series", header: ({ column }) => , cell: ({ row }) => getSeriesBadge(row.original.series), size: 100, }, ] as ColumnDef[] : []), // ═══════════════════════════════════════════════════════════════ // 공통 프로젝트 정보 // ═══════════════════════════════════════════════════════════════ { header: "프로젝트 정보", columns: [ { accessorKey: "projectCode", header: ({ column }) => , cell: ({ row }) => ( {row.original.projectCode || "-"} ), size: 120, }, { accessorKey: "projectName", header: ({ column }) => , cell: ({ row }) => (
{row.original.projectName || "-"}
), size: 200, }, ] }, // ═══════════════════════════════════════════════════════════════ // 품목 정보 // ═══════════════════════════════════════════════════════════════ { header: "품목 정보", columns: [ { accessorKey: "itemCode", header: ({ column }) => , cell: ({ row }) => ( {row.original.itemCode || "-"} ), size: 100, }, { accessorKey: "itemName", header: ({ column }) => , cell: ({ row }) => (
{row.original.itemName || "-"}
), size: 200, }, { accessorKey: "packageNo", header: ({ column }) => , cell: ({ row }) => row.original.packageNo || "-", size: 100, }, { accessorKey: "packageName", header: ({ column }) => , cell: ({ row }) => (
{row.original.packageName || "-"}
), size: 200, }, ] }, // ═══════════════════════════════════════════════════════════════ // 담당자 정보 // ═══════════════════════════════════════════════════════════════ { header: "담당자", columns: [ { accessorKey: "picUserName", header: ({ column }) => , cell: ({ row }) => row.original.picUserName || row.original.picName || "-", size: 100, }, { accessorKey: "engPicName", header: ({ column }) => , cell: ({ row }) => row.original.engPicName || "-", size: 120, }, ] }, // ═══════════════════════════════════════════════════════════════ // 일정 정보 // ═══════════════════════════════════════════════════════════════ { header: "일정", columns: [ { accessorKey: "rfqSendDate", header: ({ column }) => , cell: ({ row }) => { const date = row.original.rfqSendDate; return date ? (
{format(new Date(date), "MM-dd", { locale: ko })}
) : "-"; }, size: 90, }, { accessorKey: "dueDate", header: ({ column }) => , cell: ({ row }) => { const date = row.original.dueDate; if (!date) return "-"; const now = new Date(); const dueDate = new Date(date); const isOverdue = now > dueDate; return ( {format(dueDate, "MM-dd", { locale: ko })} ); }, size: 90, }, ] }, // ═══════════════════════════════════════════════════════════════ // 벤더 및 견적 현황 // ═══════════════════════════════════════════════════════════════ { header: "견적 현황", columns: [ { accessorKey: "vendorCount", header: ({ column }) => , cell: ({ row }) => (
{row.original.vendorCount || 0}
), size: 80, }, { accessorKey: "shortListedVendorCount", header: ({ column }) => , cell: ({ row }) => { const count = row.original.shortListedVendorCount || 0; return count > 0 ? ( {count} ) : "-"; }, size: 90, }, { accessorKey: "quotationReceivedCount", header: ({ column }) => , cell: ({ row }) => { const received = row.original.quotationReceivedCount || 0; const total = row.original.vendorCount || 0; return (
0 ? "text-green-600 font-medium" : ""}`}> {received}/{total}
); }, size: 90, }, ] }, // PR Items 정보 { accessorKey: "prItemsCount", header: ({ column }) => , cell: ({ row }) => { const prItems = row.original.prItemsCount || 0; const majorItems = row.original.majorItemsCount || 0; return (
{prItems}개 {majorItems > 0 && ( 주요 {majorItems} )}
); }, size: 90, }, // 액션 { id: "actions", header: "액션", enableHiding: false, size: 80, minSize: 80, cell: ({ row }) => { return (
상세보기
); }, }, ]; return baseColumns; }