카테고리 무한 스크롤 구현
This commit is contained in:
@@ -8,8 +8,8 @@ import { CodeCategoryFormModal } from "./CodeCategoryFormModal";
|
||||
import { CategoryItem } from "./CategoryItem";
|
||||
import { AlertModal } from "@/components/common/AlertModal";
|
||||
import { Search, Plus } from "lucide-react";
|
||||
import { useCategories, useDeleteCategory } from "@/hooks/queries/useCategories";
|
||||
import { useSearchAndFilter } from "@/hooks/useSearchAndFilter";
|
||||
import { useDeleteCategory } from "@/hooks/queries/useCategories";
|
||||
import { useCategoriesInfinite } from "@/hooks/queries/useCategoriesInfinite";
|
||||
|
||||
interface CodeCategoryPanelProps {
|
||||
selectedCategoryCode: string;
|
||||
@@ -17,20 +17,23 @@ interface CodeCategoryPanelProps {
|
||||
}
|
||||
|
||||
export function CodeCategoryPanel({ selectedCategoryCode, onSelectCategory }: CodeCategoryPanelProps) {
|
||||
// React Query로 카테고리 데이터 관리
|
||||
const { data: categories = [], isLoading, error } = useCategories();
|
||||
const deleteCategoryMutation = useDeleteCategory();
|
||||
// 검색 및 필터 상태 (먼저 선언)
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [showActiveOnly, setShowActiveOnly] = useState(false);
|
||||
|
||||
// 검색 및 필터링 훅 사용
|
||||
// React Query로 카테고리 데이터 관리 (무한 스크롤)
|
||||
const {
|
||||
searchTerm,
|
||||
setSearchTerm,
|
||||
showActiveOnly,
|
||||
setShowActiveOnly,
|
||||
filteredItems: filteredCategories,
|
||||
} = useSearchAndFilter(categories, {
|
||||
searchFields: ["category_name", "category_code"],
|
||||
data: categories = [],
|
||||
isLoading,
|
||||
error,
|
||||
handleScroll,
|
||||
isFetchingNextPage,
|
||||
hasNextPage,
|
||||
} = useCategoriesInfinite({
|
||||
search: searchTerm || undefined,
|
||||
active: showActiveOnly || undefined, // isActive -> active로 수정
|
||||
});
|
||||
const deleteCategoryMutation = useDeleteCategory();
|
||||
|
||||
// 모달 상태
|
||||
const [showFormModal, setShowFormModal] = useState(false);
|
||||
@@ -125,29 +128,44 @@ export function CodeCategoryPanel({ selectedCategoryCode, onSelectCategory }: Co
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 카테고리 목록 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{/* 카테고리 목록 (무한 스크롤) */}
|
||||
<div className="h-96 overflow-y-auto" onScroll={handleScroll}>
|
||||
{isLoading ? (
|
||||
<div className="flex h-32 items-center justify-center">
|
||||
<LoadingSpinner />
|
||||
</div>
|
||||
) : filteredCategories.length === 0 ? (
|
||||
) : categories.length === 0 ? (
|
||||
<div className="p-4 text-center text-gray-500">
|
||||
{searchTerm ? "검색 결과가 없습니다." : "카테고리가 없습니다."}
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-1 p-2">
|
||||
{filteredCategories.map((category) => (
|
||||
<CategoryItem
|
||||
key={category.category_code}
|
||||
category={category}
|
||||
isSelected={selectedCategoryCode === category.category_code}
|
||||
onSelect={() => onSelectCategory(category.category_code)}
|
||||
onEdit={() => handleEditCategory(category.category_code)}
|
||||
onDelete={() => handleDeleteCategory(category.category_code)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<>
|
||||
<div className="space-y-1 p-2">
|
||||
{categories.map((category, index) => (
|
||||
<CategoryItem
|
||||
key={`${category.category_code}-${index}`}
|
||||
category={category}
|
||||
isSelected={selectedCategoryCode === category.category_code}
|
||||
onSelect={() => onSelectCategory(category.category_code)}
|
||||
onEdit={() => handleEditCategory(category.category_code)}
|
||||
onDelete={() => handleDeleteCategory(category.category_code)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 추가 로딩 표시 */}
|
||||
{isFetchingNextPage && (
|
||||
<div className="flex justify-center py-4">
|
||||
<LoadingSpinner size="sm" />
|
||||
<span className="ml-2 text-sm text-gray-500">추가 로딩 중...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 더 이상 데이터가 없을 때 */}
|
||||
{!hasNextPage && categories.length > 0 && (
|
||||
<div className="py-4 text-center text-sm text-gray-400">모든 카테고리를 불러왔습니다.</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user