76 lines · 3.1 KB
import type { getBilling } from "~/fns/billing";
import { formatQuantity, METERS } from "~/lib/meters";
import type { MeterDef } from "~/lib/meters";
import { PRICING_BASIS, rateLabel } from "~/lib/pricing-display";
import { Panel } from "~/ui/Panel";
import { ComputeRatesNote } from "./ComputeRatesNote";
import { InfoTip } from "./InfoTip";

type Billing = Awaited<ReturnType<typeof getBilling>>;

function allowance(unit: MeterDef["unit"], value: number | undefined): string {
  if (value === undefined) return "unlimited";
  if (value === 0) return "none";
  return formatQuantity(unit, value);
}

/** Every priced meter with what each plan includes and the rate past it, all derived from src/lib/pricing.ts. */
export function RatesPanel({ billing }: { billing: Billing }) {
  const { free, pro } = billing.plans;
  const priced = METERS.filter((meter) => rateLabel(meter.id) !== null);
  return (
    <Panel
      title={
        <span className="flex items-center gap-2">
          Pricing
          <span className="text-xs font-normal text-kumo-subtle">
            Cloudflare's cost x {PRICING_BASIS.markup}, metered exactly
          </span>
        </span>
      }
    >
      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead className="text-left text-xs text-kumo-subtle">
            <tr className="border-b border-kumo-hairline">
              <th className="px-4 py-2 font-normal">Usage</th>
              <th className="px-4 py-2 font-normal">{free.label} includes</th>
              <th className="px-4 py-2 font-normal">
                {pro.label} includes (${(pro.priceCents / 100).toFixed(0)}/month)
              </th>