Files
reui-blocks/blocks/gallery9.tsx
T

182 lines
5.9 KiB
TypeScript

"use client";
import { ArrowLeft, ArrowRight, Code, GitBranch, Sparkle } from "lucide-react";
import { startTransition, useEffect, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import type { CarouselApi } from "@/components/ui/carousel";
import {
Carousel,
CarouselContent,
CarouselItem,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
const sections = [
{
img: "/block-media/shadcnblocks/block/placeholder-1.svg",
title: "طراحی",
text: "رابط و تجربه کاربری را با تیم طراحی ما از ایده اولیه تا نمونه نهایی بسازید.",
logo: <Code className="size-5" />,
},
{
img: "/block-media/shadcnblocks/block/placeholder-2.svg",
title: "توسعه",
text: "پیاده‌سازی سریع و قابل اعتماد با زیرساخت پیشرفته توسعه و استانداردهای تیم.",
logo: <GitBranch className="size-5" />,
},
{
img: "/block-media/shadcnblocks/block/placeholder-3.svg",
title: "انتشار",
text: "با اطمینان محصول خود را منتشر کنید و به کاربران واقعی تحویل دهید.",
logo: <Sparkle className="size-5" />,
},
];
interface Gallery9Props {
className?: string;
}
const Gallery9 = ({ className }: Gallery9Props) => {
const [api, setApi] = useState<CarouselApi>();
const [current, setCurrent] = useState(1);
const [canScrollPrev, setCanScrollPrev] = useState(false);
const [canScrollNext, setCanScrollNext] = useState(false);
useEffect(() => {
if (!api) return;
const updateCurrent = () => {
startTransition(() => {
setCurrent(api.selectedScrollSnap() + 1);
setCanScrollPrev(api.canScrollPrev());
setCanScrollNext(api.canScrollNext());
});
};
startTransition(() => {
setCurrent(api.selectedScrollSnap() + 1);
setCanScrollPrev(api.canScrollPrev());
setCanScrollNext(api.canScrollNext());
});
api.on("select", updateCurrent);
return () => {
api.off("select", updateCurrent);
};
}, [api]);
useEffect(() => {
if (!api) {
return;
}
api.reInit();
}, [api]);
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container">
<div className="mb-20 flex flex-col items-center justify-center gap-8 text-center">
<h1 className="text-xl">
زمان بستن حساب‌هایتان را کوتاه کنید
</h1>
<Badge
variant="secondary"
className="px-5 py-2 text-base font-normal"
>
راهکاری یکپارچه برای تیم‌های مالی و عملیات
</Badge>
</div>
<Carousel
dir="rtl"
setApi={setApi}
opts={{
align: "start",
direction: "rtl",
}}
className="flex flex-col gap-10"
>
<CarouselContent className="-ms-4 me-0">
{sections.map((item, index) => (
<CarouselItem
className="h-full w-full basis-full ps-4 pe-0"
key={index}
>
<img
src={item.img}
alt={item.title}
className="aspect-square h-full w-full object-cover md:aspect-[2]"
/>
<div className="mt-8 flex cursor-pointer flex-col gap-2 text-start md:hidden">
<div>{item.logo}</div>
<div className="text-lg font-medium">{item.title}</div>
<div className="text-lg text-muted-foreground">
{item.text}
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<div className="mb-8 hidden justify-between gap-8 text-start md:flex">
{sections.map((section, index) => (
<div
key={index}
onClick={() => api?.scrollTo(index)}
className="flex cursor-pointer flex-col gap-2"
>
<div>{section.logo}</div>
<div className="text-lg font-medium">{section.title}</div>
<div
className={cn(
"text-lg hover:text-muted-foreground",
index + 1 === current
? "text-muted-foreground"
: "text-muted-foreground/50",
)}
>
{section.text}
</div>
</div>
))}
</div>
<div className="flex items-center gap-8">
<div>
{current.toLocaleString("fa-IR")} /{" "}
{sections.length.toLocaleString("fa-IR")}
</div>
<div className="flex items-center justify-start gap-2">
<Button
type="button"
size="icon"
variant="outline"
className="static translate-none touch-manipulation"
disabled={!canScrollPrev}
onClick={() => api?.scrollPrev()}
>
<ArrowRight className="size-5" />
<span className="sr-only">اسلاید قبلی</span>
</Button>
<Button
type="button"
size="icon"
variant="outline"
className="static translate-none touch-manipulation"
disabled={!canScrollNext}
onClick={() => api?.scrollNext()}
>
<ArrowLeft className="size-5" />
<span className="sr-only">اسلاید بعدی</span>
</Button>
</div>
</div>
</Carousel>
</div>
</section>
);
};
export { Gallery9 };