import { useState, useEffect, useCallback } from 'react'; import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, Area, ComposedChart, } from 'recharts'; import type { UsageTrendResponse } from '../../types/statistics'; import { getUsageTrend } from '../../services/statisticsService'; import { CHART_COLORS_HEX } from '../../constants/chart'; import { useTheme } from '../../hooks/useTheme'; type Period = 'daily' | 'weekly' | 'monthly'; const PERIOD_OPTIONS: { key: Period; label: string }[] = [ { key: 'daily', label: '일별' }, { key: 'weekly', label: '주별' }, { key: 'monthly', label: '월별' }, ]; const formatLabel = (label: string, period: Period): string => { if (period === 'daily') { const d = new Date(label); return `${d.getMonth() + 1}/${d.getDate()}`; } if (period === 'weekly') { const d = new Date(label); return `${d.getMonth() + 1}/${d.getDate()}~`; } return label; }; const getSuccessRateColor = (rate: number): string => { if (rate >= 99) return 'text-green-600'; if (rate >= 95) return 'text-yellow-600'; return 'text-red-600'; }; const UsageTrendPage = () => { const { theme } = useTheme(); const chartColors = CHART_COLORS_HEX[theme]; const [period, setPeriod] = useState('daily'); const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const fetchData = useCallback(async () => { setIsLoading(true); try { const res = await getUsageTrend(period); if (res.success && res.data) { setData(res.data); } } finally { setIsLoading(false); } }, [period]); useEffect(() => { fetchData(); }, [fetchData]); const chartData = data?.items.map((item) => ({ ...item, formattedLabel: formatLabel(item.label, period), })) ?? []; return (

사용량 추이

{/* Period Tabs */}
{PERIOD_OPTIONS.map((opt) => ( ))}
{isLoading ? (
로딩 중...
) : !data || data.items.length === 0 ? (

데이터가 없습니다

) : ( <> {/* Chart 1: 요청 수 추이 (full width) */}

요청 수 추이

{/* Charts 2 & 3: 2 column grid */}
{/* Chart 2: 성공률 + 응답시간 추이 */}

성공률 + 응답시간 추이

{/* Chart 3: 활성 사용자 추이 */}

활성 사용자 추이

{/* Table: 상세 데이터 */}

상세 데이터

{data.items.map((item) => ( ))}
기간 총 요청 성공 실패 성공률(%) 평균 응답시간(ms) 활성 사용자
{formatLabel(item.label, period)} {item.totalRequests.toLocaleString()} {item.successCount.toLocaleString()} {item.failureCount.toLocaleString()} {item.successRate.toFixed(1)} {item.avgResponseTime.toFixed(0)} {item.activeUsers.toLocaleString()}
)}
); }; export default UsageTrendPage;