diff --git a/package-lock.json b/package-lock.json index 0adda67..2a58f62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "pasargad_bricks", "version": "0.1.0", "dependencies": { + "axios": "^1.9.0", "next": "15.3.3", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -1979,6 +1980,11 @@ "node": ">= 0.4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2003,6 +2009,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -2073,7 +2089,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -2197,6 +2212,17 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2337,6 +2363,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -2362,7 +2396,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -2463,7 +2496,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -2472,7 +2504,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -2508,7 +2539,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -2520,7 +2550,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -3141,6 +3170,25 @@ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -3156,11 +3204,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3198,7 +3259,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -3222,7 +3282,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -3304,7 +3363,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -3376,7 +3434,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -3388,7 +3445,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -3403,7 +3459,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -4255,7 +4310,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -4282,6 +4336,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4857,6 +4930,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index 5472f23..1a89825 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "axios": "^1.9.0", "next": "15.3.3", "react": "^19.0.0", "react-dom": "^19.0.0" diff --git a/public/globe.svg b/public/globe.svg index 567f17b..aaa7bc3 100644 --- a/public/globe.svg +++ b/public/globe.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/app/api/product_categories/[id]/route.ts b/src/app/api/product_categories/[id]/route.ts new file mode 100644 index 0000000..d613ef3 --- /dev/null +++ b/src/app/api/product_categories/[id]/route.ts @@ -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, + }, + }); +} diff --git a/src/app/api/product_categories/data.ts b/src/app/api/product_categories/data.ts new file mode 100644 index 0000000..48eca77 --- /dev/null +++ b/src/app/api/product_categories/data.ts @@ -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; +} diff --git a/src/app/api/product_categories/route.ts b/src/app/api/product_categories/route.ts new file mode 100644 index 0000000..812dd81 --- /dev/null +++ b/src/app/api/product_categories/route.ts @@ -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 }); +} diff --git a/src/app/api/product_category/route.ts b/src/app/api/product_category/route.ts new file mode 100644 index 0000000..1c6477a --- /dev/null +++ b/src/app/api/product_category/route.ts @@ -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 }); +} diff --git a/src/app/product-categories/[product_category_id]/page.tsx b/src/app/product-categories/[product_category_id]/page.tsx new file mode 100644 index 0000000..06446cd --- /dev/null +++ b/src/app/product-categories/[product_category_id]/page.tsx @@ -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 ( +
+ +
+
+ {products.map((product, index) => ( + + ))} +
+
+
+ ); +} diff --git a/src/app/product-categories/page.tsx b/src/app/product-categories/page.tsx new file mode 100644 index 0000000..f852052 --- /dev/null +++ b/src/app/product-categories/page.tsx @@ -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 ( +
+ +
+
+ {productCategories.map((category) => ( + + ))} +
+
+

+ {t('pages_products_content_title') as string} +

+

+ {t('pages_products_content_description') as string} +

+
+
+
+ ); +} diff --git a/src/app/products/page.tsx b/src/app/products/page.tsx deleted file mode 100644 index 0d48eba..0000000 --- a/src/app/products/page.tsx +++ /dev/null @@ -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 ( -
- -
- {productCategories.map((category) => ( - - ))} -
-
- ); -} diff --git a/src/assets/constants/footerMenu/quickLinks.const.ts b/src/assets/constants/footerMenu/quickLinks.const.ts index 897498f..f460885 100644 --- a/src/assets/constants/footerMenu/quickLinks.const.ts +++ b/src/assets/constants/footerMenu/quickLinks.const.ts @@ -6,8 +6,8 @@ export const quickLinks = [ link: routeFactory.home.route(), }, { - title: routeFactory.products.title, - link: routeFactory.products.route(), + title: routeFactory.productCategories.title, + link: routeFactory.productCategories.route(), }, { title: routeFactory.projects.title, diff --git a/src/assets/constants/routeFactory/index.ts b/src/assets/constants/routeFactory/index.ts index f4df29d..99b3409 100644 --- a/src/assets/constants/routeFactory/index.ts +++ b/src/assets/constants/routeFactory/index.ts @@ -5,9 +5,13 @@ export default { title: t('pages_home_title'), route: () => '/', }, + productCategories: { + title: t('pages_product_categories_title'), + route: () => '/product-categories', + }, products: { title: t('pages_products_title'), - route: () => '/products', + route: (productId: string) => `/product-categories/${productId}`, }, projects: { title: t('pages_projects_title'), diff --git a/src/assets/images/images.ts b/src/assets/images/images.ts index 14bc5a0..c6e4648 100644 --- a/src/assets/images/images.ts +++ b/src/assets/images/images.ts @@ -6,6 +6,7 @@ import aboutImg_1 from './about-img-1.png'; import aboutImg_2 from './about-img-2.png'; import homeProductBack from './home_product_back.jpeg'; import whatWeDoImage from './what-we-do-image.png'; +import product1 from './product1.png'; export default { homeBanner, @@ -16,4 +17,5 @@ export default { aboutImg_2, homeProductBack, whatWeDoImage, + product1, }; diff --git a/src/assets/images/product1.png b/src/assets/images/product1.png new file mode 100644 index 0000000..c8a55cb Binary files /dev/null and b/src/assets/images/product1.png differ diff --git a/src/components/layout/navbar/index.tsx b/src/components/layout/navbar/index.tsx index 6ccace0..ed4b497 100644 --- a/src/components/layout/navbar/index.tsx +++ b/src/components/layout/navbar/index.tsx @@ -17,7 +17,7 @@ // { href: '/about', label: t('pages_about_title') as string }, // { href: '/blog', label: t('pages_contact_title') as string }, // { href: '/contact', label: t('pages_contact_title') as string }, -// { href: '/product', label: t('pages_products_title') as string }, +// { href: '/product', label: t('pages_product_categories_title') as string }, // { href: '/project', label: t('pages_projects_title') as string }, // ]; @@ -104,7 +104,7 @@ export default function Navbar() { { href: '/about', label: t('pages_about_title') as string }, { href: '/blog', label: t('pages_contact_title') as string }, { href: '/contact', label: t('pages_contact_title') as string }, - { href: '/product', label: t('pages_products_title') as string }, + { href: '/product', label: t('pages_product_categories_title') as string }, { href: '/project', label: t('pages_projects_title') as string }, ]; const linkClass = (href: string) => diff --git a/src/components/pages/home/Products.tsx b/src/components/pages/home/Products.tsx index 5e1ff36..49e90ef 100644 --- a/src/components/pages/home/Products.tsx +++ b/src/components/pages/home/Products.tsx @@ -31,7 +31,7 @@ export default function HomePageProducts() {
diff --git a/src/components/pages/products/ProductCategoryCard.tsx b/src/components/pages/productCategories/ProductCategoryCard.tsx similarity index 81% rename from src/components/pages/products/ProductCategoryCard.tsx rename to src/components/pages/productCategories/ProductCategoryCard.tsx index 6b01d7e..67477f1 100644 --- a/src/components/pages/products/ProductCategoryCard.tsx +++ b/src/components/pages/productCategories/ProductCategoryCard.tsx @@ -14,7 +14,7 @@ export default function ProductsCategoryCard({ id, }: IProductCategoryCardProps) { return ( -
+
@@ -31,8 +31,14 @@ export default function ProductsCategoryCard({
-
- +
+
); diff --git a/src/components/pages/productCategories/ProductCategoryCardIcon.tsx b/src/components/pages/productCategories/ProductCategoryCardIcon.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/pages/productCategories/ProductCategoryCardInProducts.tsx b/src/components/pages/productCategories/ProductCategoryCardInProducts.tsx new file mode 100644 index 0000000..eaf3eac --- /dev/null +++ b/src/components/pages/productCategories/ProductCategoryCardInProducts.tsx @@ -0,0 +1,9 @@ +import type { IProductCategoryCardProps } from './productCategoryCard.d'; + +export default function ProductCategoryCardInProducts( + productCategory: IProductCategoryCardProps, +) { + return ( +
+ ); +} diff --git a/src/components/pages/products/productCategoryCard.d.ts b/src/components/pages/productCategories/productCategoryCard.d.ts similarity index 100% rename from src/components/pages/products/productCategoryCard.d.ts rename to src/components/pages/productCategories/productCategoryCard.d.ts diff --git a/src/components/pages/productCategories/productCategoryCardIcon.d.ts b/src/components/pages/productCategories/productCategoryCardIcon.d.ts new file mode 100644 index 0000000..96f745b --- /dev/null +++ b/src/components/pages/productCategories/productCategoryCardIcon.d.ts @@ -0,0 +1,5 @@ +export interface IProductCategoryCardIconProps { + type: IProductCategory; +} + +export type IProductCategory = 'ghazaghi' | 'ghermez' | 'zard' | 'semirom'; diff --git a/src/components/pages/products/ProductCard.tsx b/src/components/pages/products/ProductCard.tsx new file mode 100644 index 0000000..6f68b0f --- /dev/null +++ b/src/components/pages/products/ProductCard.tsx @@ -0,0 +1,21 @@ +import type { IProductCardProps } from './productCard.d'; + +export default function ProductCard({ + title, + imageSrc, + size, +}: IProductCardProps) { + return ( +
+
+ {title} +
+

{title}

+ {size} +
+ ); +} diff --git a/src/components/pages/products/productCard.d.ts b/src/components/pages/products/productCard.d.ts new file mode 100644 index 0000000..99f10f1 --- /dev/null +++ b/src/components/pages/products/productCard.d.ts @@ -0,0 +1,5 @@ +export interface IProductCardProps { + imageSrc: string; + title: string; + size: string; +} diff --git a/src/components/uikit/icons/instagramIcon.tsx b/src/components/uikit/icons/instagramIcon.tsx index 13f63a0..15c952c 100644 --- a/src/components/uikit/icons/instagramIcon.tsx +++ b/src/components/uikit/icons/instagramIcon.tsx @@ -7,7 +7,7 @@ export const InstagramIcon = (props: React.SVGProps) => ( fill="none" xmlns="http://www.w3.org/2000/svg" > - + ) => ( fill="none" xmlns="http://www.w3.org/2000/svg" > - + { + // Example: Add lang cookie from browser (client-side only) + if (typeof window !== 'undefined') { + const match = document.cookie.match(/(^| )lang=([^;]+)/); + if (match) { + config.headers['lang'] = decodeURIComponent(match[2]); + } + } + return config; + }, + (error) => Promise.reject(error), +); + +api.interceptors.response.use( + (response) => response, + (error) => { + return Promise.reject(error); + }, +); + +export default api; diff --git a/src/locales/en.ts b/src/locales/en.ts index ec3f2c2..92c55d1 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -4,6 +4,7 @@ const en = { pages_about_title: 'About Us', pages_about_description: 'Learn more about us on this page', pages_contact_title: 'Contact Us', + pages_product_categories_title: 'Products', pages_products_title: 'Products', pages_blog_title: 'Blog', pages_projects_title: 'Projects', @@ -59,6 +60,18 @@ const en = { com_products_category_Zard_title: 'Zard', com_products_category_types_count: ({ count }: { count: number }) => `${count} Types`, + com_products_category_show_all_CTA: 'Show Products', + pages_products_content_title: + 'Brick Classification: Understanding the Variety and Applications', + pages_products_content_description: `Bricks, as one of humanity's oldest and most widely used building materials, have evolved significantly throughout history. Today, they are produced and supplied in an incredibly diverse range, allowing engineers and architects to choose the most suitable brick for any project and need, from traditional and historic structures to modern and advanced buildings. To better understand this diversity, we can classify bricks based on several key criteria, each with its own specific characteristics and applications. +\n 1. Classification by Manufacturing Method: From Tradition to Advanced Industry +The method by which bricks are produced directly impacts their appearance, texture, and properties. +Hand-moulded/Stock Bricks: These bricks are produced by manually pressing clay into molds. The result is a brick with a relatively rough texture, uneven edges, and a more traditional appearance, where each piece feels unique. This type of brick is often used for restoration projects or for constructing buildings with a rustic or antique style. +Machine-made Bricks: These bricks are produced using industrial machinery, resulting in much higher precision in dimensions and uniformity in appearance. Machine-made bricks themselves are divided into two main categories: +Perforated/Hollow Bricks: These bricks have holes, offering several advantages: they reduce building weight, improve thermal and acoustic insulation, and enhance mortar adhesion. +Solid Bricks: These bricks are without holes and possess very high compressive strength. They are ideal for load-bearing structures and walls requiring maximum strength. +2. Classification by Raw Material Type and Composition: From Clay to Concrete +The material from which a brick is made determines its physical and chemical properties.`, }; export default en; diff --git a/src/locales/fa.ts b/src/locales/fa.ts index d3b336e..8f3ac9b 100644 --- a/src/locales/fa.ts +++ b/src/locales/fa.ts @@ -6,7 +6,7 @@ const fa = { pages_about_title: 'About Us', pages_about_description: 'Learn more about us on this page', pages_contact_title: 'Contact Us', - pages_products_title: 'Product', + pages_product_categories_title: 'Product', pages_blog_title: 'Blog', pages_projects_title: 'Project', pages_contact_description: 'Get in touch with us through this page', diff --git a/src/services/products.ts b/src/services/products.ts new file mode 100644 index 0000000..0194442 --- /dev/null +++ b/src/services/products.ts @@ -0,0 +1,19 @@ +import api from '@/lib/axios'; + +export function getProductCategories() { + return api + .get('/product_categories') + .then(({ data }) => { + return Promise.resolve(data.data); + }) + .catch((error) => Promise.reject(error)); +} + +export function getProductCategoryById(categoryId: string) { + return api + .get(`/product_categories/${categoryId}`) + .then(({ data }) => { + return Promise.resolve(data.data); + }) + .catch((error) => Promise.reject(error)); +}