Featured

    Pricing 2

    Pricing 2

    Source Code

    "use client"
    
    import { Check } from "lucide-react"
    import Link from "next/link"
    import { useState } from "react"
    import type { VariantProps } from "class-variance-authority"
    import { Badge } from "@/components/ui/badge"
    import { Button, buttonVariants } from "@/components/ui/button"
    import {
      Card,
      CardContent,
      CardDescription,
      CardHeader,
      CardTitle,
    } from "@/components/ui/card"
    import { Switch } from "@/components/ui/switch"
    import { IconType, LinkType } from "@/types"
    
    interface PricingPlan {
      title: string
      description: string
      price: {
        monthly: string
        yearly: string
      }
      features: string[]
      button: {
        label: string
        link: LinkType
        variant?: VariantProps<typeof buttonVariants>["variant"]
        icon?: IconType
      }
      recommended?: boolean
    }
    
    interface Props {
      badge: string
      title: string
      description: string
      plans: PricingPlan[]
    }
    
    export default function Pricing2({ badge, title, description, plans }: Props) {
      const [isYearly, setIsYearly] = useState(false)
    
      return (
        <div className="w-full py-20 lg:py-40">
          <div className="container mx-auto">
            <div className="flex text-center justify-center items-center gap-4 flex-col">
              {badge && <Badge>{badge}</Badge>}
    
              <div className="flex gap-2 flex-col">
                {title && (
                  <h2 className="text-3xl md:text-5xl tracking-tighter max-w-xl text-center font-regular">
                    {title}
                  </h2>
                )}
    
                {description && (
                  <p className="text-lg leading-relaxed tracking-tight text-muted-foreground max-w-xl text-center">
                    {description}
                  </p>
                )}
              </div>
    
              <div className="flex items-center gap-4 mt-8">
                <span
                  className={`text-sm ${
                    !isYearly ? "text-foreground" : "text-muted-foreground"
                  }`}
                >
                  Monthly
                </span>
                <Switch checked={isYearly} onCheckedChange={setIsYearly} />
                <span
                  className={`text-sm ${
                    isYearly ? "text-foreground" : "text-muted-foreground"
                  }`}
                >
                  Yearly <span className="text-primary">Save 20%</span>
                </span>
              </div>
            </div>
    
            <div className="grid pt-20 text-left grid-cols-1 lg:grid-cols-3 w-full gap-8">
              {plans.map((plan, index) => (
                <Card
                  key={index}
                  className={`w-full rounded-md relative ${
                    plan.recommended ? "border-primary shadow-lg" : ""
                  }`}
                >
                  {plan.recommended && (
                    <div className="absolute -top-4 left-1/2 -translate-x-1/2">
                      <Badge variant="default" className="px-4 py-1">
                        Most Popular
                      </Badge>
                    </div>
                  )}
                  <CardHeader>
                    <CardTitle>{plan.title}</CardTitle>
                    <CardDescription>{plan.description}</CardDescription>
                  </CardHeader>
                  <CardContent>
                    <div className="flex flex-col gap-8 justify-start">
                      <div className="flex flex-col gap-1">
                        <p className="flex flex-row items-center gap-2">
                          <span className="text-4xl font-bold">
                            {isYearly ? plan.price.yearly : plan.price.monthly}
                          </span>
                          <span className="text-sm text-muted-foreground">
                            / {isYearly ? "year" : "month"}
                          </span>
                        </p>
                        {isYearly && (
                          <p className="text-sm text-muted-foreground">
                            Billed annually
                          </p>
                        )}
                      </div>
    
                      <div className="flex flex-col gap-4 justify-start">
                        {plan.features.map((feature, index) => (
                          <div key={index} className="flex flex-row gap-4">
                            <Check className="w-4 h-4 mt-2 text-primary" />
                            <div className="flex flex-col">
                              <p>{feature}</p>
                            </div>
                          </div>
                        ))}
                      </div>
    
                      <Link
                        href={plan.button.link.href || "#"}
                        className="inline-block"
                      >
                        <Button
                          size="lg"
                          className="gap-4 w-full"
                          variant={
                            plan.recommended
                              ? "default"
                              : plan.button.variant || "outline"
                          }
                        >
                          {plan.button.label}
                          {plan.button.icon}
                        </Button>
                      </Link>
                    </div>
                  </CardContent>
                </Card>
              ))}
            </div>
          </div>
        </div>
      )
    }