perf: move date filtering to backend to massively reduce payload size and implement smart polling for instant updates without lag
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 54s

This commit is contained in:
Cauê Faleiros
2026-05-20 11:39:14 -03:00
parent cdcbfd2622
commit 4a7ff31898
3 changed files with 89 additions and 13 deletions

View File

@@ -1,8 +1,8 @@
import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';
import { Outlet, Link, useLocation } from 'react-router-dom';
import { LayoutDashboard, Users, BarChart3, ChevronLeft, ChevronRight, Package, Loader2, LogOut } from 'lucide-react';
import type { DateRange, OrderData } from '../types';
import { fetchData, logout } from '../dataService';
import { fetchData, fetchLastUpdate, logout } from '../dataService';
const Layout = () => {
const location = useLocation();
@@ -18,9 +18,10 @@ const Layout = () => {
return { start: new Date(parsed.start), end: new Date(parsed.end) };
} catch (e) { console.error(e); }
}
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 1);
start.setHours(0,0,0,0);
const end = new Date();
end.setHours(23,59,59,999);
return { start, end };
});
@@ -30,27 +31,41 @@ const Layout = () => {
const saved = localStorage.getItem('nexstar_refresh_interval');
return saved ? Number(saved) : 0;
});
const lastUpdateIdRef = useRef<number>(0);
const loadData = async (showLoading = false) => {
if (showLoading) setIsLoading(true);
const data = await fetchData();
const data = await fetchData(dateRange.start, dateRange.end);
setOrdersData(data);
// Also update the last known ID so we don't double-fetch immediately
const maxId = await fetchLastUpdate();
lastUpdateIdRef.current = maxId;
if (showLoading) setIsLoading(false);
};
// Fetch new data immediately whenever the selected date range changes
useEffect(() => {
loadData(true);
}, []);
}, [dateRange]);
// Smart Polling Logic
useEffect(() => {
if (refreshInterval === 0) return;
const intervalId = setInterval(() => {
loadData(false);
}, refreshInterval);
const checkUpdate = async () => {
const latestId = await fetchLastUpdate();
if (latestId > lastUpdateIdRef.current) {
lastUpdateIdRef.current = latestId;
loadData(false); // Background fetch of the new payload
}
};
const intervalId = setInterval(checkUpdate, refreshInterval);
return () => clearInterval(intervalId);
}, [refreshInterval]);
}, [refreshInterval, dateRange]);
useEffect(() => {
localStorage.setItem('nexstar_refresh_interval', refreshInterval.toString());

View File

@@ -33,10 +33,35 @@ export const isAuthenticated = (): boolean => {
return !!localStorage.getItem('auth_token');
};
export const fetchData = async (): Promise<OrderData[]> => {
export const fetchLastUpdate = async (): Promise<number> => {
try {
const token = localStorage.getItem('auth_token');
const response = await fetch(`${API_URL}/data`, {
const response = await fetch(`${API_URL}/last-update`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.status === 401 || response.status === 403) {
logout();
return 0;
}
if (!response.ok) return 0;
const data = await response.json();
return data.max_id || 0;
} catch (error) {
return 0;
}
};
export const fetchData = async (start?: Date, end?: Date): Promise<OrderData[]> => {
try {
const token = localStorage.getItem('auth_token');
let url = `${API_URL}/data`;
if (start && end) {
url += `?start=${start.toISOString()}&end=${end.toISOString()}`;
}
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${token}`
}