182 lines
5.9 KiB
TypeScript
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 };
|