Files
reui-blocks/blocks/feature224.tsx
T
2026-08-13 20:38:45 +03:30

218 lines
7.9 KiB
TypeScript

"use client";
import type { LucideIcon } from "lucide-react";
import {
Globe,
Lock,
ShieldCheck,
SlidersHorizontal,
Sparkles,
Workflow,
} from "lucide-react";
import { startTransition, useEffect, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import type { CarouselApi } from "@/components/ui/carousel";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
interface FeatureItem {
id: string;
title: string;
label: string;
icon: LucideIcon;
description: string;
background: string;
imageAlt: string;
}
const FEATURES: FeatureItem[] = [
{
id: "natural-patterns",
title: "تریگر رویداد",
label: "فرایند هوشمند",
icon: Workflow,
description:
"با هر رویداد مثل ثبت فرم یا تغییر وضعیت، اقدام بعدی را خودکار اجرا کنید.",
background:
"/block-media/shadcnblocks/block/photos/jeremy-bishop-iEjCQtcsVPY-unsplash.jpg",
imageAlt: "سازنده گردش‌کار",
},
{
id: "natural-security",
title: "شرط هوشمند",
label: "اتوماسیون",
icon: Lock,
description:
"مسیر متفاوت برای شرایط مختلف تعریف کنید و تصمیم‌گیری را سریع‌تر کنید.",
background:
"/block-media/shadcnblocks/block/photos/ivan-bandura-hqnUYXsN5oY-unsplash.jpg",
imageAlt: "نمای اتوماسیون فرایند",
},
{
id: "ecology-safeguards",
title: "اعلان خودکار",
label: "گردش‌کار",
icon: ShieldCheck,
description:
"تیم را در لحظه از تغییر وضعیت باخبر کنید تا هیچ موردی رها نشود.",
background:
"/block-media/shadcnblocks/block/photos/sam-wermut-FiUuNWxnb3k-unsplash.jpg",
imageAlt: "لاگ اجرای خودکار",
},
{
id: "natural-communication",
title: "تأیید چندمرحله‌ای",
label: "صرفه‌جویی زمان",
icon: SlidersHorizontal,
description:
"مسیر کار را با کشیدن و رها کردن بسازید و بدون وابستگی به تیم فنی راه بیندازید.",
background:
"/block-media/shadcnblocks/block/photos/ivan-bandura-Kj2tYAl4HZg-unsplash.jpg",
imageAlt: "سازنده گردش‌کار",
},
{
id: "multilingual-ecology",
title: "لاگ اجرا",
label: "فرایند هوشمند",
icon: Globe,
description:
"با هر رویداد مثل ثبت فرم یا تغییر وضعیت، اقدام بعدی را خودکار اجرا کنید.",
background:
"/block-media/shadcnblocks/block/photos/vasilis-karkalas-LadCWrSL7X8-unsplash.jpg",
imageAlt: "نمای اتوماسیون فرایند",
},
];
interface Feature224Props {
className?: string;
}
const Feature224 = ({ className }: Feature224Props) => {
const [api, setApi] = useState<CarouselApi>();
const [current, setCurrent] = useState(0);
useEffect(() => {
if (!api) {
return;
}
startTransition(() => {
setCurrent(api.selectedScrollSnap() + 1);
});
api.on("select", () => {
startTransition(() => {
setCurrent(api.selectedScrollSnap() + 1);
});
});
}, [api]);
const goToSlide = (index: number) => {
if (api) {
api.scrollTo(index);
}
};
return (
<section
dir="rtl"
lang="fa"
className={cn("w-full min-w-0 overflow-x-hidden py-12 sm:py-20 lg:py-32", className)}
>
<div className="container min-w-0 px-4 sm:px-6">
<div className="flex w-full min-w-0 flex-col items-center justify-center gap-4">
<h2 className="mx-auto max-w-full text-center text-xl leading-none font-medium text-balance md:max-w-112.5 md:text-2xll lg:max-w-140 lg:text-2xll">
فرایندها را استاندارد و سریع کنید
</h2>
</div>
<Carousel
opts={{
align: "start",
direction: "rtl",
}}
className="w-full min-w-0 max-w-full"
setApi={setApi}
>
<CarouselContent className="pt-12 sm:pt-20">
{FEATURES.map((card) => (
<CarouselItem
key={card.id}
className="min-w-0 basis-[85%] sm:basis-1/2 lg:basis-1/3"
>
<div className="min-w-0 p-1">
<Card className="min-w-0 border-0 py-0 shadow-none dark:bg-background">
<CardContent className="flex min-w-0 flex-col p-0">
<div
style={{ backgroundImage: `url("${card.background}")` }}
className="relative flex aspect-[0.935802469] w-full min-w-0 flex-col items-center justify-between overflow-hidden rounded-2xl bg-cover bg-center bg-no-repeat p-4 sm:p-7"
role="img"
aria-label={card.imageAlt}
>
<div className="flex size-full flex-1" />
<div className="h-12 w-full min-w-0">
<div className="mx-auto mb-6 flex w-full max-w-full min-w-0 items-center gap-3 rounded-full bg-primary px-3 py-2.5 shadow-xl sm:mb-8 sm:max-w-60 sm:gap-4 dark:bg-background">
<div className="shrink-0">
<div className="flex -space-x-2 rtl:space-x-reverse">
<div className="flex size-7 rounded-full border border-black bg-background dark:bg-primary">
<Sparkles className="m-auto size-4 dark:text-background" />
</div>
<div className="flex size-7 rounded-full border border-black bg-background dark:bg-primary">
<card.icon className="m-auto size-4 dark:text-background" />
</div>
</div>
</div>
<div className="min-w-0 text-sm font-medium text-white">
{card.label}
</div>
</div>
</div>
</div>
<div className="flex w-full min-w-0 flex-col gap-1 pt-6 text-start">
<h3 className="text-lg font-medium text-balance text-foreground sm:text-xl">
{card.title}
</h3>
<p className="text-sm text-pretty text-muted-foreground">
{card.description}
</p>
</div>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent> <div className="mt-8 hidden items-center justify-center gap-4 md:flex">
<CarouselPrevious className="static size-12 translate-y-0 rtl:rotate-180" />
<CarouselNext className="static size-12 translate-y-0 rtl:rotate-180" />
</div>
<div className="mt-6 flex w-full min-w-0 items-center gap-2 md:hidden">
{Array.from({ length: FEATURES.length }).map((_, i) => (
<button
type="button"
onClick={() => goToSlide(i % FEATURES.length)}
key={`carousel-btn-${i}`}
aria-label={`رفتن به اسلاید ${i + 1}`}
className="h-4 w-full"
>
<div
className={cn(
"my-auto h-1 w-full rounded-full",
current === i + 1 ? "bg-primary" : "bg-muted",
)}
/>
</button>
))}
</div>
</Carousel>
</div>
</section>
);
};
export { Feature224 };