返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / docs / auth / page.tsx
1 import { RefRows, withCodeSpans } from "@/components/code-spans";
2 import { getDocsAuth } from "@/lib/i18n/dictionaries";
3 import { APP_LOGIN_URL, APP_SIGNUP_URL } from "@/lib/i18n/links";
4 import { buildPageMetadata } from "@/lib/page-meta";
5
6 /** Code-owned literals from docs/CONFIGURATION.md. Not copy. */
7 const SPANS: Record<string, string> = {
8 authSet: "codewhale auth set --provider <provider>",
9 apiKeyFlag: "--api-key",
10 login: "codewhale login",
11 accountLogin: "codewhale account login",
12 profile: "--profile",
13 cloud: "codewhale cloud …",
14 keys: "codewhale account keys list|set|remove",
15 portable: "codewhale config export --portable",
16 };
17
18 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
19 const { locale } = await params;
20 const t = getDocsAuth(locale);
21 return buildPageMetadata({
22 path: "/docs/auth",
23 locale,
24 title: t.metaTitle,
25 description: t.metaDescription,
26 });
27 }
28
29 export default async function AuthPage({ params }: { params: Promise<{ locale: string }> }) {
30 const { locale } = await params;
31 const t = getDocsAuth(locale);
32
33 return (
34 <section className="space-y-10">
35 <section id="overview" className="scroll-mt-32">
36 <h1 className="font-display text-3xl mb-1">{t.overviewTitle}</h1>
37 <p className={`${t.bodyClassName} mt-3 mb-4`}>{t.overviewLead}</p>
38 <RefRows rows={t.credentials} spans={SPANS} />
39 </section>
40
41 <section id="provider-keys" className="scroll-mt-32">
42 <h2 className="font-display text-2xl mb-1">{t.providerTitle}</h2>
43 <p className={`${t.bodyClassName} mt-3`}>{withCodeSpans(t.providerLead, SPANS)}</p>
44 <pre className="code-block mt-4">{`codewhale auth set --provider deepseek
45 codewhale --model deepseek-v4-flash`}</pre>
46 </section>
47
48 <section id="account" className="scroll-mt-32">
49 <h2 className="font-display text-2xl mb-1">{t.accountTitle}</h2>
50 <p className={`${t.bodyClassName} mt-3 mb-4`}>{withCodeSpans(t.accountLead, SPANS)}</p>
51 <RefRows rows={t.accountCommands} termSpans />
52 </section>
53
54 <section id="storage" className="scroll-mt-32">
55 <h2 className="font-display text-2xl mb-1">{t.storageTitle}</h2>
56 <p className={`${t.bodyClassName} mt-3`}>{withCodeSpans(t.storageLead, SPANS)}</p>
57 </section>
58
59 <section id="vault" className="scroll-mt-32">
60 <h2 className="font-display text-2xl mb-1">{t.vaultTitle}</h2>
61 <p className={`${t.bodyClassName} mt-3`}>{withCodeSpans(t.vaultLead, SPANS)}</p>
62 </section>
63
64 <section id="portable" className="scroll-mt-32">
65 <h2 className="font-display text-2xl mb-1">{t.portableTitle}</h2>
66 <p className={`${t.bodyClassName} mt-3`}>{withCodeSpans(t.portableLead, SPANS)}</p>
67 </section>
68
69 <section id="web" className="scroll-mt-32">
70 <h2 className="font-display text-2xl mb-1">{t.appTitle}</h2>
71 <p className={`${t.bodyClassName} mt-3`}>{t.appLead}</p>
72 <div className="portal-actions">
73 <a className="portal-button portal-button-primary" href={APP_LOGIN_URL}>
74 {t.appSignIn}
75 </a>
76 <a className="portal-button portal-button-secondary" href={APP_SIGNUP_URL}>
77 {t.appRegister}
78 </a>
79 </div>
80 </section>
81
82 <section id="source" className="hairline-t pt-8">
83 <p className="text-sm text-ink-mute">{t.sourceNote}</p>
84 </section>
85 </section>
86 );
87 }
88
88 lines Plain Text