This commit is contained in:
parent
fb5a3b8093
commit
58d8b661a8
1055 changed files with 116254 additions and 89 deletions
187
sites/poetry/src/components/sections/pricing-cards.tsx
Normal file
187
sites/poetry/src/components/sections/pricing-cards.tsx
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
import { Check, ChevronRight } from "lucide-react";
|
||||
|
||||
import { PlusSigns } from "../icons/plus-signs";
|
||||
import { Button } from "../ui/button";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type PricingTier = {
|
||||
name: string;
|
||||
price: string;
|
||||
description: string;
|
||||
features: string[];
|
||||
cta: {
|
||||
text: string;
|
||||
href: string;
|
||||
};
|
||||
};
|
||||
|
||||
const ITEMS: PricingTier[] = [
|
||||
{
|
||||
name: "STARTER",
|
||||
price: "$0",
|
||||
description: "Free for everyone",
|
||||
features: ["Unlimited members", "250 transactions", "No support"],
|
||||
cta: {
|
||||
text: "Start for free",
|
||||
href: "/signup",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "BASIC",
|
||||
price: "$29.99",
|
||||
description: "per user per month",
|
||||
features: [
|
||||
"All free plan features and...",
|
||||
"Mainline AI",
|
||||
"Unlimited teams",
|
||||
],
|
||||
cta: {
|
||||
text: "7 days free",
|
||||
href: "/signup",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ENTERPRISE",
|
||||
price: "$ENT",
|
||||
description: "Custom pricing",
|
||||
features: [
|
||||
"All basic plan features and...",
|
||||
"Advanced security controls",
|
||||
"Migration support",
|
||||
],
|
||||
cta: {
|
||||
text: "Book a demo",
|
||||
href: "/contact",
|
||||
},
|
||||
},
|
||||
];
|
||||
const PricingCards = () => {
|
||||
return (
|
||||
<section className="relative py-16 md:py-28 lg:py-32">
|
||||
<div className="container">
|
||||
<h1 className="text-center text-4xl font-semibold tracking-tight md:text-5xl lg:text-6xl">
|
||||
Pricing
|
||||
</h1>
|
||||
<div className="mx-auto mt-4 max-w-[45rem] space-y-2 text-center">
|
||||
<p className="text-muted-foreground text-2xl md:text-3xl">
|
||||
Use Charter for free with your whole team. Upgrade to enable
|
||||
enhanced features.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="relative mt-8 md:mt-12 lg:mt-20">
|
||||
{/* Background and layout wrapper */}
|
||||
<div className="from-primary-900 to-primary/90 bg-linear-to-r absolute inset-0 isolate hidden rounded-3xl md:block">
|
||||
<div className="absolute inset-0 -z-10 [mask-image:linear-gradient(to_left,black_50%,transparent_100%)]">
|
||||
<PlusSigns className="h-full w-full text-white/[0.05]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:divide-background/20 relative space-y-6 md:grid md:grid-cols-3 md:space-y-0 md:divide-x md:p-6 lg:p-8">
|
||||
{ITEMS.map((tier, index) => (
|
||||
<PricingCard
|
||||
key={tier.name}
|
||||
tier={tier}
|
||||
isHighlighted={index === 1}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute -inset-40 z-[-1] [mask-image:radial-gradient(circle_at_center,black_0%,black_20%,transparent_75%)]">
|
||||
<PlusSigns className="text-foreground/[0.05] h-full w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default PricingCards;
|
||||
function PricingCard({
|
||||
tier,
|
||||
isHighlighted,
|
||||
}: {
|
||||
tier: PricingTier;
|
||||
isHighlighted: boolean;
|
||||
}) {
|
||||
const styles = {
|
||||
card: cn(
|
||||
"flex flex-col gap-6 rounded-xl p-6 sm:rounded-2xl md:rounded-none lg:p-8",
|
||||
// Mobile styles
|
||||
isHighlighted
|
||||
? "max-md:from-primary-900 max-md:to-primary/90 max-md:bg-linear-to-r"
|
||||
: "bg-background max-md:border",
|
||||
// Desktop styles
|
||||
"md:bg-transparent",
|
||||
),
|
||||
title: cn(
|
||||
"font-mono text-sm tracking-widest",
|
||||
// Mobile styles
|
||||
isHighlighted ? "text-background/70" : "text-foreground/70",
|
||||
// Desktop styles
|
||||
"md:text-background/70",
|
||||
),
|
||||
price: cn(
|
||||
"text-5xl font-semibold tracking-tight",
|
||||
// Mobile styles
|
||||
isHighlighted ? "text-background" : "text-foreground",
|
||||
// Desktop styles
|
||||
"md:text-background",
|
||||
),
|
||||
description: cn(
|
||||
"mt-2 text-xl font-medium",
|
||||
// Mobile styles
|
||||
isHighlighted ? "text-background/70" : "text-foreground/70",
|
||||
// Desktop styles
|
||||
"md:text-background/70",
|
||||
),
|
||||
features: cn(
|
||||
"space-y-3 text-sm",
|
||||
// Mobile styles
|
||||
isHighlighted ? "text-background/70" : "text-foreground/70",
|
||||
// Desktop styles
|
||||
"md:text-background/70",
|
||||
),
|
||||
button: cn(
|
||||
"group border-foreground/20 relative w-full",
|
||||
// inset shadow
|
||||
"after:from-border after:via-border after:absolute after:inset-0 after:bg-linear-to-t after:to-transparent after:content-[''] after:group-hover:opacity-100",
|
||||
// Desktop styles
|
||||
"md:border-background/40 md:text-background md:bg-transparent",
|
||||
isHighlighted &&
|
||||
"md:bg-background md:text-primary hover:md:bg-background/90",
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.card}>
|
||||
<h3 className={styles.title}>{tier.name}</h3>
|
||||
<div>
|
||||
<p className={styles.price}>{tier.price}</p>
|
||||
<p className={styles.description}>{tier.description}</p>
|
||||
</div>
|
||||
<ul className={styles.features}>
|
||||
{tier.features.map((feature) => (
|
||||
<li key={feature} className="flex items-center gap-2">
|
||||
<Check className="size-4 shrink-0" />
|
||||
<span>{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="flex flex-1 items-end">
|
||||
<Button
|
||||
asChild
|
||||
variant={isHighlighted ? "secondary" : "outline"}
|
||||
size="lg"
|
||||
className={styles.button}
|
||||
>
|
||||
<a href={tier.cta.href}>
|
||||
{tier.cta.text}
|
||||
<ChevronRight className="ml-1 size-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue