import { useEffect, useState } from 'react' import { Breadcrumbs } from '../components/Breadcrumbs' import { HomeChartSlot } from '../components/HomeChartSlot' import { PageTitle } from '../components/PageTitle' import { useTenantBranding } from '../context/TenantBrandingContext' import { useLocale } from '@meshkee/dashboard-ui' import { useT } from '../i18n/useT' import { translate, type BusinessMessageKey } from '../i18n/messages' import { ApiError } from '../lib/api' import { getViewSummary, type ViewPeriodCounts, type ViewSummaryGroupId, } from '../services/dailyActivityService' import { hasAnyBusinessModule, hasBusinessModule, isActiveHomeChart, type BusinessModuleId, } from '../utils/businessModules' import pageStyles from '../components/PageContent.module.css' import styles from './StatisticsPage.module.css' const EMPTY_COUNTS: ViewPeriodCounts = { today: 0, week: 0, month: 0, total: 0, } const METRICS: { id: keyof ViewPeriodCounts labelKey: BusinessMessageKey }[] = [ { id: 'today', labelKey: 'statistics.metric.today' }, { id: 'week', labelKey: 'statistics.metric.week' }, { id: 'month', labelKey: 'statistics.metric.month' }, { id: 'total', labelKey: 'statistics.metric.total' }, ] const STAT_ROWS: { id: ViewSummaryGroupId titleKey: BusinessMessageKey moduleId?: BusinessModuleId anyModuleIds?: BusinessModuleId[] }[] = [ { id: 'all', titleKey: 'statistics.row.all' }, { id: 'home', titleKey: 'statistics.row.home' }, { id: 'pages', titleKey: 'statistics.row.pages' }, { id: 'products', titleKey: 'statistics.row.products', anyModuleIds: ['products', 'store'], }, { id: 'blog', titleKey: 'statistics.row.blog', moduleId: 'blog' }, { id: 'portfolio', titleKey: 'statistics.row.portfolio', moduleId: 'portfolio' }, { id: 'videos', titleKey: 'statistics.row.videos', moduleId: 'videos' }, ] function formatCount(value: number) { return new Intl.NumberFormat('en-US').format(value) } export function StatisticsPage() { const t = useT() const { locale } = useLocale() const { enabledModules, homeCharts } = useTenantBranding() const [rows, setRows] = useState | null>( null, ) const [error, setError] = useState('') const [loading, setLoading] = useState(true) const visibleCharts = homeCharts.filter(isActiveHomeChart) const visibleRows = STAT_ROWS.filter((row) => { if (row.anyModuleIds) { return hasAnyBusinessModule(enabledModules, row.anyModuleIds) } return !row.moduleId || hasBusinessModule(enabledModules, row.moduleId) }) useEffect(() => { const controller = new AbortController() async function load() { setLoading(true) setError('') try { const data = await getViewSummary(controller.signal) setRows(data.rows) } catch (err) { if (err instanceof DOMException && err.name === 'AbortError') return setError(err instanceof ApiError ? err.message : t('statistics.errorLoad')) } finally { if (!controller.signal.aborted) setLoading(false) } } void load() return () => controller.abort() }, [t]) return (
{t('title.statistics')}

{t('statistics.page.subtitle')}

{visibleCharts.length > 0 ? (
{visibleCharts.map((chartId, index) => (
))}
) : null} {error ? (
{error}
) : null} {visibleRows.map((row) => { const counts = rows?.[row.id] ?? EMPTY_COUNTS return (

{t(row.titleKey)}

{locale === 'fa' ? ( {translate('en', row.titleKey)} ) : null}
{METRICS.map((metric) => (
{loading || !rows ? '—' : formatCount(counts[metric.id])} {t(metric.labelKey)}
))}
) })}
) }