234 lines
9.6 KiB
TypeScript
234 lines
9.6 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "framer-motion";
|
|
import { ArrowRight } from "lucide-react";
|
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
import {
|
|
FaApple,
|
|
FaGoogle,
|
|
FaLinkedin,
|
|
FaMicrosoft,
|
|
FaTwitter,
|
|
} from "react-icons/fa";
|
|
|
|
import { Avatar, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export const Highlight = ({
|
|
children,
|
|
className,
|
|
}: {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}) => {
|
|
return (
|
|
<motion.span
|
|
className={cn(
|
|
"bg-emerald-100 px-1 py-0.5 font-bold text-emerald-700 dark:bg-emerald-700/[0.2] dark:text-emerald-500",
|
|
className,
|
|
)}
|
|
>
|
|
{children}
|
|
</motion.span>
|
|
);
|
|
};
|
|
|
|
const CARDS = [
|
|
{
|
|
id: 0,
|
|
name: "مدیریت فروش",
|
|
designation: "سامانه مدیریت ارتباط با مشتری",
|
|
userImage: "/block-media/shadcnblocks/block/guri3/avatar1.png",
|
|
companyIcon: FaApple,
|
|
content: (
|
|
<p className="text-pretty">
|
|
پیادهسازی فوقالعاده روان بود.{" "}
|
|
<Highlight>تمام تعاملات، سرنخها و قراردادها در یک فضای کاری متمرکز جمع میشود. تیم فروش بدون جابجایی بین ابزارها، سریعتر پیشبینی میکند و معاملات بیشتری میبندد.</Highlight> از اولین تماس تا تمدید قرارداد، هر مرحله فروش قابل ردیابی است. گزارشهای لحظهای به مدیران کمک میکند گلوگاهها را قبل از از دست دادن درآمد شناسایی کنند.
|
|
</p>
|
|
),
|
|
},
|
|
{
|
|
id: 1,
|
|
name: "ارتباط با مشتری",
|
|
designation: "پایپلاین فروش",
|
|
userImage: "/block-media/shadcnblocks/block/guri3/avatar2.png",
|
|
companyIcon: FaLinkedin,
|
|
content: (
|
|
<p className="text-pretty">
|
|
بهعنوان مدیر فروش، دید لحظهای پایپلاین برایم تعیینکننده است.{" "}
|
|
<Highlight>پروفایل یکپارچه مشتری، تاریخچه تماس و وضعیت معامله را همزمان نشان میدهد. تیمها با دید مشترک، هماهنگتر پیش میروند و نرخ تبدیل بالاتر میرود.</Highlight> تمام تعاملات، سرنخها و قراردادها در یک فضای کاری متمرکز جمع میشود. تیم فروش بدون جابجایی بین ابزارها، سریعتر پیشبینی میکند و معاملات بیشتری میبندد.
|
|
</p>
|
|
),
|
|
},
|
|
{
|
|
id: 2,
|
|
name: "مدیریت فروش",
|
|
designation: "سامانه مدیریت ارتباط با مشتری",
|
|
userImage: "/block-media/shadcnblocks/block/guri3/avatar3.png",
|
|
companyIcon: FaTwitter,
|
|
content: (
|
|
<p className="text-pretty">
|
|
امکانات دسترسپذیری عالی است.{" "}
|
|
<Highlight>از اولین تماس تا تمدید قرارداد، هر مرحله فروش قابل ردیابی است. گزارشهای لحظهای به مدیران کمک میکند گلوگاهها را قبل از از دست دادن درآمد شناسایی کنند.</Highlight> پروفایل یکپارچه مشتری، تاریخچه تماس و وضعیت معامله را همزمان نشان میدهد. تیمها با دید مشترک، هماهنگتر پیش میروند و نرخ تبدیل بالاتر میرود.
|
|
</p>
|
|
),
|
|
},
|
|
{
|
|
id: 3,
|
|
name: "هر سرنخ را تا قرارداد دنبال کنید",
|
|
designation: "فروش تیمتان را یکجا مدیریت کنید",
|
|
userImage: "/block-media/shadcnblocks/block/guri3/avatar4.png",
|
|
companyIcon: FaGoogle,
|
|
content: (
|
|
<p className="text-pretty">
|
|
عملکرد استثنایی است.{" "}
|
|
<Highlight>تمام تعاملات، سرنخها و قراردادها در یک فضای کاری متمرکز جمع میشود. تیم فروش بدون جابجایی بین ابزارها، سریعتر پیشبینی میکند و معاملات بیشتری میبندد.</Highlight> از اولین تماس تا تمدید قرارداد، هر مرحله فروش قابل ردیابی است. گزارشهای لحظهای به مدیران کمک میکند گلوگاهها را قبل از از دست دادن درآمد شناسایی کنند.
|
|
</p>
|
|
),
|
|
},
|
|
{
|
|
id: 4,
|
|
name: "روابط مشتری را در یک نگاه ببینید",
|
|
designation: "پایپلاین فروش را شفاف کنید",
|
|
userImage: "/block-media/shadcnblocks/block/guri3/avatar5.png",
|
|
companyIcon: FaMicrosoft,
|
|
content: (
|
|
<p className="text-pretty">
|
|
برای نیازهای سازمانی ما عالی است.{" "}
|
|
<Highlight>پروفایل یکپارچه مشتری، تاریخچه تماس و وضعیت معامله را همزمان نشان میدهد. تیمها با دید مشترک، هماهنگتر پیش میروند و نرخ تبدیل بالاتر میرود.</Highlight> تمام تعاملات، سرنخها و قراردادها در یک فضای کاری متمرکز جمع میشود. تیم فروش بدون جابجایی بین ابزارها، سریعتر پیشبینی میکند و معاملات بیشتری میبندد.
|
|
</p>
|
|
),
|
|
},
|
|
];
|
|
|
|
type Card = {
|
|
id: number;
|
|
name: string;
|
|
designation: string;
|
|
userImage: string;
|
|
companyIcon: React.ComponentType<{ className?: string }>;
|
|
content: React.ReactNode;
|
|
};
|
|
|
|
interface Feature281Props {
|
|
className?: string;
|
|
}
|
|
|
|
const Feature281 = ({ className }: Feature281Props) => {
|
|
return (
|
|
<section
|
|
dir="rtl"
|
|
lang="fa"
|
|
className={cn("h-full w-screen overflow-hidden py-32", className)}
|
|
>
|
|
<div className="container flex w-full max-w-6xl flex-col items-center justify-center">
|
|
<div className="relative flex h-full flex-col items-center justify-center gap-8 text-center">
|
|
<p className="rounded-full bg-muted px-4 py-1 text-xs font-medium">
|
|
ارتباط با مشتری
|
|
</p>
|
|
<h1 className="w-full text-2xll font-semibold tracking-tighter text-balance lg:text-2xll">
|
|
پایپلاین فروش
|
|
</h1>
|
|
</div>
|
|
<div className="mt-24 flex items-center justify-center">
|
|
<CardStack items={CARDS} />
|
|
</div>
|
|
<Button variant="ghost" className="group/btn mt-8 w-fit" asChild>
|
|
<a href="#">
|
|
مدیریت فروش
|
|
<ArrowRight className="ms-2 size-4 transition-transform group-hover/btn:translate-x-1 rtl:rotate-180 rtl:group-hover/btn:-translate-x-1" />
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { Feature281 };
|
|
|
|
// Below is the modified component from Aceternity UI
|
|
// Original source: npx shadcn@latest add https://ui.aceternity.com/registry/card-stack.json
|
|
// Modified to follow our coding standards and design system
|
|
// We respect copyright and attribution to the original creators
|
|
|
|
const CardStack = ({
|
|
items,
|
|
offset,
|
|
scaleFactor,
|
|
}: {
|
|
items: Card[];
|
|
offset?: number;
|
|
scaleFactor?: number;
|
|
}) => {
|
|
const intervalRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
|
const CARD_OFFSET = offset || 10;
|
|
const SCALE_FACTOR = scaleFactor || 0.06;
|
|
const [cards, setCards] = useState<Card[]>(items);
|
|
|
|
const startFlipping = useCallback(() => {
|
|
intervalRef.current = setInterval(() => {
|
|
setCards((prevCards: Card[]) => {
|
|
const newArray = [...prevCards];
|
|
newArray.unshift(newArray.pop()!);
|
|
return newArray;
|
|
});
|
|
}, 5000);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
startFlipping();
|
|
|
|
return () => {
|
|
if (intervalRef.current) {
|
|
clearInterval(intervalRef.current);
|
|
}
|
|
};
|
|
}, [startFlipping]);
|
|
|
|
return (
|
|
<div className="relative h-60 w-96">
|
|
{cards.map((card, index) => {
|
|
const CompanyIcon = card.companyIcon;
|
|
return (
|
|
<motion.div
|
|
key={card.id}
|
|
className="absolute flex h-60 w-96 flex-col justify-between rounded-3xl border border-neutral-200 bg-white p-4 text-start shadow-xl shadow-black/[0.1] dark:border-white/[0.1] dark:bg-black dark:shadow-white/[0.05]"
|
|
style={{
|
|
transformOrigin: "top center",
|
|
}}
|
|
animate={{
|
|
top: index * -CARD_OFFSET,
|
|
scale: 1 - index * SCALE_FACTOR,
|
|
zIndex: cards.length - index,
|
|
}}
|
|
transition={{
|
|
duration: 0.5,
|
|
type: "spring",
|
|
bounce: 0.3,
|
|
}}
|
|
>
|
|
<div className="font-normal text-neutral-700 dark:text-neutral-200">
|
|
{card.content}
|
|
</div>
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<Avatar key={index} className="size-12">
|
|
<AvatarImage src={card.userImage} alt={card.name} />
|
|
</Avatar>
|
|
<div>
|
|
<p className="font-medium">{card.name}</p>
|
|
<p className="text-muted-foreground/80">{card.designation}</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex size-10 items-center justify-center rounded-full bg-muted-foreground/15">
|
|
<CompanyIcon className="size-5" />
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|