Full technology change: Next.js App Router replaced with Vite + react-router-dom v6. All 21 pages and 5 landing components converted (next/link -> Link, next/navigation -> react-router-dom hooks, next/font -> @fontsource/inter, process.env -> import.meta.env). Dropped the unused Stripe API routes, which can't run in a client-only Vite build anyway and were never wired to any page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
149 lines
4.7 KiB
TypeScript
149 lines
4.7 KiB
TypeScript
import { Link } from 'react-router-dom';
|
|
import { Check } from 'lucide-react';
|
|
import { clsx } from 'clsx';
|
|
|
|
const PLANS = [
|
|
{
|
|
name: 'Starter',
|
|
price: 19,
|
|
desc: 'For small Odoo users',
|
|
popular: false,
|
|
features: [
|
|
'1 Odoo connection',
|
|
'1 MCP endpoint',
|
|
'Read-only tools',
|
|
'Token rotation',
|
|
'Claude/Codex setup guide',
|
|
'1,000 MCP requests/month',
|
|
'Email support',
|
|
],
|
|
cta: 'Start Free Trial',
|
|
href: '/signup?plan=starter',
|
|
},
|
|
{
|
|
name: 'Pro',
|
|
price: 49,
|
|
desc: 'For growing businesses',
|
|
popular: true,
|
|
features: [
|
|
'3 Odoo connections',
|
|
'Read / Write tools',
|
|
'Token rotation',
|
|
'Access logs',
|
|
'10,000 MCP requests/month',
|
|
'Priority support',
|
|
],
|
|
cta: 'Start Free Trial',
|
|
href: '/signup?plan=pro',
|
|
},
|
|
{
|
|
name: 'Agency',
|
|
price: 149,
|
|
desc: 'For agencies & consultants',
|
|
popular: false,
|
|
features: [
|
|
'25 client workspaces',
|
|
'White-label endpoint',
|
|
'Team members',
|
|
'Usage dashboard',
|
|
'Custom tool permissions',
|
|
'50,000 MCP requests/month',
|
|
],
|
|
cta: 'Start Free Trial',
|
|
href: '/signup?plan=agency',
|
|
},
|
|
{
|
|
name: 'Enterprise',
|
|
price: null,
|
|
desc: 'For large organisations',
|
|
popular: false,
|
|
features: [
|
|
'Dedicated MCP server',
|
|
'Private deployment',
|
|
'SSO / OAuth',
|
|
'Advanced audit logs',
|
|
'Custom Odoo modules',
|
|
'SLA & dedicated support',
|
|
],
|
|
cta: 'Contact Sales',
|
|
href: '/contact',
|
|
},
|
|
];
|
|
|
|
export default function Pricing() {
|
|
return (
|
|
<section id="pricing" className="py-20 bg-gray-50">
|
|
<div className="max-w-7xl mx-auto px-4">
|
|
<div className="text-center mb-12">
|
|
<h2 className="text-3xl font-bold text-gray-900 mb-3">Simple, transparent pricing</h2>
|
|
<p className="text-gray-600">Choose the plan that fits your business. All plans include 7-day free trial.</p>
|
|
</div>
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
{PLANS.map((plan) => (
|
|
<div
|
|
key={plan.name}
|
|
className={clsx(
|
|
'relative rounded-2xl p-6 flex flex-col',
|
|
plan.popular
|
|
? 'gradient-brand text-white shadow-xl scale-105'
|
|
: 'bg-white border border-gray-200 shadow-sm',
|
|
)}
|
|
>
|
|
{plan.popular && (
|
|
<div className="absolute -top-3 left-1/2 -translate-x-1/2 bg-yellow-400 text-yellow-900 text-xs font-bold px-3 py-1 rounded-full">
|
|
Most Popular
|
|
</div>
|
|
)}
|
|
<div className="mb-6">
|
|
<h3 className={clsx('font-bold text-lg mb-1', plan.popular ? 'text-white' : 'text-gray-900')}>
|
|
{plan.name}
|
|
</h3>
|
|
<p className={clsx('text-xs mb-4', plan.popular ? 'text-purple-200' : 'text-gray-500')}>
|
|
{plan.desc}
|
|
</p>
|
|
<div className="flex items-end gap-1">
|
|
{plan.price ? (
|
|
<>
|
|
<span className={clsx('text-4xl font-bold', plan.popular ? 'text-white' : 'text-gray-900')}>
|
|
${plan.price}
|
|
</span>
|
|
<span className={clsx('text-sm mb-1', plan.popular ? 'text-purple-200' : 'text-gray-500')}>
|
|
/month
|
|
</span>
|
|
</>
|
|
) : (
|
|
<span className={clsx('text-4xl font-bold', plan.popular ? 'text-white' : 'text-gray-900')}>
|
|
Custom
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<ul className="flex-1 space-y-2.5 mb-6">
|
|
{plan.features.map((f) => (
|
|
<li key={f} className="flex items-start gap-2 text-xs">
|
|
<Check size={13} className={clsx('mt-0.5 shrink-0', plan.popular ? 'text-purple-200' : 'text-brand-500')} />
|
|
<span className={plan.popular ? 'text-purple-100' : 'text-gray-700'}>{f}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
|
|
<Link
|
|
to={plan.href}
|
|
className={clsx(
|
|
'block text-center text-sm font-semibold px-4 py-2.5 rounded-xl transition-all',
|
|
plan.popular
|
|
? 'bg-white text-brand-700 hover:bg-purple-50'
|
|
: 'gradient-brand text-white hover:opacity-90',
|
|
)}
|
|
>
|
|
{plan.cta}
|
|
</Link>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|