* Inner component that uses React 19's use() to read the stats promise. * Suspends while loading all-time stats, then handles date range changes without suspending.
({ allTimePromise, onClose }: StatsContentProps)
| 109 | * Suspends while loading all-time stats, then handles date range changes without suspending. |
| 110 | */ |
| 111 | function StatsContent({ allTimePromise, onClose }: StatsContentProps): React.ReactNode { |
| 112 | const allTimeResult = use(allTimePromise); |
| 113 | const [dateRange, setDateRange] = useState<StatsDateRange>('all'); |
| 114 | const [statsCache, setStatsCache] = useState<Partial<Record<StatsDateRange, ClaudeCodeStats>>>({}); |
| 115 | const [isLoadingFiltered, setIsLoadingFiltered] = useState(false); |
| 116 | const [activeTab, setActiveTab] = useState<'Overview' | 'Models'>('Overview'); |
| 117 | const [copyStatus, setCopyStatus] = useState<string | null>(null); |
| 118 | |
| 119 | // Load filtered stats when date range changes (with caching) |
| 120 | useEffect(() => { |
| 121 | if (dateRange === 'all') { |
| 122 | return; |
| 123 | } |
| 124 | |
| 125 | // Already cached |
| 126 | if (statsCache[dateRange]) { |
| 127 | return; |
| 128 | } |
| 129 | |
| 130 | let cancelled = false; |
| 131 | setIsLoadingFiltered(true); |
| 132 | |
| 133 | aggregateClaudeCodeStatsForRange(dateRange) |
| 134 | .then(data => { |
| 135 | if (!cancelled) { |
| 136 | setStatsCache(prev => ({ ...prev, [dateRange]: data })); |
| 137 | setIsLoadingFiltered(false); |
| 138 | } |
| 139 | }) |
| 140 | .catch(() => { |
| 141 | if (!cancelled) { |
| 142 | setIsLoadingFiltered(false); |
| 143 | } |
| 144 | }); |
| 145 | |
| 146 | return () => { |
| 147 | cancelled = true; |
| 148 | }; |
| 149 | }, [dateRange, statsCache]); |
| 150 | |
| 151 | // Use cached stats for current range |
| 152 | const displayStats = |
| 153 | dateRange === 'all' |
| 154 | ? allTimeResult.type === 'success' |
| 155 | ? allTimeResult.data |
| 156 | : null |
| 157 | : (statsCache[dateRange] ?? (allTimeResult.type === 'success' ? allTimeResult.data : null)); |
| 158 | |
| 159 | // All-time stats for the heatmap (always use all-time) |
| 160 | const allTimeStats = allTimeResult.type === 'success' ? allTimeResult.data : null; |
| 161 | |
| 162 | const handleClose = useCallback(() => { |
| 163 | onClose('Stats dialog dismissed', { display: 'system' }); |
| 164 | }, [onClose]); |
| 165 | |
| 166 | useKeybinding('confirm:no', handleClose, { context: 'Confirmation' }); |
| 167 | |
| 168 | useInput((input, key) => { |
nothing calls this directly
no test coverage detected