"use client" import * as React from "react" import { type DataTableRowAction } from "@/types/table" import { type ColumnDef } from "@tanstack/react-table" import { Ellipsis, InfoIcon, PenToolIcon, FileTextIcon, ClipboardListIcon, CheckIcon, XIcon, ClockIcon, Send, User, Calendar } from "lucide-react" import { formatDate, formatCurrency } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Checkbox } from "@/components/ui/checkbox" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Badge } from "@/components/ui/badge" import { useRouter } from "next/navigation" import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" import { ReviewerEvaluationView } from "@/db/schema" type NextRouter = ReturnType; interface GetColumnsProps { setRowAction: React.Dispatch | null>> router: NextRouter; } /** * 평가 진행 상태에 따른 배지 스타일 */ const getProgressBadge = (isCompleted: boolean, completedAt: Date | null) => { if (isCompleted && completedAt) { return { variant: "default" as const, icon: , label: "완료", className: "bg-green-100 text-green-800 border-green-200" } } else { return { variant: "secondary" as const, icon: , label: "미완료" } } } /** * 정기평가 상태에 따른 배지 스타일 */ const getPeriodicStatusBadge = (status: string) => { switch (status) { case 'PENDING': return { variant: "secondary" as const, icon: , label: "대기중" } case 'PENDING_SUBMISSION': return { variant: "secondary" as const, icon: , label: "업체 제출 대기중" } case 'IN_PROGRESS': return { variant: "default" as const, icon: , label: "진행중" } case 'REVIEW': return { variant: "outline" as const, icon: , label: "검토중" } case 'COMPLETED': return { variant: "default" as const, icon: , label: "완료", className: "bg-green-100 text-green-800 border-green-200" } default: return { variant: "secondary" as const, icon: null, label: status } } } /** * 평가 제출 테이블 컬럼 정의 */ 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" /> ), enableSorting: false, enableHiding: false, size: 40, } // ---------------------------------------------------------------- // 2) 기본 정보 컬럼들 // ---------------------------------------------------------------- const basicColumns: ColumnDef[] = [ { accessorKey: "evaluationYear", header: ({ column }) => ( ), cell: ({ row }) => ( {row.getValue("evaluationYear")}년 ), size: 80, }, { id: "vendorInfo", header: ({ column }) => ( ), cell: ({ row }) => { const vendorName = row.original.vendorName; const vendorCode = row.original.vendorCode; const domesticForeign = row.original.domesticForeign; return (
{vendorName}
{vendorCode} • {domesticForeign === 'DOMESTIC' ? 'D' : 'F'}
); }, enableSorting: false, size: 200, }, { id: "materialType", header: ({ column }) => ( ), cell: ({ row }) => { const materialType = row.original.materialType; const material = materialType ==="BULK" ? "벌크" :"장비재" return (
{material}
); }, enableSorting: false, }, { id: "division", header: ({ column }) => ( ), cell: ({ row }) => { const division = row.original.division; const divisionKR = division === "PLANT"?"해양":"조선"; return (
{divisionKR}
); }, enableSorting: false, }, ] // ---------------------------------------------------------------- // 3) 상태 정보 컬럼들 // ---------------------------------------------------------------- const statusColumns: ColumnDef[] = [ { id: "evaluationProgress", header: ({ column }) => ( ), cell: ({ row }) => { const isCompleted = row.original.isCompleted; const completedAt = row.original.completedAt; const badgeInfo = getProgressBadge(isCompleted, completedAt); return (
{badgeInfo.icon} {badgeInfo.label} {completedAt && (
{formatDate(completedAt,"KR")}
)}
); }, size: 130, }, { id: "periodicStatus", header: ({ column }) => ( ), cell: ({ row }) => { const status = row.original.periodicStatus; const badgeInfo = getPeriodicStatusBadge(status); return ( {badgeInfo.icon} {badgeInfo.label} ); }, size: 120, }, // { // id: "submissionInfo", // header: ({ column }) => ( // // ), // cell: ({ row }) => { // // const submissionDate = row.original.submittedAt; // const completedAt = row.original.completedAt; // return ( //
//
// // {submissionDate ? "제출완료" : "미제출"} // //
// {completedAt && ( //
// 평가완료: {formatDate(completedAt, "KR")} //
// )} // {/* {submissionDate && ( //
// 제출: {formatDate(submissionDate, "KR")} //
// )} */} //
// ); // }, // enableSorting: false, // size: 140, // }, ] // ---------------------------------------------------------------- // 4) 점수 및 평가 정보 컬럼들 // ---------------------------------------------------------------- const scoreColumns: ColumnDef[] = [ { id: "periodicScores", header: ({ column }) => ( ), cell: ({ row }) => { const finalScore = row.original.periodicFinalScore; const finalGrade = row.original.periodicFinalGrade; const evaluationScore = row.original.periodicEvaluationScore; const evaluationGrade = row.original.periodicEvaluationGrade; return (
{finalScore && finalGrade ? (
최종: {parseFloat(finalScore.toString()).toFixed(1)}점
{/* {finalGrade} */}
) : evaluationScore && evaluationGrade ? (
{parseFloat(evaluationScore.toString()).toFixed(1)}점
{/* {evaluationGrade} */}
) : ( 미산정 )}
); }, enableSorting: false, size: 120, }, ] // ---------------------------------------------------------------- // 6) 메타데이터 컬럼들 // ---------------------------------------------------------------- const metaColumns: ColumnDef[] = [ { accessorKey: "reviewerEvaluationCreatedAt", header: ({ column }) => ( ), cell: ({ row }) => { const date = row.getValue("reviewerEvaluationCreatedAt") as Date; return formatDate(date, "KR"); }, size: 140, }, { accessorKey: "reviewerEvaluationUpdatedAt", header: ({ column }) => ( ), cell: ({ row }) => { const date = row.getValue("reviewerEvaluationUpdatedAt") as Date; return formatDate(date, "KR"); }, size: 140, }, ] // ---------------------------------------------------------------- // 7) actions 컬럼 (드롭다운 메뉴) // ---------------------------------------------------------------- const actionsColumn: ColumnDef = { id: "actions", header: "작업", enableHiding: false, cell: function Cell({ row }) { const isCompleted = row.original.isCompleted; const reviewerEvaluationId = row.original.reviewerEvaluationId; return ( router.push(`/evcp/evaluation-input/${reviewerEvaluationId}`)} > {isCompleted ? "완료된 평가보기":"평가 작성하기"} ) }, size: 80, } // ---------------------------------------------------------------- // 8) 최종 컬럼 배열 // ---------------------------------------------------------------- return [ selectColumn, ...basicColumns, { id: "statusInfo", header: "상태 정보", columns: statusColumns, }, { id: "scoreInfo", header: "점수 및 평가", columns: scoreColumns, }, { id: "metadata", header: "메타데이터", columns: metaColumns, }, actionsColumn, ] } // ---------------------------------------------------------------- // 9) 컬럼 설정 (필터링용) // ---------------------------------------------------------------- export const evaluationSubmissionsColumnsConfig = [ { id: "reviewerEvaluationId", label: "평가 ID", group: "기본 정보", type: "text", excelHeader: "Evaluation ID", }, { id: "vendorName", label: "협력업체명", group: "기본 정보", type: "text", excelHeader: "Vendor Name", }, { id: "vendorCode", label: "협력업체 코드", group: "기본 정보", type: "text", excelHeader: "Vendor Code", }, { id: "evaluationYear", label: "평가연도", group: "기본 정보", type: "number", excelHeader: "Evaluation Year", }, { id: "departmentCode", label: "부서코드", group: "기본 정보", type: "text", excelHeader: "Department Code", }, { id: "isCompleted", label: "완료 여부", group: "상태 정보", type: "select", options: [ { label: "완료", value: "true" }, { label: "미완료", value: "false" }, ], excelHeader: "Is Completed", }, { id: "periodicStatus", label: "정기평가 상태", group: "상태 정보", type: "select", options: [ { label: "대기중", value: "PENDING" }, { label: "진행중", value: "IN_PROGRESS" }, { label: "검토중", value: "REVIEW" }, { label: "완료", value: "COMPLETED" }, ], excelHeader: "Periodic Status", }, { id: "documentsSubmitted", label: "문서 제출여부", group: "상태 정보", type: "select", options: [ { label: "제출완료", value: "true" }, { label: "미제출", value: "false" }, ], excelHeader: "Documents Submitted", }, { id: "periodicFinalScore", label: "최종점수", group: "점수 정보", type: "number", excelHeader: "Final Score", }, { id: "periodicFinalGrade", label: "최종등급", group: "점수 정보", type: "text", excelHeader: "Final Grade", }, { id: "reviewerEvaluationCreatedAt", label: "생성일", group: "메타데이터", type: "date", excelHeader: "Created At", }, { id: "reviewerEvaluationUpdatedAt", label: "수정일", group: "메타데이터", type: "date", excelHeader: "Updated At", }, ] as const;