Files
reui-blocks/blocks/gallery23.tsx
T

181 lines
6.3 KiB
TypeScript

"use client";
import { AnimatePresence, motion } from "framer-motion";
import { ArrowRight, ShoppingCart } from "lucide-react";
import type { SVGProps } from "react";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
const IMAGES = [
{
id: 1,
src: "/block-media/shadcnblocks/block/lummi/random5.jpeg",
alt: "لباس‌های مجموعه تابستانه",
title: "مجموعه",
titleEmphasis: "تابستانه",
code: "#۰۰۳۱",
},
{
id: 2,
src: "/block-media/shadcnblocks/block/lummi/random11.jpeg",
alt: "صحنه جشنواره موسیقی",
title: "جشنواره",
titleEmphasis: "موسیقی",
code: "#۰۰۳۰",
},
{
id: 3,
src: "/block-media/shadcnblocks/block/lummi/random13.jpeg",
alt: "لباس‌های ویژه فصل زمستان",
title: "ویژه",
titleEmphasis: "زمستان",
code: "#۰۰۳۲",
},
{
id: 4,
src: "/block-media/shadcnblocks/block/lummi/random1.jpeg",
alt: "لباس‌های نسخه بهاری",
title: "نسخه",
titleEmphasis: "بهاری",
code: "#۰۰۳۳",
},
{
id: 5,
src: "/block-media/shadcnblocks/block/lummi/random2.jpeg",
alt: "لباس‌های کلکسیون بهار",
title: "کلکسیون",
titleEmphasis: "بهار",
code: "#۰۰۳۴",
},
];
interface Gallery23Props {
className?: string;
}
const Gallery23 = ({ className }: Gallery23Props) => {
const [activeImage, setActiveImage] = useState(0);
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container overflow-hidden p-10">
<div className="relative flex flex-col items-center justify-between gap-12 border bg-muted p-10 py-20 md:flex-row">
<DashedBorderV className="absolute -top-10 -start-px h-[150%] w-px" />
<DashedBorderH className="absolute -top-px -start-10 h-px w-[150%]" />
<DashedBorderV className="absolute -top-10 -end-px h-[150%] w-px" />
<DashedBorderH className="absolute -bottom-px -start-12 h-px w-[150%]" />
<div className="flex h-142 flex-col justify-center text-start">
<h1 className="font-calSans max-w-lg text-2xll">
به حرف‌ها اعتماد نکنید؛ به نتایج ما اعتماد کنید
</h1>
<p className="text-md mt-10 max-w-md opacity-55">
با تمرکز بر کیفیت، خلاقیت و جزئیات، محصولاتی می‌سازیم که تجربه
واقعی مشتریان را بهبود می‌دهد و ارزش پایدار ایجاد می‌کند.
</p>
<Button
variant="default"
className="group mt-10 flex w-fit items-center justify-center gap-2 rounded-full tracking-tight"
>
تماس با ما
<ArrowRight className="size-4 -rotate-45 transition-all ease-out group-hover:rotate-0 rtl:rotate-[135deg] rtl:group-hover:rotate-0" />
</Button>
</div>
<div className="flex flex-col items-center justify-center gap-1">
{IMAGES.map((image, index) => (
<motion.div
key={image.id}
className="group relative cursor-pointer overflow-hidden rounded-4xl border"
initial={{ height: "2.5rem", width: "24rem" }}
animate={{
height: activeImage === index ? "24rem" : "2.5rem",
}}
transition={{ duration: 0.3, ease: "easeInOut" }}
onClick={() => setActiveImage(index)}
onHoverStart={() => setActiveImage(index)}
>
<AnimatePresence>
{activeImage === index && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="absolute h-full w-full bg-gradient-to-t from-black/80 to-transparent"
/>
)}
</AnimatePresence>
<AnimatePresence>
{activeImage === index && (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 20 }}
className="absolute flex h-full w-full flex-col items-start justify-end px-4 pb-5 text-start"
>
<p className="text-xs text-white/50">{image.code}</p>
<h3 className="text-3xl font-bold text-white">
{image.title}
<span className="font-playfair italic">
{" "}
{image.titleEmphasis}
</span>
</h3>
<Button
variant="secondary"
className="mt-3 flex w-fit items-center justify-center gap-2 rounded-full text-xs"
>
افزودن به سبد
<ShoppingCart size={14} />
</Button>
</motion.div>
)}
</AnimatePresence>
<img
src={image.src}
className="size-full object-cover"
alt={image.alt}
/>
</motion.div>
))}
</div>
</div>
</div>
</section>
);
};
const DashedBorderH = (props: SVGProps<SVGSVGElement>) => {
return (
<svg {...props} fill="none" xmlns="http://www.w3.org/2000/svg">
<line
opacity="0.2"
x1="1571.5"
y1="0.570312"
x2="0.683594"
y2="0.570271"
stroke="black"
strokeDasharray="5 5"
/>
</svg>
);
};
const DashedBorderV = (props: SVGProps<SVGSVGElement>) => {
return (
<svg {...props} fill="none" xmlns="http://www.w3.org/2000/svg">
<line
opacity="0.2"
x1="0.631348"
y1="0.208984"
x2="0.631311"
y2="828.348"
stroke="black"
strokeDasharray="5 5"
/>
</svg>
);
};
export { Gallery23 };