返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / community / page.tsx
1 import Link from "next/link";
2 import { Icon, type IconName } from "@/components/icon";
3 import { PageHeader, Section } from "@/components/page-header";
4 import { getFacts } from "@/lib/facts";
5 import { fill, getCommunity, pickTextLocale } from "@/lib/i18n/dictionaries";
6 import { buildPageMetadata } from "@/lib/page-meta";
7 import { RELEASE_CONTRIBUTORS, RELEASE_HELPERS } from "@/lib/release-credits";
8
9 export const revalidate = 300;
10
11 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
12 const { locale } = await params;
13 const t = getCommunity(locale);
14 return buildPageMetadata({
15 path: "/community",
16 locale,
17 title: t.metaTitle,
18 description: t.metaDescription,
19 });
20 }
21
22 const pathsEn = [
23 {
24 title: "Report a problem",
25 description: "File a bug, compatibility problem, or unclear behavior with system details, reproduction steps, and any logs you can share safely.",
26 cta: "File an issue",
27 href: "https://github.com/codewhale-hq/CodeWhale/issues/new/choose",
28 },
29 {
30 title: "Improve code or tests",
31 description: "Pick one problem with clear edges, write the smallest patch that fixes it, and add a regression test that covers it.",
32 cta: "Browse open issues",
33 href: "https://github.com/codewhale-hq/CodeWhale/issues",
34 },
35 {
36 title: "Improve documentation or translations",
37 description: "Fix a wrong sentence, add an example, or help finish a language pack.",
38 cta: "Open the localization guide",
39 href: "https://github.com/codewhale-hq/CodeWhale/blob/main/docs/LOCALIZATION.md",
40 },
41 {
42 title: "Reproduce and review existing work",
43 description: "Try an issue or pull request on your platform and provider. Post the commands you ran, what happened, and what is still wrong.",
44 cta: "Browse pull requests",
45 href: "https://github.com/codewhale-hq/CodeWhale/pulls",
46 },
47 ];
48
49 const pathsZh = [
50 {
51 title: "报告问题",
52 description: "报告 bug、兼容性问题或不清楚的行为,并附上系统信息、复现步骤和可以安全分享的日志。",
53 cta: "提交 issue",
54 href: "https://github.com/codewhale-hq/CodeWhale/issues/new/choose",
55 },
56 {
57 title: "改进代码或测试",
58 description: "挑一个范围清楚的问题,写最小的补丁,加一个覆盖改动的回归测试。",
59 cta: "查看开放 issues",
60 href: "https://github.com/codewhale-hq/CodeWhale/issues",
61 },
62 {
63 title: "改进文档或翻译",
64 description: "改正说错的地方,补一个示例,或者帮忙完成一个语言包。",
65 cta: "查看本地化指南",
66 href: "https://github.com/codewhale-hq/CodeWhale/blob/main/docs/LOCALIZATION.md",
67 },
68 {
69 title: "复现并审查现有工作",
70 description: "在你的平台和提供商上验证 issue 或 pull request,然后分享你运行的命令、结果和剩余问题。",
71 cta: "查看 pull requests",
72 href: "https://github.com/codewhale-hq/CodeWhale/pulls",
73 },
74 ];
75
76 const activityEn = [
77 { title: "Repository activity", description: "Recent issues and pull requests.", path: "/feed" },
78 { title: "Community digest", description: "The weekly project record, reviewed by a maintainer.", path: "/digest" },
79 { title: "Public roadmap", description: "Shipped, underway, considered, and ruled-out work.", path: "/roadmap" },
80 ];
81
82 const activityZh = [
83 { title: "仓库动态", description: "最近的 issues 与 pull requests。", path: "/feed" },
84 { title: "社区摘要", description: "经过维护者审核的每周项目记录。", path: "/digest" },
85 { title: "公开路线图", description: "已发布、正在进行、考虑中和明确不做的工作。", path: "/roadmap" },
86 ];
87
88 export default async function CommunityPage({ params }: { params: Promise<{ locale: string }> }) {
89 const { locale } = await params;
90 const t = getCommunity(locale);
91 const p = (path: string) => `/${locale}${path}`;
92 const facts = await getFacts();
93 const sourceIsPublished = facts.latestPublishedRelease?.version === facts.version;
94 const textLocale = pickTextLocale(locale);
95 const contributionPaths = { en: pathsEn, zh: pathsZh }[textLocale];
96 const activityLinks = { en: activityEn, zh: activityZh }[textLocale];
97
98
99 const activityIcons: IconName[] = ["repeat", "book", "tide"];
100
101 return (
102 <>
103 <PageHeader
104 kicker={t.kicker}
105 title={t.title}
106 lede={t.lede}
107 pose="talk"
108 actions={
109 <>
110 <Link href="https://github.com/codewhale-hq/CodeWhale/issues/new/choose" className="btn btn-primary btn-lg">
111 {t.fileIssue}
112 </Link>
113 <Link href="https://github.com/codewhale-hq/CodeWhale/pulls" className="btn btn-secondary btn-lg">
114 {t.browsePulls}
115 </Link>
116 <Link href={p("/contribute")} className="btn btn-ghost btn-lg">
117 {t.readGuide}
118 <Icon name="arrow-right" className="icon icon-flip" />
119 </Link>
120 </>
121 }
122 />
123
124 <div className="page-body">
125 <Section
126 id="community-paths"
127 title={t.pathsTitle}
128 scope={t.pathsScope}
129 >
130 <div className="grid-2">
131 {contributionPaths.map((path) => (
132 <Link key={path.title} href={path.href} className="tile">
133 <h3>{path.title}</h3>
134 <p>{path.description}</p>
135 <span className="section-link">
136 {path.cta}
137 <Icon name={path.href.includes("LOCALIZATION") ? "external" : "arrow-right"} className="icon icon-flip" />
138 </span>
139 </Link>
140 ))}
141 </div>
142 </Section>
143
144 <Section
145 id="community-record"
146 title={t.recordTitle}
147 scope={t.recordScope}
148 >
149 <ul className="dir-list dir-list-card" role="list">
150 {activityLinks.map((item, index) => (
151 <li key={item.path}>
152 <Link href={p(item.path)} className="dir-row">
153 <span className="dir-mark" aria-hidden="true"><Icon name={activityIcons[index] ?? "book"} /></span>
154 <span className="dir-text">
155 <span className="dir-title">{item.title}</span>
156 <span className="dir-purpose">{item.description}</span>
157 </span>
158 <span className="dir-action" aria-hidden="true"><Icon name="chevron-right" className="icon icon-flip" /></span>
159 </Link>
160 </li>
161 ))}
162 </ul>
163 </Section>
164
165 <Section
166 id="community-credit"
167 title={t.creditTitle}
168 scope={sourceIsPublished ? t.creditScope : t.creditScopeUnreleased}
169 >
170 <p className="page-kicker mb-4">
171 {fill(sourceIsPublished ? t.creditLabel : t.creditLabelUnreleased, { version: facts.version ?? "—" })}
172 </p>
173 <div className="grid-2">
174 <div className="tile">
175 <h3>{t.mergedTitle}</h3>
176 <ul className="credit-list" role="list">
177 {RELEASE_CONTRIBUTORS.map((handle) => (
178 <li key={handle}>
179 <Link href={`https://github.com/${handle.slice(1)}`}>{handle}</Link>
180 </li>
181 ))}
182 </ul>
183 </div>
184 {RELEASE_HELPERS.length > 0 ? (
185 <div className="tile">
186 <h3>{t.helpersTitle}</h3>
187 <ul className="credit-list" role="list">
188 {RELEASE_HELPERS.map((handle) => (
189 <li key={handle}>
190 <Link href={`https://github.com/${handle.slice(1)}`}>{handle}</Link>
191 </li>
192 ))}
193 </ul>
194 </div>
195 ) : null}
196 </div>
197 <p className="status-line mt-4">
198 <Link href="https://github.com/codewhale-hq/CodeWhale/blob/main/docs/CONTRIBUTORS.md" className="link">
199 {t.fullRecord}
200 </Link>
201 <Link href="https://github.com/codewhale-hq/CodeWhale/blob/main/CHANGELOG.md" className="link">CHANGELOG</Link>
202 </p>
203 </Section>
204 </div>
205 </>
206 );
207 }
208
208 lines Plain Text