// Billing — the plan catalogue. Per-tenant plan assignment lives on each // tenant's detail page (Plan & quotas tab); this is the platform view of what // plans exist. Entitlements and Apps aren't wired to endpoints yet, so they're // named honestly as still-to-come rather than given their own dead nav items. import { useCallback, useEffect, useState } from "react" import { Gauge, LayoutGrid, RefreshCw } from "lucide-react" import { useArcadiaClient } from "@crema/arcadia-core-client" import { AppShell } from "~/components/layout/app-shell" import { PageHeader } from "~/components/layout/page-header" import { DataState } from "~/components/data-state" import { Button } from "~/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card" import { EmptyState } from "@crema/feedback-ui" import { listPlans, type Plan } from "~/lib/arcadia/billing" import { pageTitle } from "~/lib/page-meta" import { useSession } from "~/lib/session" export const meta = () => pageTitle("Billing") export default function BillingRoute() { const session = useSession() const arcadia = useArcadiaClient() const [plans, setPlans] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const refresh = useCallback(async () => { setError(null) setLoading(true) try { setPlans(await listPlans(arcadia)) } catch (err) { setError(err) } finally { setLoading(false) } }, [arcadia]) useEffect(() => { if (session) refresh() }, [session, refresh]) return ( Refresh } /> Plan catalogue {plans.length} plan{plans.length === 1 ? "" : "s"} defined. } >
    {plans.map((plan) => (
  • {plan.name} {plan.slug} {plan.billing_track} {plan.trial_days > 0 ? ( · {plan.trial_days}-day trial ) : null}
    {plan.description ? (

    {plan.description}

    ) : null} {plan.meters.length > 0 ? (
    {plan.meters.map((m) => ( {m.meter_key} {m.included_units != null ? `: ${m.included_units} incl.` : ""} ))}
    ) : null}
  • ))}
) } function ComingSoon({ icon: Icon, title, description, }: { icon: React.ComponentType<{ className?: string }> title: string description: string }) { return (

{title}

Soon

{description}

) } export { RouteErrorBoundary as ErrorBoundary } from "~/components/route-error"