fix: stabilize color mapping by using persistent global hash and add SSE heartbeat
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m18s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m18s
This commit is contained in:
@@ -74,9 +74,15 @@ app.get('/api/stream', (req, res) => {
|
|||||||
// Send initial connection event
|
// Send initial connection event
|
||||||
res.write('data: {"connected": true}\n\n');
|
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);
|
sseClients.add(res);
|
||||||
|
|
||||||
req.on('close', () => {
|
req.on('close', () => {
|
||||||
|
clearInterval(keepAlive);
|
||||||
sseClients.delete(res);
|
sseClients.delete(res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,17 @@ const COLORS = [
|
|||||||
'#67e8f9', '#f9a8d4', '#fde047', '#a5b4fc', '#5eead4'
|
'#67e8f9', '#f9a8d4', '#fde047', '#a5b4fc', '#5eead4'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const globalColorMap: Record<string, string> = {};
|
||||||
|
let globalColorIndex = 0;
|
||||||
|
|
||||||
|
const getProductColor = (name: string) => {
|
||||||
|
if (!globalColorMap[name]) {
|
||||||
|
globalColorMap[name] = COLORS[globalColorIndex % COLORS.length];
|
||||||
|
globalColorIndex++;
|
||||||
|
}
|
||||||
|
return globalColorMap[name];
|
||||||
|
};
|
||||||
|
|
||||||
const formatCurrency = (value: number) => {
|
const formatCurrency = (value: number) => {
|
||||||
return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value);
|
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 displayProducts = Array.from(new Set([...topSalesNames, ...topRevenueNames])).sort();
|
||||||
const productColors: Record<string, string> = {};
|
const productColors: Record<string, string> = {};
|
||||||
|
|
||||||
displayProducts.forEach((name, index) => {
|
displayProducts.forEach((name) => {
|
||||||
productColors[name] = COLORS[index % COLORS.length];
|
productColors[name] = getProductColor(name);
|
||||||
});
|
});
|
||||||
|
|
||||||
const productsData = topSalesNames.map(name => ({
|
const productsData = topSalesNames.map(name => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user