summaryrefslogtreecommitdiff
path: root/lib/rfq-last/vendor/edit-contract-dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfq-last/vendor/edit-contract-dialog.tsx')
-rw-r--r--lib/rfq-last/vendor/edit-contract-dialog.tsx237
1 files changed, 237 insertions, 0 deletions
diff --git a/lib/rfq-last/vendor/edit-contract-dialog.tsx b/lib/rfq-last/vendor/edit-contract-dialog.tsx
new file mode 100644
index 00000000..62b851fa
--- /dev/null
+++ b/lib/rfq-last/vendor/edit-contract-dialog.tsx
@@ -0,0 +1,237 @@
+"use client";
+
+import * as React from "react";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog";
+import { Button } from "@/components/ui/button";
+import { Label } from "@/components/ui/label";
+import { Checkbox } from "@/components/ui/checkbox";
+import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
+import { Separator } from "@/components/ui/separator";
+import { Badge } from "@/components/ui/badge";
+import { Alert, AlertDescription } from "@/components/ui/alert";
+import { FileText, Shield, Globe, Info, Loader2 } from "lucide-react";
+import { toast } from "sonner";
+import { updateVendorContractRequirements } from "../service";
+
+interface EditContractDialogProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+ rfqId: number;
+ vendor: {
+ detailId: number;
+ vendorId: number;
+ vendorName: string;
+ vendorCode?: string;
+ vendorCountry?: string;
+ agreementYn?: boolean;
+ ndaYn?: boolean;
+ generalGtcYn?: boolean;
+ projectGtcYn?: boolean;
+ gtcType?: "general" | "project" | "none";
+ };
+ onSuccess: () => void;
+}
+
+export function EditContractDialog({
+ open,
+ onOpenChange,
+ rfqId,
+ vendor,
+ onSuccess,
+}: EditContractDialogProps) {
+ const [isLoading, setIsLoading] = React.useState(false);
+
+ // 기본계약 상태
+ const [contractAgreement, setContractAgreement] = React.useState(false);
+ const [contractNDA, setContractNDA] = React.useState(false);
+ const [contractGTC, setContractGTC] = React.useState<"general" | "project" | "none">("none");
+
+ // 국외 업체 확인
+ const isInternational = React.useMemo(() => {
+ return vendor?.vendorCountry &&
+ vendor.vendorCountry !== "KR" &&
+ vendor.vendorCountry !== "한국";
+ }, [vendor]);
+
+ // 초기값 설정
+ React.useEffect(() => {
+ if (open && vendor) {
+ setContractAgreement(vendor.agreementYn || false);
+ setContractNDA(vendor.ndaYn || false);
+
+ // GTC 타입 결정
+ if (vendor.gtcType) {
+ setContractGTC(vendor.gtcType);
+ } else if (vendor.generalGtcYn) {
+ setContractGTC("general");
+ } else if (vendor.projectGtcYn) {
+ setContractGTC("project");
+ } else {
+ setContractGTC("none");
+ }
+ }
+ }, [open, vendor]);
+
+ // 제출 처리
+ const handleSubmit = async () => {
+ setIsLoading(true);
+
+ try {
+ const result = await updateVendorContractRequirements({
+ rfqId,
+ detailId: vendor.detailId,
+ contractRequirements: {
+ agreementYn: contractAgreement,
+ ndaYn: contractNDA,
+ gtcType: isInternational ? contractGTC : "none",
+ },
+ });
+
+ if (result.success) {
+ toast.success("기본계약 요구사항이 업데이트되었습니다.");
+ onSuccess();
+ onOpenChange(false);
+ } else {
+ toast.error(result.error || "업데이트에 실패했습니다.");
+ }
+ } catch (error) {
+ console.error("Update error:", error);
+ toast.error("오류가 발생했습니다.");
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+ <Dialog open={open} onOpenChange={onOpenChange}>
+ <DialogContent className="max-w-md">
+ <DialogHeader>
+ <DialogTitle>기본계약 수정</DialogTitle>
+ <DialogDescription>
+ <div className="flex items-center gap-2 mt-2">
+ <Badge variant="outline">{vendor?.vendorCode}</Badge>
+ <span className="text-sm font-medium">{vendor?.vendorName}</span>
+ {vendor?.vendorCountry && (
+ <Badge
+ variant={isInternational ? "secondary" : "default"}
+ className="text-xs"
+ >
+ {vendor.vendorCountry}
+ </Badge>
+ )}
+ </div>
+ </DialogDescription>
+ </DialogHeader>
+
+ <div className="space-y-4 py-4">
+ {/* 필수 계약 */}
+ <div className="space-y-3">
+ <Label className="text-sm font-semibold">필수 계약</Label>
+ <div className="space-y-2">
+ <div className="flex items-center space-x-2">
+ <Checkbox
+ id="edit-agreement"
+ checked={contractAgreement}
+ onCheckedChange={(checked) => setContractAgreement(!!checked)}
+ />
+ <label
+ htmlFor="edit-agreement"
+ className="flex items-center gap-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
+ >
+ <FileText className="h-4 w-4 text-blue-500" />
+ 기술자료 제공 동의
+ </label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <Checkbox
+ id="edit-nda"
+ checked={contractNDA}
+ onCheckedChange={(checked) => setContractNDA(!!checked)}
+ />
+ <label
+ htmlFor="edit-nda"
+ className="flex items-center gap-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
+ >
+ <Shield className="h-4 w-4 text-green-500" />
+ 비밀유지 계약 (NDA)
+ </label>
+ </div>
+ </div>
+ </div>
+
+ {/* GTC 선택 (국외 업체만) */}
+ {isInternational && (
+ <>
+ <Separator />
+ <div className="space-y-3">
+ <div className="flex items-center justify-between">
+ <Label className="text-sm font-semibold flex items-center gap-2">
+ <Globe className="h-4 w-4" />
+ GTC (General Terms & Conditions)
+ </Label>
+ <Badge variant="outline" className="text-xs">
+ 국외 업체
+ </Badge>
+ </div>
+ <RadioGroup
+ value={contractGTC}
+ onValueChange={(value: any) => setContractGTC(value)}
+ >
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="none" id="edit-gtc-none" />
+ <label htmlFor="edit-gtc-none" className="text-sm">
+ GTC 요구하지 않음
+ </label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="general" id="edit-gtc-general" />
+ <label htmlFor="edit-gtc-general" className="text-sm">
+ General GTC
+ </label>
+ </div>
+ <div className="flex items-center space-x-2">
+ <RadioGroupItem value="project" id="edit-gtc-project" />
+ <label htmlFor="edit-gtc-project" className="text-sm">
+ Project GTC
+ </label>
+ </div>
+ </RadioGroup>
+ </div>
+ </>
+ )}
+
+ {/* 국내 업체 안내 */}
+ {!isInternational && (
+ <Alert>
+ <Info className="h-4 w-4" />
+ <AlertDescription>
+ 국내 업체는 GTC가 적용되지 않습니다.
+ </AlertDescription>
+ </Alert>
+ )}
+ </div>
+
+ <DialogFooter>
+ <Button
+ variant="outline"
+ onClick={() => onOpenChange(false)}
+ disabled={isLoading}
+ >
+ 취소
+ </Button>
+ <Button onClick={handleSubmit} disabled={isLoading}>
+ {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
+ 저장
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
+ );
+} \ No newline at end of file