'use client';
import React, { useState, useEffect } from 'react';
import {
Box,
Container,
Stack,
Button,
FormControl,
Select,
MenuItem,
ToggleButton,
ToggleButtonGroup,
CircularProgress,
useTheme
} from '@mui/material';
import {
Download as DownloadIcon,
FilterList as FilterListIcon,
CloudQueue as CloudQueueIcon,
CheckCircle as CheckCircleIcon
} from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import Navbar from '@/components/Navbar/index';
import StatsCards from './components/StatsCards';
import Charts from './components/Charts';
import UsageTable from './components/UsageTable';
import { useMonitoringData } from './hooks/useMonitoringData';
export default function MonitoringPage() {
const theme = useTheme();
const { t } = useTranslation();
const [projects, setProjects] = useState([]);
const {
loading,
summaryData,
logsData,
filters,
pagination,
searchTerm,
handleFilterChange,
handlePageChange,
handlePageSizeChange,
handleSearchChange
} = useMonitoringData();
// 获取项目列表用于 Navbar
useEffect(() => {
async function fetchProjects() {
try {
const response = await fetch('/api/projects');
if (response.ok) {
const data = await response.json();
setProjects(data);
}
} catch (error) {
console.error('Failed to fetch projects:', error);
}
}
fetchProjects();
}, []);
const handleTimeRangeChange = (event, newRange) => {
if (newRange !== null) {
handleFilterChange('timeRange', newRange);
}
};
const handleExport = () => {
// 简单的导出功能实现,将当前 logsData.details 导出为 CSV
if (!logsData.details || logsData.details.length === 0) return;
const headers = [
t('monitoring.table.columns.projectName'),
t('monitoring.table.columns.provider'),
t('monitoring.table.columns.model'),
t('monitoring.table.columns.status'),
t('monitoring.table.columns.failureReason'),
t('monitoring.table.columns.inputTokens'),
t('monitoring.table.columns.outputTokens'),
t('monitoring.table.columns.totalTokens'),
t('monitoring.table.columns.calls'),
t('monitoring.table.columns.avgLatency')
];
const csvContent = [
headers.join(','),
...logsData.details.map(row =>
[
row.projectName,
row.provider,
row.model,
row.status,
(row.failureReason || '').replace(/,/g, ' '),
row.inputTokens,
row.outputTokens,
row.totalTokens,
row.calls,
row.avgLatency
].join(',')
)
].join('\n');
const blob = new Blob([`\uFEFF${csvContent}`], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `llm-monitoring-export-${new Date().toISOString().slice(0, 10)}.csv`;
link.click();
};
return (
<>
{/* Header Area */}
{/* Time Range Selector */}
{t('monitoring.timeRange.24h')}
{t('monitoring.timeRange.7d')}
{t('monitoring.timeRange.30d')}
{/* Filters & Actions */}
}
onClick={handleExport}
sx={{ textTransform: 'none', px: 3 }}
>
{t('monitoring.actions.export')}
{loading ? (
) : (
{/* 统计卡片 */}
{/* 图表区域 */}
{/* 详细表格 */}
)}
>
);
}