Files
reui-blocks/blocks/incentives7.tsx
T

175 lines
5.7 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardTitle,
} from "@/components/ui/card";
import type { CarouselApi } from "@/components/ui/carousel";
import {
Carousel,
CarouselContent,
CarouselItem,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
type Incentive = {
title: string;
icon?: string;
text: string;
};
type IncentivesSection = {
list: Incentive[];
overline: string;
text: {
strong: string;
regular: string;
};
cta: {
link: string;
text: string;
};
};
interface Incentives7Props extends IncentivesSection {
className?: string;
}
const INCENTIVES_SECTION: IncentivesSection = {
overline: "درباره ما",
text: {
strong: "برای عملکرد طراحی شده، برای راحتی ساخته شده و برای ماندگاری ",
regular:
"لباس‌های ما با هر قدم، هر حرکت و هر روز استراحت همراهتانند. میانبر نیست؛ فقط پارچه‌های پیشرفته و برش استثنایی.",
},
cta: {
link: "#",
text: "بیشتر درباره ما",
},
list: [
{
icon: "/block-media/shadcnblocks/block/block-1.svg",
title: "طراحی دوستدار محیط زیست",
text: "با پارچه‌های سازگار با محیط زیست ساخته شده برای عملکرد برتر و کاهش اثر زیست‌محیطی.",
},
{
icon: "/block-media/shadcnblocks/block/block-2.svg",
title: "پرداخت امن",
text: "اطلاعات شما با پرداخت رمزنگاری‌شده محافظت می‌شود؛ تراکنش‌هایی مطمئن و بی‌دردسر.",
},
{
icon: "/block-media/shadcnblocks/block/block-3.svg",
title: "مرجوعی آسان",
text: "حس مناسب نبود؟ تا ۳۰ روز، تعویض یا مرجوعی رایگان داشته باشید.",
},
{
icon: "/block-media/shadcnblocks/block/block-4.svg",
title: "ارسال سراسری",
text: "هر جا که تمرین می‌کنید، لباس‌های ورزشی باکیفیت را تا درب منزل تحویل می‌گیرید.",
},
],
};
const Incentives7 = ({
list = INCENTIVES_SECTION.list,
overline = INCENTIVES_SECTION.overline,
text = INCENTIVES_SECTION.text,
cta = INCENTIVES_SECTION.cta,
className,
}: Incentives7Props) => {
const [current, setCurrent] = useState(0);
const [api, setApi] = useState<CarouselApi>();
useEffect(() => {
if (!api) return;
const updateCurrent = (api: CarouselApi) => {
setCurrent(api?.selectedScrollSnap() ?? 0);
};
updateCurrent(api);
api.on("reInit", updateCurrent).on("select", updateCurrent);
return () => {
api.off("reInit", updateCurrent).off("select", updateCurrent);
};
}, [api]);
return (
<section dir="rtl" lang="fa" className={cn("overflow-hidden py-32", className)}>
<div className="container">
<div className="grid grid-cols-1 justify-between gap-16 lg:grid-cols-2">
<div className="flex h-full flex-col justify-between gap-8">
<div className="space-y-4 text-start">
<h2 className="leading-normal font-medium">{overline}</h2>
<p className="text-xl font-medium sm:text-xl xl:text-3xl">
<strong>{text.strong}</strong>
{text.regular}
</p>
</div>
<div>
<Button size="lg" className="max-sm:w-full" asChild>
<a href={cta.link}>{cta.text}</a>
</Button>
</div>
</div>
<div className="space-y-4">
<Carousel
opts={{
breakpoints: {
"(min-width: 640px)": {
active: false,
},
},
direction: "rtl",
}}
setApi={setApi}
className="[&>div]:overflow-visible"
>
<CarouselContent className="sm:grid sm:grid-cols-2 sm:gap-x-6 sm:gap-y-16">
{list.map((item, index) => (
<CarouselItem key={index}>
<Card className="border-none bg-muted p-5 shadow-none sm:bg-background sm:p-0">
<CardContent className="space-y-10 p-0">
<img
className="size-11"
src={item.icon}
alt={item.title}
/>
<div className="max-w-110 space-y-1 text-start">
<CardTitle className="text-lg font-medium xl:text-xl">
{item.title}
</CardTitle>
<CardDescription className="text-sm text-balance xl:text-base">
{item.text}
</CardDescription>
</div>
</CardContent>
</Card>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
<div className="relative h-px w-full overflow-hidden bg-primary/30 sm:hidden">
<div
style={{
width: `${100 / list.length}%`,
transform: `translateX(-${current * 100}%)`,
}}
className="absolute end-0 z-10 h-full bg-primary transition-transform duration-300"
></div>
</div>
</div>
</div>
</div>
</section>
);
};
export { Incentives7 };