返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / docs / hooks / page.tsx
1 import { Fragment } from "react";
2 import { getDocsHooks, splitTokens } from "@/lib/i18n/dictionaries";
3 import { buildPageMetadata } from "@/lib/page-meta";
4
5 /**
6 * Config syntax the overview sentence typesets as inline `<code>`. These are
7 * literals, not copy, so they stay here rather than in the dictionaries —
8 * `configIntro` carries a `{token}` for each one.
9 */
10 const CODE_SPANS: Record<string, string> = {
11 hooksTable: "[[hooks.hooks]]",
12 hooksCommand: "/hooks",
13 enabledKey: "[hooks].enabled",
14 };
15
16 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
17 const { locale } = await params;
18 const t = getDocsHooks(locale);
19 return buildPageMetadata({
20 path: "/docs/hooks",
21 locale,
22 title: t.metaTitle,
23 description: t.metaDescription,
24 });
25 }
26
27 export default async function HooksPage({ params }: { params: Promise<{ locale: string }> }) {
28 const { locale } = await params;
29 const t = getDocsHooks(locale);
30
31 return (
32 <section className="space-y-10">
33 <section id="overview" className="scroll-mt-32">
34 <h1 className="font-display text-3xl mb-1">{t.overviewTitle}</h1>
35 <p className={`${t.bodyClassName} mt-3`}>{t.overviewLead}</p>
36 <p className={`${t.bodyClassName} mt-3`}>
37 {splitTokens(t.configIntro).map((part, i) =>
38 "token" in part ? (
39 <code key={`${i}-${part.token}`} className="inline">
40 {CODE_SPANS[part.token] ?? `{${part.token}}`}
41 </code>
42 ) : (
43 <Fragment key={`${i}-text`}>{part.text}</Fragment>
44 ),
45 )}
46 </p>
47 <div className="hairline-t mt-6">
48 {t.events.map(([name, detail]) => (
49 <section key={name} className="py-4 hairline-b">
50 <h3 className="font-display text-lg">{name}</h3>
51 <p className={`${t.bodyClassName} mt-1 text-sm`}>{detail}</p>
52 </section>
53 ))}
54 </div>
55 </section>
56
57 <section id="project" className="scroll-mt-32">
58 <h2 className="font-display text-2xl mb-1">{t.projectTitle}</h2>
59 <p className={`${t.bodyClassName} mt-3`}>{t.projectLead}</p>
60 </section>
61
62 <section id="source" className="hairline-t pt-8">
63 <p className="text-sm text-ink-mute">{t.sourceNote}</p>
64 </section>
65 </section>
66 );
67 }
68
68 lines Plain Text