'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import Image from 'next/image'; import Link from 'next/link'; import { useTranslation } from 'react-i18next'; import { Article } from '@/lib/types'; import { formatDate } from '@/lib/utils'; import { Skeleton } from '@/app/components/ui/skeleton'; import { Button } from '@/app/components/ui/button'; import { Card, CardContent } from '@/app/components/ui/card'; import { Badge } from '@/app/components/ui/badge'; import { Share2, ArrowLeft, Calendar, User, Tag, Clock, Eye, FileX } from 'lucide-react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import rehypeRaw from 'rehype-raw'; import rehypeSanitize from 'rehype-sanitize'; import Header from '@/app/components/Header'; import Footer from '@/app/components/Footer'; interface NewsArticlePageClientProps { articleId: string; locale: string; } // 翻译数据,与首页保持一致 const translations = { 'zh-CN': { nav: { home: '首页', products: '产品与服务', news: '新闻资讯', support: '客户支持', about: '关于我们', contact: '联系我们', }, footer: { sections: [ { title: '目录', items: ['首页', '产品与服务', '新闻资讯', '客户支持', '关于我们'], }, { title: '热门产品', items: ['轻量云服务器', '站群服务器', 'EC2服务器', '高防服务器', 'S3云存储'], }, { title: '客户支持', items: ['技术支持', '在线客服', '帮助文档', '服务状态'], }, { title: '公司信息', items: ['关于我们', '联系我们', '隐私政策', '服务条款'], }, ], }, }, 'zh-TW': { nav: { home: '首頁', products: '產品與服務', news: '新聞資訊', support: '客戶支持', about: '關於我們', contact: '聯繫我們', }, footer: { sections: [ { title: '目錄', items: ['首頁', '產品與服務', '新聞資訊', '客戶支持', '關於我們'], }, { title: '熱門產品', items: ['輕量雲服務器', '站群服務器', 'EC2服務器', '高防服務器', 'S3雲存儲'], }, { title: '客戶支持', items: ['技術支持', '在線客服', '幫助文檔', '服務狀態'], }, { title: '公司信息', items: ['關於我們', '聯繫我們', '隱私政策', '服務條款'], }, ], }, }, 'en': { nav: { home: 'Home', products: 'Products & Services', news: 'News', support: 'Support', about: 'About Us', contact: 'Contact Us', }, footer: { sections: [ { title: 'Directory', items: ['Home', 'Products & Services', 'News', 'Support', 'About Us'], }, { title: 'Popular Products', items: ['Lightweight Cloud Server', 'Station Group Server', 'EC2 Server', 'High-Defense Server', 'S3 Cloud Storage'], }, { title: 'Customer Support', items: ['Technical Support', 'Online Service', 'Documentation', 'Service Status'], }, { title: 'Company Info', items: ['About Us', 'Contact Us', 'Privacy Policy', 'Terms of Service'], }, ], }, }, }; export default function NewsArticlePageClient({ articleId, locale }: NewsArticlePageClientProps) { const { t } = useTranslation('article'); const router = useRouter(); const [article, setArticle] = useState
(null); const [relatedArticles, setRelatedArticles] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [readingProgress, setReadingProgress] = useState(0); const [language, setLanguage] = useState(locale); // 获取当前语言的翻译 const currentTranslations = translations[language as keyof typeof translations] || translations['zh-CN']; // 阅读进度条 useEffect(() => { // 确保在客户端执行 if (typeof window === 'undefined') return; const updateReadingProgress = () => { const scrollTop = window.scrollY; const docHeight = document.documentElement.scrollHeight - window.innerHeight; const progress = (scrollTop / docHeight) * 100; setReadingProgress(Math.min(100, Math.max(0, progress))); }; // 防抖处理 let timeoutId: NodeJS.Timeout; const throttledUpdateProgress = () => { if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(updateReadingProgress, 16); // ~60fps }; window.addEventListener('scroll', throttledUpdateProgress, { passive: true }); return () => { window.removeEventListener('scroll', throttledUpdateProgress); if (timeoutId) clearTimeout(timeoutId); }; }, []); useEffect(() => { const fetchArticle = async () => { try { setIsLoading(true); setError(null); // 清除之前的文章数据,避免DOM操作错误 setArticle(null); setRelatedArticles([]); const response = await fetch(`/api/articles/${articleId}?locale=${locale}`); if (!response.ok) { if (response.status === 404) { const errorMessage = locale === 'en' ? 'This article is not available in English. Please try viewing it in Chinese or check other articles.' : locale === 'zh-TW' ? '此文章沒有繁體中文版本。請嘗試查看中文版本或查看其他文章。' : '此文章不存在或已被移除。请检查网址是否正确。'; throw new Error(errorMessage); } throw new Error('Failed to fetch article'); } const data = await response.json(); setArticle(data.article); setRelatedArticles(data.relatedArticles); } catch (err) { setError(err instanceof Error ? err.message : 'An error occurred'); console.error('Error fetching article:', err); } finally { setIsLoading(false); } }; fetchArticle(); }, [articleId, locale]); // 估算阅读时间 const estimateReadingTime = (content: string) => { const wordsPerMinute = 200; const words = content.split(/\s+/).length; return Math.ceil(words / wordsPerMinute); }; // 分享文章 const handleShare = async () => { if (navigator.share && article) { try { await navigator.share({ title: article.metadata.title, text: article.metadata.description, url: typeof window !== 'undefined' ? window.location.href : '', }); } catch (err) { console.error('Error sharing article:', err); } } else { // 复制链接到剪贴板 try { await navigator.clipboard.writeText(typeof window !== 'undefined' ? window.location.href : ''); alert('链接已复制到剪贴板'); } catch (err) { console.error('Error copying link:', err); } } }; // 渲染加载状态 const renderSkeleton = () => (
); // 渲染错误状态 const renderError = () => { const errorTitle = locale === 'en' ? 'Article Not Found' : locale === 'zh-TW' ? '文章未找到' : '文章未找到'; const backButtonText = locale === 'en' ? 'Go Back' : locale === 'zh-TW' ? '返回上一頁' : '返回上一页'; const newsListText = locale === 'en' ? 'View All News' : locale === 'zh-TW' ? '查看所有新聞' : '查看所有新闻'; return (

