Add Tiny ERP order metadata ingestion

This commit is contained in:
Cauê Faleiros
2026-06-22 15:02:38 -03:00
parent 0874238fc6
commit 3568e48ce9
8 changed files with 283 additions and 38 deletions

View File

@@ -3,7 +3,7 @@ import { useParams, Link, useOutletContext } from 'react-router-dom';
import { ArrowLeft, User, Tag, Package, DollarSign, Clock, Phone, ChevronLeft, ChevronRight, ShoppingBag, ReceiptText } from 'lucide-react';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import DateRangePicker from '../components/DateRangePicker';
import type { ClientDetailsAnalytics, DateRange } from '../types';
import type { ClientDetailsAnalytics, DateRange, OrderData } from '../types';
import { fetchClientDetailsAnalytics } from '../dataService';
type CustomTooltipProps = {
@@ -26,6 +26,21 @@ const CustomTooltip = ({ active, payload, label }: CustomTooltipProps) => {
return null;
};
const getOrderMetadata = (order: OrderData) => {
const seller = [
order.nome_vendedor,
order.id_vendedor ? `#${order.id_vendedor}` : ''
].filter(Boolean).join(' ');
return [
order.cliente_nome_fantasia ? `Fantasia: ${order.cliente_nome_fantasia}` : '',
seller ? `Vendedor: ${seller}` : '',
order.marketplace ? `Marketplace: ${order.marketplace}` : '',
order.canal_venda ? `Canal: ${order.canal_venda}` : '',
order.numero_ecommerce ? `E-commerce: ${order.numero_ecommerce}` : ''
].filter(Boolean);
};
const ClientDetails = () => {
const { clientToken } = useParams<{ clientToken: string }>();
const decodedClientToken = clientToken ? decodeURIComponent(clientToken) : '';
@@ -242,43 +257,56 @@ const ClientDetails = () => {
</div>
<div className="divide-y divide-zinc-100 dark:divide-dark-border">
{group.items.map((order, index) => (
<div key={`${order.ID_Produto}-${index}`} className="px-4 py-2 flex flex-col md:flex-row md:items-center justify-between gap-3 hover:bg-zinc-50/50 dark:hover:bg-dark-input/30 transition-colors">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-0.5">
<div className="flex items-center gap-1">
<Tag className="w-3 h-3 text-zinc-400 dark:text-dark-muted" />
<span className="text-[10px] font-bold text-zinc-400 dark:text-dark-muted">ID: {order.ID_Produto}</span>
{group.items.map((order, index) => {
const metadata = getOrderMetadata(order);
return (
<div key={`${order.ID_Produto}-${index}`} className="px-4 py-2 flex flex-col md:flex-row md:items-center justify-between gap-3 hover:bg-zinc-50/50 dark:hover:bg-dark-input/30 transition-colors">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-0.5">
<div className="flex items-center gap-1">
<Tag className="w-3 h-3 text-zinc-400 dark:text-dark-muted" />
<span className="text-[10px] font-bold text-zinc-400 dark:text-dark-muted">ID: {order.ID_Produto}</span>
</div>
{order.Data_Pedido && (
<div className="flex items-center gap-1 ml-2">
<Clock className="w-3 h-3 text-zinc-400 dark:text-dark-muted" />
<span className="text-[10px] font-bold text-zinc-400 dark:text-dark-muted">
Comprado: {order.Data_Pedido}
</span>
</div>
)}
</div>
{order.Data_Pedido && (
<div className="flex items-center gap-1 ml-2">
<Clock className="w-3 h-3 text-zinc-400 dark:text-dark-muted" />
<span className="text-[10px] font-bold text-zinc-400 dark:text-dark-muted">
Comprado: {order.Data_Pedido}
</span>
<h3 className="text-sm font-bold text-zinc-900 dark:text-dark-text truncate mb-1">{order.Descricao_Produto}</h3>
<div className="flex gap-4">
<div className="flex items-center gap-1.5 text-[11px]">
<Package className="w-3.5 h-3.5 text-zinc-400 dark:text-dark-muted" />
<span className="text-zinc-500 dark:text-dark-muted font-medium">Qtd: <span className="text-zinc-900 dark:text-dark-text font-bold">{order.Quantidade}</span></span>
</div>
<div className="flex items-center gap-1.5 text-[11px]">
<DollarSign className="w-3.5 h-3.5 text-zinc-400 dark:text-dark-muted" />
<span className="text-zinc-500 dark:text-dark-muted font-medium">Preço: <span className="text-zinc-900 dark:text-dark-text font-bold">{formatCurrency(order.Valor_Unitario)}</span></span>
</div>
</div>
{metadata.length > 0 && (
<div className="mt-2 flex flex-wrap gap-1.5">
{metadata.map(value => (
<span key={value} className="max-w-full break-all rounded-md border border-zinc-200 dark:border-dark-border px-2 py-0.5 text-[10px] font-bold text-zinc-500 dark:text-dark-muted">
{value}
</span>
))}
</div>
)}
</div>
<h3 className="text-sm font-bold text-zinc-900 dark:text-dark-text truncate mb-1">{order.Descricao_Produto}</h3>
<div className="flex gap-4">
<div className="flex items-center gap-1.5 text-[11px]">
<Package className="w-3.5 h-3.5 text-zinc-400 dark:text-dark-muted" />
<span className="text-zinc-500 dark:text-dark-muted font-medium">Qtd: <span className="text-zinc-900 dark:text-dark-text font-bold">{order.Quantidade}</span></span>
</div>
<div className="flex items-center gap-1.5 text-[11px]">
<DollarSign className="w-3.5 h-3.5 text-zinc-400 dark:text-dark-muted" />
<span className="text-zinc-500 dark:text-dark-muted font-medium">Preço: <span className="text-zinc-900 dark:text-dark-text font-bold">{formatCurrency(order.Valor_Unitario)}</span></span>
</div>
<div className="text-right shrink-0">
<p className="text-[10px] font-bold text-zinc-400 dark:text-dark-muted uppercase tracking-widest mb-0.5">Subtotal</p>
<p className="text-base font-bold text-zinc-900 dark:text-dark-text">{formatCurrency(order.Quantidade * order.Valor_Unitario)}</p>
</div>
</div>
<div className="text-right shrink-0">
<p className="text-[10px] font-bold text-zinc-400 dark:text-dark-muted uppercase tracking-widest mb-0.5">Subtotal</p>
<p className="text-base font-bold text-zinc-900 dark:text-dark-text">{formatCurrency(order.Quantidade * order.Valor_Unitario)}</p>
</div>
</div>
))}
);
})}
</div>
</div>
))}

View File

@@ -9,6 +9,12 @@ export interface OrderData {
Recebido_Em?: string;
ID_Pedido?: string;
Fone_Cliente?: string;
cliente_nome_fantasia?: string;
id_vendedor?: string;
nome_vendedor?: string;
marketplace?: string;
canal_venda?: string;
numero_ecommerce?: string;
}
export interface StockData {