-
+
{/* */}
@@ -319,13 +269,13 @@ const Navbar = ({ theme }) => {
- {NavBarData.map((e, index) => (
- <>
+ {items.map((e, index) => (
+
{/* */}
<>
@@ -335,12 +285,12 @@ const Navbar = ({ theme }) => {
if (e.children.length > 0) {
setResponsiveNavBarItemStep(index);
- setActiveStepNavbar(e.id);
+ setActiveStepNavbar(e.documentId);
}
}}
>
- {e.name}
+ {e.title}
{e.children.length > 0 ? (
@@ -374,23 +324,23 @@ const Navbar = ({ theme }) => {
{responsiveNavBarItemStep === index &&
e.children.length > 0 &&
- e.id == activeStepNavbar && (
+ e.documentId == activeStepNavbar && (
{e.children.map((s, index) => (
- //
-
- //
+
+
+
))}
)}
- >
+
))}
diff --git a/src/components/Paginate/index.jsx b/src/components/Paginate/index.jsx
new file mode 100644
index 0000000..9dc434d
--- /dev/null
+++ b/src/components/Paginate/index.jsx
@@ -0,0 +1,17 @@
+"use client";
+import { usePathname, useRouter } from "next/navigation";
+import RcPagination from "rc-pagination";
+import "rc-pagination/assets/index.css";
+
+const Paginate = ({ pageInfo }) => {
+
+ const router = useRouter()
+ const pathname = usePathname()
+ const onChange = (page) => {
+ router.push(pathname + `?page=${page}`);
+ }
+
+ return
;
+};
+
+export default Paginate;
diff --git a/src/components/Product/BrandInfo.jsx b/src/components/Product/BrandInfo.jsx
new file mode 100644
index 0000000..421e458
--- /dev/null
+++ b/src/components/Product/BrandInfo.jsx
@@ -0,0 +1,20 @@
+import Image from "next/image"
+import Link from "next/link"
+
+
+export default function BrandInfo({ brand }) {
+ return (
+
+
+
{brand.title}
+
+ )
+}
+
diff --git a/src/components/Product/ProductDescription.jsx b/src/components/Product/ProductDescription.jsx
new file mode 100644
index 0000000..2058901
--- /dev/null
+++ b/src/components/Product/ProductDescription.jsx
@@ -0,0 +1,16 @@
+export default function ProductDescription({ description }) {
+ return (
+
+ {
+ description &&
+ <>
+
Product Description
+
+ >
+ }
+
+ )
+}
+
diff --git a/src/components/Product/ProductGallery.jsx b/src/components/Product/ProductGallery.jsx
new file mode 100644
index 0000000..ce47dda
--- /dev/null
+++ b/src/components/Product/ProductGallery.jsx
@@ -0,0 +1,97 @@
+"use client";
+
+import { useState } from "react";
+import Image from "next/image";
+import { ChevronLeft, ChevronRight, X } from "lucide-react";
+
+export default function ProductGallery({ images }) {
+ const [selectedImage, setSelectedImage] = useState(images[0]);
+ const [lightboxOpen, setLightboxOpen] = useState(false);
+ const [lightboxIndex, setLightboxIndex] = useState(0);
+
+ const openLightbox = (index) => {
+ setLightboxIndex(index);
+ setLightboxOpen(true);
+ };
+
+ const closeLightbox = () => {
+ setLightboxOpen(false);
+ };
+
+ const nextImage = () => {
+ setLightboxIndex((prevIndex) => (prevIndex + 1) % images.length);
+ };
+
+ const prevImage = () => {
+ setLightboxIndex((prevIndex) => (prevIndex - 1 + images.length) % images.length);
+ };
+
+ return (
+
+
+ openLightbox(images.findIndex((img) => img.documentId === selectedImage.documentId))}
+ />
+
+
+ {images.slice(0,4).map((image, index) => (
+ setSelectedImage(image)}
+ />
+ ))}
+
+
+ {lightboxOpen && (
+
+
+ {/* Close Button */}
+
+
+ {/* Lightbox Image */}
+
+
+ {/* Previous Button */}
+
+
+ {/* Next Button */}
+
+
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/Product/ProductInfo.jsx b/src/components/Product/ProductInfo.jsx
new file mode 100644
index 0000000..1b2962a
--- /dev/null
+++ b/src/components/Product/ProductInfo.jsx
@@ -0,0 +1,104 @@
+"use client"
+
+import { ShoppingCart } from "lucide-react";
+import { HardHat } from "lucide-react";
+import { Tag } from "lucide-react";
+import { useLocale } from "next-intl";
+import Link from "next/link";
+import ContactModal from "../ContactUs";
+import { useState } from "react";
+import { useTranslations } from "next-intl";
+
+
+export default function ProductInfo({ title, price, discount, showPrice, category,summery }) {
+
+ const locale = useLocale()
+
+ // Determine the currency symbol based on the locale
+ const currencySymbol = locale === "ar-OM" ? "ريال" : "$";
+ const CategoryIcon = category.slug === "fmcg" ? ShoppingCart : HardHat
+ const discountedPrice = discount ? price * (1 - discount / 100) : price;
+
+
+ const [open, setOpen] = useState(false);
+ const openModal = () => {
+ setOpen(true);
+ };
+ const closeModal = () => {
+ setOpen(false);
+ }
+
+ const t = useTranslations("ContactModal")
+
+ return (
+
+
+
{title}
+
+
+
+ {category.title}
+
+
+
+ {
+ summery
+ }
+
+ {showPrice && (
+
+ {discount ? (
+
+
+ {locale === "ar-OM" ? (
+ <>
+ {discountedPrice.toFixed(2)} {currencySymbol}
+ >
+ ) : (
+ <>
+ {currencySymbol}
+ {discountedPrice.toFixed(2)}
+ >
+ )}
+
+
+ {locale === "ar-OM" ? (
+ <>
+ {price.toFixed(2)} {currencySymbol}
+ >
+ ) : (
+ <>
+ {currencySymbol}
+ {price.toFixed(2)}
+ >
+ )}
+
+
+ {discount}% OFF
+
+
+ ) : (
+
+ {locale === "ar-OM" ? (
+ <>
+ {price.toFixed(2)} {currencySymbol}
+ >
+ ) : (
+ <>
+ {currencySymbol}
+ {price.toFixed(2)}
+ >
+ )}
+
+ )}
+
+ )}
+
+ {/* Replaced Button with Tailwind CSS */}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/Product/ProductProperties.jsx b/src/components/Product/ProductProperties.jsx
new file mode 100644
index 0000000..f2fd995
--- /dev/null
+++ b/src/components/Product/ProductProperties.jsx
@@ -0,0 +1,18 @@
+
+
+export default function ProductProperties({ properties }) {
+ return (
+
+
Product Specifications
+
+ {properties.map((prop) => (
+
+
- {prop.key}
+ - {prop.value}
+
+ ))}
+
+
+ )
+}
+
diff --git a/src/components/Product/ProductRelated.jsx b/src/components/Product/ProductRelated.jsx
new file mode 100644
index 0000000..1d18036
--- /dev/null
+++ b/src/components/Product/ProductRelated.jsx
@@ -0,0 +1,86 @@
+"use client"
+import React, { useEffect } from 'react'
+import graphql from 'src/utils/graphql'
+import ProductCarousel from '../Carousel/ProductCarousel'
+import { useTranslations } from 'next-intl'
+
+const gql = `
+query Products_connection(
+ $categoryId: ID
+ $brandId: ID
+ $locale: I18NLocaleCode
+) {
+ products_connection(
+ filters: {
+ or: [
+ { category: { documentId: { eqi: $categoryId } } }
+ { brand: { documentId: { eqi: $brandId } } }
+ ]
+ }
+ sort: ["createdAt:desc"]
+ locale: $locale
+ ) {
+ nodes {
+ documentId
+ title
+ price
+ slug
+ discount
+ showPrice
+ images {
+ documentId
+ alternativeText
+ url
+ }
+ brand {
+ title
+ documentId
+ image {
+ documentId
+ alternativeText
+ url
+ }
+ slug
+ }
+ category {
+ documentId
+ title
+ slug
+ }
+ }
+ }
+}
+
+`
+
+const ProductRelated = ({ category, brand }) => {
+ const [products, setProducts] = React.useState(null)
+ const fetchProducts = async () => {
+ const { products_connection: { nodes } } = await graphql(gql, {
+ categoryId: "",
+ brandId: brand.documentId,
+ locale: "en"
+ })
+ setProducts(nodes)
+ }
+
+ useEffect(() => {
+ fetchProducts()
+ }, [])
+
+
+ const t = useTranslations("PDP")
+ return (
+
+
+
+ {
+ products && products.length > 0 && (
+
+ )
+ }
+
+ )
+}
+
+export default ProductRelated
\ No newline at end of file
diff --git a/src/messages/ar-OM.json b/src/messages/ar-OM.json
index e7d3220..baf7b5c 100644
--- a/src/messages/ar-OM.json
+++ b/src/messages/ar-OM.json
@@ -1,17 +1,23 @@
{
+
"HomePage": {
+ "SEO":{
+ "title":"خدمات الأفق المتقدمة ش.م.م",
+ "description":"خدمات الأفق المتقدمة ش.م.م تقدم حلول سلاسل التوريد بالجملة للمنظفات والمواد الغذائية بجودة عالية وتركز على التميز والموثوقية"
+
+ },
"AboutUs": {
- "brandName": "منتجات خدمات الأفق المتقدمة ش.م.م",
+ "brandName": " خدمات الأفق المتقدمة ش.م.م",
"description": [
- "شريكك الموثوق لحلول سلاسل التوريد بالجملة",
+ "شريككم الموثوق لحلول سلاسل التوريد بالجملة",
"خدمات الأفق المتقدمة هي شركة تجارية رائدة متخصصة في حلول سلاسل التوريد بالجملة لمجموعة متنوعة من المنتجات، بما في ذلك المنظفات عالية الجودة والمواد الغذائية. مع سنوات من الخبرة والعلاقات الواسعة في الصناعة، نفخر بالتزامنا بالتميز والموثوقية ورضا العملاء.",
- "في AHS، نفهم تعقيدات سلسلة التوريد ونسعى لتبسيط العملية لشركائنا. شبكتنا الواسعة من الموردين والمصنعين تمكننا من الحصول على منتجات عالية الجودة بأسعار تنافسية، مما يضمن حصولك على أفضل قيمة لاستثمارك."
+ "في AHS، نفهم تعقيدات سلسلة التوريد ونسعى لتبسيط العملية لشركائنا. شبكتنا الواسعة من الموردين والمصنعين تمكننا من الحصول على منتجات عالية الجودة بأسعار تنافسية، مما يضمن حصولكم على أفضل قيمة لاستثماركم."
]
},
"Sides": {
"title": "اكتشف خبراتنا",
"fmcg": {
- "title": "السلع الاستهلاكية سريعة الحركة",
+ "title": "FMCG",
"subtitle": "السلع الاستهلاكية سريعة الحركة",
"description": "قسم السلع الاستهلاكية سريعة الحركة لدينا متخصص في توزيع وتسويق المنتجات الاستهلاكية اليومية. نضمن سرعة دوران المنتجات، وسلاسل توريد فعالة، واستراتيجيات تسويقية مبتكرة لتلبية الطلبات المتغيرة باستمرار للمستهلكين."
},
@@ -20,9 +26,53 @@
"subtitle": "نبني المستقبل",
"description": "ذراع الإنشاءات لدينا مكرس لخلق بنية تحتية دائمة وحلول بناء مبتكرة. من المشاريع السكنية إلى المجمعات التجارية، نقدم الخبرة والجودة والاستدامة في كل مشروع بناء."
}
+ },
+ "products": {
+ "title": [
+ "منتجات Active",
+ "الإنشاءات"
+ ]
}
},
"Footer": {
"address": "مسقط، السيب، موالح الشمالية، شارع الموج، رقم المجمع ٣٥٨، رقم المبنى ١/٢٠٣، مكتب رقم ٥٣، صندوق البريد: ٥٧ء"
+ },
+ "PLP": {
+ "title": "المنتجات",
+ "subtitle": "استكشاف مجموعتنا من المنتجات",
+ "filter": {
+ "title": "المرشحات",
+ "categories": "الفئات",
+ "brands": "العلامات التجارية"
+ }
+ },
+ "PDP": {
+ "contactUs": "اتصل بنا",
+ "home": "الصفحة الرئيسية",
+ "productDetails": "تفاصيل المنتج",
+ "productDescription": "وصف المنتج",
+ "productSpecification": "مواصفات المنتج",
+ "productRelated": "المنتجات ذات الصلة"
+ },
+ "ContactModal": {
+ "title": "اتصل بنا",
+ "email": "البريد الإلكتروني",
+ "emailPlaceholder": "أدخل بريدك الإلكتروني",
+ "company": "الشركة",
+ "companyPlaceholder": "أدخل اسم شركتك",
+ "message": "الرسالة",
+ "messagePlaceholder": "أدخل رسالتك",
+ "sendButton": "إرسال الرسالة",
+ "closeButton": "إغلاق",
+ "error": {
+ "fillAllFields": "يرجى ملء جميع الحقول",
+ "invalidEmail": "يرجى إدخال عنوان بريد إلكتروني صالح"
+ },
+ "success": "تم إرسال الرسالة بنجاح",
+ "cta": "اتصل بنا"
+ },
+ "Utils": {
+ "showMoreLink": "عرض المزيد",
+ "moreDetail": "المزيد من التفاصيل"
}
}
diff --git a/src/messages/en.json b/src/messages/en.json
index f3af2b5..56f1eec 100644
--- a/src/messages/en.json
+++ b/src/messages/en.json
@@ -1,5 +1,9 @@
{
"HomePage": {
+ "SEO":{
+ "title":"Advanced Horizon Services LLC",
+ "description":"Advanced Horizon Services LLC offers reliable wholesale supply chain solutions for high-quality detergents and food products with a focus on excellence."
+ },
"AboutUs": {
"brandName": "ADVANCED HORIZON SERVICES LLC Products",
"description": [
@@ -8,6 +12,7 @@
" At AHS, we understand the complexities of the supply chain and strive to simplify the process for our partners. Our extensive network of suppliers and manufacturers allows us to source top-notch products at competitive prices, ensuring that you receive the best value for your investment."
]
},
+
"Sides": {
"title": "Discover Our Expertise",
"fmcg": {
@@ -20,9 +25,53 @@
"subtitle": "Building the Future",
"description": "Our Construction arm is dedicated to creating lasting infrastructure and innovative building solutions.From residential projects to commercial complexes, we bring expertise, quality, and sustainability to every construction endeavor."
}
+ },
+ "products":{
+ "title":[
+"Active Products",
+"Constructions"
+ ]
}
},
"Footer": {
- "address": " Unit No. 53, Building No 203, Complex No.308 , Mawaleh North ,Road No. 108 Al Mouj Street , Muscat Uman.F.o.0ox.our.F.C.ll Muscat Airport"
+ "address": " Unit No. 53, Building No 203, Complex No.308 , Mawaleh North ,Road No. 108 Al Mouj Street , Muscat Oman.F.o.0ox.our.F.C.ll Muscat Airport"
+ },
+ "PLP":{
+ "title":"Products",
+ "subtitle":"Explore Our Range of Products",
+ "filter":{
+ "title":"Filters",
+ "categories":"Categories",
+ "brands":"Brands"
+ }
+ },
+ "PDP":{
+ "contactUs":"Contact Us",
+ "home":"Home",
+ "productDetails":"Product Details",
+ "productDescription":"Product Description",
+ "productSpecification":"Product Specification",
+ "productRelated":"Frequently Bought Together"
+ },
+ "ContactModal": {
+ "title": "Contact Us",
+ "email": "Email",
+ "emailPlaceholder": "Enter your email",
+ "company": "Company",
+ "companyPlaceholder": "Enter your company name",
+ "message": "Message",
+ "messagePlaceholder": "Enter your message",
+ "sendButton": "Send Message",
+ "closeButton": "Close",
+ "error":{
+ "fillAllFields":"Please fill all fields",
+ "invalidEmail":"Please enter a valid email address"
+ },
+ "success":"Message sent successfully",
+ "cta":"Contact Us"
+ },
+ "Utils":{
+ "showMoreLink":"Show more",
+ "moreDetail":"More detail"
}
}
diff --git a/src/styles/globals.css b/src/styles/globals.css
index f214f81..c4ae07c 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -2,6 +2,16 @@
@tailwind components;
@tailwind utilities;
+html[lang="en"] {
+
+}
+
+/* Arabic content (rtl) uses Tajawal */
+html[lang="ar-OM"] {
+
+}
+
+
@layer components {
.btn {
@apply py-2 px-4 rounded-xl transition-all shadow-lg border-2;
diff --git a/src/view/Categories/components/Content.jsx b/src/view/Categories/components/Content.jsx
index adc3d1f..9ccfff0 100644
--- a/src/view/Categories/components/Content.jsx
+++ b/src/view/Categories/components/Content.jsx
@@ -1,27 +1,164 @@
-import React from "react";
-import CardNormal from "src/components/Cards/CardNormal/page";
+"use client"
+import React, { useEffect } from "react";
+import CardNormal, { ProductCardSkeleton } from "src/components/Cards/CardNormal";
+import Paginate from "src/components/Paginate";
+import graphql from "src/utils/graphql";
+import Filters from "./Filters";
+import { useParams, useSearchParams } from "next/navigation";
+import { useTranslations } from "next-intl";
+const brandAndCategoriesGQL = `
+ query Categories($locale: I18NLocaleCode) {
+ categories(locale: $locale,pagination: { start: 0, limit: 50 }) {
+ documentId
+ slug
+ title
+ }
+ brands(locale: $locale, pagination: { start: 0, limit: 50 }) {
+ title
+ documentId
+ slug
+ }
+}
-const Content = ({ products }) => {
+`
+
+const productsGQL = `
+query Products_connection(
+ $locale: I18NLocaleCode
+ $page: Int
+ $pageSize: Int
+ $category: String
+ $brand: String
+) {
+ products_connection(
+ pagination: { page: $page, pageSize: $pageSize }
+ filters: {
+ or: [
+ { category: { slug: { eqi: $category } } }
+ { brand: { slug: { eqi: $brand } } }
+ ]
+ }
+ locale: $locale
+ ) {
+ nodes {
+ documentId
+ title
+ images {
+ documentId
+ alternativeText
+ url
+ }
+ category {
+ title
+ documentId
+ slug
+ }
+ brand {
+ documentId
+ title
+ slug
+ image {
+ documentId
+ alternativeText
+ url
+ }
+ }
+ slug
+ }
+ pageInfo {
+ total
+ page
+ pageSize
+ pageCount
+ }
+ }
+}
+
+
+`
+
+
+
+
+const Content = () => {
+ const params = useParams()
+ const searchParams = useSearchParams()
+ const { category } = params
+ const [loading, setLoading] = React.useState(true)
+ const [pageInfo, setPageInfo] = React.useState({ page: 1, pageSize: 12, total: 0, pageCount: 0 })
+ const [products, setProducts] = React.useState([])
+ const [brands, setBrands] = React.useState([])
+ const [categories, setCategories] = React.useState([])
+ const getBrandsAndCategories = async () => {
+ const { brands, categories } = await graphql(brandAndCategoriesGQL, { locale: "en" });
+ setBrands(brands)
+ setCategories(categories)
+
+ }
+ const getProducts = async () => {
+ setLoading(true)
+
+ const page = parseInt(searchParams.get("page")) || 1
+ const { products_connection: { nodes, pageInfo } } = await graphql(productsGQL, {
+ locale: "en",
+ page: page,
+ pageSize: 12,
+ brand: category,
+ category: category
+ })
+ setProducts(nodes)
+ setPageInfo(pageInfo)
+ setLoading(false)
+ }
+
+
+ useEffect(() => {
+ getBrandsAndCategories()
+
+ }, [])
+
+ useEffect(() => {
+ getProducts(category)
+ }, [searchParams])
+
+ console.log("products", products)
+ const t = useTranslations("PLP")
return (
-
-
-
-
- Product Listing Page
-
-
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Corporis,{" "}
-
-
-
-
- {products.map((product, index) => (
-
-
+ <>
+ {
+ brands && brands.length > 0 && categories && categories.length > 0 &&
+
+ }
+
+
+
+
+
+ {t("title")}
+
+
+ {t("subtitle")}
+
+
- ))}
+
+ {!loading && products.map((product, index) => (
+
+
+
+ ))}
+ {
+ loading && Array.from({ length: 12 }).map((_, index) => (
+
+ ))
+ }
+
+
+
-
+ >
);
};
diff --git a/src/view/Categories/components/Filters.jsx b/src/view/Categories/components/Filters.jsx
index 5df3dc5..5d8513b 100644
--- a/src/view/Categories/components/Filters.jsx
+++ b/src/view/Categories/components/Filters.jsx
@@ -1,46 +1,72 @@
-import React from "react";
+"use client"
+import { useTranslations } from "next-intl";
+import { useParams, useRouter } from "next/navigation";
+import React, { useEffect, useState } from "react";
-const Filters = () => {
+const CheckboxGroup = ({ title, items, selectedItem, onItemSelect }) => {
+ return (
+
+
{title}
+ {items.map((item) => (
+
+ onItemSelect(item.documentId)}
+ className="mx-2"
+ />
+
+
+ ))}
+
+ )
+}
+
+const Filters = ({ brands, categories }) => {
+ const [selectedCategory, setSelectedCategory] = useState(null)
+ const [selectedBrand, setSelectedBrand] = useState(null)
+ const params = useParams()
+ const router = useRouter()
+ const handleCategorySelect = (documentId) => {
+ setSelectedCategory((prevSelected) => (prevSelected === documentId ? null : documentId))
+ router.push("/products/"+(documentId ? `${categories.find(c=>c.documentId === documentId)?.slug}` : ""))
+ }
+
+ const handleBrandSelect = (documentId) => {
+ setSelectedBrand((prevSelected) => (prevSelected === documentId ? null : documentId))
+ router.push("/products/"+(documentId ? `${brands.find(b=>b.documentId === documentId)?.slug}` : ""))
+ }
+
+
+ useEffect(()=>{
+
+ const categoryOrBrand = params.category;
+ console.log("paramssssssssssssss", params.category,brands.find(b=>b.slug === categoryOrBrand),brands)
+
+ setSelectedBrand(brands.find(b=>b.slug === categoryOrBrand)?.documentId)
+ setSelectedCategory(categories.find(c=>c.slug === categoryOrBrand)?.documentId)
+ },[params])
+ const t = useTranslations("PLP.filter")
return (
);
};
diff --git a/src/view/Categories/index.jsx b/src/view/Categories/index.jsx
index 4df9e77..fbaa3b2 100644
--- a/src/view/Categories/index.jsx
+++ b/src/view/Categories/index.jsx
@@ -1,19 +1,52 @@
import React from "react";
-import CardNormal from "src/components/Cards/CardNormal/page";
+import CardNormal from "src/components/Cards/CardNormal";
import Navbar from "src/components/NavBar";
import Content from "./components/Content";
import Filters from "./components/Filters";
import Footer from "../Landing/components/Footer";
+import graphql from "src/utils/graphql";
+import { getLocale } from "next-intl/server";
+
+// query Products($locale:I18NLocaleCode,$page:Int,$pageSize:Int,$title:String,$categoryTitle:String,$brandTitle:String) {
+// products(
+// pagination: { page: $page, pageSize: $pageSize }
+// filters: {
+// category: { title: { contains: $categoryTitle } }
+// brand: { title: { eq: $brandTitle } }
+// title: { eq: $title }
+// }
+// locale: $locale
+// ) {
+// title
+// documentId
+// price
+// brand {
+// title
+// documentId
+// slug
+// }
+// category {
+// documentId
+// title
+// slug
+// }
+// }
+// }
+
+
+
+const CategoriesData = async ({ category }) => {
+
+ const locale = await getLocale()
-const CategoriesData = ({ products }) => {
return (
<>
-
-
-
-
+
+
+
+
-
+
>
);
};
diff --git a/src/view/Landing/components/AboutUs.jsx b/src/view/Landing/components/AboutUs.jsx
index fa2d0d5..49cd0b7 100644
--- a/src/view/Landing/components/AboutUs.jsx
+++ b/src/view/Landing/components/AboutUs.jsx
@@ -7,37 +7,40 @@ const AboutUs = () => {
const t = useTranslations("HomePage.AboutUs")
const locale = useLocale()
return (
-
-
-
-
-
-
-
-
-
- {t("brandName")}
+
+
-
-
-
- {t("description.0")}
-
-
-
- {t("description.1")}
-
- {t("description.2")}
-
- {/*
+
+
+
+
+
+
+
+
+ {t("brandName")}
+
+
+
+
+
+ {t("description.0")}
+
+
+
+ {t("description.1")}
+
+ {t("description.2")}
+
+ {/*
*/}
+
diff --git a/src/view/Landing/components/CounterDetail.jsx b/src/view/Landing/components/CounterDetail.jsx
index a54f372..624132f 100644
--- a/src/view/Landing/components/CounterDetail.jsx
+++ b/src/view/Landing/components/CounterDetail.jsx
@@ -24,11 +24,12 @@ const CounterDetail = ({ stats }) => {
{s.title}
-
+
+
))
}
diff --git a/src/view/Landing/components/Footer.jsx b/src/view/Landing/components/Footer.jsx
index cd58a04..879c41e 100644
--- a/src/view/Landing/components/Footer.jsx
+++ b/src/view/Landing/components/Footer.jsx
@@ -10,8 +10,8 @@ import { useTranslations } from "next-intl";
const Footer = () => {
const t = useTranslations("Footer")
return (
-
-
+
+ {/*
<>
@@ -27,7 +27,7 @@ const Footer = () => {
>
-
+
*/}
@@ -61,7 +61,7 @@ const Footer = () => {
© 2025. All rights reserved.
- am - Om
+ Advanced Horizon Services LLC
{/*
diff --git a/src/view/Landing/components/Products.jsx b/src/view/Landing/components/Products.jsx
index 10466de..57dcf30 100644
--- a/src/view/Landing/components/Products.jsx
+++ b/src/view/Landing/components/Products.jsx
@@ -1,33 +1,82 @@
+import { getLocale, getMessages } from "next-intl/server";
import Link from "next/link";
import React from "react";
-import CardNormal from "src/components/Cards/CardNormal/page";
+import CardNormal from "src/components/Cards/CardNormal";
import ProductCarousel from "src/components/Carousel/ProductCarousel";
+import graphql from "src/utils/graphql";
-const Products = ({ products }) => {
+const gql = `
+query Products_connection($locale: I18NLocaleCode, $page: Int, $pageSize: Int,$category:String,$brand:String) {
+ products_connection(
+ pagination: { page: $page, pageSize: $pageSize }
+ locale: $locale
+ sort: ["createdAt:desc"]
+ filters: {
+ or:[
+ {brand: { slug: { eqi: $brand } }}
+ {category:{ slug: { eqi: $category } }}
+ ]
+ }
+ ) {
+ nodes {
+ title
+ documentId
+ images {
+ alternativeText
+ documentId
+ url
+ }
+ category {
+ documentId
+ title
+ slug
+ }
+ brand {
+ title
+ documentId
+ slug
+ image {
+ url
+ alternativeText
+ documentId
+ }
+ }
+ slug
+ }
+ }
+}
+`
+const getProducts = async (brand = "", category = "") => {
+ const locale = await getLocale()
+ const products = await graphql(gql, {
+ page: 1,
+ pageSize: 20,
+ locale: "en",
+ brand: brand,
+ category: category
+ })
- console.log(products)
+ return products.products_connection.nodes;
+
+}
+const Products = async () => {
+ const products1 = await getProducts("active")
+ const products2 = await getProducts("", "construction")
+
+ const t = await getMessages()
return (
-
-
-
+
-
-
p.brand.title === "active")} subtitle={""} title={"Active Products"} />
-
+
-
-
p.brand.title === "savin")} subtitle={""} title={"Savin Products"} />
-
+
- {/*
+ {/*
{products?.map((product, index) => (
@@ -35,7 +84,7 @@ const Products = ({ products }) => {
))}
*/}
- {/*
+ {/*
*/}
-
+
);
};
diff --git a/src/view/Landing/components/Sides.jsx b/src/view/Landing/components/Sides.jsx
index 3760d11..ffe561a 100644
--- a/src/view/Landing/components/Sides.jsx
+++ b/src/view/Landing/components/Sides.jsx
@@ -1,6 +1,7 @@
import React from 'react';
import { ShoppingCart, Building2 } from 'lucide-react'; // Assuming you're using lucide-react for icons
import { useTranslations } from 'next-intl';
+import Link from 'next/link';
const Sides = () => {
@@ -13,7 +14,7 @@ const Sides = () => {
{/* First Card */}
-
+
{t("fmcg.title")}
@@ -24,10 +25,10 @@ const Sides = () => {
{t("fmcg.description")}
-
+
{/* Second Card */}
-
+
{t("construction.title")}
@@ -38,7 +39,7 @@ const Sides = () => {
{t("construction.description")}
-
+
diff --git a/src/view/Landing/index.jsx b/src/view/Landing/index.jsx
index 8c1fdcd..7b4c736 100644
--- a/src/view/Landing/index.jsx
+++ b/src/view/Landing/index.jsx
@@ -7,37 +7,6 @@ import graphql from "src/utils/graphql";
import CounterDetail from "./components/CounterDetail";
import { getLocale } from "next-intl/server";
-const gql = `
-query Products_connection($locale: I18NLocaleCode, $page: Int, $pageSize: Int) {
- products_connection(
- pagination: { page: $page, pageSize: $pageSize }
- locale: $locale,
- sort: ["createdAt:asc"]
- ) {
- nodes {
- title
- documentId
- images {
- alternativeText
- documentId
- url
- }
- category {
- documentId
- title
- slug
- }
- brand {
- title
- documentId
- slug
- }
- slug
- }
- }
-}
-
-`
const gql_stats = `
query Stats($locale:I18NLocaleCode) {
@@ -52,8 +21,8 @@ query Stats($locale:I18NLocaleCode) {
const getStats = async () => {
- const locale =await getLocale()
- console.log("locale",locale)
+ const locale = await getLocale()
+ console.log("locale", locale)
const stats = await graphql(gql_stats, {
locale: locale
})
@@ -61,33 +30,23 @@ const getStats = async () => {
return stats.stats
}
-const getProducts = async () => {
- const locale =await getLocale()
- const products = await graphql(gql, {
- page: 1,
- pageSize: 20,
- locale:locale
- })
- return products.products_connection.nodes;
-
-}
const Landing = async () => {
- const products = await getProducts()
+
const stats = await getStats()
return (
{" "}
-
+
{/*
*/}
-
+
{/*
*/}
-
+
);
};
diff --git a/src/view/Products/index.jsx b/src/view/Products/index.jsx
deleted file mode 100644
index 783da49..0000000
--- a/src/view/Products/index.jsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import React from "react";
-import test from "../../assets/images/product/1.png";
-import Navbar from "src/components/NavBar";
-import Image from "next/image";
-import GalleryBox from "src/components/GalleryBox";
-import Footer from "../Landing/components/Footer";
-
-const Product = ({ data }) => {
- const testDataCk =
- "
Hydrating Cream
A deeply moisturizing cream that keeps your skin hydrated all day long. Formulated with natural ingredients, this cream penetrates deep into the skin, providing long-lasting moisture and nourishment.
Product Features
- Deep Hydration: Keeps skin hydrated for 24 hours
- Lightweight Formula: Absorbs quickly without greasy residue
- Rich in Vitamins: Contains Vitamin E and Aloe Vera
- Dermatologically Tested: Safe for all skin types
- Paraben-Free: No harmful chemicals
Why Choose Hydrating Cream?
Our Hydrating Cream is enriched with the best natural ingredients to provide long-lasting hydration. Perfect for dry, sensitive, and combination skin.
“This is the best moisturizer I’ve ever used! My skin feels soft and hydrated all day.” - Customer Review
Directions for Use
Apply a small amount to clean skin and massage gently until fully absorbed. Use in the morning and evening for best results.
Customer Reviews
★★★★★ - Amazing! I love how light yet moisturizing this cream is.
★★★★★ - Highly Recommended My skin has never felt better!
★★★★☆ - Great Product Works well but I wish it came in a larger size.
FAQs
- Is this suitable for sensitive skin? Yes! It is dermatologically tested and safe for all skin types.
- Can I use this under makeup? Absolutely! It absorbs quickly and works well as a base.
- Does this have SPF? No, but it can be layered with sunscreen.
Order Now
Get your Hydrating Cream today and experience the difference! Available exclusively on our official store.
";
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
{data.englishName}
-
{data.englishName}
-
-
-
-
-
-
-
- {data?.description}
-
-
-
-
-
- ${data.cost.toLocaleString()}
-
-
-
-
-
-
-
-
- Property |
- Value |
-
-
-
-
- Brand |
- Nature's Essence |
-
-
- Volume |
- 250ml |
-
-
- Ingredients |
-
-
- - Aloe Vera
- - Chamomile
- - Tea Tree Oil
- - Rosemary Extract
-
- |
-
-
-
- Category |
- Hair Care |
-
-
- For Hair Type |
- All Hair Types |
-
-
-
-
-
-
-
- >
- );
-};
-
-export default Product;
diff --git a/tailwind.config.mjs b/tailwind.config.mjs
index 0484ea7..ba2d546 100644
--- a/tailwind.config.mjs
+++ b/tailwind.config.mjs
@@ -8,6 +8,10 @@ export default {
],
theme: {
extend: {
+ fontFamily:{
+ tajawal: ['var(--font-almarai)', 'sans-serif'],
+ roboto: ['var(--font-rubik)', 'sans-serif'],
+ },
colors: {
backgroundPrimary: {
100: "#FFFBE6",