all -product
This commit is contained in:
113
src/features/category/ui/AllProduct.tsx
Normal file
113
src/features/category/ui/AllProduct.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
'use client';
|
||||
|
||||
import { product_api } from '@/shared/config/api/product/api';
|
||||
import { usePathname, useRouter } from '@/shared/config/i18n/navigation';
|
||||
import { Card } from '@/shared/ui/card';
|
||||
import { GlobalPagination } from '@/shared/ui/global-pagination';
|
||||
import { Skeleton } from '@/shared/ui/skeleton';
|
||||
import { ProductCard } from '@/widgets/categories/ui/product-card';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const PAGE_SIZE = 36;
|
||||
|
||||
const AllProducts = () => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const [page, setPage] = useState(1);
|
||||
const t = useTranslations();
|
||||
|
||||
useEffect(() => {
|
||||
const urlPage = Number(searchParams.get('page')) || 1;
|
||||
setPage(urlPage);
|
||||
}, [searchParams]);
|
||||
|
||||
const {
|
||||
data: product,
|
||||
isLoading,
|
||||
isError,
|
||||
} = useQuery({
|
||||
queryKey: ['all_product_list', page],
|
||||
queryFn: () => {
|
||||
return product_api.list({
|
||||
page,
|
||||
page_size: PAGE_SIZE,
|
||||
});
|
||||
},
|
||||
select(data) {
|
||||
return data.data;
|
||||
},
|
||||
});
|
||||
|
||||
const handleBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
const handlePageChange = (newPage: number) => {
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
params.set('page', newPage.toString());
|
||||
|
||||
router.push(`${pathname}?${params.toString()}`, {
|
||||
scroll: true,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="custom-container p-4 mb-5 flex flex-col min-h-[calc(85vh)]">
|
||||
<div className="flex-1">
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<button
|
||||
onClick={handleBack}
|
||||
className="flex items-center gap-2 text-gray-600 hover:text-gray-900 mb-4"
|
||||
>
|
||||
<ArrowLeft className="w-5 h-5" />
|
||||
<span>{t('Orqaga')}</span>
|
||||
</button>
|
||||
|
||||
<p className="text-gray-600 text-sm mt-1">
|
||||
{product?.total} {t('ta mahsulot')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Products grid */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 xl:grid-cols-6 gap-3">
|
||||
{isLoading &&
|
||||
Array.from({ length: 6 }).map((_, index) => (
|
||||
<Card className="p-3 space-y-3 rounded-xl" key={index}>
|
||||
<Skeleton className="h-40 sm:h-48 md:h-56 w-full rounded-lg" />
|
||||
<Skeleton className="h-4 w-3/4" />
|
||||
<Skeleton className="h-4 w-1/2" />
|
||||
<Skeleton className="h-10 w-full rounded-lg" />
|
||||
</Card>
|
||||
))}
|
||||
{product &&
|
||||
!isLoading &&
|
||||
product.results
|
||||
.filter((product) => product.state === 'A')
|
||||
.map((item) => (
|
||||
<ProductCard key={item.id} product={item} error={isError} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pagination at the bottom */}
|
||||
{product && (
|
||||
<div className="w-full mt-5 flex justify-end">
|
||||
<GlobalPagination
|
||||
page={page}
|
||||
total={product.total ?? 0}
|
||||
pageSize={PAGE_SIZE}
|
||||
onChange={handlePageChange}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AllProducts;
|
||||
Reference in New Issue
Block a user