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", "totalUsers": "Users",
"totalReferrers": "Referrers", "totalReferrers": "Referrers",
"totalCampaigns": "Campaigns", "totalCampaigns": "Campaigns",
"totalEarnings": "Total earnings" "subscriptionRevenue": "Subscription revenue",
"totalEarnings": "Ref. earnings"
}, },
"legend": { "legend": {
"title": "Legend", "title": "Legend",

View File

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

View File

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

View File

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

View File

@@ -10,38 +10,51 @@ interface NetworkStatsProps {
export function NetworkStats({ data, className }: NetworkStatsProps) { export function NetworkStats({ data, className }: NetworkStatsProps) {
const { t } = useTranslation(); 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 ( return (
<div <div
className={`rounded-xl border border-dark-700/50 bg-dark-900/80 p-2 backdrop-blur-md sm:p-3 ${className ?? ''}`} 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"> <div className="grid grid-cols-2 gap-x-4 gap-y-1.5 sm:gap-x-6 sm:gap-y-2">
{stats.map((stat) => ( <div>
<div key={stat.label}>
<p className="text-[10px] font-medium uppercase tracking-wider text-dark-500"> <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>
<p className="font-mono text-sm font-semibold text-dark-100">{stat.value}</p>
</div> </div>
))}
</div> </div>
</div> </div>
); );

View File

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