Files
reui-blocks/blocks/feature172.tsx
T

293 lines
9.8 KiB
TypeScript

import { cn } from "@/lib/utils";
const topItems = [
{
title: "تحلیل کانال",
description:
"مسیرهای ایمیل را بدون کدنویسی برای هر سگمنت طراحی کنید.",
images: [
{
src: "/block-media/shadcnblocks/block/placeholder-1.svg",
alt: "تحلیل عملکرد کمپین",
className: "aspect-495/186 max-w-lg rounded-xl",
},
],
className:
"flex-1 [&>.title-container]:mb-5 md:[&>.title-container]:mb-8 xl:[&>.image-container]:translate-x-6 rtl:xl:[&>.image-container]:-translate-x-6 [&>.image-container]:translate-x-2 rtl:[&>.image-container]:-translate-x-2",
fade: [""] as string[],
},
{
title: "اتوماسیون ایمیل",
description: "عنوان، تصویر یا فراخوان را تست کنید و برنده را سریع پیدا کنید.",
images: [
{
src: "/block-media/shadcnblocks/block/logos/instagram-icon.svg",
alt: "نمودار ROI",
},
{
src: "/block-media/shadcnblocks/block/logos/linkedin-icon.svg",
alt: "داشبورد بازاریابی دیجیتال",
},
{
src: "/block-media/shadcnblocks/block/logos/producthunt-icon.svg",
alt: "تحلیل عملکرد کمپین",
},
{
src: "/block-media/shadcnblocks/block/logos/twitter-icon.svg",
alt: "نمودار ROI",
},
{
src: "/block-media/shadcnblocks/block/logos/astro-icon.svg",
alt: "داشبورد بازاریابی دیجیتال",
},
{
src: "/block-media/shadcnblocks/block/logos/figma-icon.svg",
alt: "تحلیل عملکرد کمپین",
},
{
src: "/block-media/shadcnblocks/block/logos/slack-icon.svg",
alt: "نمودار ROI",
},
{
src: "/block-media/shadcnblocks/block/logos/google-icon.svg",
alt: "داشبورد بازاریابی دیجیتال",
},
],
className:
"flex-1 [&>.title-container]:mb-5 md:[&>.title-container]:mb-8 md:[&>.title-container]:translate-x-2 rtl:md:[&>.title-container]:-translate-x-2 xl:[&>.title-container]:translate-x-4 rtl:xl:[&>.title-container]:-translate-x-4 [&>.title-container]:translate-x-0",
fade: [],
},
];
const bottomItems = [
{
title: "A/B تست",
description:
"چند کانال را همزمان اجرا کنید و عملکرد هر کمپین را در یک نما مقایسه کنید.",
images: [
{
src: "/block-media/shadcnblocks/block/placeholder-4.svg",
alt: "تحلیل عملکرد کمپین",
className: "aspect-305/280 rounded-ts-xl max-w-[305px]",
},
],
className:
"[&>.title-container]:mb-5 md:[&>.title-container]:mb-8 xl:[&>.image-container]:translate-x-6 rtl:xl:[&>.image-container]:-translate-x-6 [&>.image-container]:translate-x-2 rtl:[&>.image-container]:-translate-x-2",
fade: ["bottom"] as string[],
},
{
title: "تقویم محتوا",
description:
"مخاطبان را بر اساس رفتار، صنعت یا مرحله خرید دسته‌بندی کنید.",
images: [
{
src: "/block-media/shadcnblocks/block/placeholder-5.svg",
alt: "نمودار ROI",
className: "aspect-320/103 rounded-xl",
},
],
className:
"justify-normal [&>.title-container]:mb-5 md:[&>.title-container]:mb-0 [&>.image-container]:flex-1 md:[&>.image-container]:place-items-center md:[&>.image-container]:-translate-y-3",
fade: [""],
},
{
title: "ردیابی UTM",
description:
"ببینید کدام کانال بیشترین سرنخ با کیفیت را می‌آورد.",
images: [
{
src: "/block-media/shadcnblocks/block/placeholder-6.svg",
alt: "داشبورد بازاریابی دیجیتال",
className: "aspect-305/280 rounded-ts-xl max-w-[305px]",
},
],
className:
"[&>.title-container]:mb-5 md:[&>.title-container]:mb-8 xl:[&>.image-container]:translate-x-6 rtl:xl:[&>.image-container]:-translate-x-6 [&>.image-container]:translate-x-2 rtl:[&>.image-container]:-translate-x-2",
fade: ["bottom"],
},
];
interface Feature172Props {
className?: string;
}
function Feature172({ className }: Feature172Props) {
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container">
<h2 className="text-center text-3xl font-semibold tracking-tight text-balance sm:text-xl md:text-2xll lg:text-2xll">
کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند
</h2>
<div className="mt-8 md:mt-12 lg:mt-20">
<DashedLine orientation="horizontal" className="scale-x-105" />
<div className="relative flex max-md:flex-col">
{topItems.map((item, i) => (
<Item key={item.title} item={item} isLast={i === topItems.length - 1} />
))}
</div>
<DashedLine
orientation="horizontal"
className="max-w-7xl scale-x-110"
/>
<div className="relative grid max-w-7xl md:grid-cols-3">
{bottomItems.map((item, i) => (
<Item
key={item.title}
item={item}
isLast={i === bottomItems.length - 1}
className="md:pb-0"
/>
))}
</div>
</div>
<DashedLine
orientation="horizontal"
className="max-w-7xl scale-x-110"
/>
</div>
</section>
);
}
interface ItemProps {
item: {
title: string;
description: string;
images: { src: string; alt: string; className?: string }[];
className?: string;
fade: string[];
};
isLast?: boolean;
className?: string;
}
const Item = ({ item, isLast, className }: ItemProps) => {
return (
<div
className={cn(
"relative flex flex-col px-0 py-6 md:px-6 md:py-8",
className,
item.className,
)}
>
<div className="title-container max-w-md text-start text-balance">
<h3 className="inline font-semibold">{item.title} </h3>
<span className="font-medium text-pretty text-muted-foreground">
{" "}
{item.description}
</span>
</div>
{item.fade.includes("bottom") && (
<div className="absolute inset-0 z-10 bg-linear-to-t from-background/80 via-transparent to-transparent md:hidden" />
)}
{item.images.length > 4 ? (
<div className="relative overflow-hidden">
<div className="flex flex-col gap-5">
<div className="flex translate-x-4 justify-end gap-5 rtl:-translate-x-4 rtl:justify-start">
{item.images.slice(0, 4).map((image) => (
<div
key={image.alt}
className="grid aspect-square size-16 place-items-center rounded-xl bg-muted/40 p-2 lg:size-20"
>
<img
src={image.src}
alt={image.alt}
className="size-8 object-contain object-top-start lg:size-12"
/>
<div className="absolute inset-y-0 end-0 z-10 w-16 bg-linear-to-s from-background/80 to-transparent" />
</div>
))}
</div>
<div className="flex -translate-x-4 gap-5 rtl:translate-x-4">
{item.images.slice(4).map((image) => (
<div
key={image.alt}
className="grid aspect-square size-16 place-items-center rounded-xl bg-muted/40 lg:size-20"
>
<img
src={image.src}
alt={image.alt}
className="size-8 object-contain object-top-start lg:size-12"
/>
<div className="absolute inset-y-0 start-0 bottom-0 z-10 w-14 bg-linear-to-e from-background/80 to-transparent" />
</div>
))}
</div>
</div>
</div>
) : (
<div className="image-container grid grid-cols-1 gap-4">
{item.images.map((image) => (
<img
key={image.alt}
src={image.src}
alt={image.alt}
className={cn(
"w-full overflow-hidden object-cover",
image.className,
)}
/>
))}
</div>
)}
{!isLast && (
<>
<DashedLine
orientation="vertical"
className="absolute top-0 end-0 max-md:hidden"
/>
<DashedLine
orientation="horizontal"
className="absolute inset-x-0 bottom-0 md:hidden"
/>
</>
)}
</div>
);
};
interface DashedLineProps {
orientation?: "horizontal" | "vertical";
className?: string;
}
const DashedLine = ({
orientation = "horizontal",
className,
}: DashedLineProps) => {
const isHorizontal = orientation === "horizontal";
return (
<div
className={cn(
"relative text-muted-foreground",
isHorizontal ? "h-px w-full" : "h-full w-px",
className,
)}
>
<div
className={cn(
isHorizontal
? [
"h-px w-full",
"bg-[repeating-linear-gradient(90deg,transparent,transparent_4px,currentColor_4px,currentColor_10px)]",
"[mask-image:linear-gradient(90deg,transparent,black_25%,black_75%,transparent)]",
]
: [
"h-full w-px",
"bg-[repeating-linear-gradient(180deg,transparent,transparent_4px,currentColor_4px,currentColor_8px)]",
"[mask-image:linear-gradient(180deg,transparent,black_25%,black_75%,transparent)]",
],
)}
/>
</div>
);
};
export { Feature172 };