import { useAggregateEvents } from "autumn-js/react"; import { useEffect, useRef, useState } from "react"; import { Bar, BarChart, CartesianGrid, Tooltip, XAxis, YAxis } from "recharts"; import { AUTUMN_SEO_DATA_BALANCE_FEATURE_ID, AUTUMN_SEO_DATA_TOPUP_BALANCE_FEATURE_ID, autumnSeoDataCreditsToUsd, } from "@/shared/billing"; const BILLING_USAGE_FEATURE_IDS: string[] = [ AUTUMN_SEO_DATA_BALANCE_FEATURE_ID, AUTUMN_SEO_DATA_TOPUP_BALANCE_FEATURE_ID, ]; export function BillingUsageChart() { const containerRef = useRef(null); const [chartWidth, setChartWidth] = useState(0); useEffect(() => { const el = containerRef.current; if (!el) return; const update = () => setChartWidth(el.clientWidth); update(); const observer = new ResizeObserver(update); observer.observe(el); return () => observer.disconnect(); }, []); const eventsQuery = useAggregateEvents({ featureId: BILLING_USAGE_FEATURE_IDS, range: "30d", binSize: "day", }); const chartData = (eventsQuery.list ?? []).map((row) => ({ date: row.period, credits: autumnSeoDataCreditsToUsd( BILLING_USAGE_FEATURE_IDS.reduce( (sum, featureId) => sum + (row.values?.[featureId] ?? 0), 0, ), ), })); const totalSpend = chartData.reduce((sum, d) => sum + d.credits, 0); return (
Usage Last 30 days
${totalSpend.toFixed(2)}
{eventsQuery.isLoading ? null : chartData.length === 0 ? (
No usage recorded yet
) : chartWidth > 0 ? ( } cursor={{ fill: "rgba(150,150,150,0.1)" }} /> ) : null}
); } function UsageTooltip({ active, payload, label, }: { active?: boolean; payload?: Array<{ value: number }>; label?: number; }) { if (!active || !payload?.length || label == null) return null; return (

{new Date(label).toLocaleDateString("en-US", { month: "short", day: "numeric", })}

${payload[0].value.toFixed(2)}

); } function formatShortDate(timestamp: number) { return new Date(timestamp).toLocaleDateString("en-US", { month: "short", day: "numeric", }); } function formatUsdAxis(value: number) { return `$${value % 1 === 0 ? value : value.toFixed(2)}`; }