feat: add product generation and pagination components

- Implemented product generation for categories with a helper function to create 50 products per category.
- Added image assets for English and Persian language support.
- Created a reusable Pagination component for navigating through product lists.
- Developed ProductList component to display products with pagination support.
- Defined TypeScript interfaces for product list props and API response structure.
This commit is contained in:
2025-06-08 15:52:05 +03:30
parent 929960b26f
commit 7073310a22
31 changed files with 424 additions and 205 deletions
@@ -0,0 +1,25 @@
import { productCategories } from '../../data';
import type { IProductCardProps } from '@/components/pages/products/productCard.d';
// Helper to generate 50 products for a category
export function generateProductsForCategory(
categoryId: string,
categoryTitle: string,
): IProductCardProps[] {
return Array.from({ length: 50 }, (_, i) => ({
id: `${categoryId}-${i + 1}`,
title: `${categoryTitle} Product ${i + 1}`,
size: `W ${10 + i} * L${20 + i}`,
imageSrc: `/images/product${(i % 4) + 1}.png`, // Example image path
// Add other fields from IProductCardProps if needed
}));
}
// Map of categoryId to products
export const productsByCategory: Record<string, IProductCardProps[]> =
Object.fromEntries(
productCategories.map((cat) => [
cat.id,
generateProductsForCategory(cat.id, cat.title),
]),
);
@@ -1,29 +1,36 @@
import { NextResponse, NextRequest } from 'next/server';
// import type { NextApiRequestContext } from 'next';
import { cookies } from 'next/headers';
import { productCategories } from '../../data';
import images from '@/assets/images/images';
import { generateProductsForCategory } from './data';
export async function GET(request: NextRequest, context: any) {
const cookieStore = await cookies();
const lang = cookieStore.get('lang')?.value || 'en';
const lang = cookieStore.get('locale')?.value || 'en';
const category = productCategories.find(
(cat) => cat.id === context.params.id,
);
const params = context.params;
const category = productCategories.find((cat) => cat.id === params.id);
if (!category) {
return NextResponse.json({ error: 'Not found' }, { status: 404 });
}
const product = {
title: 'Product title',
size: 'W 18 * L10',
imageSrc: '/product1.png',
};
const products = Array.from({ length: 10 }, () => product);
// Pagination logic
const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get('page') || '1', 10);
const perPage = 20;
const allProducts = generateProductsForCategory(category.id, category.title);
const start = (page - 1) * perPage;
const end = start + perPage;
const paginatedProducts = allProducts.slice(start, end);
return NextResponse.json({
data: products,
data: paginatedProducts,
pagination: {
page,
perPage,
total: allProducts.length,
totalPages: Math.ceil(allProducts.length / perPage),
},
});
}
+22 -30
View File
@@ -1,45 +1,37 @@
import { NextResponse, NextRequest } from 'next/server';
// import type { NextApiRequestContext } from 'next';
'use server';
import { NextResponse, NextRequest } from 'next/server';
import { cookies } from 'next/headers';
import { productCategories } from '../data';
export async function GET(request: NextRequest, context: any) {
export async function GET(
request: NextRequest,
context: { params: { id: string } },
) {
const cookieStore = await cookies();
const lang = cookieStore.get('lang')?.value || 'en';
const lang = cookieStore.get('locale')?.value || 'en';
const category = productCategories.find(
(cat) => cat.id === context.params.id,
);
const params = await context.params;
const { id } = params;
let category = productCategories.find((cat) => cat.id === id);
if (!category) {
return NextResponse.json({ error: 'Not found' }, { status: 404 });
}
const titleData =
lang === 'fa' && category.fa_title ? category.fa_title : category.title;
const priceTypeTitleData =
lang === 'fa' && category.fa_priceTypeTitle
? category.fa_priceTypeTitle
: category.priceTypeTitle;
const bestForTitleData =
lang === 'fa' && category.fa_bestForTitle
? category.fa_bestForTitle
: category.bestForTitle;
const descriptionData =
lang === 'fa' && category.fa_description
? category.fa_description
: category.description;
if (lang === 'fa') {
category = {
...category,
title: category.fa_title || category.title,
priceTypeTitle: category.fa_priceTypeTitle || category.priceTypeTitle,
bestForTitle: category.fa_bestForTitle || category.bestForTitle,
description: category.fa_description || category.description,
};
}
return NextResponse.json({
data: {
id: category.id,
icon: category.icon,
typesCount: category.typesCount,
title: titleData,
priceTypeTitle: priceTypeTitleData,
bestForTitle: bestForTitleData,
description: descriptionData,
},
data: category,
});
}
+15 -13
View File
@@ -23,23 +23,25 @@ export async function GET(request: Request) {
description,
fa_description,
}) => {
const titleData = lang === 'fa' && fa_title ? fa_title : title;
const priceTypeTitleData =
lang === 'fa' && fa_priceTypeTitle
? fa_priceTypeTitle
: priceTypeTitle;
const bestForTitleData =
lang === 'fa' && fa_bestForTitle ? fa_bestForTitle : bestForTitle;
const descriptionData =
lang === 'fa' && fa_description ? fa_description : description;
if (lang === 'fa') {
return {
id,
icon,
typesCount,
title: fa_title || title,
priceTypeTitle: fa_priceTypeTitle || priceTypeTitle,
bestForTitle: fa_bestForTitle || bestForTitle,
description: fa_description || description,
};
}
return {
id,
icon,
typesCount,
title: titleData,
priceTypeTitle: priceTypeTitleData,
bestForTitle: bestForTitleData,
description: descriptionData,
title,
priceTypeTitle,
bestForTitle,
description,
};
},
);
-42
View File
@@ -1,42 +0,0 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { productCategories } from '../product_categories/data';
export async function GET(request: Request) {
const data = productCategories.find(
(productCategory) => productCategory.id === request.url.split('/').pop(),
);
const cookieStore = cookies();
const lang = (await cookieStore).get('lang')?.value || 'fa';
// if (lang === 'fa') {
// data = productCategories.find(
// ({
// id,
// title,
// fa_title,
// icon,
// typesCount,
// priceTypeTitle,
// fa_priceTypeTitle,
// bestForTitle,
// fa_bestForTitle,
// }) => {
// const titleData = lang === 'fa' && fa_title ? fa_title : title;
// const priceTypeTitleData =
// lang === 'fa' && fa_priceTypeTitle
// ? fa_priceTypeTitle
// : priceTypeTitle;
// const bestForTitleData =
// lang === 'fa' && fa_bestForTitle ? fa_bestForTitle : bestForTitle;
// return {data}
// }
return NextResponse.json({ data });
}
export async function POST(request: Request) {
const data = await request.json();
return NextResponse.json({ message: 'Received POST request', data });
}