import { useState, useEffect } from 'react'
interface Price {
id: string
amount: number
formatted: string
interval: string
}
interface Tier {
name: string
key: string
description: string
features: string[]
prices: Price[]
highlighted?: boolean
}
const TIER_CONFIG: Record<string, Omit<Tier, 'prices'>> = {
basic: {
name: 'Basic',
key: 'basic',
description: 'Para profissionais autonomos',
features: ['1 usuario', '1.000 transacoes/mes', 'Suporte por email', 'Relatorios basicos'],
},
pro: {
name: 'Pro',
key: 'pro',
description: 'Para pequenas e medias empresas',
features: ['Ate 10 usuarios', '10.000 transacoes/mes', 'Suporte prioritario', 'Relatorios avancados', 'API completa'],
highlighted: true,
},
enterprise: {
name: 'Enterprise',
key: 'enterprise',
description: 'Para grandes operacoes',
features: ['Usuarios ilimitados', 'Transacoes ilimitadas', 'Suporte dedicado', 'SLA 99,9%', 'API completa', 'Webhooks customizados'],
},
}
export function PricingTable() {
const [tiers, setTiers] = useState<Tier[]>([])
const [billingInterval, setBillingInterval] = useState<'month' | 'year'>('month')
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch('/api/products/prod_xxxx')
.then(r => r.json())
.then(product => {
// Agrupar precos por tier
const grouped: Record<string, Price[]> = {}
for (const price of product.prices) {
const tier = price.metadata?.tier || 'default'
if (!grouped[tier]) grouped[tier] = []
grouped[tier].push({
id: price.id,
amount: price.priceAmount,
formatted: `R$ ${(price.priceAmount / 100).toFixed(2)}`,
interval: price.recurringInterval,
})
}
const tierList = Object.entries(TIER_CONFIG).map(([key, config]) => ({
...config,
prices: grouped[key] || [],
}))
setTiers(tierList)
setLoading(false)
})
}, [])
async function handleSubscribe(priceId: string) {
const res = await fetch('/api/subscriptions/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ priceId, customerEmail: 'user@email.com' }),
})
const { checkoutUrl } = await res.json()
window.location.href = checkoutUrl
}
if (loading) return <div>Carregando planos...</div>
return (
<div>
<h2 style={{ textAlign: 'center' }}>Escolha seu plano</h2>
{/* Toggle mensal/anual */}
<div style={{ display: 'flex', justifyContent: 'center', gap: '0.5rem', marginBottom: '2rem' }}>
<button
onClick={() => setBillingInterval('month')}
style={{
padding: '0.5rem 1rem',
borderRadius: '4px',
border: '1px solid #d1d5db',
background: billingInterval === 'month' ? '#2563eb' : 'white',
color: billingInterval === 'month' ? 'white' : '#374151',
cursor: 'pointer',
}}
>
Mensal
</button>
<button
onClick={() => setBillingInterval('year')}
style={{
padding: '0.5rem 1rem',
borderRadius: '4px',
border: '1px solid #d1d5db',
background: billingInterval === 'year' ? '#2563eb' : 'white',
color: billingInterval === 'year' ? 'white' : '#374151',
cursor: 'pointer',
}}
>
Anual <span style={{ fontSize: '0.75rem' }}>(-20%)</span>
</button>
</div>
{/* Cards de planos */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '1.5rem', maxWidth: '900px', margin: '0 auto' }}>
{tiers.map(tier => {
const price = tier.prices.find(p => p.interval === billingInterval)
if (!price) return null
return (
<div
key={tier.key}
style={{
border: tier.highlighted ? '2px solid #2563eb' : '1px solid #e5e7eb',
borderRadius: '12px',
padding: '2rem',
position: 'relative',
}}
>
{tier.highlighted && (
<span style={{
position: 'absolute', top: '-12px', left: '50%', transform: 'translateX(-50%)',
background: '#2563eb', color: 'white', padding: '2px 12px', borderRadius: '12px', fontSize: '0.75rem',
}}>
Mais popular
</span>
)}
<h3>{tier.name}</h3>
<p style={{ color: '#6b7280', fontSize: '0.875rem' }}>{tier.description}</p>
<p style={{ fontSize: '2rem', fontWeight: 'bold', margin: '1rem 0' }}>
{price.formatted}
<span style={{ fontSize: '1rem', fontWeight: 'normal', color: '#6b7280' }}>
/{billingInterval === 'month' ? 'mes' : 'ano'}
</span>
</p>
<button
onClick={() => handleSubscribe(price.id)}
style={{
width: '100%', padding: '0.75rem',
background: tier.highlighted ? '#2563eb' : 'white',
color: tier.highlighted ? 'white' : '#2563eb',
border: '1px solid #2563eb', borderRadius: '6px', cursor: 'pointer',
}}
>
Assinar {tier.name}
</button>
<ul style={{ marginTop: '1.5rem', listStyle: 'none', padding: 0 }}>
{tier.features.map(feature => (
<li key={feature} style={{ padding: '0.25rem 0', fontSize: '0.875rem' }}>
{feature}
</li>
))}
</ul>
</div>
)
})}
</div>
</div>
)
}