From 69367da665e5d90b10028642a361d9db2d1ae83c Mon Sep 17 00:00:00 2001 From: "Nik (Claude)" Date: Tue, 16 Jun 2026 14:11:25 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20spending=20=E2=80=94=202=20separate=20p?= =?UTF-8?q?rovider=20blocks=20side=20by=20side?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AdminPanel.js | 125 ++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 60 deletions(-) diff --git a/components/AdminPanel.js b/components/AdminPanel.js index cb0103e..78f0d5f 100644 --- a/components/AdminPanel.js +++ b/components/AdminPanel.js @@ -339,67 +339,72 @@ function SpendingSection() { ))} - {/* По провайдерам — крупные карточки */} - {(() => { - const providers = [ - { key: 'aiprimetech', label: 'aiprimetech.io', icon: '💬', desc: 'Текст — статьи и посты', color: 'text-blue-400', bg: 'bg-blue-500/10', border: 'border-blue-500/20' }, - { key: 'routerai', label: 'routerai.ru', icon: '🖼', desc: 'Картинки к постам', color: 'text-purple-400', bg: 'bg-purple-500/10', border: 'border-purple-500/20' }, - ]; - const totalRub = providers.reduce((sum, p) => { - const d = byProv?.breakdown?.find(b => b.key === p.key); - return sum + Number(d?.cost_rub || 0); - }, 0); - return ( -
-
Расходы по провайдерам
- {providers.map(({ key, label, icon, desc, color, bg, border }) => { - const d = byProv?.breakdown?.find(b => b.key === key); - const rub = Number(d?.cost_rub || 0); - const pct = totalRub > 0 ? Math.round(rub / totalRub * 100) : 0; - const vol = key === 'routerai' - ? `${fmtI(d?.image_count || 0)} картинок` - : `${fmtI((d?.prompt_tokens||0)+(d?.completion_tokens||0))} токенов`; - return ( -
-
-
- {icon} -
-
{label}
-
{desc}
-
-
-
-
₽ {fmt(rub)}
-
{pct}% от общего
-
-
- {/* Прогресс-бар */} -
-
-
- {/* Метрики */} -
-
-
{fmtI(d?.calls)}
-
запросов
-
-
-
0 ? 'text-red-400' : 'text-gray-200'}`}>{d?.failed||0}
-
ошибок
-
-
-
{vol}
-
объём
-
-
+ {/* 2 отдельных блока — aiprimetech и routerai */} +
+ {/* aiprimetech — текст */} + {(() => { + const d = byProv?.breakdown?.find(b => b.key === 'aiprimetech'); + const rub = Number(d?.cost_rub || 0); + return ( +
+
+
💬
+
+
aiprimetech.io
+
Текст — статьи и посты
- ); - })} -
- ); - })()} +
+
₽ {fmt(rub)}
+
+
+
{fmtI(d?.calls)}
+
запросов
+
+
+
0 ? 'text-red-400' : 'text-gray-200'}`}>{d?.failed||0}
+
ошибок
+
+
+
{fmtI((d?.prompt_tokens||0)+(d?.completion_tokens||0))}
+
токенов
+
+
+
+ ); + })()} + + {/* routerai — картинки */} + {(() => { + const d = byProv?.breakdown?.find(b => b.key === 'routerai'); + const rub = Number(d?.cost_rub || 0); + return ( +
+
+
🖼
+
+
routerai.ru
+
Картинки к постам
+
+
+
₽ {fmt(rub)}
+
+
+
{fmtI(d?.calls)}
+
запросов
+
+
+
0 ? 'text-red-400' : 'text-gray-200'}`}>{d?.failed||0}
+
ошибок
+
+
+
{fmtI(d?.image_count||0)}
+
картинок
+
+
+
+ ); + })()} +
{/* Таблица по операциям */}