Files
reui-blocks/blocks/pricing10.tsx
T

272 lines
8.1 KiB
TypeScript

"use client";
import { Check, X } from "lucide-react";
import { useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
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")} ریال`;
const renderAnnualPrice = (price: number, discount?: number) => {
if (!discount) {
return formatPrice(price);
}
return (
<span className="flex items-center">
{formatPrice(price)}
<Badge className="ms-1">{discount.toLocaleString("fa-IR")}٪-</Badge>
</span>
);
};
const plans = [
{
title: "رایگان",
description: "برای پروژه‌های متن‌باز",
price: { monthly: 9, annually: 90000 },
href: "#",
recommended: false,
image: "/block-media/shadcnblocks/block/block-1.svg",
featureGroups: [
{
title: "خلاصه",
features: [
{
title: "۳ کاربر",
icon: Check,
},
],
},
{
title: "برجسته‌ها",
features: [
{
title: "امکان شامل‌شده",
icon: Check,
},
{
title: "امکان غیرفعال",
icon: X,
},
],
},
],
},
{
title: "پایه",
description: "برای پروژه‌های متن‌باز",
price: { monthly: 50, annually: 450000, annualDiscount: 10 },
href: "#",
recommended: false,
image: "/block-media/shadcnblocks/block/block-2.svg",
featureGroups: [
{
title: "خلاصه",
features: [
{
title: "۱۰ کاربر",
icon: Check,
},
],
},
{
title: "برجسته‌ها",
features: [
{
title: "امکان شامل‌شده",
icon: Check,
},
{
title: "امکان غیرفعال",
icon: X,
},
],
},
],
},
{
title: "تیم",
description: "برای پروژه‌های متن‌باز",
price: { monthly: 100, annually: 900000, annualDiscount: 10 },
href: "#",
recommended: true,
image: "/block-media/shadcnblocks/block/block-3.svg",
featureGroups: [
{
title: "خلاصه",
features: [
{
title: "۵۰ کاربر",
icon: Check,
},
],
},
{
title: "برجسته‌ها",
features: [
{
title: "امکان شامل‌شده",
icon: Check,
},
{
title: "امکان غیرفعال",
icon: X,
},
],
},
],
},
{
title: "سازمانی",
description: "برای پروژه‌های متن‌باز",
price: { monthly: 200, annually: 160000, annualDiscount: 20 },
href: "#",
recommended: false,
image: "/block-media/shadcnblocks/block/block-4.svg",
featureGroups: [
{
title: "خلاصه",
features: [
{
title: "عضو نامحدود فضای کاری",
icon: Check,
},
],
},
{
title: "برجسته‌ها",
features: [
{
title: "امکان شامل‌شده",
icon: Check,
},
{
title: "امکان غیرفعال",
icon: X,
},
],
},
],
},
];
interface Pricing10Props {
className?: string;
}
const Pricing10 = ({ className }: Pricing10Props) => {
const [annualBilling, setAnnualBilling] = useState(false);
return (
<section className={cn("py-32", className)}>
<div className="container mb-8 lg:mb-0">
<div className="flex flex-col gap-y-12 md:gap-y-16">
<div className="flex flex-col">
<h1 className="my-6 text-3xl font-bold text-pretty md:text-xl xl:text-2xll">
طرح‌های تعرفه
</h1>
<p className="text-muted-foreground lg:text-xl">
طرح مناسب خود را انتخاب کنید و همین امروز شروع رایگان.
</p>
</div>
<div className="lg:mb-8">
<div className="flex h-full flex-col justify-end">
<div className="flex items-center gap-2">
<Switch
id="annual-billing"
checked={annualBilling}
onCheckedChange={setAnnualBilling}
/>
<Label htmlFor="annual-billing">صورتحساب سالانه</Label>
</div>
</div>
</div>
</div>
</div>
<div className="container flex flex-col gap-6 gap-y-8 xl:grid xl:grid-cols-4">
{plans.map((plan) => (
<article
key={plan.title}
className={`rounded-xl border ${plan.recommended ? "border-primary" : "border-border lg:mt-7"} overflow-clip`}
>
{plan.recommended && (
<div className="flex h-7 items-center justify-center bg-primary text-center text-xs font-semibold text-primary-foreground">
پیشنهادی
</div>
)}
<header className="p-4 sm:p-6 xl:pt-12">
<div className="mb-6 md:flex md:items-center xl:block">
<div className="mb-1 flex md:flex-1 md:flex-row-reverse md:items-center xl:mb-6 xl:flex-col-reverse xl:items-start xl:gap-y-4">
<div className="flex-1 md:ms-6 xl:ms-0">
<p className="mb-1 text-xl font-medium sm:text-xl">
{plan.title}
</p>
<p className="text-xs text-muted-foreground sm:text-sm 2xl:min-h-10">
{plan.description}
</p>
</div>
<img
src={plan.image}
alt={plan.title}
className="size-16 sm:size-20"
/>
</div>
<div>
<h2 className="mb-1 flex items-start text-xl font-medium md:text-3xl 2xl:text-xl">
{annualBilling
? renderAnnualPrice(
plan.price.annually,
"annualDiscount" in plan.price
? plan.price.annualDiscount
: undefined,
)
: formatPrice(plan.price.monthly)}
</h2>
<p className="text-xs font-medium text-muted-foreground">
در ماه
</p>
</div>
</div>
<div>
<Button
variant={plan.recommended ? "default" : "outline"}
className="w-full"
>
رایگان شروع رایگان
</Button>
</div>
</header>
<main className="space-y-6 border-t border-border p-4 sm:p-6 md:grid md:grid-cols-2 md:space-y-0 xl:block xl:space-y-6">
{plan.featureGroups.map((group) => (
<div key={group.title}>
<h2 className="mb-3 text-xs font-semibold tracking-wider text-muted-foreground uppercase">
{group.title}
</h2>
<ul className="space-y-3">
{group.features.map((feature) => (
<li
key={feature.title}
className="flex items-center gap-x-2 text-xs font-medium text-muted-foreground"
>
<feature.icon className="size-4" />
{feature.title}
</li>
))}
</ul>
</div>
))}
</main>
</article>
))}
</div>
</section>
);
};
export { Pricing10 };