From 234f82b944850da377d86fad6c0061112a999d7b Mon Sep 17 00:00:00 2001 From: dohyeons Date: Thu, 30 Oct 2025 10:07:44 +0900 Subject: [PATCH] =?UTF-8?q?/dashboard=20=EC=B5=9C=EC=A0=81=ED=99=94=20?= =?UTF-8?q?=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app/(main)/dashboard/page.tsx | 184 ++++++++++++------------- 1 file changed, 85 insertions(+), 99 deletions(-) diff --git a/frontend/app/(main)/dashboard/page.tsx b/frontend/app/(main)/dashboard/page.tsx index 50245fb8..e62f08ae 100644 --- a/frontend/app/(main)/dashboard/page.tsx +++ b/frontend/app/(main)/dashboard/page.tsx @@ -1,7 +1,7 @@ -'use client'; +"use client"; -import React, { useState, useEffect } from 'react'; -import Link from 'next/link'; +import React, { useState, useEffect } from "react"; +import Link from "next/link"; interface Dashboard { id: string; @@ -23,7 +23,7 @@ interface Dashboard { export default function DashboardListPage() { const [dashboards, setDashboards] = useState([]); const [isLoading, setIsLoading] = useState(true); - const [searchTerm, setSearchTerm] = useState(''); + const [searchTerm, setSearchTerm] = useState(""); // 대시보드 목록 로딩 useEffect(() => { @@ -32,14 +32,14 @@ export default function DashboardListPage() { const loadDashboards = async () => { setIsLoading(true); - + try { // 실제 API 호출 시도 - const { dashboardApi } = await import('@/lib/api/dashboard'); - + const { dashboardApi } = await import("@/lib/api/dashboard"); + try { const result = await dashboardApi.getDashboards({ page: 1, limit: 50 }); - + // API에서 가져온 대시보드들을 Dashboard 형식으로 변환 const apiDashboards: Dashboard[] = result.dashboards.map((dashboard: any) => ({ id: dashboard.id, @@ -49,48 +49,47 @@ export default function DashboardListPage() { createdAt: dashboard.createdAt, updatedAt: dashboard.updatedAt, isPublic: dashboard.isPublic, - creatorName: dashboard.creatorName + creatorName: dashboard.creatorName, })); - + setDashboards(apiDashboards); - } catch (apiError) { - console.warn('API 호출 실패, 로컬 스토리지 및 샘플 데이터 사용:', apiError); - + console.warn("API 호출 실패, 로컬 스토리지 및 샘플 데이터 사용:", apiError); + // API 실패 시 로컬 스토리지 + 샘플 데이터 사용 - const savedDashboards = JSON.parse(localStorage.getItem('savedDashboards') || '[]'); - + const savedDashboards = JSON.parse(localStorage.getItem("savedDashboards") || "[]"); + // 샘플 대시보드들 const sampleDashboards: Dashboard[] = [ { - id: 'sales-overview', - title: '📊 매출 현황 대시보드', - description: '월별 매출 추이 및 상품별 판매 현황을 한눈에 확인할 수 있습니다.', + id: "sales-overview", + title: "📊 매출 현황 대시보드", + description: "월별 매출 추이 및 상품별 판매 현황을 한눈에 확인할 수 있습니다.", elementsCount: 3, - createdAt: '2024-09-30T10:00:00Z', - updatedAt: '2024-09-30T14:30:00Z', - isPublic: true + createdAt: "2024-09-30T10:00:00Z", + updatedAt: "2024-09-30T14:30:00Z", + isPublic: true, }, { - id: 'user-analytics', - title: '👥 사용자 분석 대시보드', - description: '사용자 행동 패턴 및 가입 추이 분석', + id: "user-analytics", + title: "👥 사용자 분석 대시보드", + description: "사용자 행동 패턴 및 가입 추이 분석", elementsCount: 1, - createdAt: '2024-09-29T15:00:00Z', - updatedAt: '2024-09-30T09:15:00Z', - isPublic: false + createdAt: "2024-09-29T15:00:00Z", + updatedAt: "2024-09-30T09:15:00Z", + isPublic: false, }, { - id: 'inventory-status', - title: '📦 재고 현황 대시보드', - description: '실시간 재고 현황 및 입출고 내역', + id: "inventory-status", + title: "📦 재고 현황 대시보드", + description: "실시간 재고 현황 및 입출고 내역", elementsCount: 4, - createdAt: '2024-09-28T11:30:00Z', - updatedAt: '2024-09-29T16:45:00Z', - isPublic: true - } + createdAt: "2024-09-28T11:30:00Z", + updatedAt: "2024-09-29T16:45:00Z", + isPublic: true, + }, ]; - + // 저장된 대시보드를 Dashboard 형식으로 변환 const userDashboards: Dashboard[] = savedDashboards.map((dashboard: any) => ({ id: dashboard.id, @@ -99,44 +98,45 @@ export default function DashboardListPage() { elementsCount: dashboard.elements?.length || 0, createdAt: dashboard.createdAt, updatedAt: dashboard.updatedAt, - isPublic: false // 사용자가 만든 대시보드는 기본적으로 비공개 + isPublic: false, // 사용자가 만든 대시보드는 기본적으로 비공개 })); - + // 사용자 대시보드를 맨 앞에 배치 setDashboards([...userDashboards, ...sampleDashboards]); } } catch (error) { - console.error('Dashboard loading error:', error); + console.error("Dashboard loading error:", error); } finally { setIsLoading(false); } }; // 검색 필터링 - const filteredDashboards = dashboards.filter(dashboard => - dashboard.title.toLowerCase().includes(searchTerm.toLowerCase()) || - dashboard.description?.toLowerCase().includes(searchTerm.toLowerCase()) + const filteredDashboards = dashboards.filter( + (dashboard) => + dashboard.title.toLowerCase().includes(searchTerm.toLowerCase()) || + dashboard.description?.toLowerCase().includes(searchTerm.toLowerCase()), ); return (
{/* 헤더 */} -
-
-
+
+
+

📊 대시보드

-

데이터를 시각화하고 인사이트를 얻어보세요

+

데이터를 시각화하고 인사이트를 얻어보세요

- + ➕ 새 대시보드 만들기
- + {/* 검색 바 */}
@@ -145,31 +145,29 @@ export default function DashboardListPage() { placeholder="대시보드 검색..." value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} - className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" + className="w-full rounded-lg border border-gray-300 py-2 pr-4 pl-10 focus:border-transparent focus:ring-2 focus:ring-blue-500" /> -
- 🔍 -
+
🔍
{/* 메인 콘텐츠 */} -
+
{isLoading ? ( // 로딩 상태 -
+
{[1, 2, 3, 4, 5, 6].map((i) => ( -
+
-
-
-
-
+
+
+
+
-
-
+
+
@@ -177,20 +175,18 @@ export default function DashboardListPage() {
) : filteredDashboards.length === 0 ? ( // 빈 상태 -
-
📊
-

- {searchTerm ? '검색 결과가 없습니다' : '아직 대시보드가 없습니다'} +
+
📊
+

+ {searchTerm ? "검색 결과가 없습니다" : "아직 대시보드가 없습니다"}

-

- {searchTerm - ? '다른 검색어로 시도해보세요' - : '첫 번째 대시보드를 만들어보세요'} +

+ {searchTerm ? "다른 검색어로 시도해보세요" : "첫 번째 대시보드를 만들어보세요"}

{!searchTerm && ( ➕ 대시보드 만들기 @@ -198,7 +194,7 @@ export default function DashboardListPage() {
) : ( // 대시보드 그리드 -
+
{filteredDashboards.map((dashboard) => ( ))} @@ -218,64 +214,54 @@ interface DashboardCardProps { */ function DashboardCard({ dashboard }: DashboardCardProps) { return ( -
+
{/* 썸네일 영역 */} -
+
-
📊
+
📊
{dashboard.elementsCount}개 요소
- + {/* 카드 내용 */}
-
-

- {dashboard.title} -

+
+

{dashboard.title}

{dashboard.isPublic ? ( - - 공개 - + 공개 ) : ( - - 비공개 - + 비공개 )}
- - {dashboard.description && ( -

- {dashboard.description} -

- )} - + + {dashboard.description &&

{dashboard.description}

} + {/* 메타 정보 */} -
+
생성: {new Date(dashboard.createdAt).toLocaleDateString()}
수정: {new Date(dashboard.updatedAt).toLocaleDateString()}
- + {/* 액션 버튼들 */}
보기 편집
); -} \ No newline at end of file +}