Match seller list loading state to table
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m1s

This commit is contained in:
Cauê Faleiros
2026-08-04 10:59:51 -03:00
parent 7d89c134cb
commit 0e06e800ec

View File

@@ -11,6 +11,19 @@ import type { DateRange, SellerAnalyticsItem } from '../types';
const formatNumber = (value: number) => new Intl.NumberFormat('pt-BR', { maximumFractionDigits: 0 }).format(value); const formatNumber = (value: number) => new Intl.NumberFormat('pt-BR', { maximumFractionDigits: 0 }).format(value);
const formatCurrency = (value: number) => new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value); const formatCurrency = (value: number) => new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value);
const SellersTableSkeleton = () => (
<div className="overflow-x-auto">
<div className="min-w-[980px]">
<div className="grid grid-cols-[90px_1.5fr_repeat(5,120px)_80px] gap-5 border-b border-dark-border bg-dark-header px-6 py-4">
{[1, 2, 3, 4, 5, 6, 7, 8].map(item => <div key={item} className="skeleton h-3" />)}
</div>
<div className="divide-y divide-dark-border">
{[1, 2, 3, 4, 5, 6].map(row => <div key={row} className="grid grid-cols-[90px_1.5fr_repeat(5,120px)_80px] items-center gap-5 px-6 py-3"><div className="skeleton h-7 w-7 rounded-full" /><div><div className="skeleton h-4 w-40" /><div className="skeleton mt-2 h-3 w-20" /></div>{[1, 2, 3, 4, 5].map(column => <div key={column} className="skeleton h-4" />)}<div className="skeleton h-8 w-8 rounded-lg" /></div>)}
</div>
</div>
</div>
);
const Sellers = () => { const Sellers = () => {
const { dateRange, setDateRange } = useOutletContext<{ dateRange: DateRange; setDateRange: (range: DateRange) => void }>(); const { dateRange, setDateRange } = useOutletContext<{ dateRange: DateRange; setDateRange: (range: DateRange) => void }>();
const [sellers, setSellers] = useState<SellerAnalyticsItem[]>([]); const [sellers, setSellers] = useState<SellerAnalyticsItem[]>([]);
@@ -62,20 +75,19 @@ const Sellers = () => {
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4"> <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
<div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm"> <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
<p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Receita da equipe</p> <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Receita da equipe</p>
<p className="mt-2 text-2xl font-bold text-brand-primary">{formatCurrency(totalRevenue)}</p> {isLoading && !sellers.length ? <div className="skeleton mt-3 h-7 w-36" /> : <p className="mt-2 text-2xl font-bold text-brand-primary">{formatCurrency(totalRevenue)}</p>}
</div> </div>
<div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm"> <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
<p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Pedidos</p> <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Pedidos</p>
<p className="mt-2 text-3xl font-bold text-dark-text">{formatNumber(totalOrders)}</p> {isLoading && !sellers.length ? <div className="skeleton mt-3 h-8 w-20" /> : <p className="mt-2 text-3xl font-bold text-dark-text">{formatNumber(totalOrders)}</p>}
</div> </div>
<div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm"> <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
<p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Clientes atendidos</p> <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Clientes atendidos</p>
<p className="mt-2 text-3xl font-bold text-dark-text">{formatNumber(totalCustomers)}</p> {isLoading && !sellers.length ? <div className="skeleton mt-3 h-8 w-20" /> : <p className="mt-2 text-3xl font-bold text-dark-text">{formatNumber(totalCustomers)}</p>}
</div> </div>
<div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm"> <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
<p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Maior receita</p> <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Maior receita</p>
<p className="mt-2 truncate text-lg font-bold text-dark-text">{topSeller ? formatDisplayName(removeTrailingSellerId(topSeller.name)) : '—'}</p> {isLoading && !sellers.length ? <><div className="skeleton mt-3 h-5 w-40" /><div className="skeleton mt-2 h-3 w-24" /></> : <><p className="mt-2 truncate text-lg font-bold text-dark-text">{topSeller ? formatDisplayName(removeTrailingSellerId(topSeller.name)) : '—'}</p><p className="mt-1 text-xs font-semibold text-dark-muted">{topSeller ? formatCurrency(topSeller.revenue) : 'Sem vendas no período'}</p></>}
<p className="mt-1 text-xs font-semibold text-dark-muted">{topSeller ? formatCurrency(topSeller.revenue) : 'Sem vendas no período'}</p>
</div> </div>
</div> </div>
@@ -92,7 +104,7 @@ const Sellers = () => {
</div> </div>
{isLoading && !sellers.length ? ( {isLoading && !sellers.length ? (
<div className="space-y-3 p-5">{[1, 2, 3, 4].map(item => <div key={item} className="skeleton h-24" />)}</div> <SellersTableSkeleton />
) : visibleSellers.length ? ( ) : visibleSellers.length ? (
<> <>
<div className="overflow-x-auto"> <div className="overflow-x-auto">