import { useEffect, useState } from 'react'; import type { TargetSummary, TargetVehicle, TrendPoint } from './types'; import { fetchTargets, fetchTargetVehicles, fetchTrend } from './api'; import AllVehiclesPanel from './statistics/AllVehiclesPanel'; import FullscreenTargetTable from './statistics/FullscreenTargetTable'; import StatisticsOverview from './statistics/StatisticsOverview'; import TargetDetailPanel from './statistics/TargetDetailPanel'; import TrendPanel from './statistics/TrendPanel'; import { deriveSelectedTargetMetrics, getCurrentDateLabel, getDefaultDate, initialAssessmentYears, orderTargets, } from './statistics/model'; export default function StatisticsView() { const currentDateLabel = getCurrentDateLabel(); const [targets, setTargets] = useState([]); const [trendData, setTrendData] = useState([]); const [targetVehiclesMap, setTargetVehiclesMap] = useState>({}); const [selectedTargetId, setSelectedTargetId] = useState(null); const [isTableFullscreen, setIsTableFullscreen] = useState(false); const [expandedTargetId, setExpandedTargetId] = useState(null); const [assessmentYearMap, setAssessmentYearMap] = useState>({}); const [viewAllTargetId, setViewAllTargetId] = useState(null); const [viewAllTargetName, setViewAllTargetName] = useState(''); const [viewAllDate, setViewAllDate] = useState(getDefaultDate); const [viewAllLoading, setViewAllLoading] = useState(false); const selectedTarget = targets.find(target => target.id === selectedTargetId); const selectedMetrics = deriveSelectedTargetMetrics( selectedTarget, selectedTarget ? assessmentYearMap[selectedTarget.id] : undefined, trendData, ); // Load targets on mount useEffect(() => { fetchTargets().then(data => { const focused = data.find(item => item.targetName.includes('羚牛136')) || data[0]; const ordered = orderTargets(data); setTargets(ordered); if (ordered.length > 0 && !selectedTargetId) { setSelectedTargetId(focused.id); setExpandedTargetId(focused.id); setAssessmentYearMap(initialAssessmentYears(ordered)); fetchTargetVehicles(focused.id).then(vehicles => { setTargetVehiclesMap(previous => ({ ...previous, [focused.id]: vehicles })); }).catch(() => {}); } }).catch(() => {}); }, []); // Load trend when selectedTargetId changes useEffect(() => { if (selectedTargetId === null) return; setExpandedTargetId(selectedTargetId); if (!targetVehiclesMap[selectedTargetId]) { fetchTargetVehicles(selectedTargetId).then(vehicles => { setTargetVehiclesMap(previous => ({ ...previous, [selectedTargetId]: vehicles })); }).catch(() => {}); } fetchTrend(selectedTargetId).then(setTrendData).catch(() => setTrendData([])); }, [selectedTargetId]); // Re-fetch target vehicles when viewAllDate changes useEffect(() => { if (viewAllTargetId === null) return; setViewAllLoading(true); fetchTargetVehicles(viewAllTargetId, viewAllDate).then(data => { setTargetVehiclesMap(previous => ({ ...previous, [viewAllTargetId]: data })); }).catch(() => {}).finally(() => setViewAllLoading(false)); }, [viewAllTargetId, viewAllDate]); function selectTarget(targetId: number) { setSelectedTargetId(targetId); setExpandedTargetId(targetId); } function expandTarget(targetId: number) { setExpandedTargetId(targetId); if (!targetVehiclesMap[targetId]) { fetchTargetVehicles(targetId).then(data => { setTargetVehiclesMap(previous => ({ ...previous, [targetId]: data })); }).catch(() => {}); } } function openAllVehicles(target: TargetSummary) { setViewAllTargetId(target.id); setViewAllTargetName(target.targetName); setViewAllDate(getDefaultDate()); } function refreshTargets() { fetchTargets().then(data => { setTargets(data); }).catch(() => {}); } return (
setIsTableFullscreen(true)} onExpandTarget={expandTarget} onAssessmentYearChange={(targetId, year) => { setAssessmentYearMap(previous => ({ ...previous, [targetId]: year })); }} onViewAll={openAllVehicles} />
setIsTableFullscreen(false)} /> setViewAllTargetId(null)} />
); }