import React, { useState, useMemo } from 'react'; import { Phone, CheckCircle, Clock, UserCheck, Activity, Filter } from 'lucide-react'; import { Card, Button } from '../components/UI'; import { mockAssistants, getDashboardStats } from '../services/mockData'; export const DashboardPage: React.FC = () => { const [timeRange, setTimeRange] = useState<'week' | 'month' | 'year'>('week'); const [selectedAssistantId, setSelectedAssistantId] = useState('all'); const stats = useMemo(() => { return getDashboardStats(timeRange, selectedAssistantId); }, [timeRange, selectedAssistantId]); return (

首页概览

{/* Filters */}
{(['week', 'month', 'year'] as const).map((r) => ( ))}
{/* Metrics Grid */}
} trend="+12.5% 较上期" /> } trend="+2.1% 较上期" /> } trend="-0.5% 较上期" /> } trend="+5% 较上期" />
{/* Charts Section */}

通话趋势图

展示选定时间范围内的通话量变化

); }; // --- Sub Components --- const StatCard: React.FC<{ title: string; value: string; icon: React.ReactNode; trend?: string }> = ({ title, value, icon, trend }) => (

{title}

{icon}
{value}
{trend &&

{trend}

}
); const SimpleAreaChart: React.FC<{ data: { label: string, value: number }[] }> = ({ data }) => { if (!data || data.length === 0) return null; const height = 250; const width = 1000; const padding = 20; const maxValue = Math.max(...data.map(d => d.value)) * 1.2; const points = data.map((d, i) => { const x = (i / (data.length - 1)) * (width - padding * 2) + padding; const y = height - (d.value / maxValue) * (height - padding * 2) - padding; return `${x},${y}`; }).join(' '); const firstPoint = points.split(' ')[0]; const lastPoint = points.split(' ')[points.split(' ').length - 1]; const fillPath = `${points} ${lastPoint.split(',')[0]},${height} ${firstPoint.split(',')[0]},${height}`; return (
{/* Tech Grid Lines */} {/* Area Fill Gradient */} {/* Glow Filter */} {/* Fill Area */} {/* Main Line with Glow */} {/* Data Points */} {data.length < 20 && data.map((d, i) => { const x = (i / (data.length - 1)) * (width - padding * 2) + padding; const y = height - (d.value / maxValue) * (height - padding * 2) - padding; return ( ); })} {/* X-Axis Labels */}
{data.filter((_, i) => i % Math.ceil(data.length / 6) === 0).map((d, i) => ( {d.label} ))}
); };