diff --git a/package.json b/package.json index c7fd197..528c967 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,12 @@ "lucide-react": "^0.475.0", "next": "15.1.6", "next-intl": "^3.26.4", + "rc-pagination": "^5.1.0", "react": "^19.0.0", "react-countup": "^6.5.3", "react-dom": "^19.0.0", "react-intersection-observer": "^9.15.1", + "react-toastify": "^11.0.3", "swiper": "^11.2.2" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6d1a62..adac5d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: next-intl: specifier: ^3.26.4 version: 3.26.4(next@15.1.6)(react@19.0.0) + rc-pagination: + specifier: ^5.1.0 + version: 5.1.0(react-dom@19.0.0)(react@19.0.0) react: specifier: ^19.0.0 version: 19.0.0 @@ -35,6 +38,9 @@ dependencies: react-intersection-observer: specifier: ^9.15.1 version: 9.15.1(react-dom@19.0.0)(react@19.0.0) + react-toastify: + specifier: ^11.0.3 + version: 11.0.3(react-dom@19.0.0)(react@19.0.0) swiper: specifier: ^11.2.2 version: 11.2.4 @@ -63,6 +69,13 @@ packages: engines: {node: '>=10'} dev: true + /@babel/runtime@7.26.9: + resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + /@emnapi/runtime@1.3.1: resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} requiresBuild: true @@ -982,10 +995,19 @@ packages: fsevents: 2.3.3 dev: true + /classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + dev: false + /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} dev: false + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: false + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2681,6 +2703,31 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /rc-pagination@5.1.0(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.26.9 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + + /rc-util@5.44.4(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.26.9 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + react-is: 18.3.1 + dev: false + /react-countup@6.5.3(react@19.0.0): resolution: {integrity: sha512-udnqVQitxC7QWADSPDOxVWULkLvKUWrDapn5i53HE4DPRVgs+Y5rr4bo25qEl8jSh+0l2cToJgGMx+clxPM3+w==} peerDependencies: @@ -2716,6 +2763,21 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true + /react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + dev: false + + /react-toastify@11.0.3(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-cbPtHJPfc0sGqVwozBwaTrTu1ogB9+BLLjd4dDXd863qYLj7DGrQ2sg5RAChjFUB4yc3w8iXOtWcJqPK/6xqRQ==} + peerDependencies: + react: ^18 || ^19 + react-dom: ^18 || ^19 + dependencies: + clsx: 2.1.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + /react@19.0.0: resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} @@ -2748,6 +2810,10 @@ packages: which-builtin-type: 1.2.1 dev: true + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false + /regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} diff --git a/public/favicons/web-app-manifest-192x192.png b/public/favicons/web-app-manifest-192x192.png new file mode 100644 index 0000000..f9cde7b Binary files /dev/null and b/public/favicons/web-app-manifest-192x192.png differ diff --git a/public/favicons/web-app-manifest-512x512.png b/public/favicons/web-app-manifest-512x512.png new file mode 100644 index 0000000..0019587 Binary files /dev/null and b/public/favicons/web-app-manifest-512x512.png differ diff --git a/src/app/[locale]/categories/[...id]/page.jsx b/src/app/[locale]/categories/[...id]/page.jsx deleted file mode 100644 index f5e376f..0000000 --- a/src/app/[locale]/categories/[...id]/page.jsx +++ /dev/null @@ -1,210 +0,0 @@ -import React from "react"; -import CategoriesData from "src/view/Categories"; - -const page = async ({ params, searchParams }) => { - const data = [ - { - id: 1, - persianName: "Hydrating Cream", - englishName: "Hydrating Cream", - description: - "A deeply moisturizing cream that keeps your skin hydrated all day long.", - cost: 250000, - costWithDiscount: 200000, - hasDiscount: true, - discountPercent: 20, - stock: 5, - mainImage: "4", - }, - { - id: 2, - persianName: "Hair Strengthening Shampoo", - englishName: "Hair Strengthening Shampoo", - description: - "A nourishing shampoo that strengthens hair roots and prevents hair fall.", - cost: 180000, - costWithDiscount: 150000, - hasDiscount: true, - discountPercent: 17, - stock: 2, - mainImage: "3", - }, - { - id: 3, - persianName: "Vitamin C Serum", - englishName: "Vitamin C Serum", - description: - "An antioxidant-rich serum that brightens skin and reduces signs of aging.", - cost: 300000, - costWithDiscount: 270000, - hasDiscount: true, - discountPercent: 10, - stock: 3, - mainImage: "1", - }, - { - id: 4, - persianName: "Charcoal Face Mask", - englishName: "Charcoal Face Mask", - description: - "A detoxifying mask that removes impurities and unclogs pores for a fresh look.", - cost: 220000, - costWithDiscount: 220000, - hasDiscount: false, - discountPercent: 0, - stock: 8, - mainImage: "4", - }, - { - id: 5, - persianName: "Body Lotion", - englishName: "Body Lotion", - description: - "A lightweight body lotion that nourishes and hydrates dry skin.", - cost: 210000, - costWithDiscount: 185000, - hasDiscount: true, - discountPercent: 12, - stock: 6, - mainImage: "2", - }, - { - id: 6, - persianName: "Aloe Vera Gel", - englishName: "Aloe Vera Gel", - description: - "A soothing gel enriched with aloe vera to calm irritated skin.", - cost: 160000, - costWithDiscount: 160000, - hasDiscount: false, - discountPercent: 0, - stock: 10, - mainImage: "3", - }, - { - id: 7, - persianName: "Sunscreen SPF 50", - englishName: "Sunscreen SPF 50", - description: - "A broad-spectrum sunscreen that protects against UV rays and prevents sunburn.", - cost: 280000, - costWithDiscount: 230000, - hasDiscount: true, - discountPercent: 18, - stock: 4, - mainImage: "1", - }, - { - id: 8, - persianName: "Face Cleanser", - englishName: "Face Cleanser", - description: - "A gentle face cleanser that removes dirt and oil without stripping moisture.", - cost: 190000, - costWithDiscount: 170000, - hasDiscount: true, - discountPercent: 10, - stock: 7, - mainImage: "2", - }, - { - id: 9, - persianName: "Moisturizing Cream", - englishName: "Moisturizing Cream", - description: - "A rich cream that provides deep hydration for soft and smooth skin.", - cost: 260000, - costWithDiscount: 260000, - hasDiscount: false, - discountPercent: 0, - stock: 9, - mainImage: "4", - }, - { - id: 10, - persianName: "Eye Serum", - englishName: "Eye Serum", - description: - "A lightweight eye serum that reduces puffiness and dark circles.", - cost: 350000, - costWithDiscount: 310000, - hasDiscount: true, - discountPercent: 12, - stock: 5, - mainImage: "3", - }, - { - id: 11, - persianName: "Lip Balm", - englishName: "Lip Balm", - description: - "A moisturizing lip balm that prevents chapped lips and adds a subtle shine.", - cost: 90000, - costWithDiscount: 80000, - hasDiscount: true, - discountPercent: 11, - stock: 12, - mainImage: "1", - }, - { - id: 12, - persianName: "Hand Cream", - englishName: "Hand Cream", - description: - "A fast-absorbing hand cream that keeps hands soft and hydrated.", - cost: 170000, - costWithDiscount: 150000, - hasDiscount: true, - discountPercent: 12, - stock: 6, - mainImage: "2", - }, - { - id: 13, - persianName: "Night Repair Serum", - englishName: "Night Repair Serum", - description: - "A serum that works overnight to repair and rejuvenate your skin.", - cost: 390000, - costWithDiscount: 350000, - hasDiscount: true, - discountPercent: 10, - stock: 4, - mainImage: "3", - }, - { - id: 14, - persianName: "Shaving Cream", - englishName: "Shaving Cream", - description: - "A rich shaving cream that provides a smooth and irritation-free shave.", - cost: 200000, - costWithDiscount: 200000, - hasDiscount: false, - discountPercent: 0, - stock: 9, - mainImage: "4", - }, - - { - id: 15, - persianName: "Shaving ", - englishName: "Shaving ", - description: - "A fast-absorbing hand cream that keeps hands soft and hydrated.", - cost: 200000, - costWithDiscount: 200000, - hasDiscount: false, - discountPercent: 0, - stock: 9, - mainImage: "1", - }, - ]; - return ( -
- -
- ); -}; - -export default page; diff --git a/src/app/[locale]/categories/page.jsx b/src/app/[locale]/categories/page.jsx deleted file mode 100644 index 420225f..0000000 --- a/src/app/[locale]/categories/page.jsx +++ /dev/null @@ -1,14 +0,0 @@ -"use client"; -import { useRouter } from "next/navigation"; -import React, { useEffect } from "react"; - -const Page = (props) => { - const router = useRouter(); - useEffect(() => { - router.push("/categories/0"); - }, []); - - return; -}; - -export default Page; diff --git a/src/app/[locale]/layout.jsx b/src/app/[locale]/layout.jsx index 8ef1e41..eed937f 100644 --- a/src/app/[locale]/layout.jsx +++ b/src/app/[locale]/layout.jsx @@ -1,13 +1,74 @@ import { NextIntlClientProvider } from "next-intl"; -import { getMessages } from "next-intl/server"; +import { getLocale, getMessages } from "next-intl/server"; import { notFound } from "next/navigation"; import { routing } from "src/i18n/routing"; import "../../styles/globals.css"; +import Navbar from "src/components/NavBar"; +import Footer from "src/view/Landing/components/Footer"; +import { ToastContainer } from 'react-toastify'; +import graphql from "src/utils/graphql"; + +import { Rubik, Roboto } from "next/font/google"; + +const gql = ` +query Navbars($locale: I18NLocaleCode) { + navbars(locale: $locale, sort: ["order:asc"]) { + documentId + title + link + children { + id + title + link + } + } +} + +` +const rubik = Rubik({ + subsets: ["arabic"], + weight: ["400", "700"], + variable: "--font-rubik", // This will create a CSS variable for easy use +}); + +const roboto = Roboto({ + subsets: ["latin"], + weight: ["400", "700"], + variable: "--font-roboto", // Create a CSS variable for Roboto +}); + +const fetchNavbarItems = async () => { + const locale = await getLocale() + const { navbars } = await graphql(gql, { + locale: locale + }) + return navbars +} + +// app/[locale]/page.js + +export const generateMetadata = async ({ params }) => { + const { locale } = params; + const t = await getMessages(locale) + // Define titles and descriptions for each locale + + + return { + title: t.HomePage.SEO.title, + description: t.HomePage.SEO.descriptions, + }; +}; + + + export default async function LocaleLayout({ children, - params: { locale } + params }) { + + const { locale } = await params + const navbaritems = await fetchNavbarItems() // Ensure that the incoming `locale` is valid if (!routing.locales.includes(locale)) { notFound(); @@ -16,13 +77,19 @@ export default async function LocaleLayout({ // Providing all messages to the client // side is the easiest way to get started const messages = await getMessages(); - console.log("messager",messages) return ( - - + + + + + + + {children} +