Build the Salar Store storefront and connect products, blogs, and home specials to the Meshkee API.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-16 01:36:29 +03:30
co-authored by Cursor
parent 2783305f07
commit 7d26eaa838
113 changed files with 3269 additions and 96 deletions
+106
View File
@@ -0,0 +1,106 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import { heroSides, heroSlides } from "@/lib/data";
const overlayStyle = {
background:
"linear-gradient(to left, rgba(0,0,0,0.88) 0%, rgba(0,0,0,0.72) 42%, rgba(0,0,0,0.28) 72%, transparent 100%)",
};
export function HeroSlider() {
const [index, setIndex] = useState(0);
const [paused, setPaused] = useState(false);
useEffect(() => {
if (paused) return;
const id = window.setInterval(() => {
setIndex((current) => (current + 1) % heroSlides.length);
}, 5000);
return () => window.clearInterval(id);
}, [paused]);
return (
<section className="container-site pt-5">
<div
className="relative overflow-hidden rounded-2xl aspect-[21/8] min-h-[240px] md:min-h-[360px]"
onMouseEnter={() => setPaused(true)}
onMouseLeave={() => setPaused(false)}
>
{heroSlides.map((slide, i) => (
<div
key={slide.title}
aria-hidden={i !== index}
className={`absolute inset-0 transition-opacity duration-700 ease-in-out ${
i === index ? "opacity-100 z-[1]" : "opacity-0 z-0 pointer-events-none"
}`}
>
<Image
src={slide.image}
alt=""
fill
sizes="1200px"
priority={i === 0}
className="object-cover object-[28%_center]"
/>
</div>
))}
<div className="pointer-events-none absolute inset-y-0 right-0 z-[2] w-[58%] md:w-[46%]" style={overlayStyle} />
{heroSlides.map((slide, i) => (
<div
key={`${slide.title}-copy`}
className={`absolute z-[3] right-6 md:right-12 top-1/2 -translate-y-1/2 max-w-[230px] sm:max-w-sm text-white text-right transition-opacity duration-700 ${
i === index ? "opacity-100" : "opacity-0 pointer-events-none"
}`}
>
<p className="text-2xl sm:text-3xl md:text-4xl font-extrabold leading-none">{slide.title}</p>
<p dir="ltr" className="mt-0.5 font-carter text-[10px] sm:text-xs md:text-sm tracking-[0.42em] text-brand uppercase">
{slide.english}
</p>
<p className="mt-1 text-lg sm:text-xl md:text-2xl font-medium leading-tight text-white/90">{slide.subtitle}</p>
<Link
href={slide.href}
className="mt-5 inline-flex items-center justify-center rounded-lg bg-brand px-5 py-2.5 text-sm sm:text-base font-bold text-white hover:bg-[#e01e1e]"
>
{slide.button}
</Link>
</div>
))}
<div className="absolute bottom-4 left-1/2 z-[4] -translate-x-1/2 flex gap-2">
{heroSlides.map((slide, i) => (
<button
key={slide.title}
type="button"
aria-label={`اسلاید ${i + 1}`}
onClick={() => setIndex(i)}
className={`h-2.5 rounded-full transition-all ${i === index ? "w-7 bg-brand" : "w-2.5 bg-white/80"}`}
/>
))}
</div>
</div>
<div className="mt-4 grid grid-cols-1 sm:grid-cols-2 gap-4">
{heroSides.map((side) => (
<Link key={side.title} href={side.href} className="relative block overflow-hidden rounded-2xl">
<div className="relative aspect-[21/8] sm:aspect-[2.6/1]">
<Image src={side.image} alt="" fill sizes="600px" className="object-cover object-[28%_center]" />
</div>
<div className="pointer-events-none absolute inset-y-0 right-0 w-[62%] md:w-[52%]" style={overlayStyle} />
<div className="absolute right-4 md:right-6 top-1/2 -translate-y-1/2 max-w-[180px] md:max-w-[220px] text-white text-right">
<p className="text-base md:text-xl font-extrabold leading-none">{side.title}</p>
<p dir="ltr" className="mt-0.5 font-carter text-[9px] md:text-[10px] tracking-[0.4em] text-brand uppercase">
{side.english}
</p>
<p className="mt-0.5 text-sm md:text-base leading-tight text-white/90">{side.subtitle}</p>
</div>
</Link>
))}
</div>
</section>
);
}