"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 { Pencil, Eye, MessageSquare, Check, X } from "lucide-react"; import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"; import { EvaluationTargetWithDepartments } from "@/db/schema"; // 상태별 색상 매핑 const getStatusBadgeVariant = (status: string) => { switch (status) { case "PENDING": return "secondary"; case "CONFIRMED": return "default"; case "EXCLUDED": return "destructive"; default: return "outline"; } }; // 의견 일치 여부 배지 const getConsensusBadge = (consensusStatus: boolean | null) => { if (consensusStatus === null) { return 검토 중; } if (consensusStatus === true) { return 의견 일치; } return 의견 불일치; }; // 구분 배지 const getDivisionBadge = (division: string) => { return ( {division === "OCEAN" ? "해양" : "조선"} ); }; // 자재구분 배지 const getMaterialTypeBadge = (materialType: string) => { const typeMap = { EQUIPMENT: "기자재", BULK: "벌크", EQUIPMENT_BULK: "기자재/벌크" }; return {typeMap[materialType] || materialType}; }; // 내외자 배지 const getDomesticForeignBadge = (domesticForeign: string) => { return ( {domesticForeign === "DOMESTIC" ? "내자" : "외자"} ); }; export function getEvaluationTargetsColumns(): ColumnDef[] { return [ // 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, }, // ░░░ 평가년도 ░░░ { accessorKey: "evaluationYear", header: ({ column }) => , cell: ({ row }) => {row.getValue("evaluationYear")}, size: 100, }, // ░░░ 구분 ░░░ { accessorKey: "division", header: ({ column }) => , cell: ({ row }) => getDivisionBadge(row.getValue("division")), size: 80, }, // ░░░ 벤더 코드 ░░░ { accessorKey: "vendorCode", header: ({ column }) => , cell: ({ row }) => ( {row.getValue("vendorCode")} ), size: 120, }, // ░░░ 벤더명 ░░░ { accessorKey: "vendorName", header: ({ column }) => , cell: ({ row }) => ( ("vendorName")!}> {row.getValue("vendorName") as string} ), size: 200, }, // ░░░ 내외자 ░░░ { accessorKey: "domesticForeign", header: ({ column }) => , cell: ({ row }) => getDomesticForeignBadge(row.getValue("domesticForeign")), size: 80, }, // ░░░ 자재구분 ░░░ { accessorKey: "materialType", header: ({ column }) => , cell: ({ row }) => getMaterialTypeBadge(row.getValue("materialType")), size: 120, }, // ░░░ 상태 ░░░ { accessorKey: "status", header: ({ column }) => , cell: ({ row }) => { const status = row.getValue("status"); const statusMap = { PENDING: "검토 중", CONFIRMED: "확정", EXCLUDED: "제외" }; return ( {statusMap[status] || status} ); }, size: 100, }, // ░░░ 의견 일치 여부 ░░░ { accessorKey: "consensusStatus", header: ({ column }) => , cell: ({ row }) => getConsensusBadge(row.getValue("consensusStatus")), size: 100, }, // ░░░ 담당자 현황 ░░░ { id: "reviewers", header: "담당자 현황", cell: ({ row }) => { const reviewers = row.original.reviewers || []; const totalReviewers = reviewers.length; const completedReviews = reviewers.filter(r => r.review?.isApproved !== null).length; const approvedReviews = reviewers.filter(r => r.review?.isApproved === true).length; return ( {approvedReviews} /{completedReviews} /{totalReviewers} {totalReviewers > 0 && ( {reviewers.slice(0, 3).map((reviewer, idx) => ( ))} {totalReviewers > 3 && ( +{totalReviewers - 3} )} )} ); }, size: 120, enableSorting: false, }, // ░░░ 관리자 의견 ░░░ { accessorKey: "adminComment", header: ({ column }) => , cell: ({ row }) => { const comment = row.getValue("adminComment"); return comment ? ( {comment} ) : ( - ); }, size: 150, }, // ░░░ 종합 의견 ░░░ { accessorKey: "consolidatedComment", header: ({ column }) => , cell: ({ row }) => { const comment = row.getValue("consolidatedComment"); return comment ? ( {comment} ) : ( - ); }, size: 150, }, // ░░░ 확정일 ░░░ { accessorKey: "confirmedAt", header: ({ column }) => , cell: ({ row }) => { const confirmedAt = row.getValue("confirmedAt"); return confirmedAt ? ( {new Intl.DateTimeFormat("ko-KR", { year: "numeric", month: "2-digit", day: "2-digit", }).format(new Date(confirmedAt))} ) : ( - ); }, size: 100, }, // ░░░ Actions ░░░ { id: "actions", enableHiding: false, size: 120, minSize: 120, cell: ({ row }) => { const record = row.original; const [openDetail, setOpenDetail] = React.useState(false); const [openEdit, setOpenEdit] = React.useState(false); const [openRequest, setOpenRequest] = React.useState(false); return ( setOpenDetail(true)} aria-label="상세보기" title="상세보기" > setOpenEdit(true)} aria-label="수정" title="수정" > setOpenRequest(true)} aria-label="의견요청" title="의견요청" > {/* TODO: 실제 다이얼로그 컴포넌트들로 교체 */} {openDetail && ( setOpenDetail(false)}> {/* */} )} {openEdit && ( setOpenEdit(false)}> {/* */} )} {openRequest && ( setOpenRequest(false)}> {/* */} )} ); }, }, ]; }