[] = React.useMemo(() => [
{
accessorKey: "vendorName",
header: ({ column }) => ,
filterFn: createFilterFn("text"),
cell: ({ row }) => (
{row.original.vendorName}
),
size: 200,
enablePinning: true,
meta: { excelHeader: "벤더명" },
},
{
accessorKey: "formCount",
header: ({ column }) => ,
filterFn: createFilterFn("number"),
cell: ({ row }) => (
{row.original.formCount}
),
size: 100,
meta: { excelHeader: "Form 개수" },
},
{
accessorKey: "tagCount",
header: ({ column }) => ,
filterFn: createFilterFn("number"),
cell: ({ row }) => (
{row.original.tagCount}
),
size: 100,
meta: { excelHeader: "Tag 개수" },
},
{
accessorKey: "totalFields",
header: ({ column }) => ,
filterFn: createFilterFn("number"),
cell: ({ row }) => (
{row.original.totalFields.toLocaleString()}
),
size: 100,
meta: { excelHeader: "전체 필드" },
},
{
accessorKey: "completedFields",
header: ({ column }) => ,
filterFn: createFilterFn("number"),
cell: ({ row }) => (
{row.original.completedFields.toLocaleString()}
),
size: 100,
meta: { excelHeader: "완료 필드" },
},
{
accessorKey: "completionRate",
header: ({ column }) => ,
filterFn: createFilterFn("number"),
cell: ({ row }) => {
const rate = row.original.completionRate;
return (
);
},
size: 180,
meta: { excelHeader: "완료율" },
},
{
id: "progress",
header: "진행 상태",
filterFn: createFilterFn("number"),
cell: ({ row }) => {
const { completedFields, totalFields } = row.original;
return (
{completedFields} / {totalFields}
);
},
size: 120,
meta: { excelHeader: "진행 상태" },
},
], []);
// 필터 필드 정의
const advancedFilterFields: DataTableAdvancedFilterField[] = [
{ id: "vendorName", label: "벤더명", type: "text" },
{ id: "formCount", label: "Form 개수", type: "number" },
{ id: "tagCount", label: "Tag 개수", type: "number" },
{ id: "completionRate", label: "완료율", type: "number" },
];
// 요약 통계
const summaryStats = React.useMemo(() => {
const totalVendors = data.length;
const totalForms = data.reduce((sum, v) => sum + v.formCount, 0);
const totalTags = data.reduce((sum, v) => sum + v.tagCount, 0);
const avgCompletionRate = data.length > 0
? data.reduce((sum, v) => sum + v.completionRate, 0) / data.length
: 0;
const fullCompletedVendors = data.filter(v => v.completionRate === 100).length;
return {
totalVendors,
totalForms,
totalTags,
avgCompletionRate,
fullCompletedVendors,
};
}, [data]);
return (
{/* 프로젝트 선택 */}
프로젝트 선택
{selectedProject && (
선택된 프로젝트: {selectedProject.projectCode} - {selectedProject.projectName}
)}
{/* 요약 카드 */}
전체 벤더
{summaryStats.totalVendors}
전체 Form
{summaryStats.totalForms.toLocaleString()}
전체 Tag
{summaryStats.totalTags.toLocaleString()}
평균 완료율
{summaryStats.avgCompletionRate.toFixed(1)}%
완료 벤더
{summaryStats.fullCompletedVendors} / {summaryStats.totalVendors}
{/* 데이터 테이블 */}
벤더별 Form 입력 현황
{selectedProject && (
({selectedProject.projectCode})
)}
{data.length > 0 ? (
) : (
{selectedProject
? "선택한 프로젝트에 대한 데이터가 없습니다."
: "데이터가 없습니다."}
)}
);
}