diff --git a/src/api/adminSalesStats.ts b/src/api/adminSalesStats.ts index 26c902a..1adb5c3 100644 --- a/src/api/adminSalesStats.ts +++ b/src/api/adminSalesStats.ts @@ -149,12 +149,19 @@ export interface DailyDepositItem { amount_kopeks: number; } +export interface DailyDepositByMethodItem { + date: string; + method: string; + amount_kopeks: number; +} + export interface DepositsStats { total_deposits: number; total_amount_kopeks: number; avg_deposit_kopeks: number; by_method: DepositByMethodItem[]; daily: DailyDepositItem[]; + daily_by_method: DailyDepositByMethodItem[]; } // ============ API ============ diff --git a/src/components/sales-stats/DepositsTab.tsx b/src/components/sales-stats/DepositsTab.tsx index c913565..cbcf3f2 100644 --- a/src/components/sales-stats/DepositsTab.tsx +++ b/src/components/sales-stats/DepositsTab.tsx @@ -1,3 +1,4 @@ +import { useCallback, useMemo } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; @@ -7,6 +8,7 @@ import { SALES_STATS } from '../../constants/salesStats'; import { useCurrency } from '../../hooks/useCurrency'; import { StatCard } from '../stats'; +import { MultiSeriesAreaChart } from './MultiSeriesAreaChart'; import { SimpleAreaChart } from './SimpleAreaChart'; import { SimpleBarChart } from './SimpleBarChart'; @@ -39,6 +41,36 @@ export function DepositsTab({ params }: DepositsTabProps) { staleTime: SALES_STATS.STALE_TIME, }); + const formatValue = useCallback((v: number) => formatWithCurrency(v), [formatWithCurrency]); + + const methodBarData = useMemo( + () => + data?.by_method.map((item) => ({ + name: METHOD_LABELS[item.method] || item.method, + value: item.amount_kopeks / SALES_STATS.KOPEKS_DIVISOR, + })) ?? [], + [data?.by_method], + ); + + const dailyData = useMemo( + () => + data?.daily.map((item) => ({ + date: item.date, + value: item.amount_kopeks / SALES_STATS.KOPEKS_DIVISOR, + })) ?? [], + [data?.daily], + ); + + const dailyByMethodData = useMemo( + () => + data?.daily_by_method.map((i) => ({ + date: i.date, + key: METHOD_LABELS[i.method] || i.method, + value: i.amount_kopeks / SALES_STATS.KOPEKS_DIVISOR, + })) ?? [], + [data?.daily_by_method], + ); + if (isLoading) { return (
@@ -53,16 +85,6 @@ export function DepositsTab({ params }: DepositsTabProps) { return
{t('admin.salesStats.loadError')}
; } - const methodBarData = data.by_method.map((item) => ({ - name: METHOD_LABELS[item.method] || item.method, - value: item.amount_kopeks / SALES_STATS.KOPEKS_DIVISOR, - })); - - const dailyData = data.daily.map((item) => ({ - date: item.date, - value: item.amount_kopeks / SALES_STATS.KOPEKS_DIVISOR, - })); - return (
@@ -84,7 +106,7 @@ export function DepositsTab({ params }: DepositsTabProps) { formatWithCurrency(v)} + valueFormatter={formatValue} /> + +
); } diff --git a/src/components/sales-stats/MultiSeriesAreaChart.tsx b/src/components/sales-stats/MultiSeriesAreaChart.tsx index 8adc060..8bc54eb 100644 --- a/src/components/sales-stats/MultiSeriesAreaChart.tsx +++ b/src/components/sales-stats/MultiSeriesAreaChart.tsx @@ -19,6 +19,7 @@ interface MultiSeriesAreaChartProps { title: string; chartId: string; valueLabel?: string; + valueFormatter?: (value: number) => string; height?: number; } @@ -27,6 +28,7 @@ export function MultiSeriesAreaChart({ title, chartId, valueLabel, + valueFormatter, height = SALES_STATS.CHART.HEIGHT, }: MultiSeriesAreaChartProps) { const { t, i18n } = useTranslation(); @@ -129,7 +131,7 @@ export function MultiSeriesAreaChart({ }} labelStyle={{ color: colors.label }} formatter={(value: number | undefined, name: string | undefined) => [ - value ?? 0, + valueFormatter ? valueFormatter(value ?? 0) : (value ?? 0), name || valueLabel || '', ]} /> diff --git a/src/locales/en.json b/src/locales/en.json index 087ea49..d3682fd 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1152,6 +1152,7 @@ "avgDeposit": "Avg Deposit", "byMethod": "By Payment Method", "dailyChart": "Daily Deposits", + "dailyByMethod": "Daily Deposits by Payment Method", "revenue": "Revenue" }, "loadError": "Failed to load statistics" diff --git a/src/locales/fa.json b/src/locales/fa.json index f81c060..00fb686 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -975,6 +975,7 @@ "avgDeposit": "میانگین شارژ", "byMethod": "بر اساس روش پرداخت", "dailyChart": "شارژ روزانه", + "dailyByMethod": "شارژ روزانه بر اساس روش پرداخت", "revenue": "درآمد" }, "loadError": "بارگذاری آمار ناموفق بود" diff --git a/src/locales/ru.json b/src/locales/ru.json index d486401..82883d4 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1173,6 +1173,7 @@ "avgDeposit": "Средний чек", "byMethod": "По способу оплаты", "dailyChart": "Пополнения по дням", + "dailyByMethod": "Пополнения по дням по платёжкам", "revenue": "Доход" }, "loadError": "Не удалось загрузить статистику" diff --git a/src/locales/zh.json b/src/locales/zh.json index e24c7dd..cb7f347 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -975,6 +975,7 @@ "avgDeposit": "平均充值", "byMethod": "按支付方式", "dailyChart": "每日充值", + "dailyByMethod": "每日按支付方式充值", "revenue": "收入" }, "loadError": "加载统计失败"