import { useEffect, useMemo, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { costsApi } from "../api/costs"; import { useCompany } from "../context/CompanyContext"; import { useBreadcrumbs } from "../context/BreadcrumbContext"; import { queryKeys } from "../lib/queryKeys"; import { EmptyState } from "../components/EmptyState"; import { PageSkeleton } from "../components/PageSkeleton"; import { formatCents, formatTokens } from "../lib/utils"; import { Identity } from "../components/Identity"; import { StatusBadge } from "../components/StatusBadge"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { DollarSign } from "lucide-react"; type DatePreset = "mtd" | "7d" | "30d" | "ytd" | "all" | "custom"; const PRESET_LABELS: Record = { mtd: "Month to Date", "7d": "Last 7 Days", "30d": "Last 30 Days", ytd: "Year to Date", all: "All Time", custom: "Custom", }; function computeRange(preset: DatePreset): { from: string; to: string } { const now = new Date(); const to = now.toISOString(); switch (preset) { case "mtd": { const d = new Date(now.getFullYear(), now.getMonth(), 1); return { from: d.toISOString(), to }; } case "7d": { const d = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); return { from: d.toISOString(), to }; } case "30d": { const d = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); return { from: d.toISOString(), to }; } case "ytd": { const d = new Date(now.getFullYear(), 0, 1); return { from: d.toISOString(), to }; } case "all": return { from: "", to: "" }; case "custom": return { from: "", to: "" }; } } export function Costs() { const { selectedCompanyId } = useCompany(); const { setBreadcrumbs } = useBreadcrumbs(); const [preset, setPreset] = useState("mtd"); const [customFrom, setCustomFrom] = useState(""); const [customTo, setCustomTo] = useState(""); useEffect(() => { setBreadcrumbs([{ label: "Costs" }]); }, [setBreadcrumbs]); const { from, to } = useMemo(() => { if (preset === "custom") { return { from: customFrom ? new Date(customFrom).toISOString() : "", to: customTo ? new Date(customTo + "T23:59:59.999Z").toISOString() : "", }; } return computeRange(preset); }, [preset, customFrom, customTo]); const { data, isLoading, error } = useQuery({ queryKey: queryKeys.costs(selectedCompanyId!, from || undefined, to || undefined), queryFn: async () => { const [summary, byAgent, byProject] = await Promise.all([ costsApi.summary(selectedCompanyId!, from || undefined, to || undefined), costsApi.byAgent(selectedCompanyId!, from || undefined, to || undefined), costsApi.byProject(selectedCompanyId!, from || undefined, to || undefined), ]); return { summary, byAgent, byProject }; }, enabled: !!selectedCompanyId, }); if (!selectedCompanyId) { return ; } if (isLoading) { return ; } const presetKeys: DatePreset[] = ["mtd", "7d", "30d", "ytd", "all", "custom"]; return (
{/* Date range selector */}
{presetKeys.map((p) => ( ))} {preset === "custom" && (
setCustomFrom(e.target.value)} className="h-8 rounded-md border border-input bg-background px-2 text-sm text-foreground" /> to setCustomTo(e.target.value)} className="h-8 rounded-md border border-input bg-background px-2 text-sm text-foreground" />
)}
{error &&

{error.message}

} {data && ( <> {/* Summary card */}

{PRESET_LABELS[preset]}

{data.summary.budgetCents > 0 && (

{data.summary.utilizationPercent}% utilized

)}

{formatCents(data.summary.spendCents)}{" "} {data.summary.budgetCents > 0 ? `/ ${formatCents(data.summary.budgetCents)}` : "Unlimited budget"}

{data.summary.budgetCents > 0 && (
90 ? "bg-red-400" : data.summary.utilizationPercent > 70 ? "bg-yellow-400" : "bg-green-400" }`} style={{ width: `${Math.min(100, data.summary.utilizationPercent)}%` }} />
)} {/* By Agent / By Project */}

By Agent

{data.byAgent.length === 0 ? (

No cost events yet.

) : (
{data.byAgent.map((row) => (
{row.agentStatus === "terminated" && ( )}
{formatCents(row.costCents)} in {formatTokens(row.inputTokens)} / out {formatTokens(row.outputTokens)} tok {(row.apiRunCount > 0 || row.subscriptionRunCount > 0) && ( {row.apiRunCount > 0 ? `api runs: ${row.apiRunCount}` : null} {row.apiRunCount > 0 && row.subscriptionRunCount > 0 ? " | " : null} {row.subscriptionRunCount > 0 ? `subscription runs: ${row.subscriptionRunCount} (${formatTokens(row.subscriptionInputTokens)} in / ${formatTokens(row.subscriptionOutputTokens)} out tok)` : null} )}
))}
)}

By Project

{data.byProject.length === 0 ? (

No project-attributed run costs yet.

) : (
{data.byProject.map((row) => (
{row.projectName ?? row.projectId ?? "Unattributed"} {formatCents(row.costCents)}
))}
)}
)}
); }