extract frontend analytics helpers
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m12s

This commit is contained in:
Cauê Faleiros
2026-05-27 15:58:12 -03:00
parent 8c2590c56a
commit 72ded82ec7
9 changed files with 362 additions and 258 deletions

View File

@@ -3,7 +3,8 @@ import { Link, useOutletContext } from 'react-router-dom';
import { Search, Package, TrendingUp, ChevronLeft, ChevronRight, Download } from 'lucide-react';
import DateRangePicker from '../components/DateRangePicker';
import type { OrderData, DateRange, StockData } from '../types';
import { parseOrderDate, exportToCSV } from '../dataService';
import { exportToCSV } from '../dataService';
import { buildProductsSummary } from '../analytics/products';
const Products = () => {
const { dateRange, setDateRange, ordersData, stockData } = useOutletContext<{
@@ -22,54 +23,7 @@ const Products = () => {
const [itemsPerPage, setItemsPerPage] = useState(10);
const productsData = useMemo(() => {
const orders = ordersData;
const productMap: Record<string, { id: string, name: string, totalSold: number, revenue: number, lastPrice: number, stock: number }> = {};
// Initialize with stock data
if (stockData && Array.isArray(stockData)) {
stockData.forEach(item => {
productMap[item.produto_id] = {
id: item.produto_id,
name: item.nome,
totalSold: 0,
revenue: 0,
lastPrice: 0,
stock: item.saldo || 0
};
});
}
orders.forEach(order => {
const orderDate = parseOrderDate(order.Data_Pedido);
if (orderDate < dateRange.start || orderDate > dateRange.end) return;
if (!productMap[order.ID_Produto]) {
productMap[order.ID_Produto] = {
id: order.ID_Produto,
name: order.Descricao_Produto.split(' TAMANHO')[0],
totalSold: 0,
revenue: 0,
lastPrice: order.Valor_Unitario,
stock: 0
};
}
// Update name if we didn't get it from stock
if (productMap[order.ID_Produto].name === 'Unknown' || !productMap[order.ID_Produto].name) {
productMap[order.ID_Produto].name = order.Descricao_Produto.split(' TAMANHO')[0];
}
productMap[order.ID_Produto].totalSold += order.Quantidade;
productMap[order.ID_Produto].revenue += (order.Quantidade * order.Valor_Unitario);
productMap[order.ID_Produto].lastPrice = order.Valor_Unitario;
});
let result = Object.values(productMap);
if (searchTerm) {
result = result.filter(p => p.name.toLowerCase().includes(searchTerm.toLowerCase()) || p.id.includes(searchTerm));
}
return result.sort((a, b) => b.totalSold - a.totalSold);
return buildProductsSummary(ordersData, stockData, dateRange, searchTerm);
}, [dateRange, searchTerm, ordersData, stockData]);
// Pagination logic