{errorTitle}

{error}

); }; if (isLoading) { return renderSkeleton(); } if (error || !article) { return renderError(); } return (
{/* 阅读进度条 */}
{/* 返回按钮 */} {/* 文章主体 */}
{/* 文章封面图 */}
{article.metadata.title}
{article.metadata.category}

{article.metadata.title}

{/* 文章元数据 */}
{formatDate(article.metadata.date, locale)}
{article.metadata.author}
{estimateReadingTime(article.content)} 分钟阅读
阅读量 {Math.floor(Math.random() * 1000) + 100}
{/* 文章摘要 */} {article.metadata.excerpt && (

{article.metadata.excerpt}

)} {/* 文章内容 */}

{children}

, h2: ({ children }) =>

{children}

, h3: ({ children }) =>

{children}

, p: ({ children }) =>

{children}

, img: ({ src, alt }) => (
{alt
), }} > {article.content}
{/* 文章标签 */}
标签: {article.metadata.tags.map((tag) => ( #{tag} ))}
{/* 分享按钮 */}
{/* 相关文章 */} {relatedArticles.length > 0 && (

相关文章推荐

{relatedArticles.map((relatedArticle) => (
{relatedArticle.metadata.title}
{relatedArticle.metadata.category}

{relatedArticle.metadata.title}

{relatedArticle.metadata.excerpt || relatedArticle.metadata.description}

{formatDate(relatedArticle.metadata.date, locale)}
))}
)}
); }