feat(portal): M10.1 — fill the 10 customer-area shells
ci / shared (push) Successful in 8s
ci / test (push) Successful in 25s
ci / e2e (push) Has been skipped
ci / image (push) Has been skipped

Four real surfaces wired to tenant-registry (settings, settings/api-keys CRUD, audit pagination, products live entitlements), five forward-looking empty states with CTAs. 56 vitest tests + 10 Playwright canaries. lib/format.ts consolidates date helpers.

Refs: M10.1
This commit was merged in pull request #12.
This commit is contained in:
2026-05-20 07:20:31 +00:00
parent ecbe6ae74b
commit e387b9a963
16 changed files with 1093 additions and 49 deletions
+17 -2
View File
@@ -1,16 +1,31 @@
import Link from "next/link";
import { auth } from "@/auth";
import { NotAuthorized, ShellEmpty } from "@/components/ShellEmpty";
import type { SessionWithExtras } from "@/lib/session";
import { canSee } from "@/lib/session";
export default async function Page() {
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const session = (await auth()) as SessionWithExtras | null;
if (!canSee(session, "billing")) return <NotAuthorized />;
return (
<ShellEmpty
title="Billing"
description="Plan, seats, invoices. Polar Checkout opens here."
description="Plan, seats, invoices. Polar Checkout opens here for plan changes."
milestone="M8.3"
details="Polar.sh is the Merchant of Record — it handles EU VAT MOSS so we don't have to. Invoices mirror to ERPNext (Customer + Sales Invoice) so accounting stays in one place."
cta={
<Link
href={`/${slug}/catalog`}
style={{ color: "#0070f3", fontSize: 14, textDecoration: "underline" }}
>
Browse the catalog
</Link>
}
/>
);
}