feat: enhance sales stats with device stats, per-tariff charts, and dual-series trials

- Add DualAreaChart component for two-series visualization (registrations vs trials)
- Add MultiSeriesAreaChart component for N-series tariff breakdown with dynamic pivoting
- AddonsTab: add device purchases and device revenue stat cards
- SalesTab: add per-tariff daily sales chart using MultiSeriesAreaChart
- TrialsTab: replace single-series area chart with dual-series registrations + trials chart
- Update TypeScript interfaces to match backend schema changes
- Add i18n keys for all new UI elements across en, ru, zh, fa locales
This commit is contained in:
Fringg
2026-03-02 21:42:25 +03:00
parent 14e5f436ce
commit 4622b4b200
11 changed files with 391 additions and 18 deletions

View File

@@ -1,3 +1,4 @@
import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
@@ -8,6 +9,7 @@ import { useCurrency } from '../../hooks/useCurrency';
import { StatCard } from '../stats';
import { DonutChart } from './DonutChart';
import { MultiSeriesAreaChart } from './MultiSeriesAreaChart';
import { SimpleAreaChart } from './SimpleAreaChart';
import { SimpleBarChart } from './SimpleBarChart';
@@ -25,6 +27,13 @@ export function SalesTab({ params }: SalesTabProps) {
staleTime: SALES_STATS.STALE_TIME,
});
const dailyByTariffData = useMemo(
() =>
data?.daily_by_tariff.map((i) => ({ date: i.date, key: i.tariff_name, value: i.count })) ??
[],
[data?.daily_by_tariff],
);
if (isLoading) {
return (
<div className="animate-pulse space-y-4">
@@ -77,6 +86,13 @@ export function SalesTab({ params }: SalesTabProps) {
chartId="sales-daily"
valueLabel={t('admin.salesStats.summary.revenue')}
/>
<MultiSeriesAreaChart
data={dailyByTariffData}
title={t('admin.salesStats.sales.dailyByTariff')}
chartId="sales-daily-by-tariff"
valueLabel={t('admin.salesStats.sales.subscriptions')}
/>
</div>
);
}