Add skeleton loaders to client and product pages
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m16s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m16s
This commit is contained in:
@@ -61,6 +61,82 @@ const getOrderMetadata = (order: OrderData) => {
|
||||
].filter(Boolean);
|
||||
};
|
||||
|
||||
const ClientDetailsSkeleton = () => (
|
||||
<div className="space-y-6" aria-label="Carregando cliente">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="skeleton h-4 w-20" />
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="skeleton h-16 w-16 rounded-2xl" />
|
||||
<div>
|
||||
<div className="skeleton h-7 w-56" />
|
||||
<div className="skeleton mt-3 h-4 w-72" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="skeleton h-10 w-64" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-4">
|
||||
{[0, 1, 2, 3].map(item => (
|
||||
<div key={`client-details-kpi-skeleton-${item}`} className="bg-dark-card p-5 rounded-2xl border border-dark-border shadow-sm">
|
||||
<div className="flex justify-between gap-5">
|
||||
<div className="w-full">
|
||||
<div className="skeleton h-3 w-32" />
|
||||
<div className="skeleton mt-3 h-7 w-28" />
|
||||
</div>
|
||||
<div className="skeleton h-11 w-11 shrink-0 rounded-xl" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl p-6 shadow-sm">
|
||||
<div className="skeleton h-5 w-36" />
|
||||
<div className="mt-8 skeleton h-[320px] w-full" />
|
||||
</div>
|
||||
|
||||
<section className="space-y-4">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<div className="skeleton h-5 w-44" />
|
||||
<div className="skeleton mt-2 h-4 w-64" />
|
||||
</div>
|
||||
<div className="skeleton h-7 w-28 rounded-full" />
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||
{[0, 1].map(item => (
|
||||
<div key={`client-pattern-skeleton-${item}`} className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl p-6 shadow-sm">
|
||||
<div className="skeleton h-4 w-40" />
|
||||
<div className="mt-5 flex h-56 items-end gap-3">
|
||||
{[0, 1, 2, 3, 4, 5, 6].map(bar => (
|
||||
<div key={`client-pattern-bar-skeleton-${item}-${bar}`} className="skeleton flex-1" style={{ height: `${20 + ((bar * 17) % 65)}%` }} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
{[0, 1, 2, 3].map(item => (
|
||||
<div key={`client-order-skeleton-${item}`} className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl p-4 shadow-sm">
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex min-w-0 items-center gap-3">
|
||||
<div className="skeleton h-8 w-8 rounded-lg" />
|
||||
<div>
|
||||
<div className="skeleton h-4 w-48" />
|
||||
<div className="skeleton mt-2 h-3 w-32" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="skeleton h-8 w-28" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ClientDetails = () => {
|
||||
const { clientToken } = useParams<{ clientToken: string }>();
|
||||
const decodedClientToken = clientToken ? decodeURIComponent(clientToken) : '';
|
||||
@@ -129,11 +205,7 @@ const ClientDetails = () => {
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-zinc-500 dark:text-dark-muted font-medium">Carregando cliente...</p>
|
||||
</div>
|
||||
);
|
||||
return <ClientDetailsSkeleton />;
|
||||
}
|
||||
|
||||
if (!details?.hasClient) {
|
||||
|
||||
Reference in New Issue
Block a user