row.toggleSelected(!!v)}
aria-label="select row"
className="translate-y-0.5"
/>
),
size: 40,
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "rfqCode",
header: ({ column }) => ,
cell: ({ row }) => {
return (
{row.original.rfqCode || "-"}
);
},
size: 120,
},
{
accessorKey: "vendorName",
header: ({ column }) => ,
cell: ({ row }) => {
const vendor = row.original;
return (
{vendor.vendorName || "-"}
{vendor.vendorCode}
);
},
size: 180,
},
{
accessorKey: "vendorCategory",
header: ({ column }) => ,
cell: ({ row }) => row.original.vendorCategory || "-",
size: 100,
},
{
accessorKey: "vendorCountry",
header: ({ column }) => ,
cell: ({ row }) => {
const country = row.original.vendorCountry;
const isLocal = country === "KR" || country === "한국";
return (
{country || "-"}
);
},
size: 100,
},
{
accessorKey: "vendorGrade",
header: ({ column }) => ,
cell: ({ row }) => {
const grade = row.original.vendorGrade;
if (!grade) return -;
const gradeColor = {
"A": "text-green-600",
"B": "text-blue-600",
"C": "text-yellow-600",
"D": "text-red-600",
}[grade] || "text-gray-600";
return {grade};
},
size: 100,
},
{
accessorKey: "basicContract",
header: ({ column }) => ,
cell: ({ row }) => row.original.basicContract || "-",
size: 100,
},
{
accessorKey: "currency",
header: ({ column }) => ,
cell: ({ row }) => {
const currency = row.original.currency;
return currency ? (
{currency}
) : (
-
);
},
size: 80,
},
{
accessorKey: "paymentTermsCode",
header: ({ column }) => ,
cell: ({ row }) => {
const code = row.original.paymentTermsCode;
const desc = row.original.paymentTermsDescription;
return (
{code || "-"}
{desc && (
{desc}
)}
);
},
size: 100,
},
{
accessorKey: "taxCode",
header: ({ column }) => ,
cell: ({ row }) => row.original.taxCode || "-",
size: 60,
},
{
accessorKey: "deliveryDate",
header: ({ column }) => ,
cell: ({ row }) => {
const deliveryDate = row.original.deliveryDate;
const contractDuration = row.original.contractDuration;
return (
{deliveryDate && !rfqCode?.startsWith("F") && (
{format(new Date(deliveryDate), "yyyy-MM-dd")}
)}
{contractDuration && rfqCode?.startsWith("F") && (
{contractDuration}
)}
{!deliveryDate && !contractDuration && (
-
)}
);
},
size: 120,
},
{
accessorKey: "incotermsCode",
header: ({ column }) => ,
cell: ({ row }) => {
const code = row.original.incotermsCode;
const detail = row.original.incotermsDetail;
return (
{code || "-"}
{detail && (
{detail}
)}
);
},
size: 100,
},
{
accessorKey: "placeOfShipping",
header: ({ column }) => ,
cell: ({ row }) => {
const place = row.original.placeOfShipping;
return place ? (
{place}
) : (
-
);
},
size: 100,
},
{
accessorKey: "placeOfDestination",
header: ({ column }) => ,
cell: ({ row }) => {
const place = row.original.placeOfDestination;
return place ? (
) : (
-
);
},
size: 100,
},
{
id: "additionalConditions",
header: "추가조건",
cell: ({ row }) => {
const conditions = formatAdditionalConditions(row.original);
if (conditions === "-") {
return -;
}
const items = conditions.split(", ");
return (
{items.map((item, idx) => (
{item}
))}
);
},
size: 120,
},
{
accessorKey: "response.submittedAt",
header: ({ column }) => ,
cell: ({ row }) => {
const submittedAt = row.original.response?.submittedAt;
if (!submittedAt) {
return 미참여;
}
return (
참여
{format(new Date(submittedAt), "MM-dd")}
);
},
size: 100,
},
{
id: "responseDetail",
header: "회신상세",
cell: ({ row }) => {
const hasResponse = !!row.original.response?.submittedAt;
if (!hasResponse) {
return -;
}
return (
);
},
size: 80,
},
{
accessorKey: "shortList",
header: ({ column }) => ,
cell: ({ row }) => (
row.original.shortList ? (
선정
) : (
대기
)
),
size: 80,
},
{
accessorKey: "updatedAt",
header: ({ column }) => ,
cell: ({ row }) => {
const date = row.original.updatedAt;
return date ? (
{format(new Date(date), "MM-dd HH:mm")}
) : (
-
);
},
size: 100,
},
{
accessorKey: "updatedByUserName",
header: ({ column }) => ,
cell: ({ row }) => {
const name = row.original.updatedByUserName;
return name ? (
{name}
) : (
-
);
},
size: 100,
},
{
id: "actions",
header: "작업",
cell: ({ row }) => {
const vendor = row.original;
const hasResponse = !!vendor.response;
return (
handleAction("view", vendor)}>
상세보기
{!hasResponse && (
handleAction("send", vendor)}
disabled={isLoadingSendData}
>
RFQ 발송
)}
handleAction("edit", vendor)}>
조건 수정
handleAction("delete", vendor)}
className="text-red-600"
>
삭제
);
},
size: 60,
},
], [handleAction, rfqCode, isLoadingSendData]);
const advancedFilterFields: DataTableAdvancedFilterField[] = [
{ id: "vendorName", label: "벤더명", type: "text" },
{ id: "vendorCode", label: "벤더코드", type: "text" },
{ id: "vendorCountry", label: "국가", type: "text" },
{
id: "response.status",
label: "응답 상태",
type: "select",
options: [
{ label: "초대됨", value: "초대됨" },
{ label: "작성중", value: "작성중" },
{ label: "제출완료", value: "제출완료" },
{ label: "수정요청", value: "수정요청" },
{ label: "최종확정", value: "최종확정" },
{ label: "취소", value: "취소" },
]
},
{
id: "shortList",
label: "Short List",
type: "select",
options: [
{ label: "선정", value: "true" },
{ label: "대기", value: "false" },
]
},
];
// 선택된 벤더 정보 (BatchUpdate용)
const selectedVendorsForBatch = React.useMemo(() => {
return selectedRows.map(row => ({
id: row.vendorId,
vendorName: row.vendorName,
vendorCode: row.vendorCode,
}));
}, [selectedRows]);
// 추가 액션 버튼들
const additionalActions = React.useMemo(() => (
{selectedRows.length > 0 && (
<>
>
)}
), [selectedRows, isRefreshing, isLoadingSendData, handleBulkSend]);
return (
<>
{additionalActions}
{/* 벤더 추가 다이얼로그 */}
{
toast.success("벤더가 추가되었습니다.");
setIsAddDialogOpen(false);
}}
/>
{/* 조건 일괄 설정 다이얼로그 */}
{
toast.success("조건이 업데이트되었습니다.");
setIsBatchUpdateOpen(false);
setSelectedRows([]);
}}
/>
{/* RFQ 발송 다이얼로그 */}
{/* 벤더 상세 다이얼로그 */}
{/* {selectedVendor && (
!open && setSelectedVendor(null)}
vendor={selectedVendor}
rfqId={rfqId}
/>
)} */}
>
);
}