405 lines
18 KiB
TypeScript
405 lines
18 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useEffect } from 'react';
|
||
import Link from 'next/link';
|
||
import Header from '@/app/components/Header';
|
||
import Footer from '@/app/components/Footer';
|
||
import { type Article } from '../../lib/types';
|
||
// News translations
|
||
export const newsTranslations = {
|
||
'zh-CN': {
|
||
nav: {
|
||
home: '首页',
|
||
products: '产品与服务',
|
||
news: '新闻资讯',
|
||
support: '客户支持',
|
||
about: '关于我们',
|
||
contact: '联系我们',
|
||
},
|
||
title: '新闻资讯',
|
||
subtitle: '了解最新的云计算技术动态和行业资讯',
|
||
categories: [
|
||
{ id: 'all', name: '全部' },
|
||
{ id: 'tech', name: '技术动态' },
|
||
{ id: 'product', name: '产品更新' },
|
||
{ id: 'industry', name: '行业资讯' },
|
||
{ id: 'company', name: '公司动态' },
|
||
],
|
||
|
||
articles: [
|
||
{
|
||
id: '1',
|
||
title: 'AWS新一代EC2实例发布,性能提升50%',
|
||
excerpt:
|
||
'AWS发布了新一代EC2实例,采用最新的处理器技术,在计算性能、网络性能和存储性能方面都有显著提升...',
|
||
category: 'tech',
|
||
date: '2024-01-15',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
{
|
||
id: '2',
|
||
title: '云安全最佳实践:保护您的AWS环境',
|
||
excerpt:
|
||
'随着云计算的普及,云安全变得越来越重要。本文将介绍AWS环境下的安全最佳实践...',
|
||
category: 'tech',
|
||
date: '2024-01-12',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
{
|
||
id: '3',
|
||
title: '合肥懂云获得AWS高级合作伙伴认证',
|
||
excerpt: '我们很高兴地宣布,合肥懂云信息科技有限公司正式获得AWS高级合作伙伴认证...',
|
||
category: 'company',
|
||
date: '2024-01-10',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
],
|
||
|
||
readMore: '阅读更多',
|
||
noArticles: '暂无相关文章',
|
||
footer: {
|
||
sections: [
|
||
{
|
||
title: '目录',
|
||
items: ['首页', '产品与服务', '新闻资讯', '客户支持', '关于我们'],
|
||
},
|
||
{
|
||
title: '热门产品',
|
||
items: ['轻量云服务器', '站群服务器', 'EC2服务器', '高防服务器', 'S3云存储'],
|
||
},
|
||
{ title: '客户支持', items: ['技术支持', '在线客服', '帮助文档', '服务状态'] },
|
||
{ title: '', items: ['新闻资讯', '关于我们', '隐私政策', '站点地图'] },
|
||
],
|
||
},
|
||
},
|
||
'zh-TW': {
|
||
nav: {
|
||
home: '首頁',
|
||
products: '產品與服務',
|
||
news: '新聞資訊',
|
||
support: '客戶支持',
|
||
about: '關於我們',
|
||
contact: '聯繫我們',
|
||
},
|
||
title: '新聞資訊',
|
||
subtitle: '了解最新的雲計算技術動態和行業資訊',
|
||
categories: [
|
||
{ id: 'all', name: '全部' },
|
||
{ id: 'tech', name: '技術動態' },
|
||
{ id: 'product', name: '產品更新' },
|
||
{ id: 'industry', name: '行業資訊' },
|
||
{ id: 'company', name: '公司動態' },
|
||
],
|
||
|
||
articles: [
|
||
{
|
||
id: '1',
|
||
title: 'AWS新一代EC2實例發布,性能提升50%',
|
||
excerpt:
|
||
'AWS發布了新一代EC2實例,採用最新的處理器技術,在計算性能、網絡性能和存儲性能方面都有顯著提升...',
|
||
category: 'tech',
|
||
date: '2024-01-15',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
{
|
||
id: '2',
|
||
title: '雲安全最佳實踐:保護您的AWS環境',
|
||
excerpt:
|
||
'隨著雲計算的普及,雲安全變得越來越重要。本文將介紹AWS環境下的安全最佳實踐...',
|
||
category: 'tech',
|
||
date: '2024-01-12',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
{
|
||
id: '3',
|
||
title: '合肥懂雲獲得AWS高級合作夥伴認證',
|
||
excerpt: '我們很高興地宣布,合肥懂雲信息科技有限公司正式獲得AWS高級合作夥伴認證...',
|
||
category: 'company',
|
||
date: '2024-01-10',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
],
|
||
|
||
readMore: '閱讀更多',
|
||
noArticles: '暫無相關文章',
|
||
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',
|
||
},
|
||
title: 'News & Updates',
|
||
subtitle: 'Stay updated with the latest cloud computing technology and industry insights',
|
||
categories: [
|
||
{ id: 'all', name: 'All' },
|
||
{ id: 'tech', name: 'Technology' },
|
||
{ id: 'product', name: 'Product Updates' },
|
||
{ id: 'industry', name: 'Industry News' },
|
||
{ id: 'company', name: 'Company News' },
|
||
],
|
||
|
||
articles: [
|
||
{
|
||
id: '1',
|
||
title: 'AWS Launches New Generation EC2 Instances with 50% Performance Boost',
|
||
excerpt:
|
||
'AWS has released new generation EC2 instances featuring the latest processor technology, with significant improvements in compute, network, and storage performance...',
|
||
category: 'tech',
|
||
date: '2024-01-15',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
{
|
||
id: '2',
|
||
title: 'Cloud Security Best Practices: Protecting Your AWS Environment',
|
||
excerpt:
|
||
'As cloud computing becomes more prevalent, cloud security is becoming increasingly important. This article covers security best practices for AWS environments...',
|
||
category: 'tech',
|
||
date: '2024-01-12',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
{
|
||
id: '3',
|
||
title: 'Hefei DongYun Achieves AWS Advanced Partner Certification',
|
||
excerpt:
|
||
'We are pleased to announce that Hefei DongYun Information Technology Co., Ltd. has officially achieved AWS Advanced Partner certification...',
|
||
category: 'company',
|
||
date: '2024-01-10',
|
||
image: '/api/placeholder/400/250',
|
||
},
|
||
],
|
||
|
||
readMore: 'Read More',
|
||
noArticles: 'No articles available',
|
||
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', 'Help Documentation', 'Service Status'] },
|
||
{ title: '', items: ['News', 'About Us', 'Privacy Policy', 'Site Map'] },
|
||
],
|
||
},
|
||
},
|
||
};
|
||
|
||
type NewsLanguage = keyof typeof newsTranslations;
|
||
|
||
interface NewsPageClientProps {
|
||
locale: string;
|
||
}
|
||
|
||
export default function NewsPageClient({ locale }: NewsPageClientProps) {
|
||
const [language, setLanguage] = useState<NewsLanguage>(
|
||
locale === 'zh' ? 'zh-CN' : locale === 'zh-TW' ? 'zh-TW' : 'en',
|
||
);
|
||
const [selectedCategory, setSelectedCategory] = useState('all');
|
||
const [articles, setArticles] = useState<Article[]>([]);
|
||
const [categories, setCategories] = useState<{ id: string; name: string }[]>([]);
|
||
const t = newsTranslations[language] || newsTranslations['zh-CN'];
|
||
const [loading, setLoading] = useState(true);
|
||
// Load articles and categories when language or category changes
|
||
useEffect(() => {
|
||
const fetchArticles = async () => {
|
||
setLoading(true);
|
||
try {
|
||
const response = await fetch(
|
||
`/api/articles?locale=${language}&category=${selectedCategory}`,
|
||
);
|
||
if (response.ok) {
|
||
const data = await response.json();
|
||
setArticles(data.articles);
|
||
|
||
// Set categories only on first load or language change
|
||
if (selectedCategory === 'all') {
|
||
const t = newsTranslations[language] || newsTranslations['zh-CN'];
|
||
const categoryMap: { [key: string]: string } = {
|
||
tech: t.categories.find((c) => c.id === 'tech')?.name || 'Technology',
|
||
product:
|
||
t.categories.find((c) => c.id === 'product')?.name || 'Product',
|
||
industry:
|
||
t.categories.find((c) => c.id === 'industry')?.name || 'Industry',
|
||
company:
|
||
t.categories.find((c) => c.id === 'company')?.name || 'Company',
|
||
};
|
||
|
||
const mappedCategories = [
|
||
{
|
||
id: 'all',
|
||
name: t.categories.find((c) => c.id === 'all')?.name || 'All',
|
||
},
|
||
...data.categories.map((cat: string) => ({
|
||
id: cat,
|
||
name: categoryMap[cat] || cat,
|
||
})),
|
||
];
|
||
|
||
setCategories(mappedCategories);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('Error fetching articles:', error);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
fetchArticles();
|
||
}, [language, selectedCategory]);
|
||
|
||
const handleLanguageChange = (newLanguage: string) => {
|
||
const validLanguage = newLanguage as NewsLanguage;
|
||
setLanguage(validLanguage);
|
||
};
|
||
|
||
return (
|
||
<div className="min-h-screen bg-white">
|
||
<Header
|
||
language={language}
|
||
setLanguage={handleLanguageChange}
|
||
translations={t}
|
||
locale={locale}
|
||
/>
|
||
|
||
{/* Hero Section */}
|
||
<section className="bg-blue-600 text-white h-96 flex items-center justify-center">
|
||
<div className="max-w-6xl mx-auto px-4 text-center">
|
||
<h1 className="text-4xl font-bold mb-4">{t.title}</h1>
|
||
<p className="text-xl">{t.subtitle}</p>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Category Filter */}
|
||
<section className="py-8 bg-gray-50">
|
||
<div className="max-w-6xl mx-auto px-4">
|
||
<div className="flex flex-wrap justify-center gap-4">
|
||
{categories.map((category) => (
|
||
<button
|
||
key={category.id}
|
||
onClick={() => setSelectedCategory(category.id)}
|
||
className={`px-6 py-2 rounded-full transition-colors ${
|
||
selectedCategory === category.id
|
||
? 'bg-blue-600 text-white'
|
||
: 'bg-white text-gray-700 hover:bg-blue-50'
|
||
}`}
|
||
>
|
||
{category.name}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Articles Section */}
|
||
<section className="py-16">
|
||
<div className="max-w-6xl mx-auto px-4">
|
||
{loading ? (
|
||
<div className="flex justify-center items-center py-16">
|
||
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-blue-600"></div>
|
||
</div>
|
||
) : (
|
||
<>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||
{articles.map((article) => {
|
||
const categoryName =
|
||
categories.find(
|
||
(cat) => cat.id === article.metadata.category,
|
||
)?.name || article.metadata.category;
|
||
|
||
return (
|
||
<article
|
||
key={`${article.id}-${article.metadata.locale}`}
|
||
className="bg-white rounded-lg shadow-lg overflow-hidden hover:shadow-xl transition-shadow"
|
||
>
|
||
<img
|
||
src={article.metadata.image}
|
||
alt={article.metadata.title}
|
||
className="w-full h-48 object-cover rounded-t-lg"
|
||
/>
|
||
|
||
<div className="p-6">
|
||
<div className="flex items-center justify-between mb-3">
|
||
<span className="text-sm text-blue-600 font-medium">
|
||
{categoryName}
|
||
</span>
|
||
<span className="text-sm text-gray-500">
|
||
{article.metadata.date}
|
||
</span>
|
||
</div>
|
||
<h3 className="text-xl font-bold mb-3 line-clamp-2">
|
||
{article.metadata.title}
|
||
</h3>
|
||
<p className="text-gray-600 mb-4 line-clamp-3">
|
||
{article.metadata.excerpt}
|
||
</p>
|
||
<Link
|
||
href={
|
||
locale === 'zh'
|
||
? `/news/${article.metadata.slug}`
|
||
: `/${locale}/news/${article.metadata.slug}`
|
||
}
|
||
className="inline-flex items-center text-blue-600 hover:text-blue-800 font-medium"
|
||
>
|
||
{t.readMore}
|
||
<svg
|
||
className="w-4 h-4 ml-2"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M9 5l7 7-7 7"
|
||
/>
|
||
</svg>
|
||
</Link>
|
||
</div>
|
||
</article>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
{articles.length === 0 && !loading && (
|
||
<div className="text-center py-16">
|
||
<p className="text-gray-500 text-lg">{t.noArticles}</p>
|
||
</div>
|
||
)}
|
||
</>
|
||
)}
|
||
</div>
|
||
</section>
|
||
<Footer translations={t} />
|
||
</div>
|
||
);
|
||
}
|