feat: show subscription revenue and referral earnings in network stats

Add subscription revenue (total from subscription payments) to the
stats panel alongside referral earnings. Layout updated to 2-column
grid with subscription revenue highlighted in accent color.
This commit is contained in:
Fringg
2026-03-22 10:31:29 +03:00
parent ebe2c3af7e
commit 5b12784ab8
6 changed files with 50 additions and 32 deletions

View File

@@ -1247,7 +1247,8 @@
"totalUsers": "Users",
"totalReferrers": "Referrers",
"totalCampaigns": "Campaigns",
"totalEarnings": "Total earnings"
"subscriptionRevenue": "Subscription revenue",
"totalEarnings": "Ref. earnings"
},
"legend": {
"title": "Legend",

View File

@@ -1081,7 +1081,8 @@
"totalUsers": "کاربران",
"totalReferrers": "ارجاع‌دهندگان",
"totalCampaigns": "کمپین‌ها",
"totalEarnings": "درآمد کل"
"subscriptionRevenue": "درآمد اشتراک",
"totalEarnings": "درآمد ارجاع"
},
"legend": {
"title": "راهنما",

View File

@@ -1268,7 +1268,8 @@
"totalUsers": "Пользователей",
"totalReferrers": "Рефереров",
"totalCampaigns": "Кампаний",
"totalEarnings": "Общий доход"
"subscriptionRevenue": "Доход с подписок",
"totalEarnings": "Реф. доход"
},
"legend": {
"title": "Легенда",

View File

@@ -1081,7 +1081,8 @@
"totalUsers": "用户",
"totalReferrers": "推荐人",
"totalCampaigns": "活动",
"totalEarnings": "收入"
"subscriptionRevenue": "订阅收入",
"totalEarnings": "推荐收入"
},
"legend": {
"title": "图例",

View File

@@ -10,38 +10,51 @@ interface NetworkStatsProps {
export function NetworkStats({ data, className }: NetworkStatsProps) {
const { t } = useTranslation();
const stats = [
{
label: t('admin.referralNetwork.stats.totalUsers'),
value: data.total_users.toLocaleString(),
},
{
label: t('admin.referralNetwork.stats.totalReferrers'),
value: data.total_referrers.toLocaleString(),
},
{
label: t('admin.referralNetwork.stats.totalCampaigns'),
value: data.total_campaigns.toLocaleString(),
},
{
label: t('admin.referralNetwork.stats.totalEarnings'),
value: `${formatKopeksToRubles(data.total_earnings_kopeks)}`,
},
];
return (
<div
className={`rounded-xl border border-dark-700/50 bg-dark-900/80 p-2 backdrop-blur-md sm:p-3 ${className ?? ''}`}
>
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-2 sm:gap-3">
{stats.map((stat) => (
<div key={stat.label}>
<div className="grid grid-cols-2 gap-x-4 gap-y-1.5 sm:gap-x-6 sm:gap-y-2">
<div>
<p className="text-[10px] font-medium uppercase tracking-wider text-dark-500">
{stat.label}
{t('admin.referralNetwork.stats.totalUsers')}
</p>
<p className="font-mono text-sm font-semibold text-dark-100">
{data.total_users.toLocaleString()}
</p>
</div>
<div>
<p className="text-[10px] font-medium uppercase tracking-wider text-dark-500">
{t('admin.referralNetwork.stats.totalReferrers')}
</p>
<p className="font-mono text-sm font-semibold text-dark-100">
{data.total_referrers.toLocaleString()}
</p>
</div>
<div>
<p className="text-[10px] font-medium uppercase tracking-wider text-dark-500">
{t('admin.referralNetwork.stats.totalCampaigns')}
</p>
<p className="font-mono text-sm font-semibold text-dark-100">
{data.total_campaigns.toLocaleString()}
</p>
</div>
<div>
<p className="text-[10px] font-medium uppercase tracking-wider text-dark-500">
{t('admin.referralNetwork.stats.subscriptionRevenue')}
</p>
<p className="font-mono text-sm font-semibold text-accent-400">
{formatKopeksToRubles(data.total_subscription_revenue_kopeks)}
</p>
</div>
<div className="col-span-2 border-t border-dark-700/30 pt-1.5">
<p className="text-[10px] font-medium uppercase tracking-wider text-dark-500">
{t('admin.referralNetwork.stats.totalEarnings')}
</p>
<p className="font-mono text-sm font-semibold text-dark-100">
{formatKopeksToRubles(data.total_earnings_kopeks)}
</p>
<p className="font-mono text-sm font-semibold text-dark-100">{stat.value}</p>
</div>
))}
</div>
</div>
);

View File

@@ -51,6 +51,7 @@ export interface NetworkGraphData {
total_referrers: number;
total_campaigns: number;
total_earnings_kopeks: number;
total_subscription_revenue_kopeks: number;
}
export interface NetworkUserDetail {