"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 { MoreHorizontal, Edit, Trash2, Paperclip } from "lucide-react" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" // bidding_companies 테이블 타입 정의 (company_condition_responses와 join) export interface BiddingCompany { id: number biddingId: number companyId: number invitationStatus: 'pending' | 'sent' | 'accepted' | 'declined' | 'submitted' invitedAt: Date | null respondedAt: Date | null preQuoteAmount: string | null preQuoteSubmittedAt: Date | null preQuoteDeadline: Date | null isPreQuoteSelected: boolean isPreQuoteParticipated: boolean | null isAttendingMeeting: boolean | null notes: string | null contactPerson: string | null contactEmail: string | null contactPhone: string | null createdAt: Date updatedAt: Date // company_condition_responses 필드들 paymentTermsResponse: string | null taxConditionsResponse: string | null proposedContractDeliveryDate: string | null priceAdjustmentResponse: boolean | null isInitialResponse: boolean | null incotermsResponse: string | null proposedShippingPort: string | null proposedDestinationPort: string | null sparePartResponse: string | null additionalProposals: string | null // 조인된 업체 정보 companyName?: string companyCode?: string } interface GetBiddingCompanyColumnsProps { onEdit: (company: BiddingCompany) => void onDelete: (company: BiddingCompany) => void onViewPriceAdjustment?: (company: BiddingCompany) => void onViewItemDetails?: (company: BiddingCompany) => void onViewAttachments?: (company: BiddingCompany) => void } export function getBiddingPreQuoteVendorColumns({ onEdit, onDelete, onViewPriceAdjustment, onViewItemDetails, onViewAttachments }: GetBiddingCompanyColumnsProps): ColumnDef[] { return [ { id: 'select', header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label="모두 선택" /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label="행 선택" /> ), enableSorting: false, enableHiding: false, }, { accessorKey: 'companyName', header: '업체명', cell: ({ row }) => (
{row.original.companyName || '-'}
), }, { accessorKey: 'companyCode', header: '업체코드', cell: ({ row }) => (
{row.original.companyCode || '-'}
), }, { accessorKey: 'invitationStatus', header: '초대 상태', cell: ({ row }) => { const status = row.original.invitationStatus let variant: any let label: string if (status === 'accepted') { variant = 'default' label = '수락' } else if (status === 'declined') { variant = 'destructive' label = '거절' } else if (status === 'pending') { variant = 'outline' label = '대기중' } else if (status === 'sent') { variant = 'outline' label = '요청됨' } else if (status === 'submitted') { variant = 'outline' label = '제출됨' } else { variant = 'outline' label = status || '-' } return {label} }, }, { accessorKey: 'preQuoteAmount', header: '사전견적금액', cell: ({ row }) => { const hasAmount = row.original.preQuoteAmount && Number(row.original.preQuoteAmount) > 0 return (
{hasAmount ? ( ) : ( - )}
) }, }, { accessorKey: 'preQuoteSubmittedAt', header: '사전견적 제출일', cell: ({ row }) => (
{row.original.preQuoteSubmittedAt ? new Date(row.original.preQuoteSubmittedAt).toLocaleDateString('ko-KR') : '-'}
), }, { accessorKey: 'preQuoteDeadline', header: '사전견적 마감일', cell: ({ row }) => { const deadline = row.original.preQuoteDeadline if (!deadline) { return
-
} const now = new Date() const deadlineDate = new Date(deadline) const isExpired = deadlineDate < now return (
{deadlineDate.toLocaleDateString('ko-KR')}
{isExpired && ( 마감 )}
) }, }, { accessorKey: 'attachments', header: '첨부파일', cell: ({ row }) => { const hasAttachments = row.original.preQuoteSubmittedAt // 제출된 경우에만 첨부파일이 있을 수 있음 return (
{hasAttachments ? ( ) : ( - )}
) }, }, { accessorKey: 'isPreQuoteParticipated', header: '사전견적 참여의사', cell: ({ row }) => { const participated = row.original.isPreQuoteParticipated if (participated === null) { return 미결정 } return ( {participated ? '참여' : '미참여'} ) }, }, { accessorKey: 'isPreQuoteSelected', header: '본입찰 선정', cell: ({ row }) => ( {row.original.isPreQuoteSelected ? '선정' : '미선정'} ), }, { accessorKey: 'isAttendingMeeting', header: '사양설명회 참석', cell: ({ row }) => { const isAttending = row.original.isAttendingMeeting if (isAttending === null) return
-
return ( {isAttending ? '참석' : '불참석'} ) }, }, { accessorKey: 'paymentTermsResponse', header: '지급조건', cell: ({ row }) => (
{row.original.paymentTermsResponse || '-'}
), }, { accessorKey: 'taxConditionsResponse', header: '세금조건', cell: ({ row }) => (
{row.original.taxConditionsResponse || '-'}
), }, { accessorKey: 'incotermsResponse', header: '운송조건', cell: ({ row }) => (
{row.original.incotermsResponse || '-'}
), }, { accessorKey: 'isInitialResponse', header: '초도여부', cell: ({ row }) => { const isInitial = row.original.isInitialResponse if (isInitial === null) return
-
return ( {isInitial ? 'Y' : 'N'} ) }, }, { accessorKey: 'priceAdjustmentResponse', header: '연동제', cell: ({ row }) => { const hasPriceAdjustment = row.original.priceAdjustmentResponse if (hasPriceAdjustment === null) return
-
return (
{hasPriceAdjustment ? '적용' : '미적용'} {hasPriceAdjustment && onViewPriceAdjustment && ( )}
) }, }, { accessorKey: 'proposedContractDeliveryDate', header: '제안납기일', cell: ({ row }) => (
{row.original.proposedContractDeliveryDate ? new Date(row.original.proposedContractDeliveryDate).toLocaleDateString('ko-KR') : '-'}
), }, { accessorKey: 'proposedShippingPort', header: '제안선적지', cell: ({ row }) => (
{row.original.proposedShippingPort || '-'}
), }, { accessorKey: 'proposedDestinationPort', header: '제안하역지', cell: ({ row }) => (
{row.original.proposedDestinationPort || '-'}
), }, { accessorKey: 'sparePartResponse', header: '스페어파트', cell: ({ row }) => (
{row.original.sparePartResponse || '-'}
), }, { accessorKey: 'additionalProposals', header: '추가제안', cell: ({ row }) => (
{row.original.additionalProposals || '-'}
), }, { id: 'actions', header: '액션', cell: ({ row }) => { const company = row.original return ( {/* onEdit(company)}> 수정 */} onDelete(company)} className="text-destructive" > 삭제 ) }, }, ] }