303 lines
10 KiB
TypeScript
303 lines
10 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect, useRef, useState } from "react";
|
|
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const FEATURES = [
|
|
{
|
|
id: "ai-analytics",
|
|
title: "تقسیم خودکار سرنخ",
|
|
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "cloud-integration",
|
|
title: "گزارش عملکرد فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "real-time-monitoring",
|
|
title: "مدیریت قرارداد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-3.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "data-visualization",
|
|
title: "تاریخچه تعاملات",
|
|
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "automated-workflows",
|
|
title: "پروفایل ۳۶۰ درجه مشتری",
|
|
image: "/block-media/shadcnblocks/block/placeholder-5.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "team-collaboration",
|
|
title: "اتوماسیون مراحل فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-6.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "api-integration",
|
|
title: "پیشبینی درآمد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "custom-dashboards",
|
|
title: "یادآور پیگیری هوشمند",
|
|
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "security-features",
|
|
title: "تقسیم خودکار سرنخ",
|
|
image: "/block-media/shadcnblocks/block/placeholder-3.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "performance-metrics",
|
|
title: "گزارش عملکرد فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "machine-learning",
|
|
title: "مدیریت قرارداد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-5.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "data-encryption",
|
|
title: "تاریخچه تعاملات",
|
|
image: "/block-media/shadcnblocks/block/placeholder-6.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "automated-testing",
|
|
title: "پروفایل ۳۶۰ درجه مشتری",
|
|
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "cicd-pipeline",
|
|
title: "اتوماسیون مراحل فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "version-control",
|
|
title: "پیشبینی درآمد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-3.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "code-analysis",
|
|
title: "یادآور پیگیری هوشمند",
|
|
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "database-management",
|
|
title: "تقسیم خودکار سرنخ",
|
|
image: "/block-media/shadcnblocks/block/placeholder-5.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "load-balancing",
|
|
title: "گزارش عملکرد فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-6.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "container-orchestration",
|
|
title: "مدیریت قرارداد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "microservices",
|
|
title: "تاریخچه تعاملات",
|
|
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "edge-computing",
|
|
title: "پروفایل ۳۶۰ درجه مشتری",
|
|
image: "/block-media/shadcnblocks/block/placeholder-3.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "serverless-functions",
|
|
title: "اتوماسیون مراحل فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "devops-tools",
|
|
title: "پیشبینی درآمد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-5.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "infrastructure-as-code",
|
|
title: "یادآور پیگیری هوشمند",
|
|
image: "/block-media/shadcnblocks/block/placeholder-6.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "authentication-services",
|
|
title: "تقسیم خودکار سرنخ",
|
|
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "message-queues",
|
|
title: "گزارش عملکرد فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "service-discovery",
|
|
title: "مدیریت قرارداد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-3.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "api-gateway",
|
|
title: "تاریخچه تعاملات",
|
|
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
{
|
|
id: "caching-solutions",
|
|
title: "پروفایل ۳۶۰ درجه مشتری",
|
|
image: "/block-media/shadcnblocks/block/placeholder-5.svg",
|
|
imageAlt: "نمای پایپلاین فروش",
|
|
},
|
|
{
|
|
id: "event-streaming",
|
|
title: "اتوماسیون مراحل فروش",
|
|
image: "/block-media/shadcnblocks/block/placeholder-6.svg",
|
|
imageAlt: "پروفایل یکپارچه مشتری",
|
|
},
|
|
{
|
|
id: "graphql-support",
|
|
title: "پیشبینی درآمد",
|
|
image: "/block-media/shadcnblocks/block/placeholder-1.svg",
|
|
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
|
|
},
|
|
];
|
|
|
|
interface Feature199Props {
|
|
className?: string;
|
|
}
|
|
|
|
const Feature199 = ({ className }: Feature199Props) => {
|
|
const [activeFeature, setActiveFeature] = useState(0);
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const checkMobile = () => {
|
|
setIsMobile(window.innerWidth < 768);
|
|
};
|
|
|
|
checkMobile();
|
|
window.addEventListener("resize", checkMobile);
|
|
|
|
return () => window.removeEventListener("resize", checkMobile);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!isMobile || !containerRef.current) return;
|
|
|
|
const handleScroll = () => {
|
|
const container = containerRef.current;
|
|
if (!container) return;
|
|
|
|
const rect = container.getBoundingClientRect();
|
|
const listHeight = container.offsetHeight;
|
|
const viewportHeight = window.innerHeight;
|
|
const scrollRange = Math.max(listHeight - viewportHeight * 0.45, 1);
|
|
const passed = Math.min(Math.max(-rect.top + viewportHeight * 0.2, 0), scrollRange);
|
|
const progress = passed / scrollRange;
|
|
const steppedIndex = Math.round(progress * (FEATURES.length - 1));
|
|
const nextIndex = Math.min(Math.max(steppedIndex, 0), FEATURES.length - 1);
|
|
|
|
setActiveFeature((prev) => (prev === nextIndex ? prev : nextIndex));
|
|
};
|
|
|
|
handleScroll();
|
|
window.addEventListener("scroll", handleScroll, { passive: true });
|
|
return () => window.removeEventListener("scroll", handleScroll);
|
|
}, [isMobile]);
|
|
|
|
return (
|
|
<section
|
|
dir="rtl"
|
|
lang="fa"
|
|
className={cn("min-w-0 overflow-x-hidden py-16 sm:py-24 lg:py-32", className)}
|
|
>
|
|
<div className="container min-w-0">
|
|
<h2 className="mb-8 text-xl font-bold text-balance sm:mb-10 sm:text-2xl lg:mb-20 lg:text-3xl">
|
|
هر سرنخ را تا قرارداد دنبال کنید
|
|
</h2>
|
|
<div className="relative min-w-0 gap-6 pb-64 sm:pb-60 lg:grid lg:grid-cols-5 lg:pb-0">
|
|
<div
|
|
className="col-span-3 min-w-0 pb-4 text-start"
|
|
ref={containerRef}
|
|
>
|
|
<Separator />
|
|
{FEATURES.map((feature, index) => (
|
|
<React.Fragment key={feature.id}>
|
|
<div
|
|
className="feature-item py-2.5 sm:py-3"
|
|
onMouseEnter={() => !isMobile && setActiveFeature(index)}
|
|
>
|
|
<div
|
|
className={cn(
|
|
"flex min-w-0 items-center gap-3 rounded-lg px-2 py-2 transition-colors sm:gap-5 sm:px-0 sm:py-0 lg:gap-16 xl:gap-28",
|
|
activeFeature === index && "bg-muted/40 sm:bg-transparent",
|
|
)}
|
|
>
|
|
<span
|
|
className={cn(
|
|
"invisible size-2 shrink-0 rounded-full bg-primary sm:size-2.5 lg:size-3",
|
|
activeFeature === index && "visible",
|
|
)}
|
|
/>
|
|
<p
|
|
className={cn(
|
|
"min-w-0 wrap-break-word text-base font-bold text-muted-foreground sm:text-lg md:text-xl lg:text-2xl xl:text-3xl",
|
|
activeFeature === index && "text-primary",
|
|
)}
|
|
>
|
|
{feature.title}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<Separator />
|
|
</React.Fragment>
|
|
))}
|
|
</div>
|
|
<div className="fixed inset-x-3 bottom-3 z-20 mx-auto max-w-md border bg-background shadow-md md:sticky md:top-20 md:bottom-auto md:inset-x-auto md:col-span-2 md:mx-0 md:max-w-none md:h-fit md:w-fit md:shadow-none">
|
|
<img
|
|
src={FEATURES[activeFeature].image}
|
|
alt={FEATURES[activeFeature].imageAlt}
|
|
className="h-44 w-full object-cover sm:h-52 md:h-72 md:w-auto md:object-fill"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { Feature199 };
|