feat: add system info card to admin dashboard

Shows cabinet version, bot version, Python version, uptime, users and
active subscriptions at the bottom of the dashboard page.
This commit is contained in:
Fringg
2026-02-08 22:52:14 +03:00
parent 5678dfd558
commit ab0270ac58
9 changed files with 107 additions and 1 deletions

View File

@@ -5,10 +5,13 @@ import {
statsApi,
type DashboardStats,
type NodeStatus,
type SystemInfo,
type TopReferrersResponse,
type TopCampaignsResponse,
type RecentPaymentsResponse,
} from '../api/admin';
const CABINET_VERSION = __APP_VERSION__;
import { useCurrency } from '../hooks/useCurrency';
import { usePlatform } from '../platform/hooks/usePlatform';
@@ -375,6 +378,7 @@ export default function AdminDashboard() {
const [campaigns, setCampaigns] = useState<TopCampaignsResponse | null>(null);
const [payments, setPayments] = useState<RecentPaymentsResponse | null>(null);
const [referrersTab, setReferrersTab] = useState<'earnings' | 'invited'>('earnings');
const [systemInfo, setSystemInfo] = useState<SystemInfo | null>(null);
const fetchStats = useCallback(async () => {
try {
@@ -392,14 +396,16 @@ export default function AdminDashboard() {
const fetchExtendedStats = useCallback(async () => {
try {
const [referrersData, campaignsData, paymentsData] = await Promise.all([
const [referrersData, campaignsData, paymentsData, sysInfoData] = await Promise.all([
statsApi.getTopReferrers(10),
statsApi.getTopCampaigns(10),
statsApi.getRecentPayments(20),
statsApi.getSystemInfo(),
]);
setReferrers(referrersData);
setCampaigns(campaignsData);
setPayments(paymentsData);
setSystemInfo(sysInfoData);
} catch (err) {
console.error('Failed to load extended stats:', err);
}
@@ -1137,6 +1143,49 @@ export default function AdminDashboard() {
</div>
</div>
)}
{/* System Info */}
{systemInfo && (
<div className="rounded-xl border border-dark-700 bg-dark-800 p-4">
<h3 className="mb-3 text-sm font-semibold text-dark-300">
{t('adminDashboard.systemInfo.title')}
</h3>
<div className="flex flex-wrap gap-x-6 gap-y-2 text-sm">
<div>
<span className="text-dark-500">{t('adminDashboard.systemInfo.cabinet')}: </span>
<span className="font-medium text-dark-200">v{CABINET_VERSION}</span>
</div>
<div>
<span className="text-dark-500">{t('adminDashboard.systemInfo.bot')}: </span>
<span className="font-medium text-dark-200">v{systemInfo.bot_version}</span>
</div>
<div>
<span className="text-dark-500">{t('adminDashboard.systemInfo.python')}: </span>
<span className="font-medium text-dark-200">{systemInfo.python_version}</span>
</div>
<div>
<span className="text-dark-500">{t('adminDashboard.systemInfo.uptime')}: </span>
<span className="font-medium text-dark-200">
{(() => {
const s = systemInfo.uptime_seconds;
const d = Math.floor(s / 86400);
const h = Math.floor((s % 86400) / 3600);
const m = Math.floor((s % 3600) / 60);
return [d > 0 && `${d}d`, h > 0 && `${h}h`, `${m}m`].filter(Boolean).join(' ');
})()}
</span>
</div>
<div>
<span className="text-dark-500">{t('adminDashboard.systemInfo.users')}: </span>
<span className="font-medium text-dark-200">{systemInfo.users_total}</span>
</div>
<div>
<span className="text-dark-500">{t('adminDashboard.systemInfo.activeSubs')}: </span>
<span className="font-medium text-dark-200">{systemInfo.subscriptions_active}</span>
</div>
</div>
</div>
)}
</div>
);
}