summaryrefslogtreecommitdiff
path: root/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-columns.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bidding/pre-quote/table/bidding-pre-quote-vendor-columns.tsx')
-rw-r--r--lib/bidding/pre-quote/table/bidding-pre-quote-vendor-columns.tsx398
1 files changed, 0 insertions, 398 deletions
diff --git a/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-columns.tsx b/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-columns.tsx
deleted file mode 100644
index 3266a568..00000000
--- a/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-columns.tsx
+++ /dev/null
@@ -1,398 +0,0 @@
-"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<BiddingCompany>[] {
- return [
- {
- id: 'select',
- header: ({ table }) => (
- <Checkbox
- checked={table.getIsAllPageRowsSelected()}
- onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
- aria-label="모두 선택"
- />
- ),
- cell: ({ row }) => (
- <Checkbox
- checked={row.getIsSelected()}
- onCheckedChange={(value) => row.toggleSelected(!!value)}
- aria-label="행 선택"
- />
- ),
- enableSorting: false,
- enableHiding: false,
- },
- {
- accessorKey: 'companyName',
- header: '업체명',
- cell: ({ row }) => (
- <div className="font-medium">{row.original.companyName || '-'}</div>
- ),
- },
- {
- accessorKey: 'companyCode',
- header: '업체코드',
- cell: ({ row }) => (
- <div className="font-mono text-sm">{row.original.companyCode || '-'}</div>
- ),
- },
- {
- 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 <Badge variant={variant}>{label}</Badge>
- },
- },
- {
- accessorKey: 'preQuoteAmount',
- header: '사전견적금액',
- cell: ({ row }) => {
- const hasAmount = row.original.preQuoteAmount && Number(row.original.preQuoteAmount) > 0
- return (
- <div className="text-right font-mono">
- {hasAmount ? (
- <button
- onClick={() => onViewItemDetails?.(row.original)}
- className="text-primary hover:text-primary/80 hover:underline cursor-pointer"
- title="품목별 견적 상세 보기"
- >
- {Number(row.original.preQuoteAmount).toLocaleString()} KRW
- </button>
- ) : (
- <span className="text-muted-foreground">-</span>
- )}
- </div>
- )
- },
- },
- {
- accessorKey: 'preQuoteSubmittedAt',
- header: '사전견적 제출일',
- cell: ({ row }) => (
- <div className="text-sm">
- {row.original.preQuoteSubmittedAt ? new Date(row.original.preQuoteSubmittedAt).toLocaleDateString('ko-KR') : '-'}
- </div>
- ),
- },
- {
- accessorKey: 'preQuoteDeadline',
- header: '사전견적 마감일',
- cell: ({ row }) => {
- const deadline = row.original.preQuoteDeadline
- if (!deadline) {
- return <div className="text-muted-foreground text-sm">-</div>
- }
-
- const now = new Date()
- const deadlineDate = new Date(deadline)
- const isExpired = deadlineDate < now
-
- return (
- <div className={`text-sm ${isExpired ? 'text-red-600' : ''}`}>
- <div>{deadlineDate.toLocaleDateString('ko-KR')}</div>
- {isExpired && (
- <Badge variant="destructive" className="text-xs mt-1">
- 마감
- </Badge>
- )}
- </div>
- )
- },
- },
- {
- accessorKey: 'attachments',
- header: '첨부파일',
- cell: ({ row }) => {
- const hasAttachments = row.original.preQuoteSubmittedAt // 제출된 경우에만 첨부파일이 있을 수 있음
- return (
- <div className="text-center">
- {hasAttachments ? (
- <Button
- variant="ghost"
- size="sm"
- onClick={() => onViewAttachments?.(row.original)}
- className="h-8 w-8 p-0"
- title="첨부파일 보기"
- >
- <Paperclip className="h-4 w-4" />
- </Button>
- ) : (
- <span className="text-muted-foreground text-sm">-</span>
- )}
- </div>
- )
- },
- },
- {
- accessorKey: 'isPreQuoteParticipated',
- header: '사전견적 참여의사',
- cell: ({ row }) => {
- const participated = row.original.isPreQuoteParticipated
- if (participated === null) {
- return <Badge variant="outline">미결정</Badge>
- }
- return (
- <Badge variant={participated ? 'default' : 'destructive'}>
- {participated ? '참여' : '미참여'}
- </Badge>
- )
- },
- },
- {
- accessorKey: 'isPreQuoteSelected',
- header: '본입찰 선정',
- cell: ({ row }) => (
- <Badge variant={row.original.isPreQuoteSelected ? 'default' : 'secondary'}>
- {row.original.isPreQuoteSelected ? '선정' : '미선정'}
- </Badge>
- ),
- },
- {
- accessorKey: 'isAttendingMeeting',
- header: '사양설명회 참석',
- cell: ({ row }) => {
- const isAttending = row.original.isAttendingMeeting
- if (isAttending === null) return <div className="text-sm">-</div>
- return (
- <Badge variant={isAttending ? 'default' : 'secondary'}>
- {isAttending ? '참석' : '불참석'}
- </Badge>
- )
- },
- },
- {
- accessorKey: 'paymentTermsResponse',
- header: '지급조건',
- cell: ({ row }) => (
- <div className="text-sm max-w-32 truncate" title={row.original.paymentTermsResponse || ''}>
- {row.original.paymentTermsResponse || '-'}
- </div>
- ),
- },
- {
- accessorKey: 'taxConditionsResponse',
- header: '세금조건',
- cell: ({ row }) => (
- <div className="text-sm max-w-32 truncate" title={row.original.taxConditionsResponse || ''}>
- {row.original.taxConditionsResponse || '-'}
- </div>
- ),
- },
- {
- accessorKey: 'incotermsResponse',
- header: '운송조건',
- cell: ({ row }) => (
- <div className="text-sm max-w-24 truncate" title={row.original.incotermsResponse || ''}>
- {row.original.incotermsResponse || '-'}
- </div>
- ),
- },
- {
- accessorKey: 'isInitialResponse',
- header: '초도여부',
- cell: ({ row }) => {
- const isInitial = row.original.isInitialResponse
- if (isInitial === null) return <div className="text-sm">-</div>
- return (
- <Badge variant={isInitial ? 'default' : 'secondary'}>
- {isInitial ? 'Y' : 'N'}
- </Badge>
- )
- },
- },
- {
- accessorKey: 'priceAdjustmentResponse',
- header: '연동제',
- cell: ({ row }) => {
- const hasPriceAdjustment = row.original.priceAdjustmentResponse
- if (hasPriceAdjustment === null) return <div className="text-sm">-</div>
- return (
- <div className="flex items-center gap-2">
- <Badge variant={hasPriceAdjustment ? 'default' : 'secondary'}>
- {hasPriceAdjustment ? '적용' : '미적용'}
- </Badge>
- {hasPriceAdjustment && onViewPriceAdjustment && (
- <Button
- variant="ghost"
- size="sm"
- onClick={() => onViewPriceAdjustment(row.original)}
- className="h-6 px-2 text-xs"
- >
- 상세
- </Button>
- )}
- </div>
- )
- },
- },
- {
- accessorKey: 'proposedContractDeliveryDate',
- header: '제안납기일',
- cell: ({ row }) => (
- <div className="text-sm">
- {row.original.proposedContractDeliveryDate ?
- new Date(row.original.proposedContractDeliveryDate).toLocaleDateString('ko-KR') : '-'}
- </div>
- ),
- },
- {
- accessorKey: 'proposedShippingPort',
- header: '제안선적지',
- cell: ({ row }) => (
- <div className="text-sm max-w-24 truncate" title={row.original.proposedShippingPort || ''}>
- {row.original.proposedShippingPort || '-'}
- </div>
- ),
- },
- {
- accessorKey: 'proposedDestinationPort',
- header: '제안하역지',
- cell: ({ row }) => (
- <div className="text-sm max-w-24 truncate" title={row.original.proposedDestinationPort || ''}>
- {row.original.proposedDestinationPort || '-'}
- </div>
- ),
- },
- {
- accessorKey: 'sparePartResponse',
- header: '스페어파트',
- cell: ({ row }) => (
- <div className="text-sm max-w-24 truncate" title={row.original.sparePartResponse || ''}>
- {row.original.sparePartResponse || '-'}
- </div>
- ),
- },
- {
- accessorKey: 'additionalProposals',
- header: '추가제안',
- cell: ({ row }) => (
- <div className="text-sm max-w-32 truncate" title={row.original.additionalProposals || ''}>
- {row.original.additionalProposals || '-'}
- </div>
- ),
- },
- {
- id: 'actions',
- header: '액션',
- cell: ({ row }) => {
- const company = row.original
-
- return (
- <DropdownMenu>
- <DropdownMenuTrigger asChild>
- <Button variant="ghost" className="h-8 w-8 p-0">
- <span className="sr-only">메뉴 열기</span>
- <MoreHorizontal className="h-4 w-4" />
- </Button>
- </DropdownMenuTrigger>
- <DropdownMenuContent align="end">
- {/* <DropdownMenuItem onClick={() => onEdit(company)}>
- <Edit className="mr-2 h-4 w-4" />
- 수정
- </DropdownMenuItem> */}
- <DropdownMenuItem
- onClick={() => onDelete(company)}
- className="text-destructive"
- >
- <Trash2 className="mr-2 h-4 w-4" />
- 삭제
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
- )
- },
- },
- ]
-}