Files
reui-blocks/blocks/feature12.tsx
T

187 lines
6.2 KiB
TypeScript
Raw Normal View History

"use client";
import {
ArrowDownToLine,
ArrowUpDown,
Code,
Redo,
Repeat,
Scaling,
Scan,
} from "lucide-react";
import { useEffect, useState } from "react";
import { Badge } from "@/components/ui/badge";
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";
const slides = [
{
title: "سطح دسترسی",
description:
"گزارش سفارشی را بدون SQL بسازید و سریع منتشر کنید.",
icon: <Code className="size-4" />,
},
{
title: "تحلیل پیش‌بین",
description:
"ابعاد مختلف را بچرخانید و الگوی پنهان را پیدا کنید.",
icon: <ArrowUpDown className="size-4" />,
},
{
title: "اشتراک گزارش",
description:
"نمای اجرایی برای تصمیم‌های سریع طراحی کنید.",
icon: <Redo className="size-4" />,
},
{
title: "مدل داده",
description:
"داده پراکنده را در یک مدل واحد ساختاردهی کنید.",
icon: <ArrowDownToLine className="size-4" />,
},
{
title: "گزارش‌ساز",
description:
"گزارش سفارشی را بدون SQL بسازید و سریع منتشر کنید.",
icon: <Repeat className="size-4" />,
},
{
title: "Pivot تعاملی",
description:
"ابعاد مختلف را بچرخانید و الگوی پنهان را پیدا کنید.",
icon: <Scan className="size-4" />,
},
{
title: "داشبورد مدیریتی",
description:
"نمای اجرایی برای تصمیم‌های سریع طراحی کنید.",
icon: <Scaling className="size-4" />,
},
];
interface Feature12Props {
className?: string;
}
const Feature12 = ({ className }: Feature12Props) => {
const [api, setApi] = useState<CarouselApi>();
const [progress, setProgress] = useState(1 / slides.length);
const [currentSlide, setCurrentSlide] = useState(1);
useEffect(() => {
if (!api) {
return;
}
const updateProgress = () => {
setProgress(
Math.max(1 / slides.length, Math.min(1, api.scrollProgress())),
);
};
const updateCurrentSlide = () => {
setCurrentSlide(api.selectedScrollSnap() + 1);
};
updateProgress();
updateCurrentSlide();
api.on("scroll", updateProgress);
api.on("select", updateCurrentSlide);
api.on("reInit", updateCurrentSlide);
return () => {
api.off("scroll", updateProgress);
api.off("select", updateCurrentSlide);
api.off("reInit", updateCurrentSlide);
};
}, [api]);
return (
2026-07-26 18:44:54 +03:30
<section
dir="rtl"
lang="fa"
className={cn("w-full overflow-hidden py-32", className)}
>
<div className="container max-w-7xl min-w-0">
<div className="mb-10 flex min-w-0 flex-col items-center gap-6 md:mb-20">
<Badge variant="outline">داده سازمانی</Badge>
2026-07-26 18:44:54 +03:30
<h2 className="mb-2 max-w-full text-center text-3xl font-semibold text-balance break-words lg:text-2xll">
تصمیم استراتژیک را داده‌محور کنید
</h2>
</div>
<Carousel
2026-07-26 18:44:54 +03:30
className="w-full min-w-0"
setApi={setApi}
opts={{
align: "start",
direction: "rtl",
}}
>
2026-07-26 18:44:54 +03:30
<div className="mb-4 space-y-4 px-1 md:mb-5 lg:flex lg:items-center lg:justify-between lg:space-y-0">
<p className="w-full min-w-0 text-pretty break-words font-medium lg:flex-1 lg:pe-3">
داشبوردهای تعاملی به تیم‌ها اجازه می‌دهد سؤال جدید بپرسند بدون
اینکه هر بار به تیم داده وابسته باشند.
</p>
<div className="flex w-full min-w-0 items-center gap-2 lg:w-auto lg:shrink-0">
<div className="me-2 flex min-w-0 flex-1 items-center gap-3 text-xs text-muted-foreground lg:flex-none">
<span className="shrink-0">
{currentSlide.toLocaleString("fa-IR").padStart(2, "۰")}
</span>
2026-07-26 18:44:54 +03:30
<div className="h-[2px] min-w-0 flex-1 overflow-hidden rounded-full bg-muted lg:w-52 lg:flex-none">
<div
className="h-full origin-start bg-primary transition-transform"
style={{ transform: `scaleX(${progress})` }}
/>
</div>
2026-07-26 18:44:54 +03:30
<span className="shrink-0">
{slides.length.toLocaleString("fa-IR").padStart(2, "۰")}
</span>
</div>
<CarouselPrevious className="static translate-y-0 rtl:rotate-180" />
<CarouselNext className="static translate-y-0 rtl:rotate-180" />
</div>
</div>
<CarouselContent>
{slides.map((slide, index) => (
<CarouselItem
key={index}
2026-07-26 18:44:54 +03:30
className="min-w-0 basis-full md:basis-1/2 lg:basis-1/3"
>
2026-07-26 18:44:54 +03:30
<div className="min-w-0 p-1">
<Card className="min-w-0 overflow-hidden">
<CardContent className="flex min-w-0 flex-col justify-center p-6">
<div className="min-w-0">
<span className="mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10">
{slide.icon}
</span>
2026-07-26 18:44:54 +03:30
<p className="text-xl font-semibold break-words md:text-xl lg:text-xl">
{slide.title}
</p>
2026-07-26 18:44:54 +03:30
<p className="pt-2 text-pretty break-words text-muted-foreground">
{slide.description}
</p>
</div>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
</div>
</section>
);
};
export { Feature12 };