返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / ratatui / [component] / page.tsx
1 import Link from "next/link";
2 import { notFound } from "next/navigation";
3 import { PageHeader } from "@/components/page-header";
4 import { RatatuiExplorer } from "@/components/ratatui/explorer";
5 import { RatatuiProjectLinks } from "@/components/ratatui/project-links";
6 import { getRatatuiCopy } from "@/lib/content/ratatui";
7 import { buildPageMetadata } from "@/lib/page-meta";
8 import { readCatalogue } from "@/lib/ratatui/catalogue";
9
10 type PageParams = Promise<{ locale: string; component: string }>;
11
12 export const revalidate = 3600;
13
14 // Render component pages on demand instead of expanding every entry across all locales at build time.
15 export function generateStaticParams() {
16 return [];
17 }
18
19 export async function generateMetadata({ params }: { params: PageParams }) {
20 const { locale, component } = await params;
21 const catalogue = await readCatalogue();
22 const entry = catalogue.entries.find((item) => item.name === component);
23 if (!entry) notFound();
24
25 return buildPageMetadata({
26 path: `/ratatui/${encodeURIComponent(entry.name)}`,
27 locale,
28 title: `${entry.title} · Codewhale Ratatui`,
29 description: entry.description,
30 });
31 }
32
33 export default async function RatatuiComponentPage({ params }: { params: PageParams }) {
34 const { locale, component } = await params;
35 const catalogue = await readCatalogue();
36 const entry = catalogue.entries.find((item) => item.name === component);
37 if (!entry) notFound();
38 const copy = getRatatuiCopy(locale);
39 const family = catalogue.families.find((item) => item.id === entry.family);
40
41 return (
42 <div className="ratatui-page">
43 <PageHeader
44 title={entry.title}
45 lede={entry.description}
46 kicker={family ? <Link href={`/${locale}/ratatui`}>{copy.title} · {family.title}</Link> : copy.title}
47 actions={
48 <>
49 <Link href={`/${locale}/ratatui`} className="btn btn-secondary">{copy.back}</Link>
50 <Link href={`/${locale}/ratatui#ratatui-install`} className="section-link">{copy.install} →</Link>
51 </>
52 }
53 />
54 <RatatuiExplorer catalogue={catalogue} locale={locale} copy={copy} initialEntry={entry.name} detail />
55 <RatatuiProjectLinks revision={catalogue.source.revision} copy={copy} />
56 </div>
57 );
58 }
59
59 lines Plain Text