Paginate product variations
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m0s

This commit is contained in:
Cauê Faleiros
2026-08-03 11:19:01 -03:00
parent ef3bf4ce5c
commit 42cee3f505

View File

@@ -7,6 +7,7 @@ import DateRangePicker from '../components/DateRangePicker';
import SkuPlanningModal from '../components/SkuPlanningModal';
import ProductTypeBadge from '../components/ProductTypeBadge';
import RefreshStatus from '../components/RefreshStatus';
import PaginationControls from '../components/PaginationControls';
import type { CutProductOverride, CuttingSettings, DateRange, ProductComposition, ProductDetailsAnalytics } from '../types';
import { fetchCuttingSettings, fetchProductComposition, fetchProductDetailsAnalytics, saveCuttingSettings } from '../dataService';
import { parseProductName } from '../productParsing';
@@ -139,6 +140,8 @@ const ProductDetails = () => {
const [planningSettings, setPlanningSettings] = useState<CuttingSettings>({ familyYields: {}, productOverrides: {} });
const [isPlanningModalOpen, setIsPlanningModalOpen] = useState(false);
const [isSavingPlanning, setIsSavingPlanning] = useState(false);
const [variantCurrentPage, setVariantCurrentPage] = useState(1);
const [variantItemsPerPage, setVariantItemsPerPage] = useState(5);
useEffect(() => {
let isMounted = true;
@@ -179,6 +182,7 @@ const ProductDetails = () => {
if (isMounted) {
setDetails(productDetails);
setComposition(productComposition);
setVariantCurrentPage(1);
setIsLoading(false);
setIsCompositionLoading(false);
}
@@ -331,6 +335,10 @@ const ProductDetails = () => {
: formatDateBucketLongLabel(selectedProductPoint.date, dateBucket)
: '';
const maxVariantQuantity = Math.max(...variantBreakdown.map(variant => variant.quantitySold), 0);
const variantTotalPages = Math.ceil(variantBreakdown.length / variantItemsPerPage);
const safeVariantCurrentPage = Math.min(variantCurrentPage, variantTotalPages || 1);
const variantStartIndex = (safeVariantCurrentPage - 1) * variantItemsPerPage;
const paginatedVariantBreakdown = variantBreakdown.slice(variantStartIndex, variantStartIndex + variantItemsPerPage);
return (
<div className="space-y-6">
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
@@ -606,7 +614,7 @@ const ProductDetails = () => {
</div>
) : (
<div className="space-y-3">
{variantBreakdown.map(variant => {
{paginatedVariantBreakdown.map(variant => {
const width = maxVariantQuantity ? Math.max(4, (variant.quantitySold / maxVariantQuantity) * 100) : 0;
const metadata = parseProductName(variant.name);
@@ -614,7 +622,9 @@ const ProductDetails = () => {
<div key={variant.id} className="rounded-xl border border-dark-border bg-dark-input/45 p-4">
<div className="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
<div className="min-w-0">
<div className="truncate text-sm font-bold text-dark-text">{variant.name}</div>
<Link to={`/products/${variant.id}`} className="block truncate text-sm font-bold text-dark-text transition-colors hover:text-brand-primary hover:underline" title={`Ver produto ${variant.name}`}>
{variant.name}
</Link>
<div className="mt-1 flex flex-wrap items-center gap-2 text-[11px] font-medium text-dark-muted">
<span>#{variant.id}</span>
{metadata.color && (
@@ -655,6 +665,25 @@ const ProductDetails = () => {
})}
</div>
)}
{variantBreakdown.length > variantItemsPerPage && (
<PaginationControls
totalItems={variantBreakdown.length}
currentPage={safeVariantCurrentPage}
totalPages={variantTotalPages}
pageSize={variantItemsPerPage}
pageSizeOptions={[5, 10, 20]}
itemLabel="variações"
pageSizeLabel="por página"
startIndex={variantStartIndex}
endIndex={Math.min(variantStartIndex + variantItemsPerPage, variantBreakdown.length)}
onPageChange={setVariantCurrentPage}
onPageSizeChange={(pageSize) => {
setVariantItemsPerPage(pageSize);
setVariantCurrentPage(1);
}}
className="mt-5 border-t border-dark-border pt-4"
/>
)}
</div>
</div>