Files
reui-blocks/blocks/pricing1.tsx
T

223 lines
6.8 KiB
TypeScript
Raw Normal View History

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 };