"use client" import * as React from "react" import { zodResolver } from "@hookform/resolvers/zod" import { Loader } from "lucide-react" import { useForm } from "react-hook-form" import { toast } from "sonner" import * as z from "zod" import { Button } from "@/components/ui/button" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription, } from "@/components/ui/form" import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "@/components/ui/sheet" import { Input } from "@/components/ui/input" import { Dropzone, DropzoneZone, DropzoneUploadIcon, DropzoneTitle, DropzoneDescription, DropzoneInput } from "@/components/ui/dropzone" import { updateTemplate } from "../service" import { BasicContractTemplate } from "@/db/schema" // 업데이트 템플릿 스키마 정의 (유효기간 필드 추가) export const updateTemplateSchema = z.object({ templateName: z.string().min(1, "템플릿 이름은 필수입니다."), validityPeriod: z.coerce .number({ invalid_type_error: "유효기간은 숫자여야 합니다." }) .int("유효기간은 정수여야 합니다.") .min(1, "유효기간은 최소 1개월 이상이어야 합니다.") .max(120, "유효기간은 최대 120개월(10년)을 초과할 수 없습니다.") .default(12), status: z.enum(["ACTIVE", "INACTIVE"], { required_error: "상태는 필수 선택사항입니다.", }), file: z.instanceof(File, { message: "파일을 업로드해주세요." }).optional(), }) export type UpdateTemplateSchema = z.infer interface UpdateTemplateSheetProps extends React.ComponentPropsWithRef { template: BasicContractTemplate | null onSuccess?: () => void } export function UpdateTemplateSheet({ template, onSuccess, ...props }: UpdateTemplateSheetProps) { const [isUpdatePending, startUpdateTransition] = React.useTransition() const [selectedFile, setSelectedFile] = React.useState(null) // 템플릿 데이터 확인을 위한 로그 console.log(template) const form = useForm({ resolver: zodResolver(updateTemplateSchema), defaultValues: { templateName: template?.templateName ?? "", validityPeriod: template?.validityPeriod ?? 12, // 기본값 12개월 status: (template?.status as "ACTIVE" | "INACTIVE") || "ACTIVE" }, mode: "onChange" }) // 파일 선택 핸들러 const handleFileChange = (files: File[]) => { if (files.length > 0) { const file = files[0]; setSelectedFile(file); form.setValue("file", file); } }; // 템플릿 변경 시 폼 값 업데이트 React.useEffect(() => { if (template) { form.reset({ templateName: template.templateName, validityPeriod: template.validityPeriod ?? 12, // 기존 값이 없으면 기본값 12개월 status: template.status as "ACTIVE" | "INACTIVE", }); } }, [template, form]); // 유효기간 선택 옵션 const validityOptions = [ { value: "3", label: "3개월" }, { value: "6", label: "6개월" }, { value: "12", label: "1년" }, { value: "24", label: "2년" }, { value: "36", label: "3년" }, { value: "60", label: "5년" }, ]; function onSubmit(input: UpdateTemplateSchema) { startUpdateTransition(async () => { if (!template) return // FormData 객체 생성하여 파일과 데이터를 함께 전송 const formData = new FormData(); formData.append("templateName", input.templateName); formData.append("validityPeriod", input.validityPeriod.toString()); // 유효기간 추가 formData.append("status", input.status); if (input.file) { formData.append("file", input.file); } try { // 서비스 함수 호출 const { error } = await updateTemplate({ id: template.id, formData, }); if (error) { toast.error(error); return; } form.reset(); setSelectedFile(null); props.onOpenChange?.(false); toast.success("템플릿이 성공적으로 업데이트되었습니다."); onSuccess?.(); } catch (error) { console.error("Update error:", error); toast.error("템플릿 업데이트 중 오류가 발생했습니다."); } }); } return ( 템플릿 업데이트 템플릿 정보를 수정하고 변경사항을 저장하세요
( 템플릿 이름 )} /> ( 계약 유효기간 계약서의 유효 기간을 설정합니다. 이 기간이 지나면 재계약이 필요합니다. )} /> ( 상태 )} /> ( 템플릿 파일 (선택사항) {selectedFile ? selectedFile.name : template?.fileName ? `현재 파일: ${template.fileName}` : "새 파일을 드래그하세요"} {selectedFile ? `파일 크기: ${(selectedFile.size / 1024).toFixed(2)} KB` : "또는 클릭하여 파일을 선택하세요 (선택사항)"} )} />
) }