diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-12-05 06:29:23 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-12-05 06:29:23 +0000 |
| commit | d47334639bd717aa860563ec1020a29827524fd4 (patch) | |
| tree | 1841a95bb6e6dc336e00faa868235bbcd9b9f3f0 /lib/bidding/detail/table/price-adjustment-dialog.tsx | |
| parent | 93b6b8868d409c7f6c9d9222b93750848caaedde (diff) | |
(최겸)구매 결재일 기준 공고 수정
Diffstat (limited to 'lib/bidding/detail/table/price-adjustment-dialog.tsx')
| -rw-r--r-- | lib/bidding/detail/table/price-adjustment-dialog.tsx | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/lib/bidding/detail/table/price-adjustment-dialog.tsx b/lib/bidding/detail/table/price-adjustment-dialog.tsx new file mode 100644 index 00000000..14bbd843 --- /dev/null +++ b/lib/bidding/detail/table/price-adjustment-dialog.tsx @@ -0,0 +1,195 @@ +"use client" + +import * as React from "react" +import { Button } from "@/components/ui/button" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { Label } from "@/components/ui/label" +import { Textarea } from "@/components/ui/textarea" +import { Switch } from "@/components/ui/switch" +import { useToast } from "@/hooks/use-toast" +import { updatePriceAdjustmentInfo } from "@/lib/bidding/detail/service" +import { QuotationVendor } from "@/lib/bidding/detail/service" +import { Loader2 } from "lucide-react" + +interface PriceAdjustmentDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + vendor: QuotationVendor | null + onSuccess: () => void +} + +export function PriceAdjustmentDialog({ + open, + onOpenChange, + vendor, + onSuccess, +}: PriceAdjustmentDialogProps) { + const { toast } = useToast() + const [isSubmitting, setIsSubmitting] = React.useState(false) + + // 폼 상태 + const [shiPriceAdjustmentApplied, setSHIPriceAdjustmentApplied] = React.useState<boolean | null>(null) + const [priceAdjustmentNote, setPriceAdjustmentNote] = React.useState("") + const [hasChemicalSubstance, setHasChemicalSubstance] = React.useState<boolean | null>(null) + + // 다이얼로그가 열릴 때 벤더 정보로 폼 초기화 + React.useEffect(() => { + if (open && vendor) { + setSHIPriceAdjustmentApplied(vendor.shiPriceAdjustmentApplied ?? null) + setPriceAdjustmentNote(vendor.priceAdjustmentNote || "") + setHasChemicalSubstance(vendor.hasChemicalSubstance ?? null) + } + }, [open, vendor]) + + const handleSubmit = async () => { + if (!vendor) return + + setIsSubmitting(true) + try { + const result = await updatePriceAdjustmentInfo({ + biddingCompanyId: vendor.id, + shiPriceAdjustmentApplied, + priceAdjustmentNote: priceAdjustmentNote || null, + hasChemicalSubstance, + }) + + if (result.success) { + toast({ + title: "저장 완료", + description: "연동제 정보가 저장되었습니다.", + }) + onOpenChange(false) + onSuccess() + } else { + toast({ + title: "오류", + description: result.error || "저장 중 오류가 발생했습니다.", + variant: "destructive", + }) + } + } catch (error) { + console.error("연동제 정보 저장 오류:", error) + toast({ + title: "오류", + description: "저장 중 오류가 발생했습니다.", + variant: "destructive", + }) + } finally { + setIsSubmitting(false) + } + } + + if (!vendor) return null + + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent className="sm:max-w-[500px]"> + <DialogHeader> + <DialogTitle>연동제 적용 설정</DialogTitle> + <DialogDescription> + <span className="font-semibold text-primary">{vendor.vendorName}</span> 업체의 연동제 적용 여부 및 화학물질 정보를 설정합니다. + </DialogDescription> + </DialogHeader> + + <div className="space-y-6 py-4"> + {/* 업체가 제출한 연동제 요청 여부 (읽기 전용) */} + <div className="flex flex-row items-center justify-between rounded-lg border p-4 bg-muted/50"> + <div className="space-y-0.5"> + <Label className="text-base">업체 연동제 요청</Label> + <p className="text-sm text-muted-foreground"> + 업체가 제출한 연동제 적용 요청 여부입니다. + </p> + </div> + <span className={`font-medium ${vendor.isPriceAdjustmentApplicableQuestion ? 'text-green-600' : 'text-gray-500'}`}> + {vendor.isPriceAdjustmentApplicableQuestion === null ? '미정' : vendor.isPriceAdjustmentApplicableQuestion ? '예' : '아니오'} + </span> + </div> + + {/* SHI 연동제 적용여부 */} + <div className="flex flex-row items-center justify-between rounded-lg border p-4"> + <div className="space-y-0.5"> + <Label className="text-base">SHI 연동제 적용</Label> + <p className="text-sm text-muted-foreground"> + 해당 업체에 연동제를 적용할지 결정합니다. + </p> + </div> + <div className="flex items-center gap-3"> + <span className={`text-sm ${shiPriceAdjustmentApplied === false ? 'font-medium' : 'text-muted-foreground'}`}> + 미적용 + </span> + <Switch + checked={shiPriceAdjustmentApplied === true} + onCheckedChange={(checked) => setSHIPriceAdjustmentApplied(checked)} + /> + <span className={`text-sm ${shiPriceAdjustmentApplied === true ? 'font-medium' : 'text-muted-foreground'}`}> + 적용 + </span> + </div> + </div> + + {/* 연동제 Note */} + <div className="space-y-2"> + <Label htmlFor="price-adjustment-note">연동제 Note</Label> + <Textarea + id="price-adjustment-note" + placeholder="연동제 관련 추가 사항을 입력하세요" + value={priceAdjustmentNote} + onChange={(e) => setPriceAdjustmentNote(e.target.value)} + rows={4} + /> + </div> + + {/* 화학물질 여부 */} + <div className="flex flex-row items-center justify-between rounded-lg border p-4"> + <div className="space-y-0.5"> + <Label className="text-base">화학물질 해당여부</Label> + <p className="text-sm text-muted-foreground"> + 해당 업체가 화학물질 취급 대상인지 여부입니다. + </p> + </div> + <div className="flex items-center gap-3"> + <span className={`text-sm ${hasChemicalSubstance === false ? 'font-medium' : 'text-muted-foreground'}`}> + 해당없음 + </span> + <Switch + checked={hasChemicalSubstance === true} + onCheckedChange={(checked) => setHasChemicalSubstance(checked)} + /> + <span className={`text-sm ${hasChemicalSubstance === true ? 'font-medium text-red-600' : 'text-muted-foreground'}`}> + 해당 + </span> + </div> + </div> + </div> + + <DialogFooter> + <Button + variant="outline" + onClick={() => onOpenChange(false)} + disabled={isSubmitting} + > + 취소 + </Button> + <Button onClick={handleSubmit} disabled={isSubmitting}> + {isSubmitting ? ( + <> + <Loader2 className="mr-2 h-4 w-4 animate-spin" /> + 저장 중... + </> + ) : ( + "저장" + )} + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) +} + |
