Files
reui-blocks/blocks/feature57.tsx
T

205 lines
8.1 KiB
TypeScript

"use client";
import { Bolt, Cloud, MessagesSquare, Star } from "lucide-react";
import { useEffect, useState } from "react";
import { Badge } from "@/components/ui/badge";
import type { CarouselApi } from "@/components/ui/carousel";
import {
Carousel,
CarouselContent,
CarouselItem,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
const features = [
{
id: "feature-1",
title: "ردیابی UTM",
description:
"چند کانال را همزمان اجرا کنید و عملکرد هر کمپین را در یک نما مقایسه کنید.",
icon: Cloud,
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
},
{
id: "feature-2",
title: "گزارش ROI",
description:
"مخاطبان را بر اساس رفتار، صنعت یا مرحله خرید دسته‌بندی کنید.",
icon: Star,
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
},
{
id: "feature-3",
title: "مدیریت کمپین",
description:
"ببینید کدام کانال بیشترین سرنخ با کیفیت را می‌آورد.",
icon: Bolt,
image: "/block-media/shadcnblocks/block/placeholder-3.svg",
},
{
id: "feature-4",
title: "سگمنت‌بندی مخاطب",
description:
"مسیرهای ایمیل را بدون کدنویسی برای هر سگمنت طراحی کنید.",
icon: MessagesSquare,
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
},
];
interface Feature57Props {
className?: string;
}
const Feature57 = ({ className }: Feature57Props) => {
const [selection, setSelection] = useState(0);
const [carouselApi, setCarouselApi] = useState<CarouselApi>();
const handleSelection = (index: number) => {
carouselApi?.scrollTo(index);
};
useEffect(() => {
if (!carouselApi) {
return;
}
const updateSelection = () => {
setSelection(carouselApi.selectedScrollSnap());
};
carouselApi.on("select", updateSelection);
return () => {
carouselApi.off("select", updateSelection);
};
}, [carouselApi]);
return (
<section
dir="rtl"
lang="fa"
className={cn("py-12 md:py-24 lg:py-32", className)}
>
<div className="container mx-auto px-4">
<div className="mb-8 text-center md:mb-12">
<Badge variant="outline" className="mb-3">
کمپین
</Badge>
<h2 className="text-3xl leading-tight font-bold md:text-xl lg:text-2xll">
کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند
</h2>
<p className="mx-auto mt-3 max-w-2xl text-sm text-muted-foreground md:mt-4 md:text-base">
با سگمنت‌بندی دقیق، پیام مناسب را به مخاطب مناسب برسانید. داده رفتاری نشان می‌دهد کدام محتوا بیشترین تأثیر را روی تبدیل دارد.
</p>
</div>
<div>
<div className="mx-auto flex max-w-6xl flex-col-reverse gap-6 md:flex-row md:gap-8 lg:gap-16">
<div className="md:w-1/2 lg:w-2/5">
<ul className="grid grid-cols-1 gap-3 md:flex md:flex-col md:gap-2">
{features.map((feature, i) => {
const isSelected = selection === i;
return (
<li
key={feature.id}
className={`group relative flex cursor-pointer rounded-xl border px-4 py-3 transition-all duration-300 md:px-5 md:py-4 ${
isSelected
? "border-border bg-accent shadow-sm"
: "border-transparent hover:border-border hover:bg-accent/30"
}`}
data-open={isSelected ? "true" : undefined}
onClick={() => handleSelection(i)}
>
<div className="flex w-full items-start gap-3 md:gap-4">
<div
className={`flex aspect-square w-9 shrink-0 items-center justify-center rounded-lg transition-colors md:w-10 ${
isSelected
? "bg-primary text-primary-foreground"
: "bg-muted text-muted-foreground"
}`}
>
<feature.icon className="size-4 md:size-5" />
</div>
<div className="min-w-0 flex-1">
<h3
className={`mb-1 text-sm font-semibold transition-colors md:text-base lg:text-lg ${
isSelected
? "text-foreground"
: "text-muted-foreground"
}`}
>
{feature.title}
</h3>
<p className="line-clamp-2 text-xs text-muted-foreground transition-all md:text-sm md:group-data-open:opacity-100 lg:text-sm">
{feature.description}
</p>
</div>
</div>
</li>
);
})}
</ul>
</div>
<div className="relative md:w-1/2 lg:w-3/5">
<div className="overflow-hidden rounded-xl border border-border shadow-sm">
<Carousel
setApi={setCarouselApi}
className="aspect-4/5 max-h-[500px] w-full md:aspect-3/4 lg:aspect-4/5 [&>div]:h-full"
opts={{
loop: true,
direction: "rtl",
}}
>
<CarouselContent className="mx-0 h-full w-full">
{features.map((feature) => (
<CarouselItem key={feature.id} className="px-0">
<div className="relative h-full w-full overflow-hidden">
<img
src={feature.image}
alt={`نمای ${feature.title}`}
className="h-full w-full object-cover object-center transition-transform duration-500"
/>
<div className="absolute inset-x-0 bottom-0 bg-linear-to-t from-background/80 via-background/40 to-transparent p-6">
<div className="flex items-start gap-3">
<div className="flex aspect-square w-10 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground">
<feature.icon className="size-5" />
</div>
<div>
<h3 className="text-xl font-semibold text-foreground">
{feature.title}
</h3>
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
{feature.description}
</p>
</div>
</div>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
</div>
<div className="mt-5 flex justify-center gap-2">
{features.map((feature, i) => (
<button
key={feature.id}
className={`size-2 rounded-full transition-all ${
selection === i
? "w-6 bg-primary"
: "bg-muted hover:bg-muted-foreground/50"
}`}
onClick={() => handleSelection(i)}
aria-label={feature.title}
/>
))}
</div>
</div>
</div>
</div>
</div>
</section>
);
};
export { Feature57 };