{leftPanelOpen && ( <> ); } const Footer = memo(function Footer() { const { lastUpdated, nodes, dataSource, pollInterval } = useTopologyStore( useShallow((s) => ({ lastUpdated: s.lastUpdated, nodes: s.nodes, dataSource: s.dataSource, pollInterval: s.pollInterval, })) ); const [countdown, setCountdown] = useState(Math.ceil(pollInterval / 1000)); const pollIntervalRef = useRef(pollInterval); pollIntervalRef.current = pollInterval; const formatTime = (date: Date | string | null) => { if (!date) return 'Never'; const d = new Date(date); return isNaN(d.getTime()) ? 'Never' : d.toLocaleTimeString(); }; useEffect(() => { setCountdown(Math.ceil(pollInterval / 1000)); const intervalId = setInterval(() => { setCountdown(prev => { if (prev <= 1) return Math.ceil(pollIntervalRef.current / 1000); return prev - 1; }); }, 1000); return () => clearInterval(intervalId); }, [lastUpdated, pollInterval]); return (
Nodes: {nodes.length}
{dataSource === 'live' ? 'Live' : 'Simulated'} Next refresh: {countdown}s Last updated: {formatTime(lastUpdated)}
); }); export default App;