返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / install / page.tsx
1 import Link from "next/link";
2 import { HeroInstall } from "@/components/hero-install";
3 import { Icon } from "@/components/icon";
4 import { InstallCodeBlock } from "@/components/install-code-block";
5 import { WhalePose } from "@/components/whale-pose";
6 import { INSTALL_COPY } from "@/lib/content/install";
7 import { INSTALL_GUIDE } from "@/lib/install-guide.generated";
8 import { getHome, pickText, pickTextLocale } from "@/lib/i18n/dictionaries";
9 import { buildPageMetadata } from "@/lib/page-meta";
10
11 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
12 const { locale } = await params;
13 return buildPageMetadata({
14 path: "/install",
15 locale,
16 title: pickText(INSTALL_COPY.metaTitle, locale),
17 description: pickText(INSTALL_COPY.metaDescription, locale),
18 });
19 }
20
21 /**
22 * /install — the quick install plate first (the two one-line installs the
23 * home page offers), then the verified guide from docs/INSTALL.md, which owns
24 * the page's heading and every other channel. The guide stays in English
25 * until its translation is verified; the notice says so.
26 */
27 export default async function InstallPage({ params }: { params: Promise<{ locale: string }> }) {
28 const { locale } = await params;
29 const home = getHome(locale);
30 const copyLocale = pickTextLocale(locale);
31 return (
32 <>
33 <div className="install-head" lang={copyLocale}>
34 <div className="install-head-inner">
35 <WhalePose pose="run" className="install-head-pose" priority />
36 <div className="install-head-text">
37 <HeroInstall ariaLabel={home.heroInstallAria} copyLabel={home.copy} copiedLabel={home.copied} />
38 <p className="install-head-source">
39 <Icon name="check" className="icon" />
40 <a href="https://github.com/codewhale-hq/CodeWhale/blob/main/docs/INSTALL.md" className="link">
41 {pickText(INSTALL_COPY.source, locale)}
42 </a>
43 </p>
44 {/* The notice speaks about the Chinese translation, so only the
45 Chinese page shows it. */}
46 {copyLocale === "zh" ? (
47 <p className="install-head-note">{pickText(INSTALL_COPY.translationNotice, locale)}</p>
48 ) : null}
49 </div>
50 </div>
51 </div>
52 <article className="install-guide" lang="en">
53 {INSTALL_GUIDE.chunks.map((chunk, index) => chunk.kind === "code" ? (
54 <InstallCodeBlock key={index} cmd={chunk.text} copyLabel={home.copy} copiedLabel={home.copied} copyLocale={locale} />
55 ) : (
56 // HTML is generated at build time with strict raw-HTML and URL guards.
57 <div key={index} dangerouslySetInnerHTML={{ __html: chunk.text }} />
58 ))}
59 <p lang={copyLocale}>
60 <Link href={`/${locale}/docs/configuration`} className="section-link">
61 {pickText(INSTALL_COPY.configuration, locale)}
62 <Icon name="arrow-right" className="icon icon-flip" />
63 </Link>
64 </p>
65 </article>
66 </>
67 );
68 }
69
69 lines Plain Text