93 lines
4.4 KiB
TypeScript
93 lines
4.4 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect } from 'react'
|
|
import Link from 'next/link'
|
|
|
|
const plans = [
|
|
{ name: 'Free', price: '$0', credits: '30 / month', features: ['9 endpoints', '1 concurrent', 'Community support'] },
|
|
{ name: 'Hobby', price: '$9', credits: '1,000 / month', features: ['9 endpoints', '3 concurrent', 'Email support', 'Webhooks'] },
|
|
{ name: 'Starter', price: '$19', credits: '3,000 / month', features: ['9 endpoints', '5 concurrent', 'Priority support', 'Webhooks', 'AI extraction'] },
|
|
{ name: 'Pro', price: '$49', credits: '10,000 / month', features: ['All endpoints', '10 concurrent', 'Priority support', 'Webhooks', 'AI extraction', 'Proxy rotation'] },
|
|
{ name: 'Startup', price: '$99', credits: '25,000 / month', features: ['All endpoints', '20 concurrent', 'Dedicated support', 'Custom integrations', 'SLA'] },
|
|
]
|
|
|
|
export default function Billing() {
|
|
const [token, setToken] = useState('')
|
|
const [credits, setCredits] = useState<number | null>(null)
|
|
const [usage, setUsage] = useState(0)
|
|
|
|
useEffect(() => {
|
|
const t = localStorage.getItem('crawlapi_token')
|
|
if (t) {
|
|
setToken(t)
|
|
fetchUser(t)
|
|
}
|
|
}, [])
|
|
|
|
async function fetchUser(t: string) {
|
|
try {
|
|
const res = await fetch('http://localhost:3000/api/auth/api-keys', {
|
|
headers: { 'x-auth-token': t }
|
|
})
|
|
// Just a mock - in production this would call a /me endpoint
|
|
setCredits(30)
|
|
setUsage(12)
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<main style={{ maxWidth: 1200, margin: '0 auto', padding: '40px 20px' }}>
|
|
<nav style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 40 }}>
|
|
<Link href="/" style={{ fontSize: 24, fontWeight: 700, color: '#fff', textDecoration: 'none' }}>Crawl API</Link>
|
|
<Link href="/" style={{ color: '#888', textDecoration: 'none' }}>← Back</Link>
|
|
</nav>
|
|
|
|
<h1 style={{ fontSize: 36, marginBottom: 8 }}>Billing</h1>
|
|
<p style={{ color: '#888', marginBottom: 40 }}>Manage your subscription and usage.</p>
|
|
|
|
{token && credits !== null && (
|
|
<div style={{ background: '#111', borderRadius: 12, padding: 24, marginBottom: 40 }}>
|
|
<h3 style={{ marginTop: 0 }}>Current Usage</h3>
|
|
<div style={{ display: 'flex', gap: 40, marginTop: 16 }}>
|
|
<div>
|
|
<div style={{ fontSize: 32, fontWeight: 700 }}>{credits - usage}</div>
|
|
<div style={{ color: '#888', fontSize: 14 }}>Credits remaining</div>
|
|
</div>
|
|
<div>
|
|
<div style={{ fontSize: 32, fontWeight: 700 }}>{usage}</div>
|
|
<div style={{ color: '#888', fontSize: 14 }}>Used this month</div>
|
|
</div>
|
|
<div>
|
|
<div style={{ fontSize: 32, fontWeight: 700 }}>{credits}</div>
|
|
<div style={{ color: '#888', fontSize: 14 }}>Total credits</div>
|
|
</div>
|
|
</div>
|
|
<div style={{ marginTop: 16, background: '#1a1a1a', borderRadius: 8, height: 8, overflow: 'hidden' }}>
|
|
<div style={{ width: `${(usage / credits) * 100}%`, background: '#4ade80', height: '100%' }} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 16 }}>
|
|
{plans.map(plan => (
|
|
<div key={plan.name} style={{ background: '#111', borderRadius: 12, padding: 24, border: plan.name === 'Hobby' ? '1px solid #4ade80' : '1px solid transparent' }}>
|
|
<div style={{ fontSize: 14, color: '#888', marginBottom: 8 }}>{plan.name}</div>
|
|
<div style={{ fontSize: 36, fontWeight: 700, marginBottom: 8 }}>{plan.price}<span style={{ fontSize: 14, color: '#888' }}>/mo</span></div>
|
|
<div style={{ fontSize: 14, marginBottom: 16, color: '#4ade80' }}>{plan.credits}</div>
|
|
<ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
|
|
{plan.features.map((f, i) => (
|
|
<li key={i} style={{ padding: '4px 0', fontSize: 14, color: '#aaa' }}>✓ {f}</li>
|
|
))}
|
|
</ul>
|
|
<button style={{ width: '100%', marginTop: 16, padding: '10px', background: plan.name === 'Hobby' ? '#4ade80' : '#fff', color: '#000', borderRadius: 6, border: 'none', fontWeight: 600, cursor: 'pointer' }}>
|
|
{plan.name === 'Free' ? 'Current Plan' : 'Upgrade'}
|
|
</button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</main>
|
|
)
|
|
}
|