返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / docs / guide / page.tsx
1 import Link from "next/link";
2 import { GettingStartedSteps } from "@/components/getting-started-steps";
3 import { SessionMedia } from "@/components/session-media";
4 import { GUIDE_NEXT_LINKS } from "@/lib/content/getting-started";
5 import { getMediaAsset } from "@/lib/media-manifest";
6 import { buildPageMetadata } from "@/lib/page-meta";
7
8 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
9 const { locale } = await params;
10 const isZh = locale === "zh";
11 return buildPageMetadata({
12 path: "/docs/guide",
13 locale,
14 title: isZh ? "新手指引 · Codewhale 文档" : "Getting started · Codewhale Docs",
15 description: isZh
16 ? "从安装到第一个 Fleet Workflow 的完整路径:安装、无需密钥的首次会话、连接提供商、运行 Fleet。"
17 : "The full path from install to a first Fleet workflow: install, a first keyless session, provider connection, and Fleet.",
18 });
19 }
20
21 export default async function GuidePage({ params }: { params: Promise<{ locale: string }> }) {
22 const { locale } = await params;
23 const isZh = locale === "zh";
24 const bodyClass = isZh
25 ? "text-ink-soft leading-[1.9] tracking-wide"
26 : "text-ink-soft leading-relaxed";
27 const session = getMediaAsset("first-fleet-session");
28
29 return (
30 <section className="space-y-10">
31 <section id="overview" className="scroll-mt-32">
32 <h2 className="font-display text-3xl mb-1">{isZh ? "新手指引" : "Getting started"}</h2>
33 <p className={`${bodyClass} mt-3`}>
34 {isZh
35 ? "从一条安装命令到第一个 Fleet Workflow,四步走完。每一步都只陈述当前版本真实的行为;未发布或待录制的内容会明确标注。"
36 : "Four steps from one install command to a first Fleet workflow. Every step states only what the current candidate actually does; anything unreleased or unrecorded is labeled as such."}
37 </p>
38 </section>
39
40 <section id="path" className="scroll-mt-32">
41 <GettingStartedSteps locale={locale} />
42 </section>
43
44 {session && (
45 <section id="session-media" className="scroll-mt-32">
46 <h2 className="font-display text-2xl mb-1">
47 {isZh ? "看一次真实会话" : "Watch a real session"}
48 </h2>
49 <p className={`${bodyClass} mt-3 mb-4`}>
50 {isZh
51 ? "下方是真实会话媒体位。它当前处于待录制状态——这是有意为之:在 v0.9.2 候选版 dogfood 录制完成前,本站不展示任何占位或摆拍影像。"
52 : "Below is the real-session media slot. It is deliberately in the pending state: until the v0.9.2 candidate dogfood recording exists, this site shows no placeholder or staged footage."}
53 </p>
54 <SessionMedia asset={session} locale={locale} />
55 </section>
56 )}
57
58 <section id="next" className="scroll-mt-32">
59 <h2 className="font-display text-2xl mb-1">{isZh ? "接下来" : "Where next"}</h2>
60 <div className="hairline-t mt-4">
61 {GUIDE_NEXT_LINKS.map((item) => (
62 <div key={item.href} className="py-4 hairline-b">
63 <h3 className="font-display text-xl">
64 <Link href={`/${locale}${item.href}`} className="hover:text-indigo transition-colors">
65 {isZh ? item.label.zh : item.label.en}
66 </Link>
67 </h3>
68 <p className={`${bodyClass} mt-1 text-sm`}>{isZh ? item.note.zh : item.note.en}</p>
69 </div>
70 ))}
71 </div>
72 </section>
73
74 <section id="source" className="hairline-t pt-8">
75 <p className="text-sm text-ink-mute">
76 {isZh
77 ? "来源文档:docs/GUIDE.md, docs/KEYBINDINGS.md · 步骤文案来自 web/lib/content/getting-started.ts;更新时请同步修改 docs-map.ts。"
78 : "Source documents: docs/GUIDE.md, docs/KEYBINDINGS.md · Step copy lives in web/lib/content/getting-started.ts; update docs-map.ts when changing."}
79 </p>
80 </section>
81 </section>
82 );
83 }
84
84 lines Plain Text