Improve consumption reference search and pagination
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 51s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 51s
This commit is contained in:
@@ -13,6 +13,7 @@ type PaginationControlsProps = {
|
|||||||
onPageChange: (page: number) => void;
|
onPageChange: (page: number) => void;
|
||||||
onPageSizeChange: (pageSize: number) => void;
|
onPageSizeChange: (pageSize: number) => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
stacked?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const clampPage = (page: number, totalPages: number) => {
|
const clampPage = (page: number, totalPages: number) => {
|
||||||
@@ -32,7 +33,8 @@ const PaginationControls = ({
|
|||||||
endIndex,
|
endIndex,
|
||||||
onPageChange,
|
onPageChange,
|
||||||
onPageSizeChange,
|
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) => {
|
}: PaginationControlsProps) => {
|
||||||
const safeTotalPages = Math.max(1, totalPages);
|
const safeTotalPages = Math.max(1, totalPages);
|
||||||
const safeCurrentPage = clampPage(currentPage, safeTotalPages);
|
const safeCurrentPage = clampPage(currentPage, safeTotalPages);
|
||||||
@@ -44,7 +46,7 @@ const PaginationControls = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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">
|
<div className="flex flex-wrap items-center justify-center gap-2 text-sm text-zinc-500 dark:text-dark-muted">
|
||||||
<span>Mostrar</span>
|
<span>Mostrar</span>
|
||||||
<select
|
<select
|
||||||
@@ -59,7 +61,7 @@ const PaginationControls = ({
|
|||||||
<span>{pageSizeLabel}</span>
|
<span>{pageSizeLabel}</span>
|
||||||
</div>
|
</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">
|
<span className="text-center text-zinc-500 dark:text-dark-muted">
|
||||||
Mostrando {totalItems > 0 ? startIndex + 1 : 0} a {endIndex} de {totalItems} {itemLabel}
|
Mostrando {totalItems > 0 ? startIndex + 1 : 0} a {endIndex} de {totalItems} {itemLabel}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ const Registrations = () => {
|
|||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [activeTab, setActiveTab] = useState<RegistrationTab>('products');
|
const [activeTab, setActiveTab] = useState<RegistrationTab>('products');
|
||||||
const [productFilter, setProductFilter] = useState<'all' | CatalogProductType>('all');
|
const [productFilter, setProductFilter] = useState<'all' | CatalogProductType>('all');
|
||||||
|
const [referenceSearch, setReferenceSearch] = useState('');
|
||||||
const [pagination, setPagination] = useState<RegistrationPagination>({
|
const [pagination, setPagination] = useState<RegistrationPagination>({
|
||||||
products: { page: 1, pageSize: 10 },
|
products: { page: 1, pageSize: 10 },
|
||||||
categories: { page: 1, pageSize: 10 },
|
categories: { page: 1, pageSize: 10 },
|
||||||
@@ -381,10 +382,20 @@ const Registrations = () => {
|
|||||||
const categoryStartIndex = (safeCategoryPage - 1) * pagination.categories.pageSize;
|
const categoryStartIndex = (safeCategoryPage - 1) * pagination.categories.pageSize;
|
||||||
const paginatedCategories = catalog.categories.slice(categoryStartIndex, categoryStartIndex + 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 safeReferencePage = Math.min(pagination.references.page, referenceTotalPages || 1);
|
||||||
const referenceStartIndex = (safeReferencePage - 1) * pagination.references.pageSize;
|
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) => {
|
const runAction = async (action: () => Promise<void>, successMessage: string) => {
|
||||||
setStatus('saving');
|
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>
|
<p className="mt-1 text-xs font-semibold text-dark-muted">Rendimento pç/kg por produto, malha, cor e tamanho.</p>
|
||||||
</div>
|
</div>
|
||||||
<span className="rounded-full border border-dark-border bg-dark-input px-3 py-1 text-xs font-bold text-dark-muted">
|
<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>
|
</span>
|
||||||
</div>
|
</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">
|
<div className="divide-y divide-dark-border">
|
||||||
{paginatedReferences.map(reference => (
|
{paginatedReferences.map(reference => (
|
||||||
<div key={reference.id} className="flex flex-col gap-3 p-4 md:flex-row md:items-start md:justify-between">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{!catalog.consumptionReferences.length && (
|
{!filteredReferences.length && (
|
||||||
<div className={emptyStateClassName}>
|
<div className={emptyStateClassName}>
|
||||||
Nenhuma referencia cadastrada.
|
{referenceSearch ? 'Nenhuma referência encontrada.' : 'Nenhuma referencia cadastrada.'}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<PaginationControls
|
<PaginationControls
|
||||||
totalItems={catalog.consumptionReferences.length}
|
totalItems={filteredReferences.length}
|
||||||
currentPage={safeReferencePage}
|
currentPage={safeReferencePage}
|
||||||
totalPages={referenceTotalPages}
|
totalPages={referenceTotalPages}
|
||||||
pageSize={pagination.references.pageSize}
|
pageSize={pagination.references.pageSize}
|
||||||
@@ -1069,9 +1094,10 @@ const Registrations = () => {
|
|||||||
itemLabel="referências"
|
itemLabel="referências"
|
||||||
pageSizeLabel="por página"
|
pageSizeLabel="por página"
|
||||||
startIndex={referenceStartIndex}
|
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 })}
|
onPageChange={(page) => updatePagination('references', { page })}
|
||||||
onPageSizeChange={(pageSize) => updatePagination('references', { page: 1, pageSize })}
|
onPageSizeChange={(pageSize) => updatePagination('references', { page: 1, pageSize })}
|
||||||
|
stacked
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user