feat: replace SSE with Grafana-style client polling and rich date presets

This commit is contained in:
Cauê Faleiros
2026-05-07 14:52:45 -03:00
parent 3bb46cff1a
commit b986eafb98
6 changed files with 145 additions and 144 deletions

View File

@@ -26,39 +26,29 @@ const Layout = () => {
const [ordersData, setOrdersData] = useState<OrderData[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [refreshInterval, setRefreshInterval] = useState<number>(0);
const loadData = async (showLoading = false) => {
if (showLoading) setIsLoading(true);
const data = await fetchData();
setOrdersData(data);
if (showLoading) setIsLoading(false);
};
useEffect(() => {
const loadInitial = async () => {
setIsLoading(true);
const data = await fetchData();
setOrdersData(data);
setIsLoading(false);
};
loadInitial();
// Set up SSE for real-time updates
const API_URL = import.meta.env.VITE_API_URL || '/api';
const sse = new EventSource(`${API_URL}/stream`);
sse.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
if (data.type === 'update') {
fetchData().then(newData => {
setOrdersData(newData);
});
}
} catch (e) {
console.error("SSE parse error", e);
}
};
return () => {
sse.close();
};
loadData(true);
}, []);
useEffect(() => {
if (refreshInterval === 0) return;
const intervalId = setInterval(() => {
loadData(false);
}, refreshInterval);
return () => clearInterval(intervalId);
}, [refreshInterval]);
useEffect(() => {
localStorage.setItem('nexstar_date_range', JSON.stringify({
start: dateRange.start.toISOString(),
@@ -149,7 +139,7 @@ const Layout = () => {
<Loader2 className="w-8 h-8 text-brand-primary animate-spin" />
</div>
) : (
<Outlet context={{ dateRange, setDateRange, ordersData }} />
<Outlet context={{ dateRange, setDateRange, ordersData, refreshInterval, setRefreshInterval, loadData }} />
)}
</div>
</main>