"use client"; import * as React from "react"; import Link from "next/link"; import { ArrowRight, PiggyBank, TrendingDown, TrendingUp, Minus, Info } from "lucide-react"; import { ProviderIcon } from "@/components/brand/provider-icon"; import { Tooltip } from "@/components/ui/tooltip"; import { cn, formatUsd, formatNumber } from "@/lib/utils"; import type { SavingsOpportunity, UsageProjection, UsageKpis } from "./types"; /** "Estimated monthly cost" — daily average over the observed part of the range × 30, plus the trend vs the previous period. */ export function ProjectionCard({ projection, kpis, rangeDays, className }: { projection: UsageProjection; kpis: UsageKpis; rangeDays: number; className?: string }) { const trend = projection.costTrendPct; const Icon = trend === null ? Minus : trend > 2 ? TrendingUp : trend < -2 ? TrendingDown : Minus; const tone = trend === null || Math.abs(trend) <= 2 ? "text-fg-muted" : trend > 0 ? "text-danger" : "text-success"; const days = projection.observedDays; return (

Estimated monthly cost

If the last {days < 1 ? "hours" : `${Math.round(days)} day${Math.round(days) === 1 ? "" : "s"}`} continued for 30 days

{formatUsd(projection.estimatedMonthlyCost)}

Daily average
{formatUsd(projection.dailyAverageCost, { precise: projection.dailyAverageCost < 0.01 })}
This period
{formatUsd(kpis.costUsd)}
{projection.previous ? ( {trend === null ? ( <>No spend in the previous {rangeDays}-day period ({formatNumber(projection.previous.requests)} requests). ) : ( <> {trend > 0 ? "+" : ""} {trend.toFixed(Math.abs(trend) >= 100 ? 0 : 1)}% {" "} vs previous period ({formatUsd(projection.previous.costUsd)}) )} ) : ( No previous period to compare against. )}
); } /** Savings opportunities computed from real records + registry pricing (top 3). Each row deep-links to the model catalog. */ export function SavingsCard({ savings, className, loading }: { savings: SavingsOpportunity[]; className?: string; loading?: boolean }) { const total = savings.reduce((a, s) => a + s.savingsUsd, 0); return (

Savings opportunities

Same tokens, cheaper sibling on the same provider

{loading ? (

Analysing…

) : savings.length === 0 ? (
Nothing to save right now. We look for a model on the same provider with the same capabilities that would have cost at least 40 % less for the traffic you actually sent — none qualifies for this period.
) : ( <>

~{formatUsd(total)}

could have been saved in this period

)}

Estimates only — quality differs between tiers. Reasoning, vision, tools and structured output must all be supported by the sibling; context windows are checked against your average prompt.

); }