Files
arjmand-pharmacy/components/home/Hero.tsx
T
Alireza HassaniandCursor 66e604c426 Connect the storefront to Meshkee catalog, blogs, and static image slots.
Wire homepage specials, product/blog pages, instant search, and the customer portal so the live pharmacy site can be managed from the dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 23:51:41 +03:30

100 lines
3.5 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { Container } from "@/components/Container";
import { SlotMedia } from "@/components/SlotMedia";
import { parseAspectRatio } from "@/lib/static-images";
import type { SlotMediaItem } from "@/lib/static-images";
type HeroProps = {
slides: SlotMediaItem[];
banners: SlotMediaItem[];
sliderAspectRatio?: string;
bannerAspectRatio?: string;
};
export function Hero({ slides = [], banners = [], sliderAspectRatio, bannerAspectRatio }: HeroProps) {
const [index, setIndex] = useState(0);
const sliderRatio = parseAspectRatio(sliderAspectRatio);
useEffect(() => {
if (slides.length <= 1) return;
const timer = setInterval(() => {
setIndex((current) => (current + 1) % slides.length);
}, 5000);
return () => clearInterval(timer);
}, [slides.length]);
const go = (direction: number) => {
if (slides.length <= 1) return;
setIndex((current) => (current + direction + slides.length) % slides.length);
};
return (
<section className="pt-5">
<Container>
<div
className={`relative overflow-hidden rounded-2xl bg-sky ${sliderRatio ? "" : "aspect-[16/6] sm:aspect-[16/5.2]"}`}
style={sliderRatio ? { aspectRatio: sliderRatio } : undefined}
>
{slides.map((slide, i) => (
<SlotMedia
key={slide.id}
fill
src={slide.image}
href={slide.href}
fallbackSrc={slide.fallbackSrc}
className={`transition-opacity duration-500 ${i === index ? "opacity-100" : "pointer-events-none opacity-0"}`}
/>
))}
{slides.length > 1 ? (
<>
<button
type="button"
onClick={() => go(-1)}
className="absolute top-1/2 right-3 z-10 grid size-9 -translate-y-1/2 place-items-center rounded-full bg-white/90 text-navy"
aria-label="اسلاید قبلی"
>
<ChevronRight className="size-5" />
</button>
<button
type="button"
onClick={() => go(1)}
className="absolute top-1/2 left-3 z-10 grid size-9 -translate-y-1/2 place-items-center rounded-full bg-white/90 text-navy"
aria-label="اسلاید بعدی"
>
<ChevronLeft className="size-5" />
</button>
<div className="absolute bottom-3 left-1/2 z-10 flex -translate-x-1/2 gap-1.5">
{slides.map((slide, i) => (
<button
key={slide.id}
type="button"
onClick={() => setIndex(i)}
className={`h-1.5 rounded-full transition-all ${i === index ? "w-6 bg-primary" : "w-2 bg-white/80"}`}
aria-label={`اسلاید ${i + 1}`}
/>
))}
</div>
</>
) : null}
</div>
<div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
{banners.map((banner) => (
<SlotMedia
key={banner.id}
src={banner.image}
href={banner.href}
fallbackSrc={banner.fallbackSrc}
aspectRatio={bannerAspectRatio}
className={`overflow-hidden rounded-xl bg-sky ${!bannerAspectRatio ? "h-[92px] sm:h-[110px]" : ""}`}
/>
))}
</div>
</Container>
</section>
);
}