192 lines
7.7 KiB
TypeScript
192 lines
7.7 KiB
TypeScript
import Image from "next/image";
|
|
import { Background } from "../../components/background";
|
|
import { ContactSection } from "../../components/contact-section";
|
|
import { DemoCta } from "../../components/demo-cta";
|
|
import { FaqSection } from "../../components/faq-section";
|
|
import { PageSchema } from "../../components/page-schema";
|
|
import { SiteFooter } from "../../components/site-footer";
|
|
import { SiteHeader } from "../../components/site-header";
|
|
import { defaultFaqs } from "../../data/faq";
|
|
import { siteInfo } from "../../data/site";
|
|
import { PricingAction } from "./pricing-actions";
|
|
|
|
export const metadata = {
|
|
title: "Pricing",
|
|
description:
|
|
"LedgerOne pricing: Free includes two accounts, Pro includes ten accounts, and Elite includes unlimited accounts.",
|
|
keywords: siteInfo.keywords
|
|
};
|
|
|
|
const plans = [
|
|
{
|
|
id: "free",
|
|
name: "Free",
|
|
price: "Free",
|
|
tagline: "Best for getting your first ledger online.",
|
|
badge: "2 accounts",
|
|
features: [
|
|
"2 active accounts",
|
|
"Core ledger views",
|
|
"Rule engine access",
|
|
"Audit logs included"
|
|
],
|
|
cta: "Start free",
|
|
primary: false
|
|
},
|
|
{
|
|
id: "pro",
|
|
name: "Pro",
|
|
price: "$9",
|
|
tagline: "For teams that need secure exports and more accounts.",
|
|
badge: "10 accounts",
|
|
features: [
|
|
"10 active accounts",
|
|
"Unlimited secure exports",
|
|
"Google Sheets sync",
|
|
"Public API access"
|
|
],
|
|
cta: "Choose Pro",
|
|
primary: true
|
|
},
|
|
{
|
|
id: "elite",
|
|
name: "Elite",
|
|
price: "Custom",
|
|
tagline: "For larger ledgers and dedicated support.",
|
|
badge: "Unlimited accounts",
|
|
features: [
|
|
"Unlimited active accounts",
|
|
"Unlimited secure exports",
|
|
"Everything in Pro",
|
|
"Dedicated support"
|
|
],
|
|
cta: "Choose Elite",
|
|
primary: false
|
|
}
|
|
] as const;
|
|
|
|
const comparisons = [
|
|
{ label: "Connected accounts", free: "2", pro: "10", elite: "Unlimited" },
|
|
{ label: "Exports", free: "Not included", pro: "Unlimited", elite: "Unlimited" },
|
|
{ label: "Google Sheets sync", free: "Not included", pro: "Included", elite: "Included" },
|
|
{ label: "Public API", free: "Not included", pro: "Included", elite: "Included" },
|
|
{ label: "Rule engine", free: "Core rules", pro: "Advanced rules", elite: "Advanced rules" },
|
|
{ label: "Support", free: "Standard", pro: "Priority", elite: "Dedicated" }
|
|
];
|
|
|
|
export default function PricingPage() {
|
|
const schema = [
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "WebPage",
|
|
name: "LedgerOne Pricing",
|
|
description:
|
|
"LedgerOne pricing: Free includes two accounts, Pro includes ten accounts, and Elite includes unlimited accounts.",
|
|
url: `${siteInfo.url}/pricing`
|
|
},
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "FAQPage",
|
|
mainEntity: defaultFaqs.map((item) => ({
|
|
"@type": "Question",
|
|
name: item.question,
|
|
acceptedAnswer: { "@type": "Answer", text: item.answer }
|
|
}))
|
|
}
|
|
];
|
|
|
|
return (
|
|
<div className="page-soft-bg min-h-screen font-sans text-foreground flex flex-col relative overflow-hidden">
|
|
<Background />
|
|
<SiteHeader />
|
|
<main className="relative z-10 flex-1 pt-24 pb-16">
|
|
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
|
<div className="text-center max-w-3xl mx-auto mb-10 animate-slide-up">
|
|
<h1 className="text-4xl font-bold tracking-tight text-foreground sm:text-5xl">
|
|
Simple, transparent pricing.
|
|
</h1>
|
|
<p className="mt-6 text-lg text-muted-foreground">
|
|
Start with two accounts for free, move to Pro for secure exports and ten accounts,
|
|
or choose Elite when your ledger needs unlimited account coverage.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="grid gap-8 md:grid-cols-3 max-w-6xl mx-auto">
|
|
{plans.map((plan) => (
|
|
<div
|
|
key={plan.name}
|
|
className={`rounded-2xl p-8 border transition-all ${plan.primary
|
|
? "border-primary bg-background shadow-glow-teal ring-1 ring-primary"
|
|
: "border-border bg-background/50 shadow-sm hover:shadow-md glass-panel"
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<h3 className="text-lg font-semibold text-foreground">{plan.name}</h3>
|
|
{plan.primary && (
|
|
<span className="inline-flex items-center rounded-full bg-primary/10 px-3 py-1 text-xs font-medium text-primary">
|
|
Most Popular
|
|
</span>
|
|
)}
|
|
</div>
|
|
<div className="mt-4 flex items-baseline text-foreground">
|
|
<span className="text-4xl font-bold tracking-tight">{plan.price}</span>
|
|
{plan.price.startsWith("$") && <span className="ml-1 text-xl font-semibold text-muted-foreground">/month</span>}
|
|
</div>
|
|
<p className="mt-2 text-sm text-muted-foreground">{plan.tagline}</p>
|
|
|
|
<ul className="mt-8 space-y-4">
|
|
{plan.features.map((feature) => (
|
|
<li key={feature} className="flex items-start">
|
|
<div className="flex-shrink-0">
|
|
<svg className="h-5 w-5 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
</div>
|
|
<p className="ml-3 text-sm text-muted-foreground">{feature}</p>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
|
|
<PricingAction plan={plan.id} label={plan.cta} primary={plan.primary} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="mt-16 max-w-4xl mx-auto glass-panel rounded-xl p-1">
|
|
<div className="px-6 py-4">
|
|
<h2 className="text-xl font-bold text-foreground">Compare plans</h2>
|
|
</div>
|
|
<div className="overflow-x-auto">
|
|
<table className="min-w-full divide-y divide-border">
|
|
<thead className="bg-secondary/30">
|
|
<tr>
|
|
<th scope="col" className="px-6 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Feature</th>
|
|
<th scope="col" className="px-6 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Free</th>
|
|
<th scope="col" className="px-6 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Pro</th>
|
|
<th scope="col" className="px-6 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Elite</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="bg-background divide-y divide-border">
|
|
{comparisons.map((item) => (
|
|
<tr key={item.label}>
|
|
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-foreground">{item.label}</td>
|
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-muted-foreground">{item.free}</td>
|
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-muted-foreground">{item.pro}</td>
|
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-muted-foreground">{item.elite}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<div className="relative z-10">
|
|
<SiteFooter />
|
|
</div>
|
|
<PageSchema schema={schema} />
|
|
</div>
|
|
);
|
|
}
|