Files
reui-blocks/blocks/pricing1.tsx
T

223 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 };