/** * ⚠️ 임시 주석 처리된 파일 * 다른 분이 범용 리스트 작업 중이어서 충돌 방지를 위해 주석 처리 * 나중에 merge 시 활성화 필요 */ "use client"; import React, { useState, useEffect } from "react"; import { DashboardElement } from "@/components/admin/dashboard/types"; interface ListSummaryWidgetProps { element: DashboardElement; } interface ColumnInfo { key: string; label: string; } // 컬럼명 한글 번역 const translateColumnName = (colName: string): string => { const columnTranslations: { [key: string]: string } = { // 공통 "id": "ID", "name": "이름", "status": "상태", "created_at": "생성일", "updated_at": "수정일", "created_date": "생성일", "updated_date": "수정일", // 기사 관련 "driver_id": "기사ID", "phone": "전화번호", "license_number": "면허번호", "vehicle_id": "차량ID", "current_location": "현재위치", "rating": "평점", "total_deliveries": "총배송건수", "average_delivery_time": "평균배송시간", "total_distance": "총운행거리", "join_date": "가입일", "last_active": "마지막활동", // 차량 관련 "vehicle_number": "차량번호", "model": "모델", "year": "연식", "color": "색상", "type": "종류", // 배송 관련 "delivery_id": "배송ID", "order_id": "주문ID", "customer_name": "고객명", "address": "주소", "delivery_date": "배송일", "estimated_time": "예상시간", // 제품 관련 "product_id": "제품ID", "product_name": "제품명", "price": "가격", "stock": "재고", "category": "카테고리", "description": "설명", // 주문 관련 "order_date": "주문일", "quantity": "수량", "total_amount": "총금액", "payment_status": "결제상태", // 고객 관련 "customer_id": "고객ID", "email": "이메일", "company": "회사", "department": "부서", }; return columnTranslations[colName.toLowerCase()] || columnTranslations[colName.replace(/_/g, '').toLowerCase()] || colName; }; /** * 범용 목록 위젯 * - SQL 쿼리 결과를 테이블 형식으로 표시 * - 어떤 데이터든 표시 가능 (기사, 차량, 제품, 주문 등) */ export default function ListSummaryWidget({ element }: ListSummaryWidgetProps) { const [data, setData] = useState([]); const [columns, setColumns] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [tableName, setTableName] = useState(null); const [searchTerm, setSearchTerm] = useState(""); useEffect(() => { loadData(); // 자동 새로고침 (30초마다) const interval = setInterval(loadData, 30000); return () => clearInterval(interval); }, [element]); const loadData = async () => { if (!element?.dataSource?.query) { setError(null); setLoading(false); setTableName(null); return; } // 쿼리에서 테이블 이름 추출 const extractTableName = (query: string): string | null => { const fromMatch = query.match(/FROM\s+([a-zA-Z0-9_가-힣]+)/i); if (fromMatch) { return fromMatch[1]; } return null; }; try { setLoading(true); const extractedTableName = extractTableName(element.dataSource.query); setTableName(extractedTableName); const token = localStorage.getItem("authToken"); const response = await fetch("/api/dashboards/execute-query", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ query: element.dataSource.query, connectionType: element.dataSource.connectionType || "current", connectionId: element.dataSource.connectionId, }), }); if (!response.ok) throw new Error("데이터 로딩 실패"); const result = await response.json(); if (result.success && result.data?.rows) { const rows = result.data.rows; // 컬럼 정보 추출 (한글 번역 적용) if (rows.length > 0) { const cols: ColumnInfo[] = Object.keys(rows[0]).map((key) => ({ key, label: translateColumnName(key), })); setColumns(cols); } setData(rows); } setError(null); } catch (err) { setError(err instanceof Error ? err.message : "데이터 로딩 실패"); } finally { setLoading(false); } }; // 테이블 이름 한글 번역 const translateTableName = (name: string): string => { const tableTranslations: { [key: string]: string } = { "drivers": "기사", "driver": "기사", "vehicles": "차량", "vehicle": "차량", "products": "제품", "product": "제품", "orders": "주문", "order": "주문", "customers": "고객", "customer": "고객", "deliveries": "배송", "delivery": "배송", "users": "사용자", "user": "사용자", }; return tableTranslations[name.toLowerCase()] || tableTranslations[name.replace(/_/g, '').toLowerCase()] || name; }; const displayTitle = tableName ? `${translateTableName(tableName)} 목록` : "데이터 목록"; // 검색 필터링 const filteredData = data.filter((row) => Object.values(row).some((value) => String(value).toLowerCase().includes(searchTerm.toLowerCase()) ) ); if (loading) { return (

데이터 로딩 중...

); } if (error) { return (

⚠️ {error}

); } if (!element?.dataSource?.query) { return (
📋

데이터 목록

📋 테이블 형식 데이터 표시 위젯

  • • SQL 쿼리로 데이터를 불러옵니다
  • • 테이블 형식으로 자동 표시
  • • 검색 기능 지원
  • • 실시간 데이터 모니터링 가능

⚙️ 설정 방법

우측 상단 톱니바퀴 버튼을 클릭하여

SQL 쿼리를 입력하고 저장하세요

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

📋 {displayTitle}

총 {filteredData.length.toLocaleString()}건

{/* 검색 */} {data.length > 0 && (
setSearchTerm(e.target.value)} className="w-full rounded border border-gray-300 px-2 py-1 text-xs focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary" />
)} {/* 테이블 */}
{filteredData.length > 0 ? ( {columns.map((col) => ( ))} {filteredData.map((row, idx) => ( {columns.map((col) => ( ))} ))}
{col.label}
{String(row[col.key] || "")}
) : (

검색 결과가 없습니다

)}
); }