From 38df8ec335ec749267dc13f80bbcb7faf32666ae Mon Sep 17 00:00:00 2001 From: ahasani194 Date: Wed, 18 Jun 2025 20:02:27 +0330 Subject: [PATCH] clean project sections and page and set pagination to projects --- messages/en.d.json.ts | 5 +- messages/en.json | 5 +- messages/fa.json | 5 +- src/app/[locale]/projects/page.tsx | 22 +++++--- src/app/api/projects/data.ts | 40 +++++++------- src/app/api/projects/route.ts | 53 ++++++++++--------- src/components/layout/header/index.tsx | 2 +- src/components/layout/pagination/index.tsx | 4 +- src/components/pages/about/TopInfo.tsx | 3 +- src/components/pages/home/Projects.tsx | 35 +++++++++--- src/components/pages/project/ProjectGrid.tsx | 34 +++++++++--- src/components/pages/project/project.d.ts | 5 ++ .../pages/project/projectGridView.tsx | 39 +++++++++++--- src/services/projects.ts | 8 ++- 14 files changed, 179 insertions(+), 81 deletions(-) diff --git a/messages/en.d.json.ts b/messages/en.d.json.ts index 03bd71c..f3cad8e 100644 --- a/messages/en.d.json.ts +++ b/messages/en.d.json.ts @@ -42,6 +42,8 @@ declare const messages: { "com_home_projects_title": "Our successful project", "com_home_projects_title_bold": "initiatives", "com_home_projects_description": "Our successful project initiatives showcase our commitment to excellence and innovation across various industries.", + "com_home_projects_show_more": "More Projects", + "com_home_projects_details_CTA": "Show Details", "footer_title": "Industrial Solutions for a Modern World", "footer_description": "We are committed to providing personalized industrial solutions that meet the unique needs of our clients. Our team of experts is dedicated to delivering high-quality products and services that drive success in today’s competitive market.", @@ -57,7 +59,7 @@ declare const messages: { "com_home_story_slogan_bold": "industrial innovation", "com_home_story_description": "We are a leading provider of industrial solutions, dedicated to delivering high-quality products and services that meet the unique needs of our clients. Our team of experts is committed to driving success in today’s competitive market through innovation and excellence.", "com_home_story_projects_count": "Completed Projects", - "com_home_story_customer_count": "Happy Customers", + "com_home_story_customer_count": "Satisfied Customer", "com_home_story_experience": "Years of Experience", "com_products_category_Ghazaghi_title": "Ghazaghi", @@ -117,6 +119,7 @@ declare const messages: { "page_projects_metadata_title": "Projects", "page_projects_metadata_description": "Discover successful projects completed using our high-quality bricks and expert craftsmanship.", + "page_projects_description": "Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship.", "page_product_categories_metadata_title": "Product Categories", "page_product_categories_metadata_description": "Browse through our product categories including Ghazaghi, yellow bricks, facing bricks, and more to find the right solution for your project.", diff --git a/messages/en.json b/messages/en.json index 5e29f07..173cf1a 100644 --- a/messages/en.json +++ b/messages/en.json @@ -39,6 +39,8 @@ "com_home_projects_title": "Our successful project", "com_home_projects_title_bold": "initiatives", "com_home_projects_description": "Our successful project initiatives showcase our commitment to excellence and innovation across various industries.", + "com_home_projects_show_more": "More Projects", + "com_home_projects_details_CTA": "Show Details", "footer_title": "Industrial Solutions for a Modern World", "footer_description": "We are committed to providing personalized industrial solutions that meet the unique needs of our clients. Our team of experts is dedicated to delivering high-quality products and services that drive success in today’s competitive market.", @@ -54,7 +56,7 @@ "com_home_story_slogan_bold": "industrial innovation", "com_home_story_description": "We are a leading provider of industrial solutions, dedicated to delivering high-quality products and services that meet the unique needs of our clients. Our team of experts is committed to driving success in today’s competitive market through innovation and excellence.", "com_home_story_projects_count": "Completed Projects", - "com_home_story_customer_count": "Happy Customers", + "com_home_story_customer_count": "Satisfied Customer", "com_home_story_experience": "Years of Experience", "com_products_category_Ghazaghi_title": "Ghazaghi", @@ -114,6 +116,7 @@ "page_projects_metadata_title": "Projects", "page_projects_metadata_description": "Discover successful projects completed using our high-quality bricks and expert craftsmanship.", + "page_projects_description": "Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship. Discover successful projects completed using our high-quality bricks and expert craftsmanship.", "page_product_categories_metadata_title": "Product Categories", "page_product_categories_metadata_description": "Browse through our product categories including Ghazaghi, yellow bricks, facing bricks, and more to find the right solution for your project.", diff --git a/messages/fa.json b/messages/fa.json index f44a34b..78e6ee6 100644 --- a/messages/fa.json +++ b/messages/fa.json @@ -39,6 +39,8 @@ "com_home_projects_title": "پروژه‌های موفق ما", "com_home_projects_title_bold": "ابتکارات", "com_home_projects_description": "ابتکارات پروژه‌های موفق ما نشان‌دهنده تعهد ما به برتری و نوآوری در صنایع مختلف است.", + "com_home_projects_show_more": "پروژه‌های بیشتر", + "com_home_projects_details_CTA": "مشاهده‌ی جزییات", "footer_title": "راهکارهای صنعتی برای دنیای مدرن", "footer_description": "ما متعهد به ارائه راهکارهای صنعتی شخصی‌سازی شده هستیم که نیازهای منحصر به فرد مشتریانمان را برآورده می‌کند. تیم متخصص ما به ارائه محصولات و خدمات با کیفیت بالا که موفقیت را در بازار رقابتی امروز تضمین می‌کند، متعهد است.", @@ -90,7 +92,7 @@ "com_contact_phone_error": "شماره تماس معتبر نیست (مثلاً: 09123456789)", "com_contact_textarea_error": "پیام باید حداقل ۱۰ کاراکتر باشد", "com_contact_button_submit": "ارسال پیام", - "pages_notFound_title": "صفحه ۴۰۴ پیدا نشد", + "pages_notFound_title": "صفحه مورد نظر پیدا نشد.", "pages_notFound_description": "صفحه‌ای که به دنبال آن هستید وجود ندارد یا منتقل شده است. لطفاً آدرس را بررسی کنید یا به صفحه اصلی بازگردید.", "pages_notFound_button": "بازگشت به صفحه اصلی", @@ -111,6 +113,7 @@ "page_projects_metadata_title": "پروژه‌ها", "page_projects_metadata_description": "نگاهی به پروژه‌های موفق ما که با استفاده از آجرهای با کیفیت اجرا شده‌اند.", + "page_projects_description": "Discover successful projects completed using our high-quality bricks and expert craftsmanship.", "page_product_categories_metadata_title": "دسته‌بندی محصولات", "page_product_categories_metadata_description": "دسته‌بندی کامل آجرها شامل آجر قزاقی، آجر زرد، آجر نما و موارد دیگر را در این بخش بررسی کنید.", diff --git a/src/app/[locale]/projects/page.tsx b/src/app/[locale]/projects/page.tsx index c64ec9f..2e32f7f 100644 --- a/src/app/[locale]/projects/page.tsx +++ b/src/app/[locale]/projects/page.tsx @@ -1,18 +1,18 @@ import { IProjectCardProps } from '@/app/api/projects/data'; +import routeFactory from '@/assets/constants/routeFactory'; import images from '@/assets/images/images'; import InnerPageBanner from '@/components/layout/innerPages/banner'; -import ProjectsGrid from '@/components/pages/project/ProjectGrid'; +import SectionTitle from '@/components/layout/sectionTitle'; import ProjectsGridView from '@/components/pages/project/projectGridView'; +import Button from '@/components/uikit/button'; import { IPageParams } from '@/models/layout'; import { getProjects } from '@/services/projects'; import { getTranslations, setRequestLocale } from 'next-intl/server'; -import Head from 'next/head'; export async function generateMetadata({ params }: { params: IPageParams }) { const { locale } = await params; setRequestLocale(locale); const t = await getTranslations({ locale }); - return { title: t('page_projects_metadata_title'), description: t('page_projects_metadata_description'), @@ -25,15 +25,25 @@ export default async function ProjectsPage({ }) { const { locale } = await params; const t = await getTranslations({ locale }); - const projects: IProjectCardProps[] = await getProjects(); + const projects = await getProjects(); + return (
-
- +
+

+ {t('page_projects_description')} +

+
); diff --git a/src/app/api/projects/data.ts b/src/app/api/projects/data.ts index 9c4a929..a0a86cd 100644 --- a/src/app/api/projects/data.ts +++ b/src/app/api/projects/data.ts @@ -1,7 +1,7 @@ import images from '@/assets/images/images'; export interface IProjectCardProps { - id:string; + id: string; title: string; fa_title?: string; imageSrc: string; @@ -9,46 +9,48 @@ export interface IProjectCardProps { export const projects = [ { - id:'1', + id: '1', title: 'Sustainable Practices Reducing Waste in Industrial Production', fa_title: 'روش‌های پایدار برای کاهش ضایعات در تولید صنعتی', imageSrc: `/images/project1.jpeg`, }, { - id:'2', + id: '2', title: 'Advanced Robotics Revolutionizing Industrial Workflows', fa_title: 'رباتیک پیشرفته و تحول فرآیندهای صنعتی', - imageSrc: `/images/project2.jpeg`, + imageSrc: `/images/project2.jpeg`, }, { - id:'3', + id: '3', title: 'Top Benefits of the Robotics in Manufacturing', fa_title: 'مزایای اصلی استفاده از رباتیک در تولید', - imageSrc: `/images/project3.jpeg`, + imageSrc: `/images/project3.jpeg`, }, { - id:'4', + id: '4', title: 'Leveraging Data Analytics for Smarter Production', fa_title: 'استفاده از تحلیل داده برای تولید هوشمندتر', - imageSrc: `/images/project4.jpeg`, - + imageSrc: `/images/project4.jpeg`, }, { - id:'5', + id: '5', title: 'Reducing Operational Costs Through Automation', fa_title: 'کاهش هزینه‌ها با اتوماسیون', - imageSrc: `/images/project1.jpeg`, + imageSrc: `/images/project1.jpeg`, }, { - id:'6', + id: '6', title: 'The Advantages of Customized Manufacturing Solutions', fa_title: 'مزایای راه‌حل‌های سفارشی‌سازی در تولید', - imageSrc: `/images/project1.jpeg`, + imageSrc: `/images/project1.jpeg`, }, -] as IProjectCardProps[] +] as IProjectCardProps[]; -export function generateProjects( -): IProjectCardProps[] { - return [...projects, ...projects, ...projects].map((e, i)=>({...e, id:String(i+1)})) - -} \ No newline at end of file +export function generateProjects(): IProjectCardProps[] { + return [...projects, ...projects, ...projects, ...projects, ...projects].map( + (e, i) => ({ + ...e, + id: String(i + 1), + }), + ); +} diff --git a/src/app/api/projects/route.ts b/src/app/api/projects/route.ts index c0acab7..23a4471 100644 --- a/src/app/api/projects/route.ts +++ b/src/app/api/projects/route.ts @@ -1,39 +1,42 @@ import { NextResponse } from 'next/server'; import { cookies } from 'next/headers'; -import { generateProjects } from './data'; - +import { generateProjects } from './data'; export async function GET(request: Request) { let projects = generateProjects(); - let data = projects + let data = projects; const cookieStore = await cookies(); - const lang = (await cookieStore).get('lang')?.value || 'fa'; + const lang = (await cookieStore).get('lang')?.value || 'fa'; + + // Pagination logic + const { searchParams } = new URL(request.url); + const page = parseInt(searchParams.get('page') || '1', 10); + const perPage = 20; + + const start = (page - 1) * perPage; + const end = start + perPage; + const paginatedProjects = projects.slice(start, end); if (lang === 'fa') { - data = projects.map( - ({ - id, - title, - fa_title, - imageSrc, - }) => { - if (lang === 'fa') { - return { - id, - title: fa_title || title, - imageSrc, - }; - } + data = paginatedProjects.map((project) => { + if (lang === 'fa') { return { - id, - title, - imageSrc, - + ...project, + title: project.fa_title || project.title, }; - }, - ); + } + return project; + }); } - return NextResponse.json({ data: projects }); + return NextResponse.json({ + data: projects, + pagination: { + page, + perPage, + total: projects.length, + totalPages: Math.ceil(projects.length / perPage), + }, + }); } diff --git a/src/components/layout/header/index.tsx b/src/components/layout/header/index.tsx index e6a74c8..79c59df 100644 --- a/src/components/layout/header/index.tsx +++ b/src/components/layout/header/index.tsx @@ -22,7 +22,7 @@ export default function Header() { return (
diff --git a/src/components/layout/pagination/index.tsx b/src/components/layout/pagination/index.tsx index 47518db..e0f05ee 100644 --- a/src/components/layout/pagination/index.tsx +++ b/src/components/layout/pagination/index.tsx @@ -23,7 +23,7 @@ export default function Pagination({ pages.push(i); } - return ( + return pages.length ? ( + ) : ( + <> ); } diff --git a/src/components/pages/about/TopInfo.tsx b/src/components/pages/about/TopInfo.tsx index a6657ae..74baa6f 100644 --- a/src/components/pages/about/TopInfo.tsx +++ b/src/components/pages/about/TopInfo.tsx @@ -29,7 +29,6 @@ export default function AboutTopInfo() {
- {' '}
))}
-
+
diff --git a/src/components/pages/home/Projects.tsx b/src/components/pages/home/Projects.tsx index 266bc4f..bb6e56b 100644 --- a/src/components/pages/home/Projects.tsx +++ b/src/components/pages/home/Projects.tsx @@ -4,30 +4,51 @@ import { TLocales } from '@/models/layout'; import { getProjects } from '@/services/projects'; import { IProjectCardProps } from '../project/project'; import ProjectsGrid from '../project/ProjectGrid'; +import Button from '@/components/uikit/button'; +import routeFactory from '@/assets/constants/routeFactory'; interface Props { locale: TLocales; } export default async function HomePageProjects({ locale }: Props) { const t = await getTranslations({ locale }); - const projects: IProjectCardProps[] = await getProjects(); + const projects = await getProjects(); + console.log(projects); + + const routes = routeFactory(t, locale); return (
-
+
-

- {t('com_home_projects_description')} -

+
+

+ {t('com_home_projects_description')} +

+ +
- + +
); diff --git a/src/components/pages/project/ProjectGrid.tsx b/src/components/pages/project/ProjectGrid.tsx index 936d8a8..407edb5 100644 --- a/src/components/pages/project/ProjectGrid.tsx +++ b/src/components/pages/project/ProjectGrid.tsx @@ -1,17 +1,26 @@ +'use client'; + import Image from 'next/image'; import Link from 'next/link'; import { IProjectCardProps } from './project'; -import { getProjects } from '@/services/projects'; +import Button from '@/components/uikit/button'; +import { useTranslations } from 'next-intl'; -export default async function ProjectsGrid({ +export default function ProjectsGrid({ projects, + className = '', }: { projects: IProjectCardProps[]; + className?: string; }) { + const t = useTranslations(); + return ( -
+
{projects.map((project, index) => ( - +
+
+ +
-
-

{project.title}

-
- + +

{project.title}

+ +
))}
); diff --git a/src/components/pages/project/project.d.ts b/src/components/pages/project/project.d.ts index 45ccdb5..a5533c2 100644 --- a/src/components/pages/project/project.d.ts +++ b/src/components/pages/project/project.d.ts @@ -3,3 +3,8 @@ export interface IProjectCardProps { title: string; link: string; } + +export interface IProjectGridViewProps { + initialProjects: IProjectCardProps[]; + initialPagination: IPagination; +} diff --git a/src/components/pages/project/projectGridView.tsx b/src/components/pages/project/projectGridView.tsx index e896c22..b97b654 100644 --- a/src/components/pages/project/projectGridView.tsx +++ b/src/components/pages/project/projectGridView.tsx @@ -1,14 +1,39 @@ -import { getProjects } from '@/services/projects'; -import { IProjectCardProps } from './project'; -import ProjectsGrid from './ProjectGrid'; +'use client'; -export default async function ProjectsGridView() { - const projects: IProjectCardProps[] = await getProjects(); +import { getProjects } from '@/services/projects'; +import { IProjectGridViewProps } from './project'; +import ProjectsGrid from './ProjectGrid'; +import Pagination from '@/components/layout/pagination'; +import { useState } from 'react'; + +export default function ProjectsGridView({ + initialProjects, + initialPagination, +}: IProjectGridViewProps) { + const [projects, setProjects] = useState(initialProjects); + const [pagination, setPagination] = useState(initialPagination); + + const fetchPage = (page: number) => { + console.log(page); + + getProjects(page) + .then((res) => { + setProjects(res.data); + setPagination(res.pagination); + + document + .getElementById('projectList') + ?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + }) + .catch((error) => { + console.error('Failed to fetch Projects:', error); + }); + }; return ( <> - - {/* */} + {projects?.length ? : <>} + ); } diff --git a/src/services/projects.ts b/src/services/projects.ts index 3c33c7a..0e9f5f7 100644 --- a/src/services/projects.ts +++ b/src/services/projects.ts @@ -3,15 +3,19 @@ import api from '@/lib/axios'; import { cookies } from 'next/headers'; -export async function getProjects() { +export async function getProjects(page = 1 as number) { const cookiesStore = await cookies(); + console.log('page'); + console.log(page); + return api .get('/projects', { + params: { page }, headers: { Cookie: cookiesStore.toString(), }, }) - .then(({ data }) => Promise.resolve(data.data)) + .then(({ data }) => Promise.resolve(data)) .catch((error) => Promise.reject(error)); }