Merge remote-tracking branch 'origin/main' into navbar

This commit is contained in:
zahravaziri
2025-06-05 14:25:22 +03:30
27 changed files with 484 additions and 80 deletions
@@ -0,0 +1,39 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { productCategories } from '../data';
export async function GET(
request: Request,
{ params }: { params: { id: string } },
) {
const cookieStore = await cookies();
const lang = cookieStore.get('lang')?.value || 'en';
const category = productCategories.find((cat) => cat.id === params.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;
return NextResponse.json({
data: {
id: category.id,
icon: category.icon,
typesCount: category.typesCount,
title: titleData,
priceTypeTitle: priceTypeTitleData,
bestForTitle: bestForTitleData,
},
});
}
+58
View File
@@ -0,0 +1,58 @@
export const productCategories = [
{
id: '1',
title: 'Ghazaghi',
fa_title: 'قزاقی',
icon: 'categoryGhazaghi',
typesCount: 22,
priceTypeTitle: 'Economy',
fa_priceTypeTitle: 'اقتصادی',
bestForTitle: 'Best For Interior Part',
fa_bestForTitle: 'Best For Interior Part',
},
{
id: '2',
title: 'Ghermez',
fa_title: 'قرمز',
icon: 'categoryGhermez',
typesCount: 12,
priceTypeTitle: 'Luxury',
fa_priceTypeTitle: 'لاکچری',
bestForTitle: 'Best For Exterior Part',
fa_bestForTitle: 'Best For Exterior Part',
},
{
id: '3',
title: 'oryZard',
fa_title: 'زرد',
icon: 'categoryZard',
typesCount: 11,
priceTypeTitle: 'Economy',
fa_priceTypeTitle: 'اقتصادی',
bestForTitle: 'Best For Facing',
fa_bestForTitle: 'Best For Facing',
},
{
id: '40',
title: 'Semirom',
fa_title: 'سمیرم',
icon: 'categorySemirom',
typesCount: 40,
priceTypeTitle: 'Economy',
fa_priceTypeTitle: 'اقتصادی',
bestForTitle: 'Best For Building',
fa_bestForTitle: 'Best For Building',
},
] as APIProductCategoryEntity[];
interface APIProductCategoryEntity {
id: string;
title: string;
fa_title?: string;
icon: string;
typesCount: number;
priceTypeTitle: string;
fa_priceTypeTitle?: string;
bestForTitle: string;
fa_bestForTitle?: string;
}
+44
View File
@@ -0,0 +1,44 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { productCategories } from './data';
export async function GET(request: Request) {
let data = productCategories;
const cookieStore = cookies();
const lang = (await cookieStore).get('lang')?.value || 'fa';
if (lang === 'fa') {
data = productCategories.map(
({
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 {
id,
icon,
typesCount,
title: titleData,
priceTypeTitle: priceTypeTitleData,
bestForTitle: bestForTitleData,
};
},
);
}
return NextResponse.json({ data: productCategories });
}
+42
View File
@@ -0,0 +1,42 @@
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 });
}
@@ -0,0 +1,36 @@
import images from '@/assets/images/images';
import InnerPageBanner from '@/components/layout/innerPages/banner';
import ProductCard from '@/components/pages/products/ProductCard';
import { getProductCategoryById } from '@/services/products';
export default async function ProductPage({
params,
}: {
params: { product_category_id: string };
}) {
const { product_category_id: productCategoryId } = params;
const productCategory = await getProductCategoryById(productCategoryId);
const product = {
title: 'Product title',
size: 'W 18 * L10',
imageSrc: images.product1.src,
};
const products = Array.from({ length: 10 }, () => product);
return (
<main className="">
<InnerPageBanner
title={productCategory.title}
imageSrc={images.homeProductBack.src}
/>
<div className="container mx-auto my-24">
<div className="grid grid-cols-4 gap-3">
{products.map((product, index) => (
<ProductCard {...product} key={index} />
))}
</div>
</div>
</main>
);
}
+35
View File
@@ -0,0 +1,35 @@
import images from '@/assets/images/images';
import InnerPageBanner from '@/components/layout/innerPages/banner';
import ProductsCategoryCard from '@/components/pages/productCategories/ProductCategoryCard';
import type { IProductCategoryCardProps } from '@/components/pages/productCategories/productCategoryCard.d';
import { t } from '@/locales/translates';
import { getProductCategories } from '@/services/products';
export default async function ProductsPage() {
const productCategories: IProductCategoryCardProps[] =
await getProductCategories();
return (
<main>
<InnerPageBanner
title={t('pages_projects_title') as string}
imageSrc={images.aboutBanner.src}
/>
<div className="container mx-auto my-24">
<div className="grid w-full grid-cols-4 gap-4">
{productCategories.map((category) => (
<ProductsCategoryCard key={category.id} {...category} />
))}
</div>
<div className="mt-20">
<h2 className="mb-4 text-2xl font-semibold text-gray-500">
{t('pages_products_content_title') as string}
</h2>
<p className="text-base font-light text-gray-400">
{t('pages_products_content_description') as string}
</p>
</div>
</div>
</main>
);
}
-55
View File
@@ -1,55 +0,0 @@
import images from '@/assets/images/images';
import InnerPageBanner from '@/components/layout/innerPages/banner';
import ProductsCategoryCard from '@/components/pages/products/ProductCategoryCard';
import type { IProductCategoryCardProps } from '@/components/pages/products/productCategoryCard.d';
import { t } from '@/locales/translates';
export default function ProductsPage() {
const productCategories = [
{
id: '1',
title: t('com_products_category_Ghazaghi_title') as string,
icon: 'categoryGhazaghi',
typesCount: 22,
priceTypeTitle: 'Economy',
bestForTitle: 'Best For Interior Part',
},
{
id: '2',
title: t('com_products_category_Ghermez_title') as string,
icon: 'categoryGhermez',
typesCount: 12,
priceTypeTitle: 'Luxury',
bestForTitle: 'Best For Exterior Part',
},
{
id: '3',
title: t('com_products_category_Zard_title') as string,
icon: 'categoryZard',
typesCount: 11,
priceTypeTitle: 'Economy',
bestForTitle: 'Best For Facing',
},
{
id: '40',
title: t('com_products_category_Semirom_title') as string,
icon: 'categorySemirom',
typesCount: 40,
priceTypeTitle: 'Economy',
bestForTitle: 'Best For Building',
},
] as IProductCategoryCardProps[];
return (
<main>
<InnerPageBanner
title={t('pages_projects_title') as string}
imageSrc={images.aboutBanner.src}
/>
<div className="container my-24 grid grid-cols-4 gap-4">
{productCategories.map((category) => (
<ProductsCategoryCard key={category.id} {...category} />
))}
</div>
</main>
);
}