Compare commits

...

3 Commits

Author SHA1 Message Date
Cauê Faleiros
4ce1e9aedb style: remove WhatsApp link from client phone number
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m24s
2026-05-22 13:57:13 -03:00
Cauê Faleiros
fc8a5e47a0 fix: send Fone_Cliente from backend to frontend API response 2026-05-22 13:40:31 -03:00
Cauê Faleiros
174bb4841e feat: display customer phone number on client details page with WhatsApp quick link 2026-05-22 12:10:10 -03:00
3 changed files with 34 additions and 10 deletions

View File

@@ -90,7 +90,8 @@ const formatRow = (row) => ({
Quantidade: row.quantidade, Quantidade: row.quantidade,
Valor_Unitario: parseFloat(row.valor_unitario), Valor_Unitario: parseFloat(row.valor_unitario),
Recebido_Em: row.created_at, Recebido_Em: row.created_at,
ID_Pedido: row.pedido_id ID_Pedido: row.pedido_id,
Fone_Cliente: row.cliente_fone
}); });
// GET data (for the frontend) // GET data (for the frontend)
@@ -177,11 +178,6 @@ app.post('/api/data', authenticateAPIKey, async (req, res) => {
})(); })();
}); });
app.listen(PORT, '0.0.0.0', () => {
console.log(`Nexstar Backend running at http://localhost:${PORT}`);
console.log(`Endpoint for n8n: POST http://localhost:${PORT}/api/data`);
});;
app.listen(PORT, '0.0.0.0', () => { app.listen(PORT, '0.0.0.0', () => {
console.log(`Nexstar Backend running at http://localhost:${PORT}`); console.log(`Nexstar Backend running at http://localhost:${PORT}`);
console.log(`Endpoint for n8n: POST http://localhost:${PORT}/api/data`); console.log(`Endpoint for n8n: POST http://localhost:${PORT}/api/data`);

View File

@@ -1,6 +1,6 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useParams, Link, useOutletContext } from 'react-router-dom'; import { useParams, Link, useOutletContext } from 'react-router-dom';
import { ArrowLeft, User, Tag, Package, DollarSign, Clock } from 'lucide-react'; import { ArrowLeft, User, Tag, Package, DollarSign, Clock, Phone } from 'lucide-react';
import type { OrderData } from '../types'; import type { OrderData } from '../types';
import { parseOrderDate } from '../dataService'; import { parseOrderDate } from '../dataService';
@@ -9,18 +9,20 @@ const ClientDetails = () => {
const decodedName = name ? decodeURIComponent(name) : ''; const decodedName = name ? decodeURIComponent(name) : '';
const { ordersData } = useOutletContext<{ ordersData: OrderData[] }>(); const { ordersData } = useOutletContext<{ ordersData: OrderData[] }>();
const { groupedOrders, totalSpent, totalItems } = useMemo(() => { const { groupedOrders, totalSpent, totalItems, clientPhone } = useMemo(() => {
const orders = ordersData; const orders = ordersData;
const clientOrders = orders.filter(order => { const clientOrders = orders.filter(order => {
const clientName = order.Nome_Cliente || `Cliente Desconhecido (Pedido ${order.Valor_Pedido})`; const clientName = order.Nome_Cliente || `Cliente Desconhecido (Pedido ${order.Valor_Pedido})`;
return clientName === decodedName; return clientName === decodedName;
}); });
let clientPhone = '';
const groupedOrdersMap: Record<string, { date: string, orderId: string, orderTotal: number, items: OrderData[] }> = {}; const groupedOrdersMap: Record<string, { date: string, orderId: string, orderTotal: number, items: OrderData[] }> = {};
let totalSpent = 0; let totalSpent = 0;
let totalItems = 0; let totalItems = 0;
clientOrders.forEach(order => { clientOrders.forEach(order => {
if (order.Fone_Cliente && !clientPhone) clientPhone = order.Fone_Cliente;
totalSpent += (order.Quantidade * order.Valor_Unitario); totalSpent += (order.Quantidade * order.Valor_Unitario);
totalItems += order.Quantidade; totalItems += order.Quantidade;
@@ -42,7 +44,7 @@ const ClientDetails = () => {
return parseOrderDate(b.date).getTime() - parseOrderDate(a.date).getTime(); return parseOrderDate(b.date).getTime() - parseOrderDate(a.date).getTime();
}); });
return { groupedOrders, totalSpent, totalItems }; return { groupedOrders, totalSpent, totalItems, clientPhone };
}, [decodedName, ordersData]); }, [decodedName, ordersData]);
const formatCurrency = (value: number) => { const formatCurrency = (value: number) => {
@@ -74,7 +76,18 @@ const ClientDetails = () => {
</div> </div>
<div> <div>
<h1 className="text-2xl font-bold text-zinc-900 dark:text-dark-text">{decodedName}</h1> <h1 className="text-2xl font-bold text-zinc-900 dark:text-dark-text">{decodedName}</h1>
<p className="text-zinc-500 dark:text-dark-muted font-medium">Histórico completo de compras</p> <div className="flex items-center gap-3 mt-1">
<p className="text-zinc-500 dark:text-dark-muted font-medium">Histórico completo de compras</p>
{clientPhone && (
<>
<span className="text-zinc-300 dark:text-dark-border"></span>
<span className="flex items-center gap-1.5 text-brand-primary font-bold text-sm bg-brand-primary/10 px-2 py-1 rounded-md">
<Phone className="w-3.5 h-3.5" />
{clientPhone}
</span>
</>
)}
</div>
</div> </div>
</div> </div>

15
test-fetch.js Normal file
View File

@@ -0,0 +1,15 @@
async function run() {
const loginRes = await fetch('http://localhost:3004/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'admin@admin.com', password: 'admin123' })
});
const { token } = await loginRes.json();
const dataRes = await fetch('http://localhost:3004/api/data?start=2020-01-01&end=2030-01-01', {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await dataRes.json();
const fabricio = data.find(d => d.Nome_Cliente.includes('Teste Hoje'));
console.log(fabricio);
}
run();