'use client'; import { useState, useEffect } from 'react'; import { Loader2, Plus, RefreshCw, Search } from 'lucide-react'; const PLAN_BADGE = { free: 'bg-gray-600 text-gray-200', starter: 'bg-blue-600 text-white', pro: 'bg-purple-600 text-white', business: 'bg-yellow-600 text-black', }; export default function AdminBillingPage() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [search, setSearch] = useState(''); const [crediting, setCrediting] = useState(null); // user being credited const [amount, setAmount] = useState(''); const [desc, setDesc] = useState(''); const [saving, setSaving] = useState(false); async function load() { setLoading(true); const res = await fetch('/api/billing/admin/users').then(r => r.json()); setUsers(Array.isArray(res) ? res : []); setLoading(false); } useEffect(() => { load(); }, []); async function handleCredit(userId) { if (!amount || isNaN(parseInt(amount))) return; setSaving(true); await fetch('/api/billing/admin/credit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user_id: userId, amount: parseInt(amount), description: desc || undefined }), }); setCrediting(null); setAmount(''); setDesc(''); setSaving(false); load(); } const filtered = users.filter(u => !search || u.email?.toLowerCase().includes(search.toLowerCase()) || u.name?.toLowerCase().includes(search.toLowerCase()) ); return (

Балансы пользователей

setSearch(e.target.value)} placeholder="Поиск по email..." className="input pl-8 py-1.5 text-sm w-48" />
{loading &&
} {!loading && (
{filtered.map(u => ( <> {crediting === u.id && ( )} ))} {!filtered.length && ( )}
Пользователь Тариф Кредиты Сброс Действия
{u.name || u.email}
{u.name &&
{u.email}
}
{u.plan_name || 'Free'} {u.credits ?? 0} {u.reset_at ? new Date(u.reset_at).toLocaleDateString('ru-RU') : '—'}
setAmount(e.target.value)} placeholder="Кол-во кредитов" className="input py-1.5 text-sm w-36" autoFocus /> setDesc(e.target.value)} placeholder="Комментарий (необязательно)" className="input py-1.5 text-sm flex-1 min-w-40" />
Пользователи не найдены
)}
); }