"use client"; import { useEffect } 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 { useCategories, useCreateCategory, useUpdateCategory } from "@/hooks/queries/useCategories"; import { createCategorySchema, updateCategorySchema, type CreateCategoryData, type UpdateCategoryData, } from "@/lib/schemas/commonCode"; import type { CodeCategory } from "@/types/commonCode"; interface CodeCategoryFormModalProps { isOpen: boolean; onClose: () => void; editingCategoryCode?: string; } export function CodeCategoryFormModal({ isOpen, onClose, editingCategoryCode }: CodeCategoryFormModalProps) { const { data: categories = [] } = useCategories(); const createCategoryMutation = useCreateCategory(); const updateCategoryMutation = useUpdateCategory(); const isEditing = !!editingCategoryCode; const editingCategory = categories.find((c) => c.category_code === editingCategoryCode); // 폼 스키마 선택 (생성/수정에 따라) const schema = isEditing ? updateCategorySchema : createCategorySchema; const form = useForm({ resolver: zodResolver(schema), mode: "onChange", // 실시간 검증 활성화 defaultValues: { categoryCode: "", categoryName: "", categoryNameEng: "", description: "", sortOrder: 1, ...(isEditing && { isActive: true }), }, }); // 편집 모드일 때 기존 데이터 로드 useEffect(() => { if (isOpen) { if (isEditing && editingCategory) { // 수정 모드: 기존 데이터 로드 form.reset({ categoryName: editingCategory.category_name, categoryNameEng: editingCategory.category_name_eng || "", description: editingCategory.description || "", sortOrder: editingCategory.sort_order, isActive: editingCategory.is_active === "Y", }); } else { // 새 카테고리 모드: 자동 순서 계산 const maxSortOrder = categories.length > 0 ? Math.max(...categories.map((c) => c.sort_order)) : 0; form.reset({ categoryCode: "", categoryName: "", categoryNameEng: "", description: "", sortOrder: maxSortOrder + 1, }); } } }, [isOpen, isEditing, editingCategory, categories, form]); const handleSubmit = form.handleSubmit(async (data) => { try { if (isEditing && editingCategoryCode) { // 수정 await updateCategoryMutation.mutateAsync({ categoryCode: editingCategoryCode, data: data as UpdateCategoryData, }); } else { // 생성 await createCategoryMutation.mutateAsync(data as CreateCategoryData); } onClose(); form.reset(); } catch (error) { console.error("카테고리 저장 실패:", error); } }); const isLoading = createCategoryMutation.isPending || updateCategoryMutation.isPending; return ( {isEditing ? "카테고리 수정" : "새 카테고리"}
{/* 카테고리 코드 (생성 시에만) */} {!isEditing && (
{form.formState.errors.categoryCode && (

{form.formState.errors.categoryCode.message}

)}
)} {/* 카테고리명 */}
{form.formState.errors.categoryName && (

{form.formState.errors.categoryName.message}

)}
{/* 영문명 */}
{form.formState.errors.categoryNameEng && (

{form.formState.errors.categoryNameEng.message}

)}
{/* 설명 */}