Match seller list loading state to table
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m1s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m1s
This commit is contained in:
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user