summaryrefslogtreecommitdiff
path: root/lib/bidding/detail/table/bidding-detail-vendor-edit-dialog.tsx
diff options
context:
space:
mode:
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.tsx260
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>
+ )
+}