'use client' 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, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' import { Check, ChevronsUpDown, Search, Loader2, X, Plus } from 'lucide-react' import { cn } from '@/lib/utils' import { createBiddingDetailVendor } from '@/lib/bidding/detail/service' import { searchVendorsForBidding } from '@/lib/bidding/service' import { useToast } from '@/hooks/use-toast' import { useTransition } from 'react' import { Badge } from '@/components/ui/badge' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' interface BiddingDetailVendorCreateDialogProps { biddingId: number open: boolean onOpenChange: (open: boolean) => void onSuccess: () => void } interface Vendor { id: number vendorName: string vendorCode: string status: string } export function BiddingDetailVendorCreateDialog({ biddingId, open, onOpenChange, onSuccess }: BiddingDetailVendorCreateDialogProps) { const { toast } = useToast() const [isPending, startTransition] = useTransition() // Vendor 검색 상태 const [vendorList, setVendorList] = React.useState([]) const [selectedVendors, setSelectedVendors] = React.useState([]) const [vendorOpen, setVendorOpen] = React.useState(false) // 폼 상태 (간소화 - 필수 항목만) const [formData, setFormData] = React.useState({ awardRatio: 100, // 기본 100% }) // 벤더 로드 const loadVendors = React.useCallback(async () => { try { const result = await searchVendorsForBidding('', biddingId) // 빈 검색어로 모든 벤더 로드 setVendorList(result || []) } catch (error) { console.error('Failed to load vendors:', error) toast({ title: '오류', description: '벤더 목록을 불러오는데 실패했습니다.', variant: 'destructive', }) setVendorList([]) } }, [biddingId]) React.useEffect(() => { if (open) { loadVendors() } }, [open, loadVendors]) // 초기화 React.useEffect(() => { if (!open) { setSelectedVendors([]) setFormData({ awardRatio: 100, // 기본 100% }) } }, [open]) // 벤더 추가 const handleAddVendor = (vendor: Vendor) => { if (!selectedVendors.find(v => v.id === vendor.id)) { setSelectedVendors([...selectedVendors, vendor]) } setVendorOpen(false) } // 벤더 제거 const handleRemoveVendor = (vendorId: number) => { setSelectedVendors(selectedVendors.filter(v => v.id !== vendorId)) } // 이미 선택된 벤더인지 확인 const isVendorSelected = (vendorId: number) => { return selectedVendors.some(v => v.id === vendorId) } const handleCreate = () => { if (selectedVendors.length === 0) { toast({ title: '오류', description: '업체를 선택해주세요.', variant: 'destructive', }) return } startTransition(async () => { let successCount = 0 let errorMessages: string[] = [] for (const vendor of selectedVendors) { try { const response = await createBiddingDetailVendor( biddingId, vendor.id ) if (response.success) { successCount++ } else { errorMessages.push(`${vendor.vendorName}: ${response.error}`) } } catch (error) { errorMessages.push(`${vendor.vendorName}: 처리 중 오류가 발생했습니다.`) } } if (successCount > 0) { toast({ title: '성공', description: `${successCount}개의 업체가 성공적으로 추가되었습니다.${errorMessages.length > 0 ? ` ${errorMessages.length}개는 실패했습니다.` : ''}`, }) onOpenChange(false) resetForm() onSuccess() } if (errorMessages.length > 0 && successCount === 0) { toast({ title: '오류', description: `업체 추가에 실패했습니다: ${errorMessages.join(', ')}`, variant: 'destructive', }) } }) } const resetForm = () => { setSelectedVendors([]) setFormData({ awardRatio: 100, // 기본 100% }) } return ( {/* 헤더 */} 협력업체 추가 입찰에 참여할 업체를 선택하세요. 여러 개 선택 가능합니다. {/* 메인 컨텐츠 */}
{/* 업체 선택 카드 */} 업체 선택 입찰에 참여할 협력업체를 선택하세요.
{/* 업체 추가 버튼 */} 검색 결과가 없습니다. {vendorList .filter(vendor => !isVendorSelected(vendor.id)) .map((vendor) => ( handleAddVendor(vendor)} >
{vendor.vendorCode} {vendor.vendorName}
))}
{/* 선택된 업체 목록 */} {selectedVendors.length > 0 && (

선택된 업체 ({selectedVendors.length}개)

{selectedVendors.map((vendor, index) => (
{index + 1}. {vendor.vendorCode} {vendor.vendorName}
))}
)} {selectedVendors.length === 0 && (

아직 선택된 업체가 없습니다.

위 버튼을 클릭하여 업체를 추가하세요.

)}
{/* 푸터 */}
) }