diff --git a/package-lock.json b/package-lock.json
index 9f5c222..6bf54bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,6 +26,7 @@
"react": "19.1.0",
"react-dom": "19.1.0",
"react-hook-form": "^7.62.0",
+ "react-infinite-scroll-component": "^6.1.0",
"react-otp-input": "^3.1.1",
"react-spinners": "^0.17.0",
"swiper": "^11.2.10",
@@ -5809,6 +5810,18 @@
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
+ "node_modules/react-infinite-scroll-component": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
+ "integrity": "sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==",
+ "license": "MIT",
+ "dependencies": {
+ "throttle-debounce": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -6509,6 +6522,15 @@
"node": ">=18"
}
},
+ "node_modules/throttle-debounce": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
+ "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/tiny-case": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
diff --git a/package.json b/package.json
index 5583af7..74d3a06 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"react": "19.1.0",
"react-dom": "19.1.0",
"react-hook-form": "^7.62.0",
+ "react-infinite-scroll-component": "^6.1.0",
"react-otp-input": "^3.1.1",
"react-spinners": "^0.17.0",
"swiper": "^11.2.10",
diff --git a/src/app/products/[id]/page.tsx b/src/app/products/[id]/page.tsx
index ca54c9c..fd226ad 100644
--- a/src/app/products/[id]/page.tsx
+++ b/src/app/products/[id]/page.tsx
@@ -12,12 +12,12 @@ import {
} from '@/components/ui/breadcrumb'
import Filters from '../components/Filters'
import Sorts from '../components/Sorts'
-import Pagination from '../components/Pagination'
import GridWrapper from '@/components/GridWrapper'
import ProductCard from '@/components/ProductCard'
import { Setting5 } from 'iconsax-react'
-import { useState, useEffect } from 'react'
-import { useCategoryProductsData } from '../hooks/useProductsData'
+import { useState, useEffect, useMemo } from 'react'
+import InfiniteScroll from 'react-infinite-scroll-component'
+import { useInfiniteCategoryProductsData } from '../hooks/useInfiniteProductsData'
import { IProduct } from '@/types/landing.types'
import { Product } from '@/types/products.types'
import { useSearchParams, useParams } from 'next/navigation'
@@ -55,8 +55,20 @@ const Products: NextPage = () => {
setFilterParams(params)
}, [searchParams])
- // دریافت دادههای محصولات از API بر اساس categoryUrl
- const { data, isLoading, error } = useCategoryProductsData(categoryUrl, filterParams)
+ // دریافت دادههای محصولات از API بر اساس categoryUrl با infinite scroll
+ const {
+ data,
+ isLoading,
+ error,
+ fetchNextPage,
+ hasNextPage
+ } = useInfiniteCategoryProductsData(categoryUrl, filterParams)
+
+ // جمعآوری تمام محصولات از صفحات مختلف
+ const allProducts = useMemo(() => {
+ if (!data?.pages) return [];
+ return data.pages.flatMap(page => page.results.products);
+ }, [data?.pages]);
// تبدیل Product به IProduct
const convertToIProduct = (product: Product): IProduct => {
@@ -91,6 +103,7 @@ const Products: NextPage = () => {
status: defaultVariant?.market_status || 'active',
imagesUrl: product.imagesUrl,
url: product.url,
+ isWishlist: false,
default_variant: {
_id: defaultVariant?._id || product._id.toString(),
market_status: defaultVariant?.market_status || 'active',
@@ -117,11 +130,11 @@ const Products: NextPage = () => {