"use client"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { LoadingSpinner } from "@/components/common/LoadingSpinner"; import { ValidationMessage } from "@/components/common/ValidationMessage"; import { useCreateCodeInfo, useUpdateCodeInfo } from "@/hooks/queries/useCodeInfo"; import { useCheckCodeInfoDuplicate } from "@/hooks/queries/useValidation"; import type { CodeInfo } from "@/types/commonCode"; import { createCodeInfoSchema, updateCodeInfoSchema, type CreateCodeInfoData, type UpdateCodeInfoData, } from "@/lib/schemas/commonCode"; interface CodeInfoFormModalProps { isOpen: boolean; onClose: () => void; editingCodeInfo?: string; existingRows: CodeInfo[]; } export function CodeInfoFormModal({ isOpen, onClose, editingCodeInfo, existingRows, }: CodeInfoFormModalProps) { const createMutation = useCreateCodeInfo(); const updateMutation = useUpdateCodeInfo(); const isEditing = !!editingCodeInfo; const editingRow = existingRows.find((r) => r.code_info === editingCodeInfo); const createForm = useForm({ resolver: zodResolver(createCodeInfoSchema), mode: "onChange", defaultValues: { code_info: "", code_name: "", code_name_eng: "", description: "", sort_order: 0, }, }); const updateForm = useForm({ resolver: zodResolver(updateCodeInfoSchema), mode: "onChange", defaultValues: { code_name: "", code_name_eng: "", description: "", sort_order: 0, is_active: "Y", }, }); const [validatedFields, setValidatedFields] = useState>(new Set()); const handleFieldBlur = (name: string) => { setValidatedFields((prev) => new Set(prev).add(name)); }; const codeCheck = useCheckCodeInfoDuplicate( "code_info", isEditing ? "" : createForm.watch("code_info"), isEditing ? editingCodeInfo : undefined, validatedFields.has("code_info"), ); const nameCheck = useCheckCodeInfoDuplicate( "code_name", isEditing ? updateForm.watch("code_name") : createForm.watch("code_name"), isEditing ? editingCodeInfo : undefined, validatedFields.has("code_name"), ); const nameEngCheck = useCheckCodeInfoDuplicate( "code_name_eng", isEditing ? updateForm.watch("code_name_eng") || "" : createForm.watch("code_name_eng") || "", isEditing ? editingCodeInfo : undefined, validatedFields.has("code_name_eng"), ); const hasDuplicateErrors = (!isEditing && codeCheck.data?.isDuplicate && validatedFields.has("code_info")) || (nameCheck.data?.isDuplicate && validatedFields.has("code_name")) || (nameEngCheck.data?.isDuplicate && validatedFields.has("code_name_eng")); const isDuplicateChecking = (!isEditing && codeCheck.isLoading) || nameCheck.isLoading || nameEngCheck.isLoading; useEffect(() => { if (!isOpen) return; setValidatedFields(new Set()); if (isEditing && editingRow) { updateForm.reset({ code_name: editingRow.code_name, code_name_eng: editingRow.code_name_eng || "", description: editingRow.description || "", sort_order: editingRow.sort_order ?? 0, is_active: (editingRow.is_active as "Y" | "N") || "Y", }); } else { const maxSort = existingRows.length > 0 ? Math.max(...existingRows.map((r) => r.sort_order ?? 0)) : 0; createForm.reset({ code_info: "", code_name: "", code_name_eng: "", description: "", sort_order: maxSort + 1, }); } }, [isOpen, isEditing, editingRow, existingRows]); // eslint-disable-line react-hooks/exhaustive-deps const handleSubmit = isEditing ? updateForm.handleSubmit(async (data) => { try { await updateMutation.mutateAsync({ codeInfo: editingCodeInfo!, data }); onClose(); updateForm.reset(); } catch (error) { console.error("그룹 수정 실패:", error); } }) : createForm.handleSubmit(async (data) => { try { await createMutation.mutateAsync(data); onClose(); createForm.reset(); } catch (error) { console.error("그룹 생성 실패:", error); } }); const isLoading = createMutation.isPending || updateMutation.isPending; return ( {isEditing ? "그룹 수정" : "새 그룹"}
{/* 그룹 코드 (code_info) */} {!isEditing && (
handleFieldBlur("code_info")} /> {createForm.formState.errors.code_info && (

{createForm.formState.errors.code_info.message}

)} {!createForm.formState.errors.code_info && ( )}
)} {isEditing && editingRow && (

그룹 코드는 수정할 수 없습니다.

)} {/* 그룹명 */}
handleFieldBlur("code_name")} /> {(isEditing ? updateForm.formState.errors.code_name : createForm.formState.errors.code_name) && (

{ (isEditing ? updateForm.formState.errors.code_name : createForm.formState.errors.code_name )?.message }

)} {!(isEditing ? updateForm.formState.errors.code_name : createForm.formState.errors.code_name) && ( )}
{/* 영문명 */}
handleFieldBlur("code_name_eng")} /> {!(isEditing ? updateForm.formState.errors.code_name_eng : createForm.formState.errors.code_name_eng) && ( )}
{/* 설명 */}