fix
parent
58051d3fcf
commit
d6e2dbf8da
|
@ -1,4 +1,13 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
const nextConfig = {
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "storage.adhorizonintl.com",
|
||||
}
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"embla-carousel-autoplay": "^8.5.2",
|
||||
"embla-carousel-react": "^8.5.2",
|
||||
"framer-motion": "^12.4.2",
|
||||
"lucide-react": "^0.475.0",
|
||||
|
|
|
@ -5,6 +5,9 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
embla-carousel-autoplay:
|
||||
specifier: ^8.5.2
|
||||
version: 8.5.2(embla-carousel@8.5.2)
|
||||
embla-carousel-react:
|
||||
specifier: ^8.5.2
|
||||
version: 8.5.2(react@19.0.0)
|
||||
|
@ -1105,6 +1108,14 @@ packages:
|
|||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
dev: true
|
||||
|
||||
/embla-carousel-autoplay@8.5.2(embla-carousel@8.5.2):
|
||||
resolution: {integrity: sha512-27emJ0px3q/c0kCHCjwRrEbYcyYUPfGO3g5IBWF1i7714TTzE6L9P81V6PHLoSMAKJ1aHoT2e7YFOsuFKCbyag==}
|
||||
peerDependencies:
|
||||
embla-carousel: 8.5.2
|
||||
dependencies:
|
||||
embla-carousel: 8.5.2
|
||||
dev: false
|
||||
|
||||
/embla-carousel-react@8.5.2(react@19.0.0):
|
||||
resolution: {integrity: sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==}
|
||||
peerDependencies:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"use client";
|
||||
|
||||
import graphql from "src/utils/graphql";
|
||||
import Landing from "src/view/Landing";
|
||||
|
||||
export default function Home() {
|
||||
|
||||
export default async function Home() {
|
||||
return <Landing />;
|
||||
}
|
||||
|
|
|
@ -1,77 +1,62 @@
|
|||
"use client";
|
||||
import React, { useContext } from "react";
|
||||
import logo from "../../../assets/images/logo.png";
|
||||
|
||||
import Image from "next/image";
|
||||
import test1 from "../../../assets/images/product/1.png";
|
||||
import test2 from "../../../assets/images/product/2.png";
|
||||
import test3 from "../../../assets/images/product/3.png";
|
||||
import test4 from "../../../assets/images/product/4.png";
|
||||
import Link from "next/link";
|
||||
|
||||
const CardNormal = ({ data, priority }) => {
|
||||
const CardNormal = ({ product, priority }) => {
|
||||
return (
|
||||
<div className="group">
|
||||
{" "}
|
||||
<>
|
||||
<Link href={`/products/${data.id}`} onClick={(e)=>e.preventDefault()} >
|
||||
<Link href={`/products/${product.slug}`} onClick={(e) => e.preventDefault()} >
|
||||
<div
|
||||
className={` tr03 py-2 overflow-hidden xs:h-[270px] lg:h-[270px] border border-gray-200 ${1 == 1 ? "bg-white rounded-xl rounded-tl-[40px]" : " opacity-70"
|
||||
className={`tr03 py-2 overflow-hidden xs:h-[270px] lg:h-[270px] border border-gray-200 ${1 == 1 ? "bg-white rounded-xl rounded-tl-[40px]" : " opacity-70"
|
||||
}`}
|
||||
>
|
||||
|
||||
|
||||
<div className="w-full h-fit flex justify-center ">
|
||||
{!!data.mainImage ? (
|
||||
|
||||
<div className="w-full h-full flex justify-center relative p-2 ">
|
||||
{!!product?.images?.[0]?.url ? (
|
||||
<Image
|
||||
src={
|
||||
data.mainImage == "1"
|
||||
? test1
|
||||
: data.mainImage == "2"
|
||||
? test2
|
||||
: data.mainImage == "3"
|
||||
? test3
|
||||
: data.mainImage == "4"
|
||||
? test4
|
||||
: test1
|
||||
product?.images?.[0]?.url
|
||||
}
|
||||
width={200}
|
||||
height={200}
|
||||
className="xs:!w-[110px] lg:!w-[130px] mx-auto"
|
||||
fill
|
||||
className="object-contain"
|
||||
priority={!!priority}
|
||||
alt={`${data.persianName} - ${data.englishName}`}
|
||||
alt={`${product?.images?.[0]?.alternativeText}`}
|
||||
/>
|
||||
) : (
|
||||
<div className="xs:!w-[85px] lg:!w-[85px] h-[90px] xs:mt-5 lg:mt-10 ">
|
||||
<Image
|
||||
src={logo}
|
||||
className="xs:!w-[70px] lg:!w-[70px] mx-auto opacity-25 mt-5"
|
||||
alt="وسمه"
|
||||
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="p-3 text-left">
|
||||
<p className="mb-0 text-[16px] max-h-[44px] overflow-hidden font-bold ">
|
||||
{data.englishName}
|
||||
</p>
|
||||
|
||||
<p className="mb-0 text-[13px] text-gray-600 mt-2">
|
||||
{data.description}
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</>
|
||||
<div className="relative">
|
||||
<div className="absolute w-full bottom-0 ">
|
||||
<div className="bg-gray-100 rounded-t-3xl flex ltr mt-2 border border-gray-100 p-2 items-center">
|
||||
<div className="flex w-full">
|
||||
<div className="bg-gray-100 rounded-t-3xl ltr mt-2 border border-gray-100 p-2 flex flex-col gap-1">
|
||||
<p className="mb-0 text-base text-left">
|
||||
{product.title}
|
||||
</p>
|
||||
{/* <div className="flex w-full">
|
||||
<p className="mb-0 text-base ">${data.cost.toLocaleString()}</p>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="w-full text-right rounded-full pr-2">
|
||||
<p className="mb-0 text-base rounded-lg underline">Detail</p>
|
||||
<p className="mb-0 text-sm rounded-lg text-left">{product.category.title} - {product.brand.title}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,57 +1,69 @@
|
|||
"use client"
|
||||
import { useCallback } from "react"
|
||||
|
||||
import useEmblaCarousel from "embla-carousel-react"
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react"
|
||||
import { useCallback } from "react"
|
||||
import CardNormal from "../Cards/CardNormal/page"
|
||||
import Autoplay from "embla-carousel-autoplay"
|
||||
|
||||
export function ProductCarouselSection({products}) {
|
||||
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: false, align: "start" })
|
||||
|
||||
const scrollPrev = useCallback(() => {
|
||||
if (emblaApi) emblaApi.scrollPrev()
|
||||
}, [emblaApi])
|
||||
|
||||
const scrollNext = useCallback(() => {
|
||||
if (emblaApi) emblaApi.scrollNext()
|
||||
}, [emblaApi])
|
||||
|
||||
return (
|
||||
<section className="py-12 px-4 md:px-6 lg:px-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h2 className="text-3xl font-bold text-center mb-2">Our Featured Products</h2>
|
||||
<p className="text-xl text-center text-gray-600 mb-8">Discover our handpicked selection of top-quality items</p>
|
||||
|
||||
<div className="relative">
|
||||
<div className="overflow-hidden" ref={emblaRef}>
|
||||
<div className="flex">
|
||||
{products.map((product) => (
|
||||
<div
|
||||
key={product.id}
|
||||
className="flex-[0_0_100%] min-w-0 sm:flex-[0_0_50%] md:flex-[0_0_33.33%] lg:flex-[0_0_25%] pl-4"
|
||||
>
|
||||
<CardNormal {...product} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="absolute top-1/2 left-4 transform -translate-y-1/2"
|
||||
onClick={scrollPrev}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="absolute top-1/2 right-4 transform -translate-y-1/2"
|
||||
onClick={scrollNext}
|
||||
>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
export default function ProductCarousel({ title, subtitle, products }) {
|
||||
|
||||
const [emblaRef, emblaApi] = useEmblaCarousel(
|
||||
{ loop: true, align: "start" },
|
||||
[
|
||||
Autoplay({ delay: 3000, stopOnInteraction: true }),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
const scrollPrev = useCallback(() => {
|
||||
if (emblaApi) emblaApi.scrollPrev()
|
||||
}, [emblaApi])
|
||||
|
||||
const scrollNext = useCallback(() => {
|
||||
if (emblaApi) emblaApi.scrollNext()
|
||||
}, [emblaApi])
|
||||
|
||||
return (
|
||||
<section className="py-12 px-4 md:px-6 lg:px-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h2 className="text-3xl font-bold text-center mb-2">{title}</h2>
|
||||
<p className="text-xl text-center text-gray-600 mb-8">{subtitle}</p>
|
||||
|
||||
<div className="relative">
|
||||
<div className="overflow-hidden" ref={emblaRef}>
|
||||
<div className="flex">
|
||||
{products.map((product) => (
|
||||
<div
|
||||
key={product.id}
|
||||
className="flex-[0_0_100%] min-w-0 sm:flex-[0_0_50%] md:flex-[0_0_33.33%] lg:flex-[0_0_25%] pl-4"
|
||||
>
|
||||
<CardNormal product={product} priority={true} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="absolute top-1/2 left-4 transform -translate-y-1/2 bg-gray-200 rounded-full size-4"
|
||||
onClick={scrollPrev}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="absolute top-1/2 right-4 transform -translate-y-1/2 bg-gray-200 rounded-full size-4"
|
||||
onClick={scrollNext}
|
||||
>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,207 +1,11 @@
|
|||
import Link from "next/link";
|
||||
import React from "react";
|
||||
import CardNormal from "src/components/Cards/CardNormal/page";
|
||||
import ProductCarousel from "src/components/Carousel/ProductCarousel";
|
||||
|
||||
const Products = () => {
|
||||
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",
|
||||
},
|
||||
];
|
||||
const Products = ({ products }) => {
|
||||
|
||||
console.log(products)
|
||||
return (
|
||||
<div className="my-[120px]">
|
||||
<div className="xs:px-3 md:px-10 md:container md:mx-auto mb-10">
|
||||
|
@ -210,17 +14,26 @@ const Products = () => {
|
|||
ADVANCED HORIZON SERVICES LLC Products{" "}
|
||||
</h2>
|
||||
<p className="mb-0 text-sm text-gray-400 xs:text-center lg:text-left">
|
||||
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid xs:grid-cols-2 lg:grid-cols-5 gap-5">
|
||||
{data?.map((e, index) => (
|
||||
|
||||
<div>
|
||||
<ProductCarousel products={products.filter(p => p.brand.title === "active")} subtitle={""} title={"Active Products"} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ProductCarousel products={products.filter(p => p.brand.title === "savin")} subtitle={""} title={"Savin Products"} />
|
||||
</div>
|
||||
|
||||
{/* <div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
|
||||
{products?.map((product, index) => (
|
||||
<div key={index} className="relative">
|
||||
<CardNormal data={e} priority />
|
||||
<CardNormal product={product} priority />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* <div className="flex justify-center">
|
||||
<Link href={"categories/Product-20Listing-Page"}>
|
||||
|
|
|
@ -3,17 +3,63 @@ import AboutUs from "./components/AboutUs";
|
|||
import Footer from "./components/Footer";
|
||||
import Products from "./components/Products";
|
||||
import Sides from "./components/Sides";
|
||||
import graphql from "src/utils/graphql";
|
||||
|
||||
const Landing = () => {
|
||||
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 getProducts = async () => {
|
||||
const products = await graphql(gql, {
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
locale: "en"
|
||||
})
|
||||
|
||||
return products.products_connection.nodes;
|
||||
|
||||
}
|
||||
|
||||
const Landing = async () => {
|
||||
const products = await getProducts()
|
||||
console.log(products)
|
||||
return (
|
||||
<div className=" text-center text-6xl">
|
||||
{" "}
|
||||
<Navbar theme={1} />
|
||||
{/* <HeroSection /> */}
|
||||
<AboutUs />
|
||||
<Sides/>
|
||||
<Sides />
|
||||
{/* <CounterDetail /> */}
|
||||
<Products />
|
||||
<Products products={products} />
|
||||
{/* <WhyHorizon/> */}
|
||||
<Footer />
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue