Ben Senescu 724a92db0c refactor: move hosted billing to Autumn hooks (#48)
* refactor: move lighthouse audits to dataforseo (#43)

* refactor: move lighthouse audits to dataforseo

* chore: remove obsolete audit settings modal

* refactor: rename psi flows to lighthouse

* save

* refactor: simplify audit lighthouse storage flow

* fix: separate lighthouse metrics from actionable audits

* refactor: remove redundant audit project inputs

* feat: redesign lighthouse issues screen with score gauges and table layout

Replace flat score cards with circular SVG gauges, condense metrics into
a compact grid, and switch issue list from cards to an expandable table
with fixed column widths.


* test: harden lighthouse regression coverage

* fix: restore project-scoped audit inputs

* refactor: simplify lighthouse payload handling

* refactor: inline lighthouse server handlers

* refactor: share audit workflow types

* refactor: simplify lighthouse payload flows

* save

* refactor: drop project pagespeed api key

* fix: restore lighthouse issues loading with resilient project context

* fix: restore audit issues back navigation

* refactor: simplify project context and lighthouse error handling

* fix: tolerate DataForSEO lighthouse payload drift

* refactor: route audit lighthouse through dataforseo client

---------


* refactor: move hosted billing to Autumn hooks

* fix: satisfy ci checks for hosted billing

* refactor: simplify hosted Autumn billing integration

Limit Autumn wiring to the billing route and remove billing-specific indirection so the hosted billing flow is easier to reason about. Stop sending organization IDs as fake customer names to keep customer identity data honest.

* fix: satisfy ci line-limit check for hosted billing

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:28:28 -04:00

82 lines
2.0 KiB
TypeScript

import { createFileRoute, notFound } from "@tanstack/react-router";
import { AutumnProvider, useCustomer, useListPlans } from "autumn-js/react";
import { LoaderCircle } from "lucide-react";
import { CenteredCard } from "@/client/features/billing/BillingRouteParts";
import { HostedBillingContent } from "@/client/features/billing/HostedBillingContent";
import { useSession } from "@/lib/auth-client";
import { isHostedClientAuthMode } from "@/lib/auth-mode";
export const Route = createFileRoute("/_app/billing")({
beforeLoad: () => {
if (!isHostedClientAuthMode()) {
throw notFound();
}
},
component: BillingPage,
});
function BillingPage() {
return (
<AutumnProvider>
<BillingPageContent />
</AutumnProvider>
);
}
function BillingPageContent() {
const { data: session, isPending: isSessionPending } = useSession();
const customerQuery = useCustomer({
queryOptions: {
enabled: Boolean(session?.user?.id),
},
});
const plansQuery = useListPlans({
queryOptions: {
enabled: Boolean(session?.user?.id),
},
});
if (
isSessionPending ||
(session?.user?.id && (customerQuery.isLoading || plansQuery.isLoading))
) {
return (
<div className="flex h-full items-center justify-center">
<LoaderCircle className="h-6 w-6 animate-spin text-base-content/60" />
</div>
);
}
if (!session?.user?.id) {
return (
<CenteredCard
title="Sign in to manage billing"
body="Your hosted billing settings are tied to your OpenSEO organization."
action={
<a className="btn btn-primary" href="/sign-in">
Go to sign in
</a>
}
/>
);
}
if (customerQuery.isError || plansQuery.isError) {
return (
<CenteredCard
title="Billing unavailable"
body="We could not load your billing details right now. Please reload and try again."
/>
);
}
return (
<HostedBillingContent
customerQuery={customerQuery}
plans={plansQuery.data ?? []}
/>
);
}