Skip to content

Commit c220abd

Browse files
committed
Merge pull request #4364 from idling11/feat/web-keyword-search
feat(web): add keyword search to docs hub and FAQ pages Resolved a generatedAt-timestamp conflict in web/lib/facts.generated.ts against the post-#4362 main; both sides already agreed on toolCount 85.
2 parents e2197b2 + 2d5b09e commit c220abd

8 files changed

Lines changed: 660 additions & 123 deletions

File tree

web/app/[locale]/docs/page.tsx

Lines changed: 2 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import Link from "next/link";
2-
import {
3-
getTopicsByCategory,
4-
REPO_DOCS_BASE,
5-
type DocTopic,
6-
} from "@/lib/docs-map";
1+
import { DocsSearch } from "@/components/docs-search";
72
import { buildPageMetadata } from "@/lib/page-meta";
83

94
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
@@ -19,94 +14,7 @@ export async function generateMetadata({ params }: { params: Promise<{ locale: s
1914
});
2015
}
2116

22-
/* ------------------------------------------------------------------ */
23-
/* Locale-aware strings */
24-
/* ------------------------------------------------------------------ */
25-
26-
const CATEGORY_LABELS: Record<string, { en: string; zh: string }> = {
27-
"getting-started": { en: "Getting started", zh: "入门" },
28-
"core-concepts": { en: "Core concepts", zh: "核心概念" },
29-
reference: { en: "Reference", zh: "参考" },
30-
extending: { en: "Extending", zh: "扩展" },
31-
operations: { en: "Operations & community", zh: "运维与社区" },
32-
};
33-
34-
/* ------------------------------------------------------------------ */
35-
36-
function topicHref(topic: DocTopic, locale: string): string {
37-
if (topic.hasPage) {
38-
return `/${locale}/docs/${topic.slug}`;
39-
}
40-
const src = Array.isArray(topic.repoSource) ? topic.repoSource[0] : topic.repoSource;
41-
return `${REPO_DOCS_BASE}/${src}`;
42-
}
43-
44-
function topicSources(topic: DocTopic): string[] {
45-
return Array.isArray(topic.repoSource) ? topic.repoSource : [topic.repoSource];
46-
}
47-
48-
/* ------------------------------------------------------------------ */
49-
5017
export default async function DocsHubPage({ params }: { params: Promise<{ locale: string }> }) {
5118
const { locale } = await params;
52-
const isZh = locale === "zh";
53-
const byCategory = getTopicsByCategory();
54-
55-
const body = (
56-
<div className="space-y-12">
57-
{[...byCategory.entries()].map(([cat, topics]) => (
58-
<section key={cat} id={cat}>
59-
<h2 className="font-display text-2xl mb-1">
60-
{isZh ? CATEGORY_LABELS[cat]?.zh ?? cat : CATEGORY_LABELS[cat]?.en ?? cat}
61-
</h2>
62-
<div className="grid sm:grid-cols-2 gap-4 mt-4">
63-
{topics.map((t) => {
64-
const href = topicHref(t, locale);
65-
const sources = topicSources(t);
66-
const isExternal = !t.hasPage;
67-
return (
68-
<Link
69-
key={t.id}
70-
href={href}
71-
target={isExternal ? "_blank" : undefined}
72-
className="hairline-t hairline-b hairline-l hairline-r p-4 hover:bg-paper-deep transition-colors group block"
73-
>
74-
<div className="flex items-center gap-2 mb-1.5">
75-
<span className="font-mono text-[0.62rem] uppercase tracking-widest text-ink-mute">
76-
{isZh ? t.label.zh : t.label.en}
77-
</span>
78-
{isExternal && (
79-
<span className="font-mono text-[0.6rem] text-ink-mute"></span>
80-
)}
81-
</div>
82-
<p className="text-sm text-ink-soft leading-relaxed">
83-
{isZh ? t.description.zh : t.description.en}
84-
</p>
85-
<div className="mt-2 font-mono text-[0.62rem] text-ink-mute truncate">
86-
{sources.map((s, i) => (
87-
<span key={s}>
88-
{i > 0 && ", "}
89-
{s}
90-
</span>
91-
))}
92-
</div>
93-
</Link>
94-
);
95-
})}
96-
</div>
97-
</section>
98-
))}
99-
100-
{/* Parapgraph about the docs approach */}
101-
<section className="hairline-t pt-8">
102-
<p className="text-sm text-ink-mute leading-relaxed max-w-2xl">
103-
{isZh
104-
? "§ 标记的条目在 CodeWhale 网站上有独立页面;↗ 标记的条目链接到 GitHub 仓库中的源文档。所有内容来源于 docs/ 目录下的 40+ 篇 Markdown 文档,通过 docs-map.ts 注册表维护。"
105-
: "Entries marked § have dedicated pages on codewhale.net; entries marked ↗ link to source documents in the GitHub repository. All content is sourced from 40+ Markdown documents in the docs/ directory, maintained through the docs-map.ts registry."}
106-
</p>
107-
</section>
108-
</div>
109-
);
110-
111-
return body;
19+
return <DocsSearch locale={locale} />;
11220
}

