"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { dashboardApi } from "@/lib/api/dashboard"; import { Dashboard } from "@/lib/api/dashboard"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { useToast } from "@/hooks/use-toast"; import { Pagination, PaginationInfo } from "@/components/common/Pagination"; import { Plus, Search, Edit, Trash2, Copy, LayoutDashboard, MoreHorizontal } from "lucide-react"; /** * 대시보드 관리 페이지 * - 대시보드 목록 조회 * - 대시보드 생성/수정/삭제/복사 */ export default function DashboardListPage() { const router = useRouter(); const { toast } = useToast(); const [dashboards, setDashboards] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(""); // 페이지네이션 상태 const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [totalCount, setTotalCount] = useState(0); // 모달 상태 const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [deleteTarget, setDeleteTarget] = useState<{ id: string; title: string } | null>(null); // 대시보드 목록 로드 const loadDashboards = async () => { try { setLoading(true); const result = await dashboardApi.getMyDashboards({ search: searchTerm, page: currentPage, limit: pageSize, }); setDashboards(result.dashboards); setTotalCount(result.pagination.total); } catch (err) { console.error("Failed to load dashboards:", err); toast({ title: "오류", description: "대시보드 목록을 불러오는데 실패했습니다.", variant: "destructive", }); } finally { setLoading(false); } }; useEffect(() => { loadDashboards(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchTerm, currentPage, pageSize]); // 페이지네이션 정보 계산 const paginationInfo: PaginationInfo = { currentPage, totalPages: Math.ceil(totalCount / pageSize), totalItems: totalCount, itemsPerPage: pageSize, startItem: totalCount === 0 ? 0 : (currentPage - 1) * pageSize + 1, endItem: Math.min(currentPage * pageSize, totalCount), }; // 페이지 변경 핸들러 const handlePageChange = (page: number) => { setCurrentPage(page); }; // 페이지 크기 변경 핸들러 const handlePageSizeChange = (size: number) => { setPageSize(size); setCurrentPage(1); // 페이지 크기 변경 시 첫 페이지로 }; // 대시보드 삭제 확인 모달 열기 const handleDeleteClick = (id: string, title: string) => { setDeleteTarget({ id, title }); setDeleteDialogOpen(true); }; // 대시보드 삭제 실행 const handleDeleteConfirm = async () => { if (!deleteTarget) return; try { await dashboardApi.deleteDashboard(deleteTarget.id); setDeleteDialogOpen(false); setDeleteTarget(null); toast({ title: "성공", description: "대시보드가 삭제되었습니다.", }); loadDashboards(); } catch (err) { console.error("Failed to delete dashboard:", err); setDeleteDialogOpen(false); toast({ title: "오류", description: "대시보드 삭제에 실패했습니다.", variant: "destructive", }); } }; // 대시보드 복사 const handleCopy = async (dashboard: Dashboard) => { try { const fullDashboard = await dashboardApi.getDashboard(dashboard.id); await dashboardApi.createDashboard({ title: `${fullDashboard.title} (복사본)`, description: fullDashboard.description, elements: fullDashboard.elements || [], isPublic: false, tags: fullDashboard.tags, category: fullDashboard.category, settings: fullDashboard.settings as { resolution?: string; backgroundColor?: string }, }); toast({ title: "성공", description: "대시보드가 복사되었습니다.", }); loadDashboards(); } catch (err) { console.error("Failed to copy dashboard:", err); toast({ title: "오류", description: "대시보드 복사에 실패했습니다.", variant: "destructive", }); } }; // 포맷팅 헬퍼 const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString("ko-KR", { year: "numeric", month: "2-digit", day: "2-digit", }); }; return (
{/* 페이지 제목 */}

대시보드 관리

대시보드를 생성하고 관리할 수 있습니다

{/* 검색 및 필터 */}
setSearchTerm(e.target.value)} className="w-64 pl-10" />
{/* 대시보드 목록 */} {loading ? (
로딩 중...
) : dashboards.length === 0 ? (

등록된 대시보드가 없습니다

첫 번째 대시보드를 생성하여 데이터 시각화를 시작하세요.

) : ( 제목 설명 생성일 작업 {dashboards.map((dashboard) => (
{dashboard.title}
{dashboard.description || "-"} {formatDate(dashboard.createdAt)}
))}
)} {/* 페이지네이션 */} {!loading && dashboards.length > 0 && ( )}
{/* 삭제 확인 모달 */} 대시보드 삭제 확인 "{deleteTarget?.title}" 대시보드를 삭제하시겠습니까?
이 작업은 되돌릴 수 없습니다.
취소 삭제
); }