diff options
Diffstat (limited to 'lib/bidding/detail/table')
8 files changed, 6 insertions, 220 deletions
diff --git a/lib/bidding/detail/table/bidding-detail-content.tsx b/lib/bidding/detail/table/bidding-detail-content.tsx index a96509a9..895016a2 100644 --- a/lib/bidding/detail/table/bidding-detail-content.tsx +++ b/lib/bidding/detail/table/bidding-detail-content.tsx @@ -35,7 +35,7 @@ export function BiddingDetailContent({ award: false }) - const [refreshTrigger, setRefreshTrigger] = React.useState(0) + const [, setRefreshTrigger] = React.useState(0) // PR 아이템 다이얼로그 관련 state const [isItemDetailsDialogOpen, setIsItemDetailsDialogOpen] = React.useState(false) @@ -80,14 +80,10 @@ export function BiddingDetailContent({ bidding={bidding} vendors={quotationVendors} onRefresh={handleRefresh} - onOpenItemsDialog={() => openDialog('items')} onOpenTargetPriceDialog={() => openDialog('targetPrice')} onOpenSelectionReasonDialog={() => openDialog('selectionReason')} - onOpenAwardDialog={() => openDialog('award')} onViewItemDetails={handleViewItemDetails} onEdit={undefined} - onDelete={undefined} - onSelectWinner={undefined} /> <BiddingDetailItemsDialog diff --git a/lib/bidding/detail/table/bidding-detail-header.tsx b/lib/bidding/detail/table/bidding-detail-header.tsx deleted file mode 100644 index 8d18472f..00000000 --- a/lib/bidding/detail/table/bidding-detail-header.tsx +++ /dev/null @@ -1,103 +0,0 @@ -'use client' - -import * as React from 'react' -import { useRouter } from 'next/navigation' -import { Bidding, biddingStatusLabels, contractTypeLabels, biddingTypeLabels } from '@/db/schema' -import { Badge } from '@/components/ui/badge' -import { Button } from '@/components/ui/button' -import { - ArrowLeft, - Send, - RotateCcw, - XCircle, - Calendar, - Building2, - User, - Package, - DollarSign, - Hash -} from 'lucide-react' - -import { formatDate } from '@/lib/utils' -import { - registerBidding, - markAsDisposal, - createRebidding -} from '@/lib/bidding/detail/service' -import { useToast } from '@/hooks/use-toast' -import { useTransition } from 'react' - -interface BiddingDetailHeaderProps { - bidding: Bidding -} - -export function BiddingDetailHeader({ bidding }: BiddingDetailHeaderProps) { - const router = useRouter() - const { toast } = useToast() - const [isPending, startTransition] = useTransition() - - const handleGoBack = () => { - router.push('/evcp/bid') - } - - return ( - <div className="border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"> - <div className="px-6 py-4"> - {/* 헤더 메인 영역 */} - <div className="flex items-center justify-between mb-4"> - <div className="flex items-center gap-4 flex-1 min-w-0"> - {/* 제목과 배지 */} - <div className="flex items-center gap-3 flex-1 min-w-0"> - <h1 className="text-xl font-semibold truncate">{bidding.title}</h1> - <div className="flex items-center gap-2 flex-shrink-0"> - <Badge variant="outline" className="font-mono text-xs"> - <Hash className="w-3 h-3 mr-1" /> - {bidding.biddingNumber} - {bidding.revision && bidding.revision > 0 && ` Rev.${bidding.revision}`} - </Badge> - <Badge variant={ - bidding.status === 'bidding_disposal' ? 'destructive' : - bidding.status === 'vendor_selected' ? 'default' : - 'secondary' - } className="text-xs"> - {biddingStatusLabels[bidding.status]} - </Badge> - </div> - </div> - </div> - </div> - - {/* 세부 정보 영역 */} - - {/* 일정 정보 */} - {/* {(bidding.submissionStartDate || bidding.evaluationDate || bidding.preQuoteDate || bidding.biddingRegistrationDate) && ( - <div className="flex flex-wrap items-center gap-4 mt-3 pt-3 border-t border-border/50"> - <Calendar className="w-4 h-4 text-muted-foreground flex-shrink-0" /> - <div className="flex flex-wrap items-center gap-4 text-sm text-muted-foreground"> - {bidding.submissionStartDate && bidding.submissionEndDate && ( - <div> - <span className="font-medium">제출기간:</span> {formatDate(bidding.submissionStartDate, 'KR')} ~ {formatDate(bidding.submissionEndDate, 'KR')} - </div> - )} - {bidding.evaluationDate && ( - <div> - <span className="font-medium">평가일:</span> {formatDate(bidding.evaluationDate, 'KR')} - </div> - )} - {bidding.preQuoteDate && ( - <div> - <span className="font-medium">사전견적일:</span> {formatDate(bidding.preQuoteDate, 'KR')} - </div> - )} - {bidding.biddingRegistrationDate && ( - <div> - <span className="font-medium">입찰등록일:</span> {formatDate(bidding.biddingRegistrationDate, 'KR')} - </div> - )} - </div> - </div> - )} */} - </div> - </div> - ) -}
\ No newline at end of file diff --git a/lib/bidding/detail/table/bidding-detail-items-dialog.tsx b/lib/bidding/detail/table/bidding-detail-items-dialog.tsx index 2bab3ef0..8c2ae44a 100644 --- a/lib/bidding/detail/table/bidding-detail-items-dialog.tsx +++ b/lib/bidding/detail/table/bidding-detail-items-dialog.tsx @@ -17,7 +17,6 @@ import { TableHeader, TableRow, } from '@/components/ui/table' -import { Badge } from '@/components/ui/badge' import { formatDate } from '@/lib/utils' interface PrItem { diff --git a/lib/bidding/detail/table/bidding-detail-vendor-columns.tsx b/lib/bidding/detail/table/bidding-detail-vendor-columns.tsx index 3b42cc88..782c5f7a 100644 --- a/lib/bidding/detail/table/bidding-detail-vendor-columns.tsx +++ b/lib/bidding/detail/table/bidding-detail-vendor-columns.tsx @@ -6,7 +6,7 @@ import { Checkbox } from "@/components/ui/checkbox" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { - MoreHorizontal, Edit, Trash2, Trophy + MoreHorizontal } from "lucide-react" import { DropdownMenu, @@ -20,8 +20,6 @@ import { QuotationVendor } from "@/lib/bidding/detail/service" interface GetVendorColumnsProps { onEdit: (vendor: QuotationVendor) => void - onDelete: (vendor: QuotationVendor) => void - onSelectWinner: (vendor: QuotationVendor) => void onViewPriceAdjustment?: (vendor: QuotationVendor) => void onViewItemDetails?: (vendor: QuotationVendor) => void onSendBidding?: (vendor: QuotationVendor) => void @@ -30,9 +28,6 @@ interface GetVendorColumnsProps { export function getBiddingDetailVendorColumns({ onEdit, - onDelete, - onSelectWinner, - onViewPriceAdjustment, onViewItemDetails, onSendBidding, onUpdateParticipation @@ -182,17 +177,6 @@ export function getBiddingDetailVendorColumns({ <span className="text-xs text-muted-foreground ml-2">(입찰참여 필요)</span> )} </DropdownMenuItem> - {vendor.status !== 'selected' && ( - <DropdownMenuItem - onClick={() => onSelectWinner(vendor)} - disabled={vendor.isBiddingParticipated !== true} - > - 낙찰 선정 - {vendor.isBiddingParticipated !== true && ( - <span className="text-xs text-muted-foreground ml-2">(입찰참여 필요)</span> - )} - </DropdownMenuItem> - )} {/* 입찰 참여여부 관리 */} {vendor.isBiddingParticipated === null && onUpdateParticipation && ( @@ -217,13 +201,6 @@ export function getBiddingDetailVendorColumns({ </> )} - <DropdownMenuSeparator /> - <DropdownMenuItem - onClick={() => onDelete(vendor)} - className="text-destructive" - > - 삭제 - </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> ) diff --git a/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx b/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx index e029d536..f43e850a 100644 --- a/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx +++ b/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx @@ -4,8 +4,6 @@ import * as React from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' -import { Textarea } from '@/components/ui/textarea' -import { Checkbox } from '@/components/ui/checkbox' import { Dialog, DialogContent, @@ -14,13 +12,6 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog' -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select' import { updateBiddingDetailVendor } from '@/lib/bidding/detail/service' import { QuotationVendor } from '@/lib/bidding/detail/service' import { useToast } from '@/hooks/use-toast' diff --git a/lib/bidding/detail/table/bidding-detail-vendor-table.tsx b/lib/bidding/detail/table/bidding-detail-vendor-table.tsx index a9778636..3e8adda9 100644 --- a/lib/bidding/detail/table/bidding-detail-vendor-table.tsx +++ b/lib/bidding/detail/table/bidding-detail-vendor-table.tsx @@ -7,33 +7,22 @@ import { useDataTable } from '@/hooks/use-data-table' import { DataTable } from '@/components/data-table/data-table' import { DataTableAdvancedToolbar } from '@/components/data-table/data-table-advanced-toolbar' import { BiddingDetailVendorToolbarActions } from './bidding-detail-vendor-toolbar-actions' -import { BiddingDetailVendorCreateDialog } from './bidding-detail-vendor-create-dialog' import { BiddingDetailVendorEditDialog } from './bidding-detail-vendor-edit-dialog' import { BiddingAwardDialog } from './bidding-award-dialog' import { getBiddingDetailVendorColumns } from './bidding-detail-vendor-columns' import { QuotationVendor, getPriceAdjustmentFormByBiddingCompanyId } from '@/lib/bidding/detail/service' import { Bidding } from '@/db/schema' import { PriceAdjustmentDialog } from '@/components/bidding/price-adjustment-dialog' -import { - deleteQuotationVendor, - selectWinner -} from '@/lib/bidding/detail/service' -import { selectWinnerSchema } from '@/lib/bidding/validation' import { useToast } from '@/hooks/use-toast' -import { useTransition, useCallback } from 'react' interface BiddingDetailVendorTableContentProps { biddingId: number bidding: Bidding vendors: QuotationVendor[] onRefresh: () => void - onOpenItemsDialog: () => void onOpenTargetPriceDialog: () => void onOpenSelectionReasonDialog: () => void - onOpenAwardDialog: () => void onEdit?: (vendor: QuotationVendor) => void - onDelete?: (vendor: QuotationVendor) => void - onSelectWinner?: (vendor: QuotationVendor) => void onViewItemDetails?: (vendor: QuotationVendor) => void } @@ -93,18 +82,12 @@ export function BiddingDetailVendorTableContent({ bidding, vendors, onRefresh, - onOpenItemsDialog, onOpenTargetPriceDialog, - onOpenSelectionReasonDialog, - onOpenAwardDialog, onEdit, - onDelete, - onSelectWinner, onViewItemDetails }: BiddingDetailVendorTableContentProps) { const { data: session } = useSession() const { toast } = useToast() - const [isPending, startTransition] = useTransition() // 세션에서 사용자 ID 가져오기 const userId = session?.user?.id || '' @@ -114,52 +97,6 @@ export function BiddingDetailVendorTableContent({ const [priceAdjustmentData, setPriceAdjustmentData] = React.useState<any>(null) const [isPriceAdjustmentDialogOpen, setIsPriceAdjustmentDialogOpen] = React.useState(false) - const handleSelectWinner = useCallback((vendor: QuotationVendor) => { - if (!vendor.awardRatio || vendor.awardRatio <= 0) { - toast({ - title: '오류', - description: '발주비율을 먼저 설정해주세요.', - variant: 'destructive', - }) - return - } - - if (!confirm(`${vendor.vendorName} 업체를 낙찰자로 선정하시겠습니까?`)) return - - startTransition(async () => { - const result = selectWinnerSchema.safeParse({ - biddingId, - vendorId: vendor.id, - awardRatio: vendor.awardRatio || 0, - }) - - if (!result.success) { - toast({ - title: '유효성 오류', - description: result.error.issues[0]?.message || '입력값을 확인해주세요.', - variant: 'destructive', - }) - return - } - - const response = await selectWinner(biddingId, vendor.id, vendor.awardRatio || 0, userId) - - if (response.success) { - toast({ - title: '성공', - description: response.message, - }) - onRefresh() - } else { - toast({ - title: '오류', - description: response.error, - variant: 'destructive', - }) - } - }) - }, [toast, startTransition, biddingId, userId, selectWinnerSchema, selectWinner, onRefresh]) - const handleEdit = (vendor: QuotationVendor) => { setSelectedVendor(vendor) setIsEditDialogOpen(true) @@ -192,12 +129,10 @@ export function BiddingDetailVendorTableContent({ const columns = React.useMemo( () => getBiddingDetailVendorColumns({ onEdit: onEdit || handleEdit, - onDelete: onDelete, - onSelectWinner: onSelectWinner || handleSelectWinner, onViewPriceAdjustment: handleViewPriceAdjustment, onViewItemDetails: onViewItemDetails }), - [onEdit, onDelete, onSelectWinner, handleEdit, handleSelectWinner, handleViewPriceAdjustment, onViewItemDetails] + [onEdit, handleEdit, handleViewPriceAdjustment, onViewItemDetails] ) const { table } = useDataTable({ @@ -224,11 +159,9 @@ export function BiddingDetailVendorTableContent({ shallow={false} > <BiddingDetailVendorToolbarActions - table={table} biddingId={biddingId} bidding={bidding} userId={userId} - onOpenItemsDialog={onOpenItemsDialog} onOpenTargetPriceDialog={onOpenTargetPriceDialog} onOpenAwardDialog={() => setIsAwardDialogOpen(true)} onSuccess={onRefresh} diff --git a/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx b/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx index eec44bb1..5d1bfde7 100644 --- a/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx +++ b/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx @@ -1,12 +1,11 @@ "use client" import * as React from "react" -import { type Table } from "@tanstack/react-table" import { useRouter } from "next/navigation" import { useTransition } from "react" import { Button } from "@/components/ui/button" import { Plus, Send, RotateCcw, XCircle, Trophy, FileText, DollarSign } from "lucide-react" -import { QuotationVendor, registerBidding, markAsDisposal, createRebidding, awardBidding } from "@/lib/bidding/detail/service" +import { registerBidding, markAsDisposal, createRebidding } from "@/lib/bidding/detail/service" import { sendBiddingBasicContracts, getSelectedVendorsForBidding } from "@/lib/bidding/pre-quote/service" import { BiddingDetailVendorCreateDialog } from "./bidding-detail-vendor-create-dialog" @@ -17,22 +16,18 @@ import { useToast } from "@/hooks/use-toast" import { BiddingInvitationDialog } from "./bidding-invitation-dialog" interface BiddingDetailVendorToolbarActionsProps { - table: Table<QuotationVendor> biddingId: number bidding: Bidding userId: string - onOpenItemsDialog: () => void onOpenTargetPriceDialog: () => void onOpenAwardDialog: () => void onSuccess: () => void } export function BiddingDetailVendorToolbarActions({ - table, biddingId, bidding, userId, - onOpenItemsDialog, onOpenTargetPriceDialog, onOpenAwardDialog, onSuccess @@ -306,7 +301,7 @@ export function BiddingDetailVendorToolbarActions({ biddingTitle={bidding.title} budget={bidding.budget ? parseFloat(bidding.budget.toString()) : null} targetPrice={bidding.targetPrice ? parseFloat(bidding.targetPrice.toString()) : null} - currency={bidding.currency} + currency={bidding.currency || ''} /> <BiddingInvitationDialog @@ -315,7 +310,7 @@ export function BiddingDetailVendorToolbarActions({ vendors={selectedVendors} biddingId={biddingId} biddingTitle={bidding.title || ''} - projectName={bidding.projectName} + projectName={bidding.projectName || ''} onSend={handleBiddingInvitationSend} /> </> diff --git a/lib/bidding/detail/table/bidding-vendor-prices-dialog.tsx b/lib/bidding/detail/table/bidding-vendor-prices-dialog.tsx index fb54eaba..c12ac1df 100644 --- a/lib/bidding/detail/table/bidding-vendor-prices-dialog.tsx +++ b/lib/bidding/detail/table/bidding-vendor-prices-dialog.tsx @@ -28,7 +28,6 @@ import { TrendingUp } from 'lucide-react' import { useToast } from '@/hooks/use-toast' -import { useTransition } from 'react' import { getVendorPricesForBidding } from '../service' interface VendorPrice { @@ -70,7 +69,6 @@ export function BiddingVendorPricesDialog({ currency = 'KRW' }: BiddingVendorPricesDialogProps) { const { toast } = useToast() - const [isPending, startTransition] = useTransition() const [vendorPrices, setVendorPrices] = React.useState<VendorPrice[]>([]) const [isLoading, setIsLoading] = React.useState(false) const [viewMode, setViewMode] = React.useState<'quantity' | 'weight'>('quantity') |
