'use client' import { useState, useEffect } from 'react' import { Container, Box, Typography, Button, Card, CardContent, Paper, LinearProgress, Chip, CircularProgress, Alert, Switch, FormControlLabel, Divider } from '@mui/material' import { CheckCircle, Favorite, TrendingUp, Settings as SettingsIcon } from '@mui/icons-material' import { useRouter } from 'next/navigation' import { useTranslations, useLocale } from 'next-intl' interface UserSubscriptionData { tier: string status: string conversationLimit: number conversationCount: number limitResetDate: string | null } const STRIPE_PRICES = { monthly: process.env.NEXT_PUBLIC_STRIPE_PREMIUM_MONTHLY_PRICE_ID || '', yearly: process.env.NEXT_PUBLIC_STRIPE_PREMIUM_YEARLY_PRICE_ID || '' } export default function SubscriptionPage() { const router = useRouter() const locale = useLocale() const t = useTranslations('subscription') const [loading, setLoading] = useState(true) const [processing, setProcessing] = useState(false) const [error, setError] = useState('') const [userData, setUserData] = useState(null) const [billingInterval, setBillingInterval] = useState<'month' | 'year'>('month') useEffect(() => { fetchUserData() }, []) const fetchUserData = async () => { try { const token = localStorage.getItem('authToken') if (!token) { router.push(`/${locale}/login`) return } const response = await fetch('/api/user/profile', { headers: { 'Authorization': `Bearer ${token}` } }) if (response.ok) { const data = await response.json() setUserData({ tier: data.user.subscriptionTier || 'free', status: data.user.subscriptionStatus || 'active', conversationLimit: data.user.conversationLimit || 10, conversationCount: data.user.conversationCount || 0, limitResetDate: data.user.limitResetDate }) } else { setError(t('errors.loadFailed')) } } catch (err) { console.error('Error fetching user data:', err) setError(t('errors.generic')) } finally { setLoading(false) } } const handleUpgrade = async () => { setProcessing(true) setError('') try { const token = localStorage.getItem('authToken') if (!token) { router.push(`/${locale}/login`) return } const priceId = billingInterval === 'month' ? STRIPE_PRICES.monthly : STRIPE_PRICES.yearly const response = await fetch('/api/subscriptions/checkout', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ priceId, interval: billingInterval, locale }) }) const data = await response.json() if (data.success && data.url) { window.location.href = data.url } else { setError(data.error || t('errors.checkoutFailed')) } } catch (err) { console.error('Error creating checkout:', err) setError(t('errors.generic')) } finally { setProcessing(false) } } const handleManageSubscription = async () => { setProcessing(true) setError('') try { const token = localStorage.getItem('authToken') if (!token) { router.push(`/${locale}/login`) return } const response = await fetch('/api/subscriptions/portal', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ locale }) }) const data = await response.json() if (data.success && data.url) { window.location.href = data.url } else { setError(data.error || t('errors.portalFailed')) } } catch (err) { console.error('Error opening portal:', err) setError(t('errors.generic')) } finally { setProcessing(false) } } const formatResetDate = (dateString: string | null) => { if (!dateString) return '' const date = new Date(dateString) return date.toLocaleDateString(locale, { year: 'numeric', month: 'long', day: 'numeric' }) } const isPremium = userData?.tier === 'premium' const usagePercentage = userData ? (userData.conversationCount / userData.conversationLimit) * 100 : 0 const remaining = userData ? Math.max(0, userData.conversationLimit - userData.conversationCount) : 0 if (loading) { return ( ) } return ( {/* Header */} {t('title')} {t('subtitle')} {/* Error Alert */} {error && ( setError('')}> {error} )} {/* Current Plan & Usage */} {userData && ( {t('currentPlan')} {isPremium && ( )} {isPremium && ( )} {/* Usage Statistics */} {t('usage.title')} {t('usage.conversations')} {isPremium ? ( t('usage.unlimited') ) : ( `${userData.conversationCount} ${t('usage.of')} ${userData.conversationLimit}` )} {!isPremium && ( <> {remaining} {t('usage.remaining')} • {t('usage.resetsOn')} {formatResetDate(userData.limitResetDate)} )} )} {/* Billing Interval Toggle */} {!isPremium && ( setBillingInterval(e.target.checked ? 'year' : 'month')} /> } label={ {t('billing.yearly')} } /> )} {/* Plan Comparison */} {/* Free Plan */} {t('free.name')} {t('free.price')} {t('free.period')} {t('free.description')} {[ t('free.features.conversations'), t('free.features.bible'), t('free.features.prayer'), t('free.features.bookmarks') ].map((feature, index) => ( {feature} ))} {/* Premium Plan */} {!isPremium && ( )} {t('premium.name')} {billingInterval === 'month' ? t('premium.priceMonthly') : t('premium.priceYearly')} {billingInterval === 'month' ? t('premium.periodMonthly') : t('premium.periodYearly')} {t('premium.description')} {[ t('premium.features.conversations'), t('premium.features.bible'), t('premium.features.prayer'), t('premium.features.bookmarks'), t('premium.features.support'), t('premium.features.early') ].map((feature, index) => ( {feature} ))} ) }