'use client' import { useState, useTransition } from 'react' import { useRouter } from 'next/navigation' import { Zap, Check, CreditCard, AlertCircle, Loader2, ExternalLink, Calendar, Shield } from 'lucide-react' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Alert, AlertDescription } from '@/components/ui/alert' import { Separator } from '@/components/ui/separator' interface BillingSettingsProps { currentPlan: 'free' | 'pro' subscriptionStatus?: string | null subscriptionEnd?: Date | null cancelAtPeriodEnd?: boolean } export function BillingSettings({ currentPlan, subscriptionStatus, subscriptionEnd, cancelAtPeriodEnd, }: BillingSettingsProps) { const router = useRouter() const [isPending, startTransition] = useTransition() const [error, setError] = useState(null) const isPro = currentPlan === 'pro' && subscriptionStatus === 'active' const isTrial = subscriptionStatus === 'trialing' const isPastDue = subscriptionStatus === 'past_due' const handleUpgrade = () => { setError(null) startTransition(async () => { try { const res = await fetch('/api/stripe/checkout', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ plan: 'pro_monthly' }), }) const data = await res.json() if (data.url) { window.location.href = data.url } else { setError(data.error || 'Failed to start checkout') } } catch { setError('Something went wrong. Please try again.') } }) } const handleManageBilling = () => { setError(null) startTransition(async () => { try { const res = await fetch('/api/stripe/portal', { method: 'POST' }) const data = await res.json() if (data.url) { window.location.href = data.url } else { setError(data.error || 'Failed to open billing portal') } } catch { setError('Something went wrong. Please try again.') } }) } return (
{/* Current plan card */} Current Plan Manage your subscription and billing information
{currentPlan} Plan {isTrial && ( Free Trial )} {isPastDue && ( Payment Failed )} {cancelAtPeriodEnd && ( Cancels soon )}

{isPro || isTrial ? 'Unlimited executions · API access · Private prompts' : '10 executions/hr · 10 prompts · Community access'}

{isPro || isTrial ? '$9' : '$0'}

{isPro || isTrial ? '/month' : 'forever'}

{/* Subscription details */} {subscriptionEnd && (
{cancelAtPeriodEnd ? ( Access ends on{' '} {new Date(subscriptionEnd).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric', })} ) : ( Next billing date:{' '} {new Date(subscriptionEnd).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric', })} )}
)} {/* Payment failed warning */} {isPastDue && ( Your last payment failed. Please update your payment method to continue Pro access. )} {error && ( {error} )} {/* CTA buttons */}
{isPro || isTrial ? ( ) : ( )}
{/* Feature comparison */} Plan Features
{[ { feature: 'Public prompt access', free: true, pro: true }, { feature: 'AI tool executions', free: '10/hr', pro: 'Unlimited' }, { feature: 'Create prompts', free: '10 max', pro: 'Unlimited' }, { feature: 'Private prompts', free: false, pro: true }, { feature: 'REST API access', free: false, pro: true }, { feature: 'Execution history', free: false, pro: true }, { feature: 'Advanced analytics', free: false, pro: true }, { feature: 'Remove embed branding', free: false, pro: true }, { feature: 'Priority support', free: false, pro: true }, ].map((row) => (
{row.feature}
{row.free === true ? ( ) : row.free === false ? ( ) : ( {row.free} )} {row.pro === true ? ( ) : ( {row.pro} )}
))}
FREE PRO
{/* Security note */}
Payments are securely processed by{' '} Stripe . We never store your card details.
) }