Files
spsays-training/app/(app)/c/[id]/page.tsx
T
2026-06-14 01:29:08 +05:30

52 lines
1.4 KiB
TypeScript

/**
* /c/[id] — public collection.
*
* Server shell: exports `generateMetadata` so a shared collection link
* unfurls with a rich OG card (pointing at /api/og/collection/<id>), then
* mounts the client body. The server fetch is unauthenticated, so only
* public collections produce a card — private ones fall back to the default
* (and never leak).
*/
import type { Metadata } from "next";
import { bff } from "@/lib/bff";
import { ogDefault, ogForCollection } from "@/lib/og";
import { CollectionContent } from "./collection-content";
type Props = { params: Promise<{ id: string }> };
type CollectionEnvelope = {
collection: {
id: string;
title: string;
description: string | null;
is_public: boolean;
item_count: number;
};
};
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { id } = await params;
try {
const data = await bff<CollectionEnvelope>(
`/collections/${encodeURIComponent(id)}`,
{ revalidate: 60 },
);
const c = data?.collection;
if (!c || !c.is_public) return ogDefault();
return ogForCollection({
id: c.id,
title: c.title,
description: c.description,
itemCount: c.item_count,
});
} catch {
// Private (403) / unreachable → fall back to the site card.
return ogDefault();
}
}
export default function PublicCollectionPage({ params }: Props) {
return <CollectionContent params={params} />;
}