"use client"; import { useCallback, useEffect, useMemo, useState } from "react"; import { fetchAnalyticsSummary, type AnalyticsDailyRow, type AnalyticsSummaryResponse, } from "@/features/agent/services/analyticsApi"; import { Button } from "@/components/ui/button"; import { toast } from "@/hooks/useToast"; import type { I18nKey } from "@/lib/i18n/dict"; import { useI18n } from "@/lib/i18n/provider"; function formatPercent(n: number) { if (Number.isNaN(n)) return "—"; return `${n.toFixed(2)}%`; } function StatCard({ title, value, sub, }: { title: string; value: string | number; sub?: string; }) { return (
{title}
{value}
{sub ?
{sub}
: null}
); } function DailyBars({ daily, field, label, color, emptyLabel, }: { daily: AnalyticsDailyRow[]; field: keyof Pick< AnalyticsDailyRow, "widget_opens" | "sessions" | "messages" | "ai_replies" >; label: string; color: string; emptyLabel: string; }) { const max = useMemo(() => { let m = 1; for (const row of daily) { const v = Number(row[field]) || 0; if (v > m) m = v; } return m; }, [daily, field]); if (daily.length === 0) { return

{emptyLabel}

; } return (
{label}
{daily.map((row) => { const v = Number(row[field]) || 0; const h = Math.round((v / max) * 100); return (
0 ? 8 : 0)}%`, backgroundColor: color, minHeight: v > 0 ? 4 : 0, }} /> {row.date.slice(5)}
); })}
); } export default function AnalyticsPage(_props: { embedded?: boolean }) { const { t } = useI18n(); const tr = (key: I18nKey, vars?: Record) => { let s = t(key); if (!vars) return s; for (const k of Object.keys(vars)) { s = s.replaceAll(`{{${k}}}`, vars[k] ?? ""); } return s; }; const [from, setFrom] = useState(() => { const d = new Date(); d.setDate(d.getDate() - 6); return d.toISOString().slice(0, 10); }); const [to, setTo] = useState(() => new Date().toISOString().slice(0, 10)); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const load = useCallback(async () => { setLoading(true); try { const res = await fetchAnalyticsSummary(from, to); setData(res); } catch (e) { toast.error((e as Error).message); setData(null); } finally { setLoading(false); } }, [from, to]); useEffect(() => { void load(); }, [load]); const totals = data?.totals; return (

{t("agent.analytics.title")}

{t("agent.analytics.subtitle")}

{data && (

{data.note}

)} {totals && ( <>
)} {!loading && !totals && (

{t("agent.analytics.emptyOrFailed")}

)}
); }