import Link from "next/link";
import { CreditCard, Receipt } from "lucide-react";
import { requireAdmin } from "@/lib/session";
import { getBillingOverview } from "@/lib/queries/admin";
import { formatNumber, formatUsd } from "@/lib/format";
import { PageHeader } from "@/components/ui/page-header";
import { Alert } from "@/components/ui/alert";
import { Badge, StatusBadge } from "@/components/ui/badge";
import { EmptyState } from "@/components/ui/empty-state";
import { Stat, StatGrid } from "@/components/ui/stat";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { DateCell, MarginText, Mono, Panel, PlanBadge, numCell } from "@/components/admin/primitives";
export const dynamic = "force-dynamic";
export default async function AdminBillingPage() {
await requireAdmin();
const b = await getBillingOverview();
const paying = b.distribution.filter((d) => d.price > 0).reduce((s, d) => s + d.orgs, 0);
return (
<>
{!b.stripeConfigured ? (
`STRIPE_SECRET_KEY` is not set and there is nothing to bill: every organization is on the Unlimited plan (private platform, no billing). Subscriptions and billing events below stay empty unless a Stripe integration is added later.
) : null}
0 ? ((b.usageRevenue30d - b.usageCost30d) / b.usageRevenue30d) * 100 : null} />} hint="vs upstream cost" />
Plan
Organizations
List price / mo
MRR
{b.distribution.map((d) => (
{formatNumber(d.orgs)}
{formatUsd(d.price)}
{formatUsd(d.mrr)}
view →
))}
{b.unknown.map((u) => (
{u.plan} legacy plan value — treated as Unlimited; run `pnpm db:seed` to normalize
{u.n}
—
—
))}
{b.subs.length === 0 ? (
) : (
Organization
Plan
Status
Period
Stripe
{b.subs.map((s) => (
{s.orgName ?? s.organizationId}
{s.cancelAtPeriodEnd ? cancels : null}
→
{s.stripeSubscriptionId ?? "—"}
))}
)}
{b.events.length === 0 ? (
) : (
When
Type
Organization
Stripe event
{b.events.map((e) => (
{e.type}
{e.orgName ?? e.organizationId ?? "—"}
{e.stripeEventId ?? "—"}
))}
)}
>
);
}