web/app/[locale]/faq/page.tsx

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Link from "next/link";
22
import { Seal } from "@/components/seal";
3+
import { FaqSearch } from "@/components/faq-search";
34

45
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
56
const { locale } = await params;
@@ -732,34 +733,7 @@ export default async function FaqPage({ params }: { params: Promise<{ locale: st
732733
</section>
733734

734735
<section className="mx-auto max-w-[1400px] px-6 pb-20">
735-
<div className="space-y-0 hairline-t hairline-b">
736-
{items.map((item, i) => (
737-
<details key={i} className="group hairline-b last:border-b-0">
738-
<summary className="px-0 py-5 cursor-pointer flex items-start gap-4 hover:text-indigo transition-colors">
739-
<span className="font-mono text-indigo tabular text-sm pt-0.5 shrink-0">
740-
{String(i + 1).padStart(2, "0")}
741-
</span>
742-
<span className="font-display text-lg leading-snug flex-1">{item.q}</span>
743-
<span className="font-mono text-ink-mute text-sm group-open:rotate-45 transition-transform shrink-0">+</span>
744-
</summary>
745-
<div className="pb-5 pl-10 pr-4">
746-
<div className={`text-ink-soft leading-relaxed ${isZh ? "leading-[1.9] tracking-wide" : ""}`}>
747-
{item.a}
748-
</div>
749-
{item.sources && item.sources.length > 0 && (
750-
<div className="mt-3 flex items-center gap-2 flex-wrap">
751-
<span className="font-mono text-[0.66rem] text-ink-mute uppercase tracking-wider">
752-
{isZh ? "来源" : "Sources"}:
753-
</span>
754-
{item.sources.map((s) => (
755-
<span key={s} className="font-mono text-[0.7rem] text-indigo">{s}</span>
756-
))}
757-
</div>
758-
)}
759-
</div>
760-
</details>
761-
))}
762-
</div>
736+
<FaqSearch items={items} locale={locale} />
763737

764738
<div className="mt-12 text-center">
765739
<p className="text-ink-soft text-sm mb-4">

web/app/globals.css

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,31 @@ code.inline {
273273
border-radius: 2px;
274274
}
275275

276+
277+
/* ---------- search ---------- */
278+
.search-input {
279+
font-family: var(--font-body), system-ui, sans-serif;
280+
font-size: 1rem;
281+
padding: 0.75rem 2.5rem 0.75rem 1rem;
282+
background: var(--paper);
283+
color: var(--ink);
284+
border: 1px solid var(--hairline);
285+
transition: border-color 180ms ease, box-shadow 180ms ease;
286+
}
287+
.search-input::placeholder { color: var(--ink-mute); }
288+
.search-input:focus {
289+
outline: none;
290+
border-color: var(--indigo);
291+
box-shadow: 0 0 0 3px var(--indigo-pale);
292+
}
293+
294+
mark.search-highlight {
295+
background: var(--indigo-pale);
296+
color: var(--indigo-deep);
297+
padding: 0.02em 0.08em;
298+
border-radius: 2px;
299+
}
300+
276301
/* ---------- nav link ---------- */
277302
.site-nav {
278303
position: sticky;

0 commit comments

Comments
 (0)