Add full pagination controls
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 53s

This commit is contained in:
Cauê Faleiros
2026-07-01 11:26:09 -03:00
parent f5e2de9a35
commit e2b2163c83
6 changed files with 219 additions and 238 deletions

View File

@@ -1,7 +1,8 @@
import { useEffect, useMemo, useRef, useState } from 'react';
import { Link, useOutletContext } from 'react-router-dom';
import { Search, ChevronRight, Filter, ChevronLeft, X } from 'lucide-react';
import { Search, ChevronRight, Filter, X } from 'lucide-react';
import { BarChart, Bar, Cell, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import PaginationControls from '../components/PaginationControls';
import RefreshStatus from '../components/RefreshStatus';
import type { ClientAnalyticsItem, ClientFilterOptions, ClientMetadataFilters, ClientPurchasePatternAnalytics, DateRange, RfmAnalytics, RfmClient } from '../types';
import { fetchClientAnalytics, fetchClientFilterOptions, fetchClientPurchasePatternAnalytics, fetchRfmAnalytics, getCachedClientAnalytics, getCachedClientFilterOptions, getCachedRfmAnalytics } from '../dataService';
@@ -390,7 +391,8 @@ const Clients = () => {
// Pagination logic
const totalPages = Math.ceil(clientsData.length / itemsPerPage);
const startIndex = (currentPage - 1) * itemsPerPage;
const safeCurrentPage = Math.min(currentPage, totalPages || 1);
const startIndex = (safeCurrentPage - 1) * itemsPerPage;
const paginatedData = clientsData.slice(startIndex, startIndex + itemsPerPage);
const formatCurrency = (value: number) => {
@@ -803,48 +805,22 @@ const Clients = () => {
</table>
</div>
{/* Pagination Controls */}
<div className="px-6 py-4 border-t border-zinc-100 dark:border-dark-border flex flex-col sm:flex-row items-center justify-between gap-4">
<div className="flex items-center gap-2 text-sm text-zinc-500 dark:text-dark-muted">
<span>Mostrar</span>
<select
value={itemsPerPage}
onChange={(e) => {
setItemsPerPage(Number(e.target.value));
setCurrentPage(1);
}}
className="bg-dark-card border border-dark-border rounded-lg px-2 py-1 focus:outline-none focus:border-brand-primary cursor-pointer text-dark-text"
>
<option value={10}>10</option>
<option value={20}>20</option>
<option value={50}>50</option>
<option value={100}>100</option>
</select>
<span>itens por página</span>
</div>
<div className="flex items-center gap-4 text-sm">
<span className="text-zinc-500 dark:text-dark-muted">
Mostrando {clientsData.length > 0 ? startIndex + 1 : 0} a {Math.min(startIndex + itemsPerPage, clientsData.length)} de {clientsData.length} clientes
</span>
<div className="flex gap-1">
<button
onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
disabled={currentPage === 1}
className="p-1 rounded-lg border border-dark-border disabled:opacity-50 disabled:cursor-not-allowed hover:border-brand-primary transition-colors text-dark-muted hover:text-dark-text cursor-pointer bg-dark-card"
>
<ChevronLeft className="w-5 h-5" />
</button>
<button
onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
disabled={currentPage === totalPages || totalPages === 0}
className="p-1 rounded-lg border border-dark-border disabled:opacity-50 disabled:cursor-not-allowed hover:border-brand-primary transition-colors text-dark-muted hover:text-dark-text cursor-pointer bg-dark-card"
>
<ChevronRight className="w-5 h-5" />
</button>
</div>
</div>
</div>
<PaginationControls
totalItems={clientsData.length}
currentPage={safeCurrentPage}
totalPages={totalPages}
pageSize={itemsPerPage}
pageSizeOptions={[10, 20, 50, 100]}
itemLabel="clientes"
pageSizeLabel="itens por página"
startIndex={startIndex}
endIndex={Math.min(startIndex + itemsPerPage, clientsData.length)}
onPageChange={setCurrentPage}
onPageSizeChange={(pageSize) => {
setItemsPerPage(pageSize);
setCurrentPage(1);
}}
/>
</div>
)}