summaryrefslogtreecommitdiff
path: root/lib/rfq-last/vendor-response/editor/commercial-terms-form.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfq-last/vendor-response/editor/commercial-terms-form.tsx')
-rw-r--r--lib/rfq-last/vendor-response/editor/commercial-terms-form.tsx713
1 files changed, 713 insertions, 0 deletions
diff --git a/lib/rfq-last/vendor-response/editor/commercial-terms-form.tsx b/lib/rfq-last/vendor-response/editor/commercial-terms-form.tsx
new file mode 100644
index 00000000..143d08f3
--- /dev/null
+++ b/lib/rfq-last/vendor-response/editor/commercial-terms-form.tsx
@@ -0,0 +1,713 @@
+"use client"
+
+import * as React from "react"
+import { useFormContext } from "react-hook-form"
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
+import { Label } from "@/components/ui/label"
+import { Input } from "@/components/ui/input"
+import { Textarea } from "@/components/ui/textarea"
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
+import { Checkbox } from "@/components/ui/checkbox"
+import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
+import { Alert, AlertDescription } from "@/components/ui/alert"
+import { InfoIcon, ChevronsUpDown, Check, CalendarIcon, Loader2 } from "lucide-react"
+import { format } from "date-fns"
+import { Calendar } from "@/components/ui/calendar"
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
+import { Button } from "@/components/ui/button"
+import { cn } from "@/lib/utils"
+import { Badge } from "@/components/ui/badge"
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "@/components/ui/command"
+import {
+ getIncotermsForSelection,
+ getPaymentTermsForSelection,
+ getPlaceOfShippingForSelection,
+ getPlaceOfDestinationForSelection
+} from "@/lib/procurement-select/service"
+import { toast } from "sonner"
+
+interface CommercialTermsFormProps {
+ rfqDetail: any
+ rfq: any
+}
+
+interface SelectOption {
+ id: number
+ code: string
+ description: string
+}
+
+export default function CommercialTermsForm({ rfqDetail, rfq }: CommercialTermsFormProps) {
+ const { register, setValue, watch, formState: { errors } } = useFormContext()
+
+ console.log(rfqDetail,"rfqDetail")
+
+ // RFQ 코드가 F로 시작하는지 확인
+ const isFrameContract = rfq?.rfqCode?.startsWith("F")
+
+ // Select 옵션들 상태
+ const [incoterms, setIncoterms] = React.useState<SelectOption[]>([])
+ const [paymentTerms, setPaymentTerms] = React.useState<SelectOption[]>([])
+ const [shippingPlaces, setShippingPlaces] = React.useState<SelectOption[]>([])
+ const [destinationPlaces, setDestinationPlaces] = React.useState<SelectOption[]>([])
+
+ // 로딩 상태
+ const [incotermsLoading, setIncotermsLoading] = React.useState(false)
+ const [paymentTermsLoading, setPaymentTermsLoading] = React.useState(false)
+ const [shippingLoading, setShippingLoading] = React.useState(false)
+ const [destinationLoading, setDestinationLoading] = React.useState(false)
+
+ // Popover 열림 상태
+ const [incotermsOpen, setIncotermsOpen] = React.useState(false)
+ const [paymentTermsOpen, setPaymentTermsOpen] = React.useState(false)
+ const [shippingOpen, setShippingOpen] = React.useState(false)
+ const [destinationOpen, setDestinationOpen] = React.useState(false)
+
+ const vendorCurrency = watch("vendorCurrency")
+ const vendorPaymentTermsCode = watch("vendorPaymentTermsCode")
+ const vendorIncotermsCode = watch("vendorIncotermsCode")
+ const vendorDeliveryDate = watch("vendorDeliveryDate")
+ const vendorContractDuration = watch("vendorContractDuration")
+ const vendorFirstYn = watch("vendorFirstYn")
+ const vendorSparepartYn = watch("vendorSparepartYn")
+ const vendorMaterialPriceRelatedYn = watch("vendorMaterialPriceRelatedYn")
+
+ // 구매자 제시 조건과 다른지 확인
+ const isDifferentCurrency = vendorCurrency !== rfqDetail.currency
+ const isDifferentPaymentTerms = vendorPaymentTermsCode !== rfqDetail.paymentTermsCode
+ const isDifferentIncoterms = vendorIncotermsCode !== rfqDetail.incotermsCode
+ const isDifferentDeliveryDate = !isFrameContract && vendorDeliveryDate?.toISOString() !== rfqDetail.deliveryDate
+ const isDifferentContractDuration = isFrameContract && vendorContractDuration !== rfqDetail.contractDuration
+
+ // 데이터 로드 함수들
+ const loadIncoterms = React.useCallback(async () => {
+ setIncotermsLoading(true)
+ try {
+ const data = await getIncotermsForSelection()
+ setIncoterms(data)
+ } catch (error) {
+ console.error("Failed to load incoterms:", error)
+ toast.error("Incoterms 목록을 불러오는데 실패했습니다.")
+ } finally {
+ setIncotermsLoading(false)
+ }
+ }, [])
+
+ const loadPaymentTerms = React.useCallback(async () => {
+ setPaymentTermsLoading(true)
+ try {
+ const data = await getPaymentTermsForSelection()
+ setPaymentTerms(data)
+ } catch (error) {
+ console.error("Failed to load payment terms:", error)
+ toast.error("결제조건 목록을 불러오는데 실패했습니다.")
+ } finally {
+ setPaymentTermsLoading(false)
+ }
+ }, [])
+
+ const loadShippingPlaces = React.useCallback(async () => {
+ setShippingLoading(true)
+ try {
+ const data = await getPlaceOfShippingForSelection()
+ setShippingPlaces(data)
+ } catch (error) {
+ console.error("Failed to load shipping places:", error)
+ toast.error("선적지 목록을 불러오는데 실패했습니다.")
+ } finally {
+ setShippingLoading(false)
+ }
+ }, [])
+
+ const loadDestinationPlaces = React.useCallback(async () => {
+ setDestinationLoading(true)
+ try {
+ const data = await getPlaceOfDestinationForSelection()
+ setDestinationPlaces(data)
+ } catch (error) {
+ console.error("Failed to load destination places:", error)
+ toast.error("도착지 목록을 불러오는데 실패했습니다.")
+ } finally {
+ setDestinationLoading(false)
+ }
+ }, [])
+
+ // 컴포넌트 마운트 시 데이터 로드
+ React.useEffect(() => {
+ loadIncoterms()
+ loadPaymentTerms()
+ loadShippingPlaces()
+ loadDestinationPlaces()
+ }, [loadIncoterms, loadPaymentTerms, loadShippingPlaces, loadDestinationPlaces])
+
+ // 선택된 옵션 찾기
+ const selectedIncoterm = incoterms.find(i => i.code === vendorIncotermsCode)
+ const selectedPaymentTerm = paymentTerms.find(p => p.code === vendorPaymentTermsCode)
+ const selectedShipping = shippingPlaces.find(s => s.code === watch("vendorPlaceOfShipping"))
+ const selectedDestination = destinationPlaces.find(d => d.code === watch("vendorPlaceOfDestination"))
+
+ return (
+ <div className="space-y-6">
+ {/* 기본 상업 조건 */}
+ <Card>
+ <CardHeader>
+ <CardTitle>기본 상업 조건</CardTitle>
+ <CardDescription>
+ 구매자가 제시한 조건과 다른 경우, 변경 사유를 반드시 입력해주세요.
+ </CardDescription>
+ </CardHeader>
+ <CardContent className="space-y-6">
+ {/* 통화 */}
+ <div className="grid grid-cols-2 gap-4">
+ <div className="space-y-2">
+ <Label>구매자 제시 통화</Label>
+ <Input value={rfqDetail.currency || '-'} disabled />
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorCurrency">벤더 제안 통화</Label>
+ <Select
+ value={vendorCurrency}
+ onValueChange={(value) => setValue("vendorCurrency", value)}
+ >
+ <SelectTrigger>
+ <SelectValue placeholder="통화 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ <SelectItem value="USD">USD</SelectItem>
+ <SelectItem value="KRW">KRW</SelectItem>
+ <SelectItem value="EUR">EUR</SelectItem>
+ <SelectItem value="JPY">JPY</SelectItem>
+ <SelectItem value="CNY">CNY</SelectItem>
+ </SelectContent>
+ </Select>
+ </div>
+ </div>
+ {isDifferentCurrency && (
+ <div className="space-y-2">
+ <Label htmlFor="currencyReason">통화 변경 사유 *</Label>
+ <Textarea
+ id="currencyReason"
+ {...register("currencyReason")}
+ placeholder="통화 변경 사유를 입력하세요"
+ className="min-h-[80px]"
+ />
+ </div>
+ )}
+
+ {/* 지불 조건 */}
+ <div className="grid grid-cols-2 gap-4">
+ <div className="space-y-2">
+ <Label>구매자 제시 지불조건</Label>
+ <Input value={rfqDetail.paymentTermsDescription || rfqDetail.paymentTermsCode || '-'} disabled />
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorPaymentTermsCode">벤더 제안 지불조건</Label>
+ <Popover open={paymentTermsOpen} onOpenChange={setPaymentTermsOpen}>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ role="combobox"
+ aria-expanded={paymentTermsOpen}
+ className="w-full justify-between"
+ disabled={paymentTermsLoading}
+ >
+ {selectedPaymentTerm ? (
+ <span className="truncate">
+ {selectedPaymentTerm.code} - {selectedPaymentTerm.description}
+ </span>
+ ) : (
+ <span className="text-muted-foreground">
+ {paymentTermsLoading ? "로딩 중..." : "지불조건 선택"}
+ </span>
+ )}
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-full p-0" align="start">
+ <Command>
+ <CommandInput placeholder="코드 또는 설명으로 검색..." />
+ <CommandList>
+ <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+ <CommandGroup>
+ {paymentTerms.map((term) => (
+ <CommandItem
+ key={term.id}
+ value={`${term.code} ${term.description}`}
+ onSelect={() => {
+ setValue("vendorPaymentTermsCode", term.code)
+ setPaymentTermsOpen(false)
+ }}
+ >
+ <div className="flex items-center gap-2 w-full">
+ <span className="font-medium">{term.code}</span>
+ <span className="text-muted-foreground">-</span>
+ <span className="truncate">{term.description}</span>
+ <Check
+ className={cn(
+ "ml-auto h-4 w-4",
+ term.code === vendorPaymentTermsCode ? "opacity-100" : "opacity-0"
+ )}
+ />
+ </div>
+ </CommandItem>
+ ))}
+ </CommandGroup>
+ </CommandList>
+ </Command>
+ </PopoverContent>
+ </Popover>
+ </div>
+ </div>
+ {isDifferentPaymentTerms && (
+ <div className="space-y-2">
+ <Label htmlFor="paymentTermsReason">지불조건 변경 사유 *</Label>
+ <Textarea
+ id="paymentTermsReason"
+ {...register("paymentTermsReason")}
+ placeholder="지불조건 변경 사유를 입력하세요"
+ className="min-h-[80px]"
+ />
+ </div>
+ )}
+
+ {/* 인코텀즈 */}
+ <div className="grid grid-cols-2 gap-4">
+ <div className="space-y-2">
+ <Label>구매자 제시 인코텀즈</Label>
+ <Input value={`${rfqDetail.incotermsCode || ''} ${rfqDetail.incotermsDetail || ''}`.trim() || '-'} disabled />
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorIncotermsCode">벤더 제안 인코텀즈</Label>
+ <Popover open={incotermsOpen} onOpenChange={setIncotermsOpen}>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ role="combobox"
+ aria-expanded={incotermsOpen}
+ className="w-full justify-between"
+ disabled={incotermsLoading}
+ >
+ {selectedIncoterm ? (
+ <span className="truncate">
+ {selectedIncoterm.code} - {selectedIncoterm.description}
+ </span>
+ ) : (
+ <span className="text-muted-foreground">
+ {incotermsLoading ? "로딩 중..." : "인코텀즈 선택"}
+ </span>
+ )}
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-full p-0" align="start">
+ <Command>
+ <CommandInput placeholder="코드 또는 설명으로 검색..." />
+ <CommandList>
+ <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+ <CommandGroup>
+ {incoterms.map((incoterm) => (
+ <CommandItem
+ key={incoterm.id}
+ value={`${incoterm.code} ${incoterm.description}`}
+ onSelect={() => {
+ setValue("vendorIncotermsCode", incoterm.code)
+ setIncotermsOpen(false)
+ }}
+ >
+ <div className="flex items-center gap-2 w-full">
+ <span className="font-medium">{incoterm.code}</span>
+ <span className="text-muted-foreground">-</span>
+ <span className="truncate">{incoterm.description}</span>
+ <Check
+ className={cn(
+ "ml-auto h-4 w-4",
+ incoterm.code === vendorIncotermsCode ? "opacity-100" : "opacity-0"
+ )}
+ />
+ </div>
+ </CommandItem>
+ ))}
+ </CommandGroup>
+ </CommandList>
+ </Command>
+ </PopoverContent>
+ </Popover>
+ </div>
+ </div>
+ {isDifferentIncoterms && (
+ <div className="space-y-2">
+ <Label htmlFor="incotermsReason">인코텀즈 변경 사유 *</Label>
+ <Textarea
+ id="incotermsReason"
+ {...register("incotermsReason")}
+ placeholder="인코텀즈 변경 사유를 입력하세요"
+ className="min-h-[80px]"
+ />
+ </div>
+ )}
+
+ {/* 납기일 또는 계약 기간 */}
+ {isFrameContract ? (
+ // 계약 기간 (F로 시작하는 경우)
+ <div className="grid grid-cols-2 gap-4">
+ <div className="space-y-2">
+ <Label>구매자 제시 계약기간</Label>
+ <Input value={rfqDetail.contractDuration || '-'} disabled />
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorContractDuration">벤더 제안 계약기간</Label>
+ <Input
+ id="vendorContractDuration"
+ {...register("vendorContractDuration")}
+ placeholder="예: 12개월"
+ />
+ </div>
+ </div>
+ ) : (
+ // 납기일 (일반적인 경우)
+ <div className="grid grid-cols-2 gap-4">
+ <div className="space-y-2">
+ <Label>구매자 제시 납기일</Label>
+ <Input
+ value={rfqDetail.deliveryDate ? format(new Date(rfqDetail.deliveryDate), "yyyy-MM-dd") : '-'}
+ disabled
+ />
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorDeliveryDate">벤더 제안 납기일</Label>
+ <Popover>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ className={cn(
+ "w-full justify-start text-left font-normal",
+ !vendorDeliveryDate && "text-muted-foreground"
+ )}
+ >
+ <CalendarIcon className="mr-2 h-4 w-4" />
+ {vendorDeliveryDate ? format(vendorDeliveryDate, "yyyy-MM-dd") : "날짜 선택"}
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-auto p-0">
+ <Calendar
+ mode="single"
+ selected={vendorDeliveryDate}
+ onSelect={(date) => setValue("vendorDeliveryDate", date)}
+ initialFocus
+ />
+ </PopoverContent>
+ </Popover>
+ </div>
+ </div>
+ )}
+
+ {/* 납기일/계약기간 변경 사유 (공통) */}
+ {(isDifferentDeliveryDate || isDifferentContractDuration) && (
+ <div className="space-y-2">
+ <Label htmlFor="deliveryDateReason">
+ {isFrameContract ? "계약기간 변경 사유 *" : "납기일 변경 사유 *"}
+ </Label>
+ <Textarea
+ id="deliveryDateReason"
+ {...register("deliveryDateReason")}
+ placeholder={isFrameContract ? "계약기간 변경 사유를 입력하세요" : "납기일 변경 사유를 입력하세요"}
+ className="min-h-[80px]"
+ />
+ </div>
+ )}
+
+ {/* 기타 조건들 */}
+ <div className="grid grid-cols-2 gap-4">
+ <div className="space-y-2">
+ <Label htmlFor="vendorTaxCode">세금 코드</Label>
+ <Input
+ id="vendorTaxCode"
+ {...register("vendorTaxCode")}
+ placeholder="세금 코드 입력"
+ />
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorPlaceOfShipping">선적지</Label>
+ <Popover open={shippingOpen} onOpenChange={setShippingOpen}>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ role="combobox"
+ aria-expanded={shippingOpen}
+ className="w-full justify-between"
+ disabled={shippingLoading}
+ >
+ {selectedShipping ? (
+ <span className="truncate">
+ {selectedShipping.code} - {selectedShipping.description}
+ </span>
+ ) : (
+ <span className="text-muted-foreground">
+ {shippingLoading ? "로딩 중..." : "선적지 선택"}
+ </span>
+ )}
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-full p-0" align="start">
+ <Command>
+ <CommandInput placeholder="선적지 검색..." />
+ <CommandList>
+ <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+ <CommandGroup>
+ {shippingPlaces.map((place) => (
+ <CommandItem
+ key={place.id}
+ value={`${place.code} ${place.description}`}
+ onSelect={() => {
+ setValue("vendorPlaceOfShipping", place.code)
+ setShippingOpen(false)
+ }}
+ >
+ <div className="flex items-center gap-2 w-full">
+ <span className="font-medium">{place.code}</span>
+ <span className="text-muted-foreground">-</span>
+ <span className="truncate">{place.description}</span>
+ <Check
+ className={cn(
+ "ml-auto h-4 w-4",
+ place.code === watch("vendorPlaceOfShipping") ? "opacity-100" : "opacity-0"
+ )}
+ />
+ </div>
+ </CommandItem>
+ ))}
+ </CommandGroup>
+ </CommandList>
+ </Command>
+ </PopoverContent>
+ </Popover>
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorPlaceOfDestination">도착지</Label>
+ <Popover open={destinationOpen} onOpenChange={setDestinationOpen}>
+ <PopoverTrigger asChild>
+ <Button
+ variant="outline"
+ role="combobox"
+ aria-expanded={destinationOpen}
+ className="w-full justify-between"
+ disabled={destinationLoading}
+ >
+ {selectedDestination ? (
+ <span className="truncate">
+ {selectedDestination.code} - {selectedDestination.description}
+ </span>
+ ) : (
+ <span className="text-muted-foreground">
+ {destinationLoading ? "로딩 중..." : "도착지 선택"}
+ </span>
+ )}
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+ </Button>
+ </PopoverTrigger>
+ <PopoverContent className="w-full p-0" align="start">
+ <Command>
+ <CommandInput placeholder="도착지 검색..." />
+ <CommandList>
+ <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+ <CommandGroup>
+ {destinationPlaces.map((place) => (
+ <CommandItem
+ key={place.id}
+ value={`${place.code} ${place.description}`}
+ onSelect={() => {
+ setValue("vendorPlaceOfDestination", place.code)
+ setDestinationOpen(false)
+ }}
+ >
+ <div className="flex items-center gap-2 w-full">
+ <span className="font-medium">{place.code}</span>
+ <span className="text-muted-foreground">-</span>
+ <span className="truncate">{place.description}</span>
+ <Check
+ className={cn(
+ "ml-auto h-4 w-4",
+ place.code === watch("vendorPlaceOfDestination") ? "opacity-100" : "opacity-0"
+ )}
+ />
+ </div>
+ </CommandItem>
+ ))}
+ </CommandGroup>
+ </CommandList>
+ </Command>
+ </PopoverContent>
+ </Popover>
+ </div>
+ </div>
+ </CardContent>
+ </Card>
+
+ {/* 특수 조건 */}
+ <Card>
+ <CardHeader>
+ <CardTitle>특수 조건</CardTitle>
+ <CardDescription>
+ 구매자가 요청한 특수 조건에 대한 응답을 입력하세요.
+ </CardDescription>
+ </CardHeader>
+ <CardContent className="space-y-6">
+ {/* 초도품 관리 */}
+ {rfqDetail.firstYn && (
+ <div className="space-y-4">
+ <div className="flex items-center justify-between">
+ <Label>초도품 관리 요청</Label>
+ <Badge variant="secondary">요청됨</Badge>
+ </div>
+ {rfqDetail.firstDescription && (
+ <Alert>
+ <InfoIcon className="h-4 w-4" />
+ <AlertDescription>{rfqDetail.firstDescription}</AlertDescription>
+ </Alert>
+ )}
+ <div className="space-y-2">
+ <Label>초도품 관리 수용 여부</Label>
+ <RadioGroup
+ value={watch("vendorFirstAcceptance") || ""}
+ onValueChange={(value) => setValue("vendorFirstAcceptance", value)}
+ >
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="수용" id="first-accept" />
+ <Label htmlFor="first-accept">수용</Label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="부분수용" id="first-partial" />
+ <Label htmlFor="first-partial">부분수용</Label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="거부" id="first-reject" />
+ <Label htmlFor="first-reject">거부</Label>
+ </div>
+ </RadioGroup>
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorFirstDescription">초도품 관리 응답 상세</Label>
+ <Textarea
+ id="vendorFirstDescription"
+ {...register("vendorFirstDescription")}
+ placeholder="초도품 관리에 대한 상세 응답을 입력하세요"
+ className="min-h-[100px]"
+ />
+ </div>
+ </div>
+ )}
+
+ {/* Spare Part */}
+ {rfqDetail.sparepartYn && (
+ <div className="space-y-4">
+ <div className="flex items-center justify-between">
+ <Label>Spare Part 요청</Label>
+ <Badge variant="secondary">요청됨</Badge>
+ </div>
+ {rfqDetail.sparepartDescription && (
+ <Alert>
+ <InfoIcon className="h-4 w-4" />
+ <AlertDescription>{rfqDetail.sparepartDescription}</AlertDescription>
+ </Alert>
+ )}
+ <div className="space-y-2">
+ <Label>Spare Part 수용 여부</Label>
+ <RadioGroup
+ value={watch("vendorSparepartAcceptance") || ""}
+ onValueChange={(value) => setValue("vendorSparepartAcceptance", value)}
+ >
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="수용" id="spare-accept" />
+ <Label htmlFor="spare-accept">수용</Label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="부분수용" id="spare-partial" />
+ <Label htmlFor="spare-partial">부분수용</Label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="거부" id="spare-reject" />
+ <Label htmlFor="spare-reject">거부</Label>
+ </div>
+ </RadioGroup>
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorSparepartDescription">Spare Part 응답 상세</Label>
+ <Textarea
+ id="vendorSparepartDescription"
+ {...register("vendorSparepartDescription")}
+ placeholder="Spare Part에 대한 상세 응답을 입력하세요"
+ className="min-h-[100px]"
+ />
+ </div>
+ </div>
+ )}
+
+ {/* 연동제 적용 */}
+ {rfqDetail.materialPriceRelatedYn && (
+ <div className="space-y-4">
+ <div className="flex items-center justify-between">
+ <Label>연동제 적용 요청</Label>
+ <Badge variant="secondary">요청됨</Badge>
+ </div>
+ <div className="flex items-center space-x-2">
+ <Checkbox
+ id="vendorMaterialPriceRelatedYn"
+ checked={vendorMaterialPriceRelatedYn}
+ onCheckedChange={(checked) => setValue("vendorMaterialPriceRelatedYn", checked)}
+ />
+ <Label htmlFor="vendorMaterialPriceRelatedYn">연동제 적용 동의</Label>
+ </div>
+ <div className="space-y-2">
+ <Label htmlFor="vendorMaterialPriceRelatedReason">연동제 관련 의견</Label>
+ <Textarea
+ id="vendorMaterialPriceRelatedReason"
+ {...register("vendorMaterialPriceRelatedReason")}
+ placeholder="연동제 적용에 대한 의견을 입력하세요"
+ className="min-h-[100px]"
+ />
+ </div>
+ </div>
+ )}
+ </CardContent>
+ </Card>
+
+ {/* 추가 의견 */}
+ <Card>
+ <CardHeader>
+ <CardTitle>추가 의견</CardTitle>
+ <CardDescription>
+ 견적서에 대한 추가 의견을 입력하세요.
+ </CardDescription>
+ </CardHeader>
+ <CardContent className="space-y-4">
+ {/* <div className="space-y-2">
+ <Label htmlFor="technicalProposal">기술 제안서</Label>
+ <Textarea
+ id="technicalProposal"
+ {...register("technicalProposal")}
+ placeholder="기술적 제안사항을 입력하세요"
+ className="min-h-[120px]"
+ />
+ </div> */}
+ <div className="space-y-2">
+ {/* <Label htmlFor="generalRemark">일반 비고</Label> */}
+ <Textarea
+ id="generalRemark"
+ {...register("generalRemark")}
+ placeholder="추가 비고사항을 입력하세요"
+ className="min-h-[120px]"
+ />
+ </div>
+ </CardContent>
+ </Card>
+ </div>
+ )
+} \ No newline at end of file