115 lines
4.3 KiB
TypeScript
115 lines
4.3 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import ReactMarkdown from 'react-markdown';
|
|
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
|
import { tomorrow } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
|
import { ContentItem } from '@/lib/content';
|
|
import { Header } from '@/components/Header';
|
|
import { Footer } from '@/components/Footer';
|
|
import Link from 'next/link';
|
|
|
|
interface DocDetailProps {
|
|
doc: ContentItem | null;
|
|
relatedDocs: ContentItem[];
|
|
currentLang: string;
|
|
}
|
|
|
|
export default function DocDetail({ doc, relatedDocs, currentLang }: DocDetailProps) {
|
|
const [lang, setLang] = useState(currentLang);
|
|
|
|
// 你原有的语言检测逻辑也可以放在这里
|
|
useEffect(() => {
|
|
const browserLang = navigator.language;
|
|
if (browserLang.startsWith('zh-TW') || browserLang.startsWith('zh-HK')) {
|
|
setLang('zh-TW');
|
|
} else if (browserLang.startsWith('en')) {
|
|
setLang('en');
|
|
} else {
|
|
setLang('zh-CN');
|
|
}
|
|
}, []);
|
|
|
|
if (!doc) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center">
|
|
<h1 className="text-2xl font-bold">文档未找到</h1>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 你原先的多语言文本映射
|
|
const contentMap = {
|
|
'zh-CN': { backTo: '← 返回文档', related: '相关文档' },
|
|
'zh-TW': { backTo: '← 返回文檔', related: '相關文檔' },
|
|
en: { backTo: '← Back to Docs', related: 'Related Documents' },
|
|
};
|
|
|
|
const labels = contentMap[lang] || contentMap['zh-CN'];
|
|
|
|
return (
|
|
<div className="min-h-screen bg-white">
|
|
<Header
|
|
currentLang={lang}
|
|
setCurrentLang={setLang}
|
|
currentPage="docs"
|
|
navContent={{ docs: labels.backTo /* ... */ }}
|
|
/>
|
|
|
|
<div className="max-w-4xl mx-auto px-4 py-8">
|
|
<Link href="/docs" className="text-blue-600 hover:underline mb-4 inline-block">
|
|
{labels.backTo}
|
|
</Link>
|
|
|
|
<article className="prose prose-lg">
|
|
<h1>{doc.metadata.title}</h1>
|
|
<p className="text-gray-600">{doc.metadata.description}</p>
|
|
<ReactMarkdown
|
|
components={{
|
|
code({ inline, className, children, ...props }) {
|
|
const match = /language-(\w+)/.exec(className || '');
|
|
return !inline && match ? (
|
|
<SyntaxHighlighter
|
|
style={tomorrow}
|
|
language={match[1]}
|
|
PreTag="div"
|
|
{...props}
|
|
>
|
|
{String(children).replace(/\n$/, '')}
|
|
</SyntaxHighlighter>
|
|
) : (
|
|
<code className={className} {...props}>
|
|
{children}
|
|
</code>
|
|
);
|
|
},
|
|
}}
|
|
>
|
|
{doc.content}
|
|
</ReactMarkdown>
|
|
</article>
|
|
|
|
{relatedDocs.length > 0 && (
|
|
<section className="mt-12">
|
|
<h2 className="text-xl font-semibold mb-4">{labels.related}</h2>
|
|
<ul className="space-y-2">
|
|
{relatedDocs.map((item) => (
|
|
<li key={item.slug}>
|
|
<Link
|
|
href={`/docs/${item.slug}`}
|
|
className="text-blue-600 hover:underline"
|
|
>
|
|
{item.metadata.title}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</section>
|
|
)}
|
|
</div>
|
|
|
|
<Footer currentLang={lang} navContent={{ docs: labels.backTo /* ... */ }} />
|
|
</div>
|
|
);
|
|
}
|