/products (search), product pages with revisions, getting and staying on a revision, retracting; /products/:id/edit; /create and new revisions upload from the browser straight to the catalog with a token from the hub; /library; /catalogs (directory, registering with a once-shown key); /console/catalogs to approve or reject. Every page now sends a nonce-based CSP (proxy.ts), so product descriptions can't run scripts. buttonVariants now merges classes, so outline links get their border. Co-Authored-By: Claude Opus 5.5 <[email protected]>
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
import { redirect } from "next/navigation";
|
|
import { ActionForm, SubmitButton } from "@/components/forms";
|
|
import { Empty, ProductCard } from "@/components/products";
|
|
import { PageHeader } from "@/components/status";
|
|
import { api, getMe, unwrap } from "@/lib/api";
|
|
import { libraryAction } from "../products/actions";
|
|
|
|
export const metadata: Metadata = { title: "Library" };
|
|
|
|
export default async function Library() {
|
|
const me = await getMe();
|
|
if (!me) redirect("/signin?next=/library");
|
|
const { library } = await api.library.get().then(unwrap);
|
|
|
|
return (
|
|
<>
|
|
<PageHeader title="Your library">Products your T5DE uses, on all your IMVU accounts.</PageHeader>
|
|
{library.length === 0 ? (
|
|
<Empty>
|
|
Nothing yet.{" "}
|
|
<Link href="/products" className="text-foreground underline underline-offset-4">
|
|
Browse products
|
|
</Link>
|
|
.
|
|
</Empty>
|
|
) : (
|
|
<ul className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
{library.map(({ product, stayOn }) => (
|
|
<li key={product.id}>
|
|
<ProductCard product={product}>
|
|
{stayOn !== null && <p className="text-xs">Staying on revision {stayOn}</p>}
|
|
<ActionForm action={libraryAction} fields={{ id: product.id }} className="pt-1">
|
|
<SubmitButton size="sm" variant="outline" name="intent" value="remove" pendingLabel="Removing…">
|
|
Remove
|
|
</SubmitButton>
|
|
</ActionForm>
|
|
</ProductCard>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</>
|
|
);
|
|
}
|