"use client" import * as React from "react" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { z } from "zod" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "@/components/ui/sheet" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { GENERAL_CONTRACT_CATEGORIES, GENERAL_CONTRACT_TYPES, GENERAL_EXECUTION_METHODS, } from "@/lib/general-contracts/types" import { updateContract } from "../service" import { GeneralContractListItem } from "./general-contracts-table-columns" import { useSession } from "next-auth/react" const updateContractSchema = z.object({ category: z.string().min(1, "계약구분을 선택해주세요"), type: z.string().min(1, "계약종류를 선택해주세요"), executionMethod: z.string().min(1, "체결방식을 선택해주세요"), name: z.string().min(1, "계약명을 입력해주세요"), startDate: z.string().optional(), // AD, LO, OF 계약인 경우 선택사항 endDate: z.string().optional(), // AD, LO, OF 계약인 경우 선택사항 validityEndDate: z.string().optional(), contractScope: z.string().optional(), notes: z.string().optional(), linkedRfqOrItb: z.string().optional(), linkedPoNumber: z.string().optional(), linkedBidNumber: z.string().optional(), }).superRefine((data, ctx) => { // AD, LO, OF 계약이 아닌 경우 계약기간 필수값 체크 if (!['AD', 'LO', 'OF'].includes(data.type)) { if (!data.startDate) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "계약시작일을 선택해주세요", path: ["startDate"], }) } if (!data.endDate) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "계약종료일을 선택해주세요", path: ["endDate"], }) } } }) type UpdateContractFormData = z.infer interface GeneralContractUpdateSheetProps { contract: GeneralContractListItem | null open: boolean onOpenChange: (open: boolean) => void onSuccess?: () => void } export function GeneralContractUpdateSheet({ contract, open, onOpenChange, onSuccess, }: GeneralContractUpdateSheetProps) { const [isSubmitting, setIsSubmitting] = React.useState(false) const session = useSession() const userId = session.data?.user?.id ? Number(session.data.user.id) : null const form = useForm({ resolver: zodResolver(updateContractSchema), defaultValues: { category: "", type: "", executionMethod: "", name: "", startDate: "", endDate: "", validityEndDate: "", contractScope: "", notes: "", linkedRfqOrItb: "", linkedPoNumber: "", linkedBidNumber: "", }, }) // 계약확정범위에 따른 품목정보 필드 비활성화 여부 const watchedContractScope = form.watch("contractScope") const isItemsDisabled = watchedContractScope === '단가' || watchedContractScope === '물량(실적)' // 계약 데이터가 변경될 때 폼 초기화 React.useEffect(() => { if (contract) { console.log("Loading contract data:", contract) // 날짜 포맷팅 헬퍼 (YYYY-MM-DD) const formatDateValue = (dateStr: string | null | undefined) => { if (!dateStr) return "" // KST 기준 날짜 변환 (입찰 로직과 동일) const date = new Date(dateStr) return new Date(date.getTime() + 9 * 60 * 60 * 1000).toISOString().slice(0, 10) } const formData = { category: contract.category || "", type: contract.type || "", executionMethod: contract.executionMethod || "", name: contract.name || "", startDate: formatDateValue(contract.startDate), endDate: formatDateValue(contract.endDate), validityEndDate: formatDateValue(contract.validityEndDate), contractScope: contract.contractScope || "", notes: contract.notes || "", linkedRfqOrItb: contract.linkedRfqOrItb || "", linkedPoNumber: contract.linkedPoNumber || "", linkedBidNumber: contract.linkedBidNumber || "", } console.log("Form data to reset:", formData) form.reset(formData) } }, [contract, form]) const onSubmit = async (data: UpdateContractFormData) => { if (!contract) return try { setIsSubmitting(true) await updateContract(contract.id, { category: data.category, type: data.type, executionMethod: data.executionMethod, name: data.name, startDate: data.startDate, endDate: data.endDate, validityEndDate: data.validityEndDate, contractScope: data.contractScope, notes: data.notes, linkedRfqOrItb: data.linkedRfqOrItb, linkedPoNumber: data.linkedPoNumber, linkedBidNumber: data.linkedBidNumber, vendorId: contract.vendorId, lastUpdatedById: userId, }) toast.success("계약 정보가 성공적으로 수정되었습니다.") onOpenChange(false) onSuccess?.() } catch (error) { console.error("Error updating contract:", error) toast.error("계약 정보 수정 중 오류가 발생했습니다.") } finally { setIsSubmitting(false) } } return ( 계약 정보 수정 계약의 기본 정보를 수정합니다. 변경사항은 즉시 저장됩니다.
{/* 계약구분 */} ( 계약구분 * )} /> {/* 계약종류 */} ( 계약종류 * {field.value === 'SC' && (

납품예정 품목 및 수량을 명기하세요. 납품 품목 또는 작업 내용은 구체적으로 작성하되, 수량(물량)이 정확하지 않을 경우, 상호협의하에 변경 가능하며, 수량(물량) 등은 개별계약(PO)시 명기하세요

)}
)} /> {/* 계약번호 */}
{/* 체결방식 */} ( 체결방식 * )} /> {/* 계약명 */} ( 계약명 * )} /> {/* 협력업체명 + 코드 */}
{/* 계약시작일 */} ( 계약시작일 {!['AD', 'LO', 'OF'].includes(form.watch('type')) && *} )} /> {/* 계약종료일 */} ( 계약종료일 {!['AD', 'LO', 'OF'].includes(form.watch('type')) && *} )} /> {/* 유효기간종료일 */} ( 유효기간종료일 )} /> {/* 계약확정범위 */} {/* ( 계약확정범위

해당 계약으로 확정되는 범위를 선택하세요.

)} /> */} {/* 비고 */} ( 비고