diff options
Diffstat (limited to 'lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx')
| -rw-r--r-- | lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx b/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx new file mode 100644 index 00000000..a48aadd2 --- /dev/null +++ b/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx @@ -0,0 +1,260 @@ +'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 { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { updateQuotationVendor } from '@/lib/bidding/detail/service' +import { updateQuotationVendorSchema } from '@/lib/bidding/validation' +import { QuotationVendor } from '@/lib/bidding/detail/service' +import { useToast } from '@/hooks/use-toast' +import { useTransition } from 'react' + +interface BiddingDetailVendorEditDialogProps { + vendor: QuotationVendor | null + open: boolean + onOpenChange: (open: boolean) => void + onSuccess: () => void +} + +export function BiddingDetailVendorEditDialog({ + vendor, + open, + onOpenChange, + onSuccess +}: BiddingDetailVendorEditDialogProps) { + const { toast } = useToast() + const [isPending, startTransition] = useTransition() + + // 폼 상태 + const [formData, setFormData] = React.useState({ + vendorName: '', + vendorCode: '', + contactPerson: '', + contactEmail: '', + contactPhone: '', + quotationAmount: 0, + currency: 'KRW', + paymentTerms: '', + taxConditions: '', + deliveryDate: '', + awardRatio: 0, + status: 'pending' as const, + }) + + // vendor가 변경되면 폼 데이터 업데이트 + React.useEffect(() => { + if (vendor) { + setFormData({ + vendorName: vendor.vendorName, + vendorCode: vendor.vendorCode, + contactPerson: vendor.contactPerson || '', + contactEmail: vendor.contactEmail || '', + contactPhone: vendor.contactPhone || '', + quotationAmount: vendor.quotationAmount, + currency: vendor.currency, + paymentTerms: vendor.paymentTerms || '', + taxConditions: vendor.taxConditions || '', + deliveryDate: vendor.deliveryDate || '', + awardRatio: vendor.awardRatio || 0, + status: vendor.status, + }) + } + }, [vendor]) + + const handleEdit = () => { + if (!vendor) return + + const result = updateQuotationVendorSchema.safeParse({ + id: vendor.id, + ...formData, + }) + + if (!result.success) { + toast({ + title: '유효성 오류', + description: result.error.issues[0]?.message || '입력값을 확인해주세요.', + variant: 'destructive', + }) + return + } + + startTransition(async () => { + const response = await updateQuotationVendor(vendor.id, result.data, 'current-user') + + if (response.success) { + toast({ + title: '성공', + description: response.message, + }) + onOpenChange(false) + onSuccess() + } else { + toast({ + title: '오류', + description: response.error, + variant: 'destructive', + }) + } + }) + } + + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent className="sm:max-w-[600px]"> + <DialogHeader> + <DialogTitle>협력업체 수정</DialogTitle> + <DialogDescription> + 협력업체 정보를 수정해주세요. + </DialogDescription> + </DialogHeader> + <div className="grid gap-4 py-4"> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="edit-vendorName">업체명</Label> + <Input + id="edit-vendorName" + value={formData.vendorName} + onChange={(e) => setFormData({ ...formData, vendorName: e.target.value })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-vendorCode">업체코드</Label> + <Input + id="edit-vendorCode" + value={formData.vendorCode} + onChange={(e) => setFormData({ ...formData, vendorCode: e.target.value })} + /> + </div> + </div> + <div className="grid grid-cols-3 gap-4"> + <div className="space-y-2"> + <Label htmlFor="edit-contactPerson">담당자</Label> + <Input + id="edit-contactPerson" + value={formData.contactPerson} + onChange={(e) => setFormData({ ...formData, contactPerson: e.target.value })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-contactEmail">이메일</Label> + <Input + id="edit-contactEmail" + type="email" + value={formData.contactEmail} + onChange={(e) => setFormData({ ...formData, contactEmail: e.target.value })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-contactPhone">연락처</Label> + <Input + id="edit-contactPhone" + value={formData.contactPhone} + onChange={(e) => setFormData({ ...formData, contactPhone: e.target.value })} + /> + </div> + </div> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="edit-quotationAmount">견적금액</Label> + <Input + id="edit-quotationAmount" + type="number" + value={formData.quotationAmount} + onChange={(e) => setFormData({ ...formData, quotationAmount: Number(e.target.value) })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-currency">통화</Label> + <Select value={formData.currency} onValueChange={(value) => setFormData({ ...formData, currency: value })}> + <SelectTrigger> + <SelectValue /> + </SelectTrigger> + <SelectContent> + <SelectItem value="KRW">KRW</SelectItem> + <SelectItem value="USD">USD</SelectItem> + <SelectItem value="EUR">EUR</SelectItem> + </SelectContent> + </Select> + </div> + </div> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="edit-awardRatio">발주비율 (%)</Label> + <Input + id="edit-awardRatio" + type="number" + min="0" + max="100" + value={formData.awardRatio} + onChange={(e) => setFormData({ ...formData, awardRatio: Number(e.target.value) })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-status">상태</Label> + <Select value={formData.status} onValueChange={(value: any) => setFormData({ ...formData, status: value })}> + <SelectTrigger> + <SelectValue /> + </SelectTrigger> + <SelectContent> + <SelectItem value="pending">대기</SelectItem> + <SelectItem value="submitted">제출</SelectItem> + <SelectItem value="selected">선정</SelectItem> + <SelectItem value="rejected">거절</SelectItem> + </SelectContent> + </Select> + </div> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-paymentTerms">지급조건</Label> + <Input + id="edit-paymentTerms" + value={formData.paymentTerms} + onChange={(e) => setFormData({ ...formData, paymentTerms: e.target.value })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-taxConditions">세금조건</Label> + <Input + id="edit-taxConditions" + value={formData.taxConditions} + onChange={(e) => setFormData({ ...formData, taxConditions: e.target.value })} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="edit-deliveryDate">납품일</Label> + <Input + id="edit-deliveryDate" + type="date" + value={formData.deliveryDate} + onChange={(e) => setFormData({ ...formData, deliveryDate: e.target.value })} + /> + </div> + </div> + <DialogFooter> + <Button variant="outline" onClick={() => onOpenChange(false)}> + 취소 + </Button> + <Button onClick={handleEdit} disabled={isPending}> + 수정 + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) +} |
