223 lines
6.8 KiB
TypeScript
223 lines
6.8 KiB
TypeScript
import { Check } from "lucide-react";
|
||
|
||
import { Button } from "@/components/ui/button";
|
||
import { cn } from "@/lib/utils";
|
||
|
||
const formatPrice = (value: string | number) =>
|
||
`${(typeof value === "string" ? Number(value) : value).toLocaleString("fa-IR")} ریال`;
|
||
|
||
// Features for each pricing tier
|
||
const freeFeatures = [
|
||
"همزمانی تیم فروش روی یک قیف",
|
||
"۱ گیگابایت فضای فایل معاملات",
|
||
"۲ فضای کاری فروش",
|
||
"پشتیبانی ایمیلی در ساعات کاری",
|
||
"قالب ایمیل و فیلد سفارشی پایه",
|
||
"اتصال ایمیل و تقویم",
|
||
"پیشنهاد هوشمند پیگیری (پایه)",
|
||
];
|
||
|
||
const proFeatures = [
|
||
"۲ عضو تیم",
|
||
"۱۰ گیگابایت فضای ذخیره",
|
||
"۱۰ پروژه",
|
||
"پشتیبانی اولویتدار",
|
||
"شخصیسازی کامل",
|
||
"یکپارچهسازی کامل",
|
||
"دسترسی کامل به اتصال هوشمند",
|
||
];
|
||
|
||
const premiumFeatures = [
|
||
"۵ عضو تیم",
|
||
"۵۰ گیگابایت فضای ذخیره",
|
||
"۵۰ پروژه",
|
||
"پشتیبانی اختصاصی",
|
||
"شخصیسازی پیشرفته",
|
||
"تحلیلها",
|
||
"گزارشها",
|
||
];
|
||
|
||
const entrepriseFeatures = [
|
||
"بیش از ۱۰ عضو تیم",
|
||
"بیش از ۱۰۰ گیگابایت فضای ذخیره",
|
||
"بیش از ۱۰۰ پروژه",
|
||
"مدیر موفقیت مشتری اختصاصی",
|
||
"ویژگیهای سفارشی",
|
||
"پشتیبانی سفارشی",
|
||
"یکپارچهسازی سفارشی",
|
||
];
|
||
|
||
// Pricing tier type definition
|
||
type PricingTier = {
|
||
name: string;
|
||
description: string;
|
||
price: number | null;
|
||
bgClass: string;
|
||
interval: string;
|
||
buttonText: string;
|
||
buttonVariant:
|
||
| "default"
|
||
| "outline"
|
||
| "secondary"
|
||
| "destructive"
|
||
| "ghost"
|
||
| "link";
|
||
features: string[];
|
||
comparison: string;
|
||
hasPurchaseOption: boolean;
|
||
};
|
||
|
||
// Pricing tier data
|
||
const pricingTiers: PricingTier[] = [
|
||
{
|
||
name: "رایگان",
|
||
description: "برای استفاده شخصی با امکانات و پشتیبانی محدود",
|
||
price: 0,
|
||
bgClass: "",
|
||
interval: "شامل ۱ کاربر.",
|
||
buttonText: "شروع رایگان",
|
||
buttonVariant: "outline",
|
||
features: freeFeatures,
|
||
comparison: "امکانات",
|
||
hasPurchaseOption: false,
|
||
},
|
||
{
|
||
name: "حرفهای",
|
||
description: "برای کسبوکارهای کوچک با تمام امکانات و پشتیبانی",
|
||
price: 290000,
|
||
bgClass: "bg-muted",
|
||
interval: "به ازای هر کاربر، ماهانه.",
|
||
buttonText: "خرید",
|
||
buttonVariant: "default",
|
||
features: proFeatures,
|
||
comparison: "همهچیز در رایگان، بهعلاوه:",
|
||
hasPurchaseOption: true,
|
||
},
|
||
{
|
||
name: "پریمیوم",
|
||
description:
|
||
"برای تیمها و سازمانها با امکانات و پشتیبانی پیشرفته",
|
||
price: 590000,
|
||
bgClass: "",
|
||
interval: "به ازای هر کاربر، ماهانه.",
|
||
buttonText: "خرید",
|
||
buttonVariant: "outline",
|
||
features: premiumFeatures,
|
||
comparison: "همهچیز در حرفهای، بهعلاوه:",
|
||
hasPurchaseOption: true,
|
||
},
|
||
{
|
||
name: "سازمانی",
|
||
description:
|
||
"برای شرکتهای بزرگ با امکانات سفارشی، پشتیبانی ویژه و مدیر موفقیت مشتری اختصاصی",
|
||
price: null,
|
||
bgClass: "",
|
||
interval: "",
|
||
buttonText: "گفتگو با فروش",
|
||
buttonVariant: "outline",
|
||
features: entrepriseFeatures,
|
||
comparison: "همهچیز در پریمیوم، بهعلاوه:",
|
||
hasPurchaseOption: false,
|
||
},
|
||
];
|
||
|
||
const PricingCard = ({
|
||
tier,
|
||
className,
|
||
}: {
|
||
tier: PricingTier;
|
||
className?: string;
|
||
}) => {
|
||
return (
|
||
<div className={cn("flex h-full flex-col", tier.bgClass, className)}>
|
||
{/* Card top part with fixed height */}
|
||
<div className="h-[360px] flex-none">
|
||
<div className="flex h-full flex-col">
|
||
{/* Header */}
|
||
<div className="px-8 pt-8 pb-3">
|
||
<h3 className="text-3xl font-semibold">{tier.name}</h3>
|
||
</div>
|
||
|
||
{/* Description */}
|
||
<div className="px-8 pb-6">
|
||
<p className="line-clamp-2 text-balance text-muted-foreground">
|
||
{tier.description}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Price */}
|
||
<div className="flex grow flex-col justify-start px-8 pb-6">
|
||
{tier.price !== null && (
|
||
<div className="mb-4 flex items-start justify-center">
|
||
<div className="text-center">
|
||
<p className="text-2xll font-semibold">
|
||
{formatPrice(tier.price)}
|
||
</p>
|
||
{tier.interval && (
|
||
<p className="mt-2 text-sm text-muted-foreground">
|
||
{tier.interval}
|
||
</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* CTA Button */}
|
||
<div className="mt-auto px-8 pb-8">
|
||
<Button variant={tier.buttonVariant} className="w-full py-6">
|
||
{tier.buttonText}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Features */}
|
||
<div className="grow border-t p-8 text-start">
|
||
<p className="mb-4 text-lg font-semibold">{tier.comparison}</p>
|
||
<ul className="space-y-4">
|
||
{tier.features.map((feature, featureIndex) => (
|
||
<li key={featureIndex} className="flex items-center gap-3">
|
||
<Check className="size-5 text-primary" />
|
||
<span>{feature}</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
interface Pricing1Props {
|
||
className?: string;
|
||
}
|
||
|
||
const Pricing1 = ({ className }: Pricing1Props) => {
|
||
return (
|
||
<section className={cn("py-32", className)}>
|
||
<div className="container">
|
||
<div className="mx-auto mb-20 max-w-5xl text-center">
|
||
<h2 className="mb-3 text-xl font-bold text-pretty lg:text-2xll">
|
||
تعرفهها
|
||
</h2>
|
||
<p className="text-muted-foreground lg:text-xl">
|
||
طرحهای مقرونبهصرفه ما را ببینید و مناسبترین گزینه را انتخاب
|
||
کنید. اگر به طرح سفارشی نیاز دارید، با ما تماس بگیرید.
|
||
</p>
|
||
</div>
|
||
|
||
{/* Grid layout for pricing tiers */}
|
||
<div className="mx-auto grid max-w-xl rounded-md border lg:max-w-none lg:grid-cols-4 lg:divide-s">
|
||
{pricingTiers.map((tier) => (
|
||
<div key={tier.name} className={`${tier.bgClass} h-full`}>
|
||
<PricingCard tier={tier} />
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
};
|
||
|
||
export { Pricing1 };
|