summaryrefslogtreecommitdiff
path: root/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx')
-rw-r--r--lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx88
1 files changed, 80 insertions, 8 deletions
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 484b1b1e..0b707944 100644
--- a/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx
+++ b/lib/bidding/detail/table/bidding-detail-vendor-toolbar-actions.tsx
@@ -7,11 +7,14 @@ 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 { sendBiddingBasicContracts, getSelectedVendorsForBidding } from "@/lib/bidding/pre-quote/service"
+
import { BiddingDetailVendorCreateDialog } from "./bidding-detail-vendor-create-dialog"
import { BiddingDocumentUploadDialog } from "./bidding-document-upload-dialog"
import { BiddingVendorPricesDialog } from "./bidding-vendor-prices-dialog"
import { Bidding } from "@/db/schema"
import { useToast } from "@/hooks/use-toast"
+import { BiddingInvitationDialog } from "./bidding-invitation-dialog"
interface BiddingDetailVendorToolbarActionsProps {
table: Table<QuotationVendor>
@@ -40,6 +43,17 @@ export function BiddingDetailVendorToolbarActions({
const [isCreateDialogOpen, setIsCreateDialogOpen] = React.useState(false)
const [isDocumentDialogOpen, setIsDocumentDialogOpen] = React.useState(false)
const [isPricesDialogOpen, setIsPricesDialogOpen] = React.useState(false)
+ const [isBiddingInvitationDialogOpen, setIsBiddingInvitationDialogOpen] = React.useState(false)
+ const [selectedVendors, setSelectedVendors] = React.useState<any[]>([])
+
+ // 본입찰 초대 다이얼로그가 열릴 때 선정된 업체들 조회
+ React.useEffect(() => {
+ if (isBiddingInvitationDialogOpen) {
+ getSelectedVendors().then(vendors => {
+ setSelectedVendors(vendors)
+ })
+ }
+ }, [isBiddingInvitationDialogOpen, biddingId])
const handleCreateVendor = () => {
setIsCreateDialogOpen(true)
@@ -54,23 +68,71 @@ export function BiddingDetailVendorToolbarActions({
}
const handleRegister = () => {
- startTransition(async () => {
- const result = await registerBidding(bidding.id, userId)
+ // 본입찰 초대 다이얼로그 열기
+ setIsBiddingInvitationDialogOpen(true)
+ }
- if (result.success) {
+ const handleBiddingInvitationSend = async (data: any) => {
+ try {
+ // 1. 기본계약 발송
+ const contractResult = await sendBiddingBasicContracts(
+ biddingId,
+ data.vendors,
+ data.generatedPdfs,
+ data.message
+ )
+
+ if (!contractResult.success) {
toast({
- title: result.message,
- description: result.message,
+ title: '기본계약 발송 실패',
+ description: contractResult.error,
+ variant: 'destructive',
+ })
+ return
+ }
+
+ // 2. 입찰 등록 진행
+ const registerResult = await registerBidding(bidding.id, userId)
+
+ if (registerResult.success) {
+ toast({
+ title: '본입찰 초대 완료',
+ description: '기본계약 발송 및 본입찰 초대가 완료되었습니다.',
})
+ setIsBiddingInvitationDialogOpen(false)
router.refresh()
+ onSuccess()
} else {
toast({
- title: result.error,
- description: result.error,
+ title: '오류',
+ description: registerResult.error,
variant: 'destructive',
})
}
- })
+ } catch (error) {
+ console.error('본입찰 초대 실패:', error)
+ toast({
+ title: '오류',
+ description: '본입찰 초대에 실패했습니다.',
+ variant: 'destructive',
+ })
+ }
+ }
+
+ // 선정된 업체들 조회 (서버 액션 함수 사용)
+ const getSelectedVendors = async () => {
+ try {
+ const result = await getSelectedVendorsForBidding(biddingId)
+ if (result.success) {
+ return result.vendors
+ } else {
+ console.error('선정된 업체 조회 실패:', result.error)
+ return []
+ }
+ } catch (error) {
+ console.error('선정된 업체 조회 실패:', error)
+ return []
+ }
}
const handleMarkAsDisposal = () => {
@@ -234,6 +296,16 @@ export function BiddingDetailVendorToolbarActions({
targetPrice={bidding.targetPrice ? parseFloat(bidding.targetPrice.toString()) : null}
currency={bidding.currency}
/>
+
+ <BiddingInvitationDialog
+ open={isBiddingInvitationDialogOpen}
+ onOpenChange={setIsBiddingInvitationDialogOpen}
+ vendors={selectedVendors}
+ biddingId={biddingId}
+ biddingTitle={bidding.title || ''}
+ projectName={bidding.projectName}
+ onSend={handleBiddingInvitationSend}
+ />
</>
)
}