Improve consumption reference search and pagination
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 51s

This commit is contained in:
Cauê Faleiros
2026-08-26 16:03:52 -03:00
parent 5f767a96b6
commit 38add708ff
2 changed files with 38 additions and 10 deletions

View File

@@ -13,6 +13,7 @@ type PaginationControlsProps = {
onPageChange: (page: number) => void;
onPageSizeChange: (pageSize: number) => void;
className?: string;
stacked?: boolean;
};
const clampPage = (page: number, totalPages: number) => {
@@ -32,7 +33,8 @@ const PaginationControls = ({
endIndex,
onPageChange,
onPageSizeChange,
className = 'px-6 py-4 border-t border-zinc-100 dark:border-dark-border'
className = 'px-6 py-4 border-t border-zinc-100 dark:border-dark-border',
stacked = false
}: PaginationControlsProps) => {
const safeTotalPages = Math.max(1, totalPages);
const safeCurrentPage = clampPage(currentPage, safeTotalPages);
@@ -44,7 +46,7 @@ const PaginationControls = ({
};
return (
<div className={`${className} flex flex-col items-center justify-between gap-4 lg:flex-row`}>
<div className={`${className} ${stacked ? 'flex flex-col items-center gap-3' : 'flex flex-col items-center justify-between gap-4 lg:flex-row'}`}>
<div className="flex flex-wrap items-center justify-center gap-2 text-sm text-zinc-500 dark:text-dark-muted">
<span>Mostrar</span>
<select
@@ -59,7 +61,7 @@ const PaginationControls = ({
<span>{pageSizeLabel}</span>
</div>
<div className="flex flex-wrap items-center justify-center gap-3 text-sm">
<div className={stacked ? 'flex flex-col items-center gap-2 text-sm' : 'flex flex-wrap items-center justify-center gap-3 text-sm'}>
<span className="text-center text-zinc-500 dark:text-dark-muted">
Mostrando {totalItems > 0 ? startIndex + 1 : 0} a {endIndex} de {totalItems} {itemLabel}
</span>

View File

@@ -197,6 +197,7 @@ const Registrations = () => {
const [isLoading, setIsLoading] = useState(true);
const [activeTab, setActiveTab] = useState<RegistrationTab>('products');
const [productFilter, setProductFilter] = useState<'all' | CatalogProductType>('all');
const [referenceSearch, setReferenceSearch] = useState('');
const [pagination, setPagination] = useState<RegistrationPagination>({
products: { page: 1, pageSize: 10 },
categories: { page: 1, pageSize: 10 },
@@ -381,10 +382,20 @@ const Registrations = () => {
const categoryStartIndex = (safeCategoryPage - 1) * pagination.categories.pageSize;
const paginatedCategories = catalog.categories.slice(categoryStartIndex, categoryStartIndex + pagination.categories.pageSize);
const referenceTotalPages = Math.ceil(catalog.consumptionReferences.length / pagination.references.pageSize);
const filteredReferences = useMemo(() => {
const query = referenceSearch.trim().toLocaleLowerCase('pt-BR');
if (!query) return catalog.consumptionReferences;
return catalog.consumptionReferences.filter(reference => (
`${reference.productSku} ${reference.productName} ${reference.materialSku} ${reference.materialName} ${reference.color}`
.toLocaleLowerCase('pt-BR')
.includes(query)
));
}, [catalog.consumptionReferences, referenceSearch]);
const referenceTotalPages = Math.ceil(filteredReferences.length / pagination.references.pageSize);
const safeReferencePage = Math.min(pagination.references.page, referenceTotalPages || 1);
const referenceStartIndex = (safeReferencePage - 1) * pagination.references.pageSize;
const paginatedReferences = catalog.consumptionReferences.slice(referenceStartIndex, referenceStartIndex + pagination.references.pageSize);
const paginatedReferences = filteredReferences.slice(referenceStartIndex, referenceStartIndex + pagination.references.pageSize);
const runAction = async (action: () => Promise<void>, successMessage: string) => {
setStatus('saving');
@@ -993,9 +1004,23 @@ const Registrations = () => {
<p className="mt-1 text-xs font-semibold text-dark-muted">Rendimento pç/kg por produto, malha, cor e tamanho.</p>
</div>
<span className="rounded-full border border-dark-border bg-dark-input px-3 py-1 text-xs font-bold text-dark-muted">
{catalog.consumptionReferences.length} referencias
{referenceSearch ? `${filteredReferences.length} de ${catalog.consumptionReferences.length}` : catalog.consumptionReferences.length} referencias
</span>
</div>
<div className="border-b border-dark-border p-4">
<label className="relative block">
<Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-dark-muted" />
<input
value={referenceSearch}
onChange={(event) => {
setReferenceSearch(event.target.value);
updatePagination('references', { page: 1 });
}}
placeholder="Buscar por produto, SKU ou material..."
className={`${inputClassName} pl-9`}
/>
</label>
</div>
<div className="divide-y divide-dark-border">
{paginatedReferences.map(reference => (
<div key={reference.id} className="flex flex-col gap-3 p-4 md:flex-row md:items-start md:justify-between">
@@ -1054,14 +1079,14 @@ const Registrations = () => {
</div>
</div>
))}
{!catalog.consumptionReferences.length && (
{!filteredReferences.length && (
<div className={emptyStateClassName}>
Nenhuma referencia cadastrada.
{referenceSearch ? 'Nenhuma referência encontrada.' : 'Nenhuma referencia cadastrada.'}
</div>
)}
</div>
<PaginationControls
totalItems={catalog.consumptionReferences.length}
totalItems={filteredReferences.length}
currentPage={safeReferencePage}
totalPages={referenceTotalPages}
pageSize={pagination.references.pageSize}
@@ -1069,9 +1094,10 @@ const Registrations = () => {
itemLabel="referências"
pageSizeLabel="por página"
startIndex={referenceStartIndex}
endIndex={Math.min(referenceStartIndex + pagination.references.pageSize, catalog.consumptionReferences.length)}
endIndex={Math.min(referenceStartIndex + pagination.references.pageSize, filteredReferences.length)}
onPageChange={(page) => updatePagination('references', { page })}
onPageSizeChange={(pageSize) => updatePagination('references', { page: 1, pageSize })}
stacked
/>
</div>