Add skeleton loaders to client and product pages
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m16s

This commit is contained in:
Cauê Faleiros
2026-06-29 09:55:19 -03:00
parent a0a1108f3a
commit ff55d0618e
5 changed files with 216 additions and 19 deletions

View File

@@ -133,6 +133,40 @@ const dateFilterPresets = [
const filterSelectClassName = "w-full h-9 bg-dark-input border border-dark-border text-dark-text text-sm rounded-lg px-3 focus:outline-none focus:border-brand-primary transition-colors cursor-pointer";
const ClientsTableSkeleton = () => (
<div className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl overflow-hidden shadow-sm" aria-label="Carregando clientes">
<div className="border-b border-zinc-100 p-4 dark:border-dark-border">
<div className="grid grid-cols-[72px_1.4fr_150px_110px_140px_140px_170px_110px] gap-5">
{[0, 1, 2, 3, 4, 5, 6, 7].map(item => (
<div key={`clients-head-skeleton-${item}`} className="skeleton h-3" />
))}
</div>
</div>
<div className="divide-y divide-zinc-100 dark:divide-dark-border">
{[0, 1, 2, 3, 4, 5, 6, 7].map(row => (
<div key={`clients-row-skeleton-${row}`} className="grid grid-cols-[72px_1.4fr_150px_110px_140px_140px_170px_110px] gap-5 px-6 py-4">
<div className="skeleton h-7 w-7 rounded-full" />
<div className="skeleton h-4 w-4/5" />
<div className="skeleton h-7 rounded-full" />
<div className="flex gap-1">
<div className="skeleton h-6 w-6 rounded-md" />
<div className="skeleton h-6 w-6 rounded-md" />
<div className="skeleton h-6 w-6 rounded-md" />
</div>
<div className="skeleton h-4" />
<div className="skeleton h-4" />
<div className="skeleton h-4" />
<div className="skeleton h-4" />
</div>
))}
</div>
<div className="flex items-center justify-between border-t border-zinc-100 p-4 dark:border-dark-border">
<div className="skeleton h-4 w-48" />
<div className="skeleton h-8 w-56" />
</div>
</div>
);
const Clients = () => {
const { dateRange, setDateRange, themeMode } = useOutletContext<{
dateRange: DateRange,
@@ -152,6 +186,7 @@ const Clients = () => {
const filterMenuRef = useRef<HTMLDivElement>(null);
const [rfmAnalytics, setRfmAnalytics] = useState<RfmAnalytics | null>(initialRfmAnalytics || null);
const [clientAnalytics, setClientAnalytics] = useState<ClientAnalyticsItem[]>(initialClientAnalytics || []);
const [isLoading, setIsLoading] = useState(!initialClientAnalytics);
// Pagination state
const [currentPage, setCurrentPage] = useState(1);
@@ -164,11 +199,13 @@ const Clients = () => {
const cachedOptions = getCachedClientFilterOptions(dateRange);
const cachedClients = getCachedClientAnalytics(dateRange, metadataFilters);
const cachedRfm = getCachedRfmAnalytics(dateRange, metadataFilters);
const hasCachedClients = Boolean(cachedClients);
if (isMounted) {
if (cachedOptions) setFilterOptions(cachedOptions);
if (cachedClients) setClientAnalytics(cachedClients);
setRfmAnalytics(cachedRfm || null);
setIsLoading(!hasCachedClients);
}
const filterOptionsPromise = fetchClientFilterOptions(dateRange, { force: true });
@@ -179,6 +216,7 @@ const Clients = () => {
if (isMounted) {
setFilterOptions(options);
setClientAnalytics(clientsData);
setIsLoading(false);
}
const rfmData = await rfmPromise;
@@ -599,6 +637,9 @@ const Clients = () => {
</div>
</div>
{isLoading && clientAnalytics.length === 0 ? (
<ClientsTableSkeleton />
) : (
<div className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl overflow-hidden shadow-sm">
<div className="overflow-x-auto">
<table className="w-full text-left text-sm">
@@ -710,6 +751,7 @@ const Clients = () => {
</div>
</div>
</div>
)}
</div>
);
};