import { TEST_NODES, LatencyResult, getLatencyColor, getLatencyLevel } from '@shared/types' import { useLanguage } from '../contexts/LanguageContext' import './ResultsPanel.css' interface ResultsPanelProps { results: Map selectedNodeId: string | null onNodeSelect: (nodeId: string | null) => void } export default function ResultsPanel({ results, selectedNodeId, onNodeSelect }: ResultsPanelProps) { const { t } = useLanguage() if (results.size === 0) return null const sortedNodes = [...TEST_NODES].sort((a, b) => { const aResult = results.get(a.id) const bResult = results.get(b.id) const aLatency = aResult?.latency ?? Infinity const bLatency = bResult?.latency ?? Infinity return aLatency - bLatency }) const completedResults = sortedNodes .map((node) => ({ node, result: results.get(node.id) })) .filter(({ result }) => result?.status === 'success' || result?.status === 'failed') const avgLatency = completedResults.length > 0 ? Math.round( completedResults .filter(({ result }) => result?.latency !== null) .reduce((sum, { result }) => sum + (result?.latency ?? 0), 0) / completedResults.filter(({ result }) => result?.latency !== null).length ) : null const regionMap: Record = { 'North America': '北美', 'Europe': '欧洲', 'Asia': '亚洲', 'Middle East': '中东', 'South America': '南美', 'Africa': '非洲', 'Oceania': '大洋洲' } return (

{t('测试结果', 'Test Results')}

0ms 50 100 150 200 250+
{avgLatency !== null && (
{t('平均', 'Avg')}: {avgLatency}ms
)}
{sortedNodes.map((node) => { const result = results.get(node.id) const isTesting = result?.status === 'testing' const hasResult = result?.status === 'success' || result?.status === 'failed' const isSelected = selectedNodeId === node.id return (
onNodeSelect(isSelected ? null : node.id)} >
{t(regionMap[node.region] || node.region, node.region)}
{node.name}
{isTesting ? ( {t('测试中...', 'Testing...')} ) : hasResult ? ( {result?.latency !== null ? `${result.latency}ms` : t('超时', 'Timeout')} ) : ( )}
) })}
) }