'use client'; import { useState, useEffect } from 'react'; import { Coins, RefreshCw, TrendingDown, TrendingUp, Loader2, ArrowRight } from 'lucide-react'; import Link from 'next/link'; const TYPE_LABELS = { spend_image: { label: 'Генерация картинки', sign: '-', color: 'text-red-400' }, spend_text_post: { label: 'Генерация поста', sign: '-', color: 'text-red-400' }, spend_article: { label: 'Генерация статьи', sign: '-', color: 'text-red-400' }, spend_autopublish:{ label: 'Публикация', sign: '-', color: 'text-gray-400' }, plan_credit: { label: 'Начисление по тарифу',sign: '+', color: 'text-green-400' }, topup: { label: 'Пополнение', sign: '+', color: 'text-green-400' }, bonus: { label: 'Бонус', sign: '+', color: 'text-blue-400' }, refund: { label: 'Возврат', sign: '+', color: 'text-blue-400' }, }; function fmtDate(s) { const d = new Date(s); return d.toLocaleString('ru-RU', { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' }); } export default function BillingPage() { const [balance, setBalance] = useState(null); const [txs, setTxs] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(true); const [page, setPage] = useState(0); const PER_PAGE = 30; async function load(p = 0) { setLoading(true); try { const [balRes, txRes] = await Promise.all([ fetch('/api/billing/balance').then(r => r.json()), fetch(`/api/billing/transactions?limit=${PER_PAGE}&offset=${p * PER_PAGE}`).then(r => r.json()), ]); setBalance(balRes); setTxs(txRes.transactions || []); setTotal(txRes.total || 0); } catch {} setLoading(false); } useEffect(() => { load(0); }, []); const PLAN_COLORS = { free: 'text-gray-400', starter: 'text-blue-400', pro: 'text-purple-400', business: 'text-yellow-400' }; return (

Баланс и кредиты

{/* Баланс */} {balance && (
{balance.isUnlimited ? '∞' : balance.credits}
кредитов осталось
{balance.planName}
текущий тариф
{balance.resetAt ? new Date(balance.resetAt).toLocaleDateString('ru-RU') : '—'}
сброс кредитов
)} {/* CTA апгрейд */} {balance?.plan === 'free' && (
Хотите больше кредитов?
Starter — 500 кредитов за ₽490/мес
Тарифы
)} {/* Стоимость операций */}
Стоимость операций
{[ { label: 'Картинка', credits: 5, icon: '🖼' }, { label: 'Пост', credits: 2, icon: '✍️' }, { label: 'Статья', credits: 5, icon: '📝' }, { label: 'Публикация', credits: 0, icon: '📤' }, ].map(op => (
{op.icon}
{op.label}
{op.credits === 0 ? 'бесплатно' : `${op.credits} кр`}
))}
{/* История транзакций */}

История

{loading &&
} {!loading && (
{txs.length === 0 && (
Транзакций пока нет
)} {txs.map(tx => { const meta = TYPE_LABELS[tx.type] || { label: tx.type, sign: tx.amount > 0 ? '+' : '-', color: 'text-gray-400' }; return (
{tx.description || meta.label}
{fmtDate(tx.created_at)}
{meta.sign}{Math.abs(tx.amount)} кр
= {tx.balance_after === -1 ? '∞' : tx.balance_after} кр
); })}
)} {/* Пагинация */} {total > PER_PAGE && (
{page+1} / {Math.ceil(total/PER_PAGE)}
)}
); }