Files
reui-blocks/blocks/pricing2.tsx
T

163 lines
4.9 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.
"use client";
import { CircleCheck } from "lucide-react";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
const formatPrice = (value: string | number) =>
`${(typeof value === "string" ? Number(value) : value).toLocaleString("fa-IR")} ریال`;
interface PricingFeature {
text: string;
}
interface PricingPlan {
id: string;
name: string;
description: string;
monthlyPrice: number;
yearlyPrice: number;
features: PricingFeature[];
button: {
text: string;
url: string;
};
}
interface Pricing2Props {
heading?: string;
description?: string;
plans?: PricingPlan[];
className?: string;
}
const Pricing2 = ({
heading = "تعرفه‌ها",
description = "طرح‌های مقرون‌به‌صرفه ما را ببینید",
plans = [
{
id: "plus",
name: "پلاس",
description: "برای استفاده شخصی",
monthlyPrice: 190000,
yearlyPrice: 179000,
features: [
{ text: "تا ۵ عضو تیم" },
{ text: "کتابخانه کامپوننت‌های پایه" },
{ text: "پشتیبانی انجمن" },
{ text: "۱ گیگابایت فضای فایل معاملات" },
],
button: {
text: "خرید",
url: "https://ShadcnBlocks",
},
},
{
id: "pro",
name: "حرفه‌ای",
description: "برای حرفه‌ای‌ها",
monthlyPrice: 490000,
yearlyPrice: 359000,
features: [
{ text: "اعضای تیم نامحدود" },
{ text: "کامپوننت‌های پیشرفته" },
{ text: "پشتیبانی اولویت‌دار" },
{ text: "فضای فایل نامحدود" },
],
button: {
text: "خرید",
url: "https://ShadcnBlocks",
},
},
],
className,
}: Pricing2Props) => {
const [isYearly, setIsYearly] = useState(false);
return (
<section className={cn("py-32", className)}>
<div className="container">
<div className="mx-auto flex max-w-5xl flex-col items-center gap-6 text-center">
<h2 className="text-xl font-semibold text-pretty lg:text-2xll">
{heading}
</h2>
<p className="text-muted-foreground lg:text-xl">{description}</p>
<div className="flex items-center gap-3 text-lg">
ماهانه
<Switch
checked={isYearly}
onCheckedChange={() => setIsYearly(!isYearly)}
/>
سالانه
</div>
<div className="flex flex-col items-stretch gap-6 md:flex-row">
{plans.map((plan) => (
<Card
key={plan.id}
className="flex w-80 flex-col justify-between text-start"
>
<CardHeader>
<CardTitle>
<p>{plan.name}</p>
</CardTitle>
<p className="text-sm text-muted-foreground">
{plan.description}
</p>
<div className="flex items-end gap-1">
<span className="text-xl font-semibold">
{formatPrice(
isYearly ? plan.yearlyPrice : plan.monthlyPrice,
)}
</span>
<span className="text-xl font-semibold text-muted-foreground">
{isYearly ? "در سال" : "در ماه"}
</span>
</div>
</CardHeader>
<CardContent>
<Separator className="mb-6" />
{plan.id === "pro" && (
<p className="mb-3 font-semibold">
همه‌چیز در پلاس، به‌علاوه:
</p>
)}
<ul className="space-y-4">
{plan.features.map((feature, index) => (
<li
key={index}
className="flex items-center gap-2 text-sm"
>
<CircleCheck className="size-4 shrink-0" />
<span>{feature.text}</span>
</li>
))}
</ul>
</CardContent>
<CardFooter className="mt-auto">
<Button asChild className="w-full">
<a href={plan.button.url} target="_blank">
{plan.button.text}
</a>
</Button>
</CardFooter>
</Card>
))}
</div>
</div>
</div>
</section>
);
};
export { Pricing2 };