From a3915377bd22b9bfd56eac6717fe5a18c4a17f13 Mon Sep 17 00:00:00 2001 From: ahasani194 Date: Sat, 7 Jun 2025 16:31:52 +0330 Subject: [PATCH] feat: implement internationalization and routing for locale-based pages - Added RootLayout component to handle locale and message loading. - Created Home page with header, about info, products, and story sections. - Developed ProductPage for displaying product categories and products. - Implemented ProductsPage to list product categories with banners. - Added Projects page with a grid layout for project display. - Configured server settings for port and host. - Established navigation and routing for internationalization. - Set up request handling for locale and message retrieval. - Defined routing structure for supported locales. - Created middleware for locale-based routing. - Defined layout parameters for locale handling. --- declarations.d.ts | 4 + global.ts | 9 ++ messages/en.d.json.ts | 63 +++++++++ messages/en.json | 59 +++++++++ messages/fa.json | 59 +++++++++ middleware.ts | 43 ++++++ next-intl.ts | 4 + next.config.ts | 13 +- package-lock.json | 125 +++++++++++++++++- package.json | 1 + src/app/[locale]/about-us/page.tsx | 30 +++++ src/app/{ => [locale]}/blog/page.tsx | 18 +-- src/app/{ => [locale]}/contact-us/page.tsx | 18 +-- src/app/[locale]/favicon.ico | Bin 0 -> 25931 bytes src/app/[locale]/layout.tsx | 43 ++++++ src/app/{ => [locale]}/page.tsx | 15 ++- .../[product_category_id]/page.tsx | 12 +- .../product-categories/page.tsx | 17 ++- src/app/{ => [locale]}/projects/page.tsx | 18 +-- src/app/about-us/page.tsx | 25 ---- src/app/layout.tsx | 27 ---- src/assets/constants/footerMenu/index.ts | 24 +++- .../constants/footerMenu/quickLinks.const.ts | 31 +++-- .../constants/footerMenu/whoAreWe.const.ts | 23 ++-- src/assets/constants/index.ts | 2 +- src/assets/constants/routeFactory/index.ts | 47 ++++--- src/components/layout/footer/Footer.tsx | 38 +++--- src/components/layout/footer/FooterInfo.tsx | 8 +- .../layout/footer/FooterMenuBuilder.tsx | 4 +- src/components/layout/hamburgerMenu/index.tsx | 17 ++- src/components/layout/header/index.tsx | 23 ++-- src/components/layout/navbar/index.tsx | 110 +++------------ src/components/pages/about/TopInfo.tsx | 32 +++-- .../pages/home/HomeStorySection.tsx | 20 +-- src/components/pages/home/Products.tsx | 25 ++-- .../productCategories/ProductCategoryCard.tsx | 20 +-- .../ProductCategoryCardInProducts.tsx | 22 +-- src/config.ts | 4 + src/i18n/navigation.ts | 5 + src/i18n/request.ts | 16 +++ src/i18n/routing.ts | 12 ++ src/locales/translates.ts | 2 +- src/middleware.ts | 8 ++ src/models/layout.d.ts | 3 + 44 files changed, 775 insertions(+), 324 deletions(-) create mode 100644 declarations.d.ts create mode 100644 global.ts create mode 100644 messages/en.d.json.ts create mode 100644 messages/en.json create mode 100644 messages/fa.json create mode 100644 middleware.ts create mode 100644 next-intl.ts create mode 100644 src/app/[locale]/about-us/page.tsx rename src/app/{ => [locale]}/blog/page.tsx (53%) rename src/app/{ => [locale]}/contact-us/page.tsx (78%) create mode 100644 src/app/[locale]/favicon.ico create mode 100644 src/app/[locale]/layout.tsx rename src/app/{ => [locale]}/page.tsx (55%) rename src/app/{ => [locale]}/product-categories/[product_category_id]/page.tsx (81%) rename src/app/{ => [locale]}/product-categories/page.tsx (70%) rename src/app/{ => [locale]}/projects/page.tsx (53%) delete mode 100644 src/app/about-us/page.tsx delete mode 100644 src/app/layout.tsx create mode 100644 src/config.ts create mode 100644 src/i18n/navigation.ts create mode 100644 src/i18n/request.ts create mode 100644 src/i18n/routing.ts create mode 100644 src/middleware.ts create mode 100644 src/models/layout.d.ts diff --git a/declarations.d.ts b/declarations.d.ts new file mode 100644 index 0000000..bbab69d --- /dev/null +++ b/declarations.d.ts @@ -0,0 +1,4 @@ +declare module '*.json' { + const value: any; + export default value; +} diff --git a/global.ts b/global.ts new file mode 100644 index 0000000..acc506e --- /dev/null +++ b/global.ts @@ -0,0 +1,9 @@ +import { routing } from '@/i18n/routing'; +import messages from './messages/en.json'; + +declare module 'next-intl' { + interface AppConfig { + Locale: (typeof routing.locales)[number]; + Messages: typeof messages; + } +} diff --git a/messages/en.d.json.ts b/messages/en.d.json.ts new file mode 100644 index 0000000..26cb1c1 --- /dev/null +++ b/messages/en.d.json.ts @@ -0,0 +1,63 @@ +// This file is auto-generated by next-intl, do not edit directly. +// See: https://next-intl.dev/docs/workflows/typescript#messages-arguments + +declare const messages: { + "pages_home_title": "Home", + "pages_home_description": "Welcome to the home page", + "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", + "pages_contact_description": "Get in touch with us through this page", + "com_home_banner_title": "Excellence innovating", + "com_home_banner_title_bold": "industry for today", + "com_home_banner_description": "At the heart of our operations is a commitment to delivering superior products through cutting-
edge technology and innovative processes.", + "com_home_banner_button": " Explore More", + "com_home_Banner_link1": " Advanced Manufacturing Solutions", + "com_home_Banner_link2": "Quality Assurance Systems", + "com_home_Banner_link3": "State-of-the-Art Technology", + + "com_about_info_title": "Building quality through", + "com_about_info_title_bold": "industrial innovation", + "com_about_info_description": "At the heart of our operations is a commitment to delivering superior products through cutting-edge technology and innovative processes.", + "com_about_info_years_experience": "years of experience", + "com_about_info_achievements_1": "Sustainable Manufacturing", + "com_about_info_achievements_2": "Advanced Automation", + "com_about_info_achievements_3": "Efficient Production Processes", + "com_about_info_achievements_4": "Reliable Delivery Services", + + "com_home_products_title": "The Qualified bricks for Your Projects", + "com_home_products_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + + "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.", + "footer_slogan": "We are committed to providing personalized industrial solutions.", + "footer_links_quick_links": "Quick Links", + "footer_links_who_we_are": "Who We Are", + "footer_links_contact": "Contact", + "footer_copyright": "Copyright © 2025 All Rights Reserved.", + "footer_links_address": "123 Industrial Ave, Suite 456, City, Country", + + "com_home_story_title": "Our Story", + "com_home_story_slogan": "Building quality through", + "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_experience": "Years of Experience", + + "com_products_category_Ghazaghi_title": "Ghazaghi", + "com_products_category_Ghermez_title": "Ghermez", + "com_products_category_Semirom_title": "Semirom", + "com_products_category_Zard_title": "Zard", + "com_products_category_types_count": "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 IndustryThe 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.", + + "com_products_products_category_title": "Products of {title} Category" +}; +export default messages; \ No newline at end of file diff --git a/messages/en.json b/messages/en.json new file mode 100644 index 0000000..2d04522 --- /dev/null +++ b/messages/en.json @@ -0,0 +1,59 @@ +{ + "pages_home_title": "Home", + "pages_home_description": "Welcome to the home page", + "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", + "pages_contact_description": "Get in touch with us through this page", + "com_home_banner_title": "Excellence innovating", + "com_home_banner_title_bold": "industry for today", + "com_home_banner_description": "At the heart of our operations is a commitment to delivering superior products through cutting-
edge technology and innovative processes.", + "com_home_banner_button": " Explore More", + "com_home_Banner_link1": " Advanced Manufacturing Solutions", + "com_home_Banner_link2": "Quality Assurance Systems", + "com_home_Banner_link3": "State-of-the-Art Technology", + + "com_about_info_title": "Building quality through", + "com_about_info_title_bold": "industrial innovation", + "com_about_info_description": "At the heart of our operations is a commitment to delivering superior products through cutting-edge technology and innovative processes.", + "com_about_info_years_experience": "years of experience", + "com_about_info_achievements_1": "Sustainable Manufacturing", + "com_about_info_achievements_2": "Advanced Automation", + "com_about_info_achievements_3": "Efficient Production Processes", + "com_about_info_achievements_4": "Reliable Delivery Services", + + "com_home_products_title": "The Qualified bricks for Your Projects", + "com_home_products_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + + "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.", + "footer_slogan": "We are committed to providing personalized industrial solutions.", + "footer_links_quick_links": "Quick Links", + "footer_links_who_we_are": "Who We Are", + "footer_links_contact": "Contact", + "footer_copyright": "Copyright © 2025 All Rights Reserved.", + "footer_links_address": "123 Industrial Ave, Suite 456, City, Country", + + "com_home_story_title": "Our Story", + "com_home_story_slogan": "Building quality through", + "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_experience": "Years of Experience", + + "com_products_category_Ghazaghi_title": "Ghazaghi", + "com_products_category_Ghermez_title": "Ghermez", + "com_products_category_Semirom_title": "Semirom", + "com_products_category_Zard_title": "Zard", + "com_products_category_types_count": "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 IndustryThe 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.", + + "com_products_products_category_title": "Products of {title} Category" +} diff --git a/messages/fa.json b/messages/fa.json new file mode 100644 index 0000000..2d04522 --- /dev/null +++ b/messages/fa.json @@ -0,0 +1,59 @@ +{ + "pages_home_title": "Home", + "pages_home_description": "Welcome to the home page", + "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", + "pages_contact_description": "Get in touch with us through this page", + "com_home_banner_title": "Excellence innovating", + "com_home_banner_title_bold": "industry for today", + "com_home_banner_description": "At the heart of our operations is a commitment to delivering superior products through cutting-
edge technology and innovative processes.", + "com_home_banner_button": " Explore More", + "com_home_Banner_link1": " Advanced Manufacturing Solutions", + "com_home_Banner_link2": "Quality Assurance Systems", + "com_home_Banner_link3": "State-of-the-Art Technology", + + "com_about_info_title": "Building quality through", + "com_about_info_title_bold": "industrial innovation", + "com_about_info_description": "At the heart of our operations is a commitment to delivering superior products through cutting-edge technology and innovative processes.", + "com_about_info_years_experience": "years of experience", + "com_about_info_achievements_1": "Sustainable Manufacturing", + "com_about_info_achievements_2": "Advanced Automation", + "com_about_info_achievements_3": "Efficient Production Processes", + "com_about_info_achievements_4": "Reliable Delivery Services", + + "com_home_products_title": "The Qualified bricks for Your Projects", + "com_home_products_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + + "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.", + "footer_slogan": "We are committed to providing personalized industrial solutions.", + "footer_links_quick_links": "Quick Links", + "footer_links_who_we_are": "Who We Are", + "footer_links_contact": "Contact", + "footer_copyright": "Copyright © 2025 All Rights Reserved.", + "footer_links_address": "123 Industrial Ave, Suite 456, City, Country", + + "com_home_story_title": "Our Story", + "com_home_story_slogan": "Building quality through", + "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_experience": "Years of Experience", + + "com_products_category_Ghazaghi_title": "Ghazaghi", + "com_products_category_Ghermez_title": "Ghermez", + "com_products_category_Semirom_title": "Semirom", + "com_products_category_Zard_title": "Zard", + "com_products_category_types_count": "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 IndustryThe 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.", + + "com_products_products_category_title": "Products of {title} Category" +} diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..63fa951 --- /dev/null +++ b/middleware.ts @@ -0,0 +1,43 @@ +import { NextResponse } from 'next/server'; +import type { NextRequest } from 'next/server'; + +const PUBLIC_FILE = /\.(.*)$/; +const locales = ['en', 'fa']; +const defaultLocale = 'en'; + +export function middleware(request: NextRequest) { + const { pathname } = request.nextUrl; + + // Ignore public files and API routes + if ( + pathname.startsWith('/api') || + PUBLIC_FILE.test(pathname) + ) { + return NextResponse.next(); + } + + // Check if the pathname already includes a locale + const pathnameIsMissingLocale = locales.every( + (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` + ); + + if (pathnameIsMissingLocale) { + // Redirect to default locale + return NextResponse.redirect( + new URL(`/${defaultLocale}${pathname}`, request.url) + ); + } + + return NextResponse.next(); +} + +export const config = { + matcher: [ + /* + Match all request paths except for: + - static files (/_next/static/) + - API routes (/api/) + */ + '/((?!_next/static|_next/image|favicon.ico|api).*)', + ], +}; \ No newline at end of file diff --git a/next-intl.ts b/next-intl.ts new file mode 100644 index 0000000..1ebee31 --- /dev/null +++ b/next-intl.ts @@ -0,0 +1,4 @@ +export default { + locales: ['en', 'fa'], + defaultLocale: 'en', +}; diff --git a/next.config.ts b/next.config.ts index b22af96..c049cbc 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,5 +1,12 @@ -import type { NextConfig } from 'next'; +import { NextConfig } from 'next'; +import createNextIntlPlugin from 'next-intl/plugin'; -const nextConfig: NextConfig = {}; +const withNextIntl = createNextIntlPlugin({ + experimental: { + createMessagesDeclaration: './messages/en.json', + }, +}); -export default nextConfig; +const config: NextConfig = {}; + +export default withNextIntl(config); diff --git a/package-lock.json b/package-lock.json index 3b96c41..c75439e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "axios": "^1.9.0", "leaflet": "^1.9.4", "next": "15.3.3", + "next-intl": "^4.1.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-leaflet": "^5.0.0" @@ -218,6 +219,60 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz", + "integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==", + "dependencies": { + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.1", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/ecma402-abstract/node_modules/@formatjs/intl-localematcher": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz", + "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz", + "integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/icu-skeleton-parser": "1.8.14", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz", + "integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.4", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz", + "integrity": "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==", + "dependencies": { + "tslib": "2" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -939,6 +994,11 @@ "integrity": "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==", "dev": true }, + "node_modules/@schummar/icu-type-parser": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz", + "integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==" + }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -2336,6 +2396,11 @@ } } }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -3527,6 +3592,17 @@ "node": ">= 0.4" } }, + "node_modules/intl-messageformat": { + "version": "10.7.16", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz", + "integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.2", + "tslib": "^2.8.0" + } + }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -4475,6 +4551,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/next": { "version": "15.3.3", "resolved": "https://registry.npmjs.org/next/-/next-15.3.3.tgz", @@ -4528,6 +4612,32 @@ } } }, + "node_modules/next-intl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.1.0.tgz", + "integrity": "sha512-JNJRjc7sdnfUxhZmGcvzDszZ60tQKrygV/VLsgzXhnJDxQPn1cN2rVpc53adA1SvBJwPK2O6Sc6b4gYSILjCzw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/amannn" + } + ], + "dependencies": { + "@formatjs/intl-localematcher": "^0.5.4", + "negotiator": "^1.0.0", + "use-intl": "^4.1.0" + }, + "peerDependencies": { + "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0", + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -5822,7 +5932,7 @@ "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5896,6 +6006,19 @@ "punycode": "^2.1.0" } }, + "node_modules/use-intl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.1.0.tgz", + "integrity": "sha512-mQvDYFvoGn+bm/PWvlQOtluKCknsQ5a9F1Cj0hMfBjMBVTwnOqLPd6srhjvVdEQEQFVyHM1PfyifKqKYb11M9Q==", + "dependencies": { + "@formatjs/fast-memoize": "^2.2.0", + "@schummar/icu-type-parser": "1.21.5", + "intl-messageformat": "^10.5.14" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index e9b6247..af4798b 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "axios": "^1.9.0", "leaflet": "^1.9.4", "next": "15.3.3", + "next-intl": "^4.1.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-leaflet": "^5.0.0" diff --git a/src/app/[locale]/about-us/page.tsx b/src/app/[locale]/about-us/page.tsx new file mode 100644 index 0000000..3a711c3 --- /dev/null +++ b/src/app/[locale]/about-us/page.tsx @@ -0,0 +1,30 @@ +import images from '@/assets/images/images'; +import InnerPageBanner from '@/components/layout/innerPages/banner'; +import AboutTopInfo from '@/components/pages/about/TopInfo'; +import { ILayoutLocaleParams } from '@/models/layout'; +import { useTranslations } from 'next-intl'; +import { setRequestLocale } from 'next-intl/server'; +import { getTranslations } from 'next-intl/server'; + +export default async function AboutUs({ + params, +}: Readonly<{ + params: ILayoutLocaleParams; +}>) { + const { locale } = await params; + + // Enable static rendering + setRequestLocale(locale); + + const t = await getTranslations({ locale }); + + return ( +
+ + +
+ ); +} diff --git a/src/app/blog/page.tsx b/src/app/[locale]/blog/page.tsx similarity index 53% rename from src/app/blog/page.tsx rename to src/app/[locale]/blog/page.tsx index 10cf9bc..aab6f67 100644 --- a/src/app/blog/page.tsx +++ b/src/app/[locale]/blog/page.tsx @@ -1,20 +1,20 @@ import images from '@/assets/images/images'; import InnerPageBanner from '@/components/layout/innerPages/banner'; import PostsGrid from '@/components/pages/blog/PostsGrid'; -import { t } from '@/locales/translates'; +import { ILayoutLocaleParams } from '@/models/layout'; +import { getTranslations } from 'next-intl/server'; -async function getData() { - await new Promise((resolve) => setTimeout(resolve, 1000)); - return { message: 'This data was fetched on the server!' }; -} - -export default async function Blog() { - const data = await getData(); +export default async function Blog({ + params, +}: { + params: ILayoutLocaleParams; +}) { + const t = await getTranslations({ locale: params.locale }); return (
diff --git a/src/app/contact-us/page.tsx b/src/app/[locale]/contact-us/page.tsx similarity index 78% rename from src/app/contact-us/page.tsx rename to src/app/[locale]/contact-us/page.tsx index 98ca9ba..70bbc9f 100644 --- a/src/app/contact-us/page.tsx +++ b/src/app/[locale]/contact-us/page.tsx @@ -3,21 +3,21 @@ import InnerPageBanner from '@/components/layout/innerPages/banner'; import ContactMap from '@/components/layout/map'; import ContactForm from '@/components/pages/contact/ContactMeForm'; import TouchUs from '@/components/pages/contact/TouchUs'; -import { t } from '@/locales/translates'; import Image from 'next/image'; +import { getTranslations } from 'next-intl/server'; +import { ILayoutLocaleParams } from '@/models/layout'; -async function getData() { - await new Promise((resolve) => setTimeout(resolve, 1000)); - return { message: 'This data was fetched on the server!' }; -} - -export default async function Contact() { - const data = await getData(); +export default async function Contact({ + params, +}: { + params: ILayoutLocaleParams; +}) { + const t = await getTranslations({ locale: params.locale }); return (
diff --git a/src/app/[locale]/favicon.ico b/src/app/[locale]/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx new file mode 100644 index 0000000..4cfb0ff --- /dev/null +++ b/src/app/[locale]/layout.tsx @@ -0,0 +1,43 @@ +import Footer from '@/components/layout/footer/Footer'; +import '@/app/globals.css'; +import 'leaflet/dist/leaflet.css'; +import { notFound } from 'next/navigation'; +import { NextIntlClientProvider } from 'next-intl'; +import type { ILayoutLocaleParams } from '@/models/layout.d'; + +// export const metadata: Metadata = { +// title: 'Create Next App', +// description: 'Generated by create next app', +// }; + +export default async function RootLayout({ + children, + params, +}: Readonly<{ + children: React.ReactNode; + params: ILayoutLocaleParams; +}>) { + const locale = params.locale; + console.log(locale); + + let messages; + try { + console.log(await import(`../../../messages/en.json`)); + messages = (await import(`../../../messages/en.json`)).default; + } catch (error) { + console.log(error); + + notFound(); + } + + return ( + + + + {children} +