'use client'; import { useEffect, useState } from 'react'; import { useTranslations } from 'next-intl'; import { Link, useRouter } from '@/i18n/navigation'; import { useAuth } from '@/lib/hooks/useAuth'; import { authApi } from '@/lib/api/auth'; import { Button } from '@/components/ui/shared/Button'; import { Toast } from '@/components/ui/shared/Toast'; import type { SubscriptionAlertData } from '@/types/subscription'; const PLAN_OPTIONS = [ { id: 'solo', nameKey: 'planSolo' as const, maxUsers: 1, price: 19 }, { id: 'small', nameKey: 'planSmall' as const, maxUsers: 5, price: 49 }, { id: 'medium', nameKey: 'planMedium' as const, maxUsers: 10, price: 89 }, { id: 'large', nameKey: 'planLarge' as const, maxUsers: 15, price: 129 }, { id: 'enterprise', nameKey: 'planEnterprise' as const, maxUsers: null, price: 199 }, ] as const; export default function SubscriptionsSettingsPage() { const t = useTranslations('settings'); const tCommon = useTranslations('common'); const { currentOrganization } = useAuth(); const router = useRouter(); const [alert, setAlert] = useState(null); const [selectedPlanId, setSelectedPlanId] = useState(PLAN_OPTIONS[0].id); const [purchaseNotice, setPurchaseNotice] = useState(null); useEffect(() => { if (currentOrganization && !currentOrganization.isOwner) { router.replace('/today'); } }, [currentOrganization, router]); useEffect(() => { if (!currentOrganization?.isOwner) return; void authApi.getSubscriptionAlert().then((r) => { if (r.success) setAlert(r.data); }); }, [currentOrganization?.id, currentOrganization?.isOwner]); if (!currentOrganization) { return (

{tCommon('loadingEllipsis')}

); } if (!currentOrganization.isOwner) { return (

{tCommon('redirecting')}

); } const plan = currentOrganization.plan; const hasActiveSubscription = Boolean(plan); const selectedPlan = PLAN_OPTIONS.find((option) => option.id === selectedPlanId); const maxUsers = plan?.maxUsers; const isUnlimited = typeof maxUsers === 'number' && maxUsers >= 999999; const seatsUsed = alert?.seatsUsed; const seatsRemaining = typeof seatsUsed === 'number' && typeof maxUsers === 'number' && !isUnlimited ? Math.max(0, maxUsers - seatsUsed) : null; const daysUntilPlanEnd = alert?.daysUntilPlanEnd ?? null; const planDayTone = daysUntilPlanEnd == null ? 'text-text-primary' : daysUntilPlanEnd > 20 ? 'text-emerald-400' : daysUntilPlanEnd >= 10 ? 'text-amber-300' : 'text-red-400'; return (
{tCommon('backToApp')}

{t('subscriptionsTitle')}

{t('subscriptionsSubtitle', { orgName: currentOrganization.name })}

{!hasActiveSubscription && (

{t('noSubscriptionNotice')}

)}

{t('currentPlan')}

{plan?.name ?? '—'}

{t('planPrice')}

{typeof plan?.price === 'number' ? `$${plan.price}` : '—'}

{t('seatsUsed')}

{typeof seatsUsed === 'number' ? seatsUsed : '—'} {typeof maxUsers === 'number' ? ` / ${isUnlimited ? t('unlimited') : maxUsers}` : ''}

{t('seatsRemaining')}

{isUnlimited ? t('unlimited') : seatsRemaining ?? '—'}

{t('daysRemaining')}

{daysUntilPlanEnd ?? '—'}

{alert?.showWarning && (
{alert.noActiveSubscription && (

{t('noActiveSubscription')}

)} {alert.trialExpired && (

{t('trialEnded')}

)} {!alert.trialExpired && alert.trialEndingSoon && (

{t('trialEndsIn', { days: alert.daysUntilTrialEnd ?? '—' })}

)} {!alert.trialExpired && !alert.trialEndingSoon && alert.seatsLow && (

{t('seatsLow')}

)}
)}

{t('choosePlanIntro')}

{PLAN_OPTIONS.map((option) => { const selected = selectedPlanId === option.id; return ( ); })}
{purchaseNotice && (
{purchaseNotice}
)}
); }