"use client"; import React, { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { LoadingSpinner } from "@/components/common/LoadingSpinner"; import { CodeCategoryFormModal } from "./CodeCategoryFormModal"; import { CategoryItem } from "./CategoryItem"; import { AlertModal } from "@/components/common/AlertModal"; import { Search, Plus } from "lucide-react"; import { useDeleteCategory } from "@/hooks/queries/useCategories"; import { useCategoriesInfinite } from "@/hooks/queries/useCategoriesInfinite"; interface CodeCategoryPanelProps { selectedCategoryCode: string; onSelectCategory: (categoryCode: string) => void; } export function CodeCategoryPanel({ selectedCategoryCode, onSelectCategory }: CodeCategoryPanelProps) { // 검색 및 필터 상태 (먼저 선언) const [searchTerm, setSearchTerm] = useState(""); const [showActiveOnly, setShowActiveOnly] = useState(false); // React Query로 카테고리 데이터 관리 (무한 스크롤) const { data: categories = [], isLoading, error, handleScroll, isFetchingNextPage, hasNextPage, } = useCategoriesInfinite({ search: searchTerm || undefined, active: showActiveOnly || undefined, // isActive -> active로 수정 }); const deleteCategoryMutation = useDeleteCategory(); // 모달 상태 const [showFormModal, setShowFormModal] = useState(false); const [editingCategory, setEditingCategory] = useState(""); const [showDeleteModal, setShowDeleteModal] = useState(false); const [deletingCategory, setDeletingCategory] = useState(""); // 새 카테고리 생성 const handleNewCategory = () => { setEditingCategory(""); setShowFormModal(true); }; // 카테고리 수정 const handleEditCategory = (categoryCode: string) => { setEditingCategory(categoryCode); setShowFormModal(true); }; // 카테고리 삭제 확인 const handleDeleteCategory = (categoryCode: string) => { setDeletingCategory(categoryCode); setShowDeleteModal(true); }; // 카테고리 삭제 실행 const handleConfirmDelete = async () => { if (!deletingCategory) return; try { await deleteCategoryMutation.mutateAsync(deletingCategory); // 삭제된 카테고리가 선택된 상태라면 선택 해제 if (selectedCategoryCode === deletingCategory) { onSelectCategory(""); } setShowDeleteModal(false); setDeletingCategory(""); } catch (error) { console.error("카테고리 삭제 실패:", error); } }; if (error) { return (

카테고리를 불러오는 중 오류가 발생했습니다.

); } return (
{/* 검색 및 액션 */}
{/* 검색 + 버튼 */}
setSearchTerm(e.target.value)} className="h-10 pl-10 text-sm" />
{/* 활성 필터 */}
setShowActiveOnly(e.target.checked)} className="h-4 w-4 rounded border-input" />
{/* 카테고리 목록 (무한 스크롤) */}
{isLoading ? (
) : categories.length === 0 ? (

{searchTerm ? "검색 결과가 없습니다." : "카테고리가 없습니다."}

) : ( <> {categories.map((category, index) => ( onSelectCategory(category.category_code)} onEdit={() => handleEditCategory(category.category_code)} onDelete={() => handleDeleteCategory(category.category_code)} /> ))} {/* 추가 로딩 표시 */} {isFetchingNextPage && (
추가 로딩 중...
)} {/* 더 이상 데이터가 없을 때 */} {!hasNextPage && categories.length > 0 && (
모든 카테고리를 불러왔습니다.
)} )}
{/* 카테고리 폼 모달 */} {showFormModal && ( setShowFormModal(false)} editingCategoryCode={editingCategory} categories={categories} /> )} {/* 삭제 확인 모달 */} {showDeleteModal && ( setShowDeleteModal(false)} type="error" title="카테고리 삭제" message="정말로 이 카테고리를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다." confirmText="삭제" onConfirm={handleConfirmDelete} /> )}
); }