Add registry kind indexes and entity pages.

CONTENT-WP-0002-T02 reads kinds from each snapshot and serves both example dataspaces without oncology imports.

Assistant: grok
Assistant-Session: 01a1346c-fdff-7741-b1af-b7283661554b
This commit is contained in:
tegwick 2026-10-13 22:56:52 +02:00
parent a6e360aaa5
commit e16aa03393
21 changed files with 608 additions and 59 deletions

View file

@ -0,0 +1,26 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { EntityDetail } from "@/components/EntityDetail";
import { findEntity } from "@/lib/catalog";
export async function generateMetadata({
params,
}: {
params: Promise<{ dataspace: string; kind: string; slug: string }>;
}): Promise<Metadata> {
const { dataspace, kind, slug } = await params;
const view = findEntity(dataspace, kind, slug);
if (!view) return { title: "Content Explorer" };
return { title: `${view.title} · ${view.kindLabel} · Content Explorer`, description: view.tldr };
}
export default async function EntityPage({
params,
}: {
params: Promise<{ dataspace: string; kind: string; slug: string }>;
}) {
const { dataspace, kind, slug } = await params;
const view = findEntity(dataspace, kind, slug);
if (!view) notFound();
return <EntityDetail entity={view} />;
}

View file

@ -0,0 +1,18 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { KindIndex } from "@/components/KindIndex";
import { findKind } from "@/lib/catalog";
export async function generateMetadata({ params }: { params: Promise<{ dataspace: string; kind: string }> }): Promise<Metadata> {
const { dataspace, kind } = await params;
const view = findKind(dataspace, kind);
if (!view) return { title: "Content Explorer" };
return { title: `${view.plural} · ${view.dataspaceTitle} · Content Explorer` };
}
export default async function KindPage({ params }: { params: Promise<{ dataspace: string; kind: string }> }) {
const { dataspace, kind } = await params;
const view = findKind(dataspace, kind);
if (!view) notFound();
return <KindIndex kind={view} />;
}

View file

@ -0,0 +1,15 @@
import type { Metadata } from "next";
import { DataspaceHome } from "@/components/DataspaceHome";
import { findDataspace } from "@/lib/catalog";
export async function generateMetadata({ params }: { params: Promise<{ dataspace: string }> }): Promise<Metadata> {
const { dataspace } = await params;
const view = findDataspace(dataspace);
if (!view) return { title: "Content Explorer" };
return { title: `${view.title} · Content Explorer`, description: view.description };
}
export default async function DataspacePage({ params }: { params: Promise<{ dataspace: string }> }) {
const { dataspace } = await params;
return <DataspaceHome id={dataspace} />;
}

View file

@ -3,6 +3,7 @@ import type { ReactNode } from "react";
import { SiteFooter } from "@/components/SiteFooter";
import { SiteHeader } from "@/components/SiteHeader";
import { SkipLink } from "@/components/SkipLink";
import { listNavigation } from "@/lib/catalog";
import "./globals.css";
export const metadata: Metadata = {
@ -15,7 +16,7 @@ export default function RootLayout({ children }: { children: ReactNode }) {
<html lang="en">
<body>
<SkipLink />
<SiteHeader />
<SiteHeader dataspaces={listNavigation()} />
<main id="main">{children}</main>
<SiteFooter />
</body>

View file

@ -1,13 +1,5 @@
import { Hero } from "@/components/Hero";
import { RecordBrowser } from "@/components/RecordBrowser";
import { loadSystemsThinking } from "@/lib/fixture";
import { DataspaceHome } from "@/components/DataspaceHome";
export default function HomePage() {
const fixture = loadSystemsThinking();
return (
<>
<Hero dataspace={fixture.title} description={fixture.description} />
<RecordBrowser rows={fixture.rows} />
</>
);
return <DataspaceHome id="systems-thinking" />;
}