"use client"; import { useState, useMemo } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Search, Plus, Edit2, Trash2, Eye, Copy, Download, Upload, ArrowUpDown, Filter, RefreshCw } from "lucide-react"; import { LoadingSpinner } from "@/components/common/LoadingSpinner"; import { toast } from "sonner"; import { useTemplates, TemplateStandard } from "@/hooks/admin/useTemplates"; import Link from "next/link"; export default function TemplatesManagePage() { const [searchTerm, setSearchTerm] = useState(""); const [categoryFilter, setCategoryFilter] = useState("all"); const [activeFilter, setActiveFilter] = useState("Y"); const [sortField, setSortField] = useState("sort_order"); const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc"); // 템플릿 데이터 조회 const { templates, categories, isLoading, error, deleteTemplate, isDeleting, deleteError, refetch, exportTemplate } = useTemplates({ active: activeFilter === "all" ? undefined : activeFilter, search: searchTerm || undefined, category: categoryFilter === "all" ? undefined : categoryFilter, }); // 필터링 및 정렬된 데이터 const filteredAndSortedTemplates = useMemo(() => { let filtered = [...templates]; // 정렬 filtered.sort((a, b) => { let aValue: any = a[sortField as keyof typeof a]; let bValue: any = b[sortField as keyof typeof b]; // 숫자 필드 처리 if (sortField === "sort_order") { aValue = aValue || 0; bValue = bValue || 0; } // 문자열 필드 처리 if (typeof aValue === "string") { aValue = aValue.toLowerCase(); } if (typeof bValue === "string") { bValue = bValue.toLowerCase(); } if (aValue < bValue) return sortDirection === "asc" ? -1 : 1; if (aValue > bValue) return sortDirection === "asc" ? 1 : -1; return 0; }); return filtered; }, [templates, sortField, sortDirection]); // 정렬 변경 핸들러 const handleSort = (field: string) => { if (sortField === field) { setSortDirection(sortDirection === "asc" ? "desc" : "asc"); } else { setSortField(field); setSortDirection("asc"); } }; // 삭제 핸들러 const handleDelete = async (templateCode: string, templateName: string) => { try { await deleteTemplate(templateCode); toast.success(`템플릿 '${templateName}'이 삭제되었습니다.`); } catch (error) { toast.error(`템플릿 삭제 중 오류가 발생했습니다: ${deleteError?.message || error}`); } }; // 내보내기 핸들러 const handleExport = async (templateCode: string, templateName: string) => { try { const templateData = await exportTemplate(templateCode); // JSON 파일로 다운로드 const blob = new Blob([JSON.stringify(templateData, null, 2)], { type: "application/json", }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `template-${templateCode}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); toast.success(`템플릿 '${templateName}'이 내보내기되었습니다.`); } catch (error: any) { toast.error(`템플릿 내보내기 중 오류가 발생했습니다: ${error.message}`); } }; // 아이콘 렌더링 함수 const renderIcon = (iconName?: string) => { if (!iconName) return null; // 간단한 아이콘 매핑 (실제로는 더 복잡한 시스템 필요) const iconMap: Record = { table:
, "mouse-pointer":
, upload:
, }; return iconMap[iconName] ||
; }; if (error) { return (

템플릿 목록을 불러오는 중 오류가 발생했습니다.

); } return (
{/* 페이지 제목 */}

템플릿 관리

화면 디자이너에서 사용할 템플릿을 관리합니다

{/* 필터 및 검색 */} 필터 및 검색
{/* 검색 */}
setSearchTerm(e.target.value)} className="pl-10" />
{/* 카테고리 필터 */}
{/* 활성화 상태 필터 */}
{/* 새로고침 버튼 */}
{/* 템플릿 목록 테이블 */} 템플릿 목록 ({filteredAndSortedTemplates.length}개)
카테고리 설명 아이콘 기본 크기 공개 여부 활성화 수정일 작업 {isLoading ? ( 템플릿 목록을 불러오는 중... ) : filteredAndSortedTemplates.length === 0 ? ( 검색 조건에 맞는 템플릿이 없습니다. ) : ( filteredAndSortedTemplates.map((template) => ( {template.sort_order || 0} {template.template_code} {template.template_name} {template.template_name_eng && (
{template.template_name_eng}
)}
{template.category} {template.description || "-"}
{renderIcon(template.icon_name)}
{template.default_size ? `${template.default_size.width}×${template.default_size.height}` : "-"} {template.is_public === "Y" ? "공개" : "비공개"} {template.is_active === "Y" ? "활성화" : "비활성화"} {template.updated_date ? new Date(template.updated_date).toLocaleDateString("ko-KR") : "-"}
템플릿 삭제 템플릿 '{template.template_name}'을 정말 삭제하시겠습니까?
이 작업은 되돌릴 수 없습니다.
취소 handleDelete(template.template_code, template.template_name)} className="bg-red-600 hover:bg-red-700" disabled={isDeleting} > 삭제
)) )}
); }