diff --git a/backend-node/src/services/DashboardService.ts b/backend-node/src/services/DashboardService.ts index 6b709235..c25efe4f 100644 --- a/backend-node/src/services/DashboardService.ts +++ b/backend-node/src/services/DashboardService.ts @@ -301,29 +301,30 @@ export class DashboardService { // 3. 요소 데이터 변환 console.log('📊 대시보드 요소 개수:', elementsResult.rows.length); - if (elementsResult.rows.length > 0) { - console.log('📊 첫 번째 요소 raw data:', elementsResult.rows[0]); - } - const elements: DashboardElement[] = elementsResult.rows.map((row: any) => ({ - id: row.id, - type: row.element_type, - subtype: row.element_subtype, - position: { - x: row.position_x, - y: row.position_y - }, - size: { - width: row.width, - height: row.height - }, - title: row.title, - content: row.content, - dataSource: JSON.parse(row.data_source_config || '{}'), - chartConfig: JSON.parse(row.chart_config || '{}') - })); - - console.log('📊 변환된 첫 번째 요소:', elements[0]); + const elements: DashboardElement[] = elementsResult.rows.map((row: any, index: number) => { + const element = { + id: row.id, + type: row.element_type, + subtype: row.element_subtype, + position: { + x: row.position_x, + y: row.position_y + }, + size: { + width: row.width, + height: row.height + }, + title: row.title, + content: row.content, + dataSource: JSON.parse(row.data_source_config || '{}'), + chartConfig: JSON.parse(row.chart_config || '{}') + }; + + console.log(`📊 위젯 #${index + 1}: type="${element.type}", subtype="${element.subtype}", title="${element.title}"`); + + return element; + }); return { id: dashboard.id, diff --git a/frontend/components/dashboard/DashboardViewer.tsx b/frontend/components/dashboard/DashboardViewer.tsx index e94d6fe5..036a18ac 100644 --- a/frontend/components/dashboard/DashboardViewer.tsx +++ b/frontend/components/dashboard/DashboardViewer.tsx @@ -5,8 +5,113 @@ import { DashboardElement, QueryResult } from "@/components/admin/dashboard/type import { ChartRenderer } from "@/components/admin/dashboard/charts/ChartRenderer"; import dynamic from "next/dynamic"; -// 위젯 동적 import +// 위젯 동적 import - 모든 위젯 const ListSummaryWidget = dynamic(() => import("./widgets/ListSummaryWidget"), { ssr: false }); +const MapSummaryWidget = dynamic(() => import("./widgets/MapSummaryWidget"), { ssr: false }); +const StatusSummaryWidget = dynamic(() => import("./widgets/StatusSummaryWidget"), { ssr: false }); +const RiskAlertWidget = dynamic(() => import("./widgets/RiskAlertWidget"), { ssr: false }); +const WeatherWidget = dynamic(() => import("./widgets/WeatherWidget"), { ssr: false }); +const ExchangeWidget = dynamic(() => import("./widgets/ExchangeWidget"), { ssr: false }); +const VehicleStatusWidget = dynamic(() => import("./widgets/VehicleStatusWidget"), { ssr: false }); +const VehicleListWidget = dynamic(() => import("./widgets/VehicleListWidget"), { ssr: false }); +const VehicleMapOnlyWidget = dynamic(() => import("./widgets/VehicleMapOnlyWidget"), { ssr: false }); +const CargoListWidget = dynamic(() => import("./widgets/CargoListWidget"), { ssr: false }); +const CustomerIssuesWidget = dynamic(() => import("./widgets/CustomerIssuesWidget"), { ssr: false }); +const DeliveryStatusWidget = dynamic(() => import("./widgets/DeliveryStatusWidget"), { ssr: false }); +const DeliveryStatusSummaryWidget = dynamic(() => import("./widgets/DeliveryStatusSummaryWidget"), { ssr: false }); +const DeliveryTodayStatsWidget = dynamic(() => import("./widgets/DeliveryTodayStatsWidget"), { ssr: false }); +const TodoWidget = dynamic(() => import("./widgets/TodoWidget"), { ssr: false }); +const DocumentWidget = dynamic(() => import("./widgets/DocumentWidget"), { ssr: false }); +const BookingAlertWidget = dynamic(() => import("./widgets/BookingAlertWidget"), { ssr: false }); +const MaintenanceWidget = dynamic(() => import("./widgets/MaintenanceWidget"), { ssr: false }); +const CalculatorWidget = dynamic(() => import("./widgets/CalculatorWidget"), { ssr: false }); + +/** + * 위젯 렌더링 함수 - DashboardSidebar의 모든 subtype 처리 + * ViewerElement에서 사용하기 위해 컴포넌트 외부에 정의 + */ +function renderWidget(element: DashboardElement) { + switch (element.subtype) { + // 차트는 ChartRenderer에서 처리됨 (이 함수 호출 안됨) + + // === 위젯 종류 === + case "exchange": + return ; + case "weather": + return ; + case "calculator": + return ; + case "clock": + return ( +
+
+
+
시계 위젯 (개발 예정)
+
+
+ ); + case "map-summary": + return ; + case "list-summary": + return ; + case "risk-alert": + return ; + case "calendar": + return ( +
+
+
📅
+
달력 위젯 (개발 예정)
+
+
+ ); + case "status-summary": + return ; + + // === 운영/작업 지원 === + case "todo": + return ; + case "booking-alert": + return ; + case "maintenance": + return ; + case "document": + return ; + case "list": + return ; + + // === 차량 관련 (추가 위젯) === + case "vehicle-status": + return ; + case "vehicle-list": + return ; + case "vehicle-map": + return ; + + // === 배송 관련 (추가 위젯) === + case "delivery-status": + return ; + case "delivery-status-summary": + return ; + case "delivery-today-stats": + return ; + case "cargo-list": + return ; + case "customer-issues": + return ; + + // === 기본 fallback === + default: + return ( +
+
+
+
알 수 없는 위젯 타입: {element.subtype}
+
+
+ ); + } +} interface DashboardViewerProps { elements: DashboardElement[]; @@ -202,21 +307,7 @@ function ViewerElement({ element, data, isLoading, onRefresh }: ViewerElementPro
{element.type === "chart" ? ( - ) : element.subtype === "list" ? ( - // 리스트 위젯 - - ) : ( - // 기타 위젯 렌더링 -
-
-
- {element.subtype === "exchange" && "💱"} - {element.subtype === "weather" && "☁️"} -
-
{element.content}
-
-
- )} + ) : renderWidget(element)}
{/* 로딩 오버레이 */}