'use client'; import { useState, useEffect } from 'react'; import { Check, Zap, Loader2 } from 'lucide-react'; import Link from 'next/link'; const PLAN_STYLE = { free: { color: 'border-border', badge: null, btnClass: 'btn-ghost' }, starter: { color: 'border-blue-500/50', badge: null, btnClass: 'btn-primary' }, pro: { color: 'border-purple-500/60', badge: 'Популярный', btnClass: 'bg-purple-600 hover:bg-purple-500 text-white px-4 py-2 rounded-lg font-medium transition-colors' }, business: { color: 'border-yellow-500/40', badge: 'Для агентств', btnClass: 'bg-yellow-600 hover:bg-yellow-500 text-white px-4 py-2 rounded-lg font-medium transition-colors' }, }; const FEATURES = { free: ['1 канал', '50 кредитов/мес', 'TG и VK публикация', 'Ручная генерация'], starter: ['2 канала', '500 кредитов/мес', 'Автогенерация постов', 'Календарь публикаций', 'Аналитика канала'], pro: ['5 каналов', '2000 кредитов/мес', 'Всё из Starter', 'Приоритетная генерация', 'История контента'], business: ['Без ограничений', 'Безлимит кредитов', 'Всё из Pro', 'Поддержка 24/7', 'API доступ'], }; export default function PlansPage() { const [plans, setPlans] = useState([]); const [costs, setCosts] = useState({}); const [balance, setBalance] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { Promise.all([ fetch('/api/billing/plans').then(r => r.json()), fetch('/api/billing/balance').then(r => r.json()).catch(() => null), ]).then(([pd, bd]) => { setPlans(pd.plans || []); setCosts(Object.fromEntries((pd.costs || []).map(c => [c.operation, c.credits]))); setBalance(bd); setLoading(false); }); }, []); if (loading) return (
); return (

Тарифы

Выберите план под ваши задачи. Все планы включают публикацию в TG и VK.

{balance && (

Сейчас у вас: {balance.planName} · {balance.isUnlimited ? '∞' : balance.credits} кредитов

)}
{/* Карточки планов */}
{plans.map(plan => { const style = PLAN_STYLE[plan.code] || PLAN_STYLE.free; const features = FEATURES[plan.code] || []; const isCurrent = balance?.plan === plan.code; const isUnlimited = plan.credits_month === -1; return (
{style.badge && (
{style.badge}
)}
{plan.name}
{plan.price_rub === 0 ? Бесплатно : <>₽{plan.price_rub}/мес }
{isUnlimited ? '∞ кредитов' : `${plan.credits_month} кредитов/мес`}
    {features.map(f => (
  • {f}
  • ))}
{isCurrent ? (
Текущий план
) : plan.price_rub === 0 ? ( Начать бесплатно ) : ( )}
); })}
{/* Стоимость операций */}

Стоимость генерации

{[ { label: 'Картинка', op: 'image', icon: '🖼', note: 'gpt-5-image-mini' }, { label: 'Пост', op: 'text_post', icon: '✍️', note: 'aiprimetech' }, { label: 'Статья', op: 'article', icon: '📝', note: 'Claude Sonnet' }, { label: 'Публикация', op: 'autopublish',icon: '📤', note: 'TG / VK / MAX' }, ].map(op => (
{op.icon}
{op.label}
{(costs[op.op] || 0) === 0 ? 'бесплатно' : `${costs[op.op]} кр`}
{op.note}
))}
{/* FAQ */}

Часто спрашивают

{[ ['Что такое кредиты?', '1 кредит = 1 рубль. Кредиты списываются при каждой AI-генерации. Публикация постов — всегда бесплатна.'], ['Что будет если кредиты закончатся?', 'Генерация будет заблокирована до пополнения. Уже опубликованные посты и автопостинг продолжают работать.'], ['Переносятся ли кредиты на следующий месяц?', 'Нет, кредиты по тарифу сбрасываются раз в 30 дней. Дополнительно купленные кредиты не сгорают.'], ['Можно ли купить кредиты отдельно?', 'Скоро. Сейчас кредиты начисляются только по тарифному плану.'], ].map(([q, a]) => (
{q}

{a}

))}
); }