diff --git a/backend/index.js b/backend/index.js index 79a1be8..a4d5757 100644 --- a/backend/index.js +++ b/backend/index.js @@ -74,9 +74,15 @@ app.get('/api/stream', (req, res) => { // Send initial connection event res.write('data: {"connected": true}\n\n'); + // Keep connection alive through Nginx/Cloudflare + const keepAlive = setInterval(() => { + res.write(':\n\n'); // SSE comment to prevent idle timeout + }, 15000); + sseClients.add(res); req.on('close', () => { + clearInterval(keepAlive); sseClients.delete(res); }); }); diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 159be65..7c6e762 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -15,6 +15,17 @@ const COLORS = [ '#67e8f9', '#f9a8d4', '#fde047', '#a5b4fc', '#5eead4' ]; +const globalColorMap: Record = {}; +let globalColorIndex = 0; + +const getProductColor = (name: string) => { + if (!globalColorMap[name]) { + globalColorMap[name] = COLORS[globalColorIndex % COLORS.length]; + globalColorIndex++; + } + return globalColorMap[name]; +}; + const formatCurrency = (value: number) => { return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value); }; @@ -75,8 +86,8 @@ const Dashboard = () => { const displayProducts = Array.from(new Set([...topSalesNames, ...topRevenueNames])).sort(); const productColors: Record = {}; - displayProducts.forEach((name, index) => { - productColors[name] = COLORS[index % COLORS.length]; + displayProducts.forEach((name) => { + productColors[name] = getProductColor(name); }); const productsData = topSalesNames.map(name => ({