"use client"; import React, { useState, useMemo } from "react"; import { Search, Plus, Edit, Trash2, RefreshCw, Package, Filter } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { AlertModal } from "@/components/common/AlertModal"; import { useComponents, useComponentCategories, useComponentStatistics, useDeleteComponent, useCreateComponent, useUpdateComponent, } from "@/hooks/admin/useComponents"; import { ComponentFormModal } from "@/components/admin/ComponentFormModal"; // 컴포넌트 카테고리 정의 const COMPONENT_CATEGORIES = [ { id: "input", name: "입력", color: "blue" }, { id: "action", name: "액션", color: "green" }, { id: "display", name: "표시", color: "purple" }, { id: "layout", name: "레이아웃", color: "orange" }, { id: "other", name: "기타", color: "gray" }, ]; export default function ComponentManagementPage() { const [searchTerm, setSearchTerm] = useState(""); const [selectedCategory, setSelectedCategory] = useState("all"); const [sortBy, setSortBy] = useState("sort_order"); const [sortOrder, setSortOrder] = useState<"asc" | "desc">("asc"); const [selectedComponent, setSelectedComponent] = useState(null); const [showDeleteModal, setShowDeleteModal] = useState(false); const [showNewComponentModal, setShowNewComponentModal] = useState(false); const [showEditComponentModal, setShowEditComponentModal] = useState(false); // 컴포넌트 데이터 가져오기 const { data: componentsData, isLoading: loading, error, refetch, } = useComponents({ category: selectedCategory === "all" ? undefined : selectedCategory, active: "Y", search: searchTerm, sort: sortBy, order: sortOrder, }); // 카테고리와 통계 데이터 const { data: categories } = useComponentCategories(); const { data: statistics } = useComponentStatistics(); // 뮤테이션 const deleteComponentMutation = useDeleteComponent(); const createComponentMutation = useCreateComponent(); const updateComponentMutation = useUpdateComponent(); // 컴포넌트 목록 (이미 필터링과 정렬이 적용된 상태) const components = componentsData?.components || []; // 카테고리별 통계 (백엔드에서 가져온 데이터 사용) const categoryStats = useMemo(() => { if (!statistics?.byCategory) return {}; const stats: Record = {}; statistics.byCategory.forEach(({ category, count }) => { stats[category] = count; }); return stats; }, [statistics]); // 카테고리 이름 및 색상 가져오기 const getCategoryInfo = (categoryId: string) => { const category = COMPONENT_CATEGORIES.find((cat) => cat.id === categoryId); return category || { id: "other", name: "기타", color: "gray" }; }; // 삭제 처리 const handleDelete = async () => { if (!selectedComponent) return; try { await deleteComponentMutation.mutateAsync(selectedComponent.component_code); setShowDeleteModal(false); setSelectedComponent(null); } catch (error) { console.error("컴포넌트 삭제 실패:", error); } }; // 컴포넌트 생성 처리 const handleCreate = async (data: any) => { await createComponentMutation.mutateAsync(data); setShowNewComponentModal(false); }; // 컴포넌트 수정 처리 const handleUpdate = async (data: any) => { if (!selectedComponent) return; await updateComponentMutation.mutateAsync({ component_code: selectedComponent.component_code, data, }); setShowEditComponentModal(false); setSelectedComponent(null); }; if (loading) { return (

컴포넌트 목록을 불러오는 중...

); } if (error) { return (

컴포넌트 목록을 불러오는데 실패했습니다.

); } return (
{/* 헤더 */}

컴포넌트 관리

화면 설계에 사용되는 컴포넌트들을 관리합니다

{/* 카테고리 통계 */}
{COMPONENT_CATEGORIES.map((category) => { const count = categoryStats[category.id] || 0; return ( setSelectedCategory(category.id)} >
{count}
{category.name}
); })}
{/* 검색 및 필터 */}
{/* 검색 */}
setSearchTerm(e.target.value)} className="pl-9" />
{/* 카테고리 필터 */} {/* 정렬 */}
{/* 컴포넌트 목록 테이블 */} 컴포넌트 목록 ({components.length}개)
컴포넌트 이름 컴포넌트 코드 카테고리 타입 상태 수정일 작업 {components.map((component) => { const categoryInfo = getCategoryInfo(component.category || "other"); return (
{component.component_name}
{component.component_name_eng && (
{component.component_name_eng}
)}
{component.component_code} {categoryInfo.name} {component.component_config ? ( {component.component_config.type || component.component_code} ) : ( 없음 )} {component.is_active === "Y" ? "활성" : "비활성"} {component.updated_date ? new Date(component.updated_date).toLocaleDateString() : "-"}
); })}
{/* 삭제 확인 모달 */} setShowDeleteModal(false)} onConfirm={handleDelete} type="warning" title="컴포넌트 삭제" message={`정말로 "${selectedComponent?.component_name}" 컴포넌트를 삭제하시겠습니까?`} confirmText="삭제" /> {/* 새 컴포넌트 추가 모달 */} setShowNewComponentModal(false)} onSubmit={handleCreate} mode="create" /> {/* 컴포넌트 편집 모달 */} { setShowEditComponentModal(false); setSelectedComponent(null); }} onSubmit={handleUpdate} initialData={selectedComponent} mode="edit" />
); }