From 65177f12a7117b3612866d0dbed300a8bfe9401a Mon Sep 17 00:00:00 2001 From: yoge Date: Wed, 25 Mar 2026 13:27:25 +0800 Subject: [PATCH] feat: wire Docs and Blog pages to markdown content pipeline Co-Authored-By: Claude Opus 4.6 --- src/pages/BlogDetailPage.tsx | 37 +++++++++++++++++++++++++++++++++--- src/pages/BlogListPage.tsx | 32 ++++++++++++++++++------------- src/pages/DocDetailPage.tsx | 34 ++++++++++++++++++++++++++++++--- src/pages/DocsListPage.tsx | 18 ++++++++++++------ 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/src/pages/BlogDetailPage.tsx b/src/pages/BlogDetailPage.tsx index 1d6d94b..fc34503 100644 --- a/src/pages/BlogDetailPage.tsx +++ b/src/pages/BlogDetailPage.tsx @@ -1,14 +1,45 @@ +import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import SEOHead from '../components/seo/SEOHead'; +import { useLanguage } from '../contexts/LanguageContext'; +import { loadContent, type ContentItem } from '../lib/content'; export default function BlogDetailPage() { const { slug } = useParams<{ slug: string }>(); + const { language } = useLanguage(); + const [content, setContent] = useState(null); + + useEffect(() => { + if (slug) { + loadContent('blog', language, slug) + .then(setContent) + .catch(() => setContent(null)); + } + }, [slug, language]); + + if (!content) { + return ( +
+

{language === 'en' ? 'Loading...' : '加载中...'}

+
+ ); + } + return ( <> - +
-

{slug?.replace(/-/g, ' ')}

-

Content coming soon.

+
{content.meta.date}
+
); diff --git a/src/pages/BlogListPage.tsx b/src/pages/BlogListPage.tsx index e15f664..d2f4c14 100644 --- a/src/pages/BlogListPage.tsx +++ b/src/pages/BlogListPage.tsx @@ -1,20 +1,19 @@ +import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import SEOHead from '../components/seo/SEOHead'; import { useLanguage } from '../contexts/LanguageContext'; - -const posts = [ - { - slug: 'introducing-texpixel', - title: 'Introducing TexPixel', - titleZh: 'TexPixel 介绍', - description: 'Meet TexPixel — your AI-powered formula recognition tool', - descriptionZh: '认识 TexPixel — 你的 AI 公式识别工具', - date: '2026-03-25', - }, -]; +import { loadManifest, type ContentMeta } from '../lib/content'; export default function BlogListPage() { const { language } = useLanguage(); + const [posts, setPosts] = useState([]); + + useEffect(() => { + loadManifest('blog').then(manifest => { + setPosts(manifest[language] || []); + }); + }, [language]); + return ( <> @@ -24,8 +23,15 @@ export default function BlogListPage() { {posts.map((post) => (
{post.date}
-

{language === 'en' ? post.title : post.titleZh}

-

{language === 'en' ? post.description : post.descriptionZh}

+

{post.title}

+

{post.description}

+ {post.tags.length > 0 && ( +
+ {post.tags.map(tag => ( + {tag} + ))} +
+ )} ))} diff --git a/src/pages/DocDetailPage.tsx b/src/pages/DocDetailPage.tsx index 18cab51..64fe0ef 100644 --- a/src/pages/DocDetailPage.tsx +++ b/src/pages/DocDetailPage.tsx @@ -1,14 +1,42 @@ +import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import SEOHead from '../components/seo/SEOHead'; +import { useLanguage } from '../contexts/LanguageContext'; +import { loadContent, type ContentItem } from '../lib/content'; export default function DocDetailPage() { const { slug } = useParams<{ slug: string }>(); + const { language } = useLanguage(); + const [content, setContent] = useState(null); + + useEffect(() => { + if (slug) { + loadContent('docs', language, slug) + .then(setContent) + .catch(() => setContent(null)); + } + }, [slug, language]); + + if (!content) { + return ( +
+

{language === 'en' ? 'Loading...' : '加载中...'}

+
+ ); + } + return ( <> - +
-

{slug?.replace(/-/g, ' ')}

-

Content coming soon.

+
); diff --git a/src/pages/DocsListPage.tsx b/src/pages/DocsListPage.tsx index 3708997..e4644c3 100644 --- a/src/pages/DocsListPage.tsx +++ b/src/pages/DocsListPage.tsx @@ -1,13 +1,19 @@ +import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import SEOHead from '../components/seo/SEOHead'; import { useLanguage } from '../contexts/LanguageContext'; - -const docs = [ - { slug: 'getting-started', title: 'Getting Started', titleZh: '快速开始', description: 'Learn how to use TexPixel for formula recognition', descriptionZh: '了解如何使用 TexPixel 进行公式识别' }, -]; +import { loadManifest, type ContentMeta } from '../lib/content'; export default function DocsListPage() { const { language } = useLanguage(); + const [docs, setDocs] = useState([]); + + useEffect(() => { + loadManifest('docs').then(manifest => { + setDocs(manifest[language] || []); + }); + }, [language]); + return ( <> @@ -16,8 +22,8 @@ export default function DocsListPage() {
{docs.map((doc) => ( -

{language === 'en' ? doc.title : doc.titleZh}

-

{language === 'en' ? doc.description : doc.descriptionZh}

+

{doc.title}

+

{doc.description}

))}