TechCorp/components/NewsPage.tsx
2025-09-16 17:40:37 +08:00

1196 lines
72 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { useState, useCallback, useEffect } from 'react';
import { useTranslation } from '../lib/i18n/useTranslation';
import { languages } from '../lib/i18n/config';
// ===== 类型定义 =====
export interface NewsItem {
id: string;
title: string;
title_zh_CN?: string;
title_zh_TW?: string;
summary: string;
summary_zh_CN?: string;
summary_zh_TW?: string;
category: string;
date: string;
readTime: string;
tags: string[];
tags_zh_CN?: string[];
tags_zh_TW?: string[];
image?: string;
}
interface NewsPageProps {
initialLanguage?: string;
newsList?: NewsItem[];
}
// ===== 常量定义 =====
const newsCategories = ['all', 'company', 'product', 'industry', 'technology'];
const categoryIcons = {
company: '🏢',
product: '📦',
industry: '🏭',
technology: '💻',
all: '📰',
};
const newsImages = [
'https://images.unsplash.com/photo-1504711434969-e33886168f5c?w=400&h=300&fit=crop',
'https://images.unsplash.com/photo-1586953208448-b95a79798f07?w=400&h=300&fit=crop',
'https://images.unsplash.com/photo-1552664730-d307ca884978?w=400&h=300&fit=crop',
'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=400&h=300&fit=crop',
'https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=400&h=300&fit=crop',
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=300&fit=crop',
];
// ===== 工具函数 =====
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
};
// ===== 组件主体 =====
export default function NewsPage({ initialLanguage, newsList = [] }: NewsPageProps) {
// ===== 国际化与状态 =====
const { language, t, changeLanguage, getLocalizedPath, isInitialized } =
useTranslation(initialLanguage);
const [selectedCategory, setSelectedCategory] = useState<string>('all');
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
const [searchTerm, setSearchTerm] = useState<string>('');
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
const [sortBy, setSortBy] = useState<'date' | 'title' | 'category'>('date');
const [showScrollTop, setShowScrollTop] = useState<boolean>(false);
// ===== 事件处理 =====
const handleLanguageChange = useCallback(
(newLanguage: string) => {
changeLanguage(newLanguage);
},
[changeLanguage],
);
// ===== 本地化内容辅助函数 =====
const getLocalizedNewsData = (news: NewsItem) => {
switch (language) {
case 'zh-CN':
return {
title: news.title_zh_CN || news.title,
summary: news.summary_zh_CN || news.summary,
tags: news.tags_zh_CN || news.tags,
};
case 'zh-TW':
return {
title: news.title_zh_TW || news.title,
summary: news.summary_zh_TW || news.summary,
tags: news.tags_zh_TW || news.tags,
};
default:
return {
title: news.title,
summary: news.summary,
tags: news.tags,
};
}
};
// ===== 搜索和筛选逻辑 =====
const filteredNews = (newsList || [])
.filter((news: NewsItem) => {
const matchesCategory =
selectedCategory === 'all' || news.category === selectedCategory;
const matchesSearch =
searchTerm === '' ||
(news.title && news.title.toLowerCase().includes(searchTerm.toLowerCase())) ||
(news.summary && news.summary.toLowerCase().includes(searchTerm.toLowerCase())) ||
(news.tags &&
news.tags.some((tag: string) =>
tag.toLowerCase().includes(searchTerm.toLowerCase()),
));
return matchesCategory && matchesSearch;
})
.sort((a: NewsItem, b: NewsItem) => {
switch (sortBy) {
case 'date':
return new Date(b.date).getTime() - new Date(a.date).getTime();
case 'title':
return (a.title || '').localeCompare(b.title || '');
case 'category':
return (a.category || '').localeCompare(b.category || '');
default:
return 0;
}
});
// ===== 滚动监听 =====
useEffect(() => {
const handleScroll = () => {
setShowScrollTop(window.scrollY > 300);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// ===== 日期格式化 =====
const formatDate = (dateString: string) => {
const date = new Date(dateString);
if (language === 'en') {
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
} else {
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
}
};
// ===== 加载状态 =====
if (!isInitialized) {
return (
<div
className="min-h-screen bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 flex items-center justify-center"
data-oid="ky6y3aw"
>
<div className="text-center" data-oid="gj44w4:">
<div
className="w-12 h-12 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mx-auto mb-4"
data-oid="jxkzr4a"
></div>
<p className="text-gray-600" data-oid="la0_u.h">
Loading...
</p>
</div>
</div>
);
}
// ===== 导航项 =====
const navItems = [
{ key: 'home', label: t.nav.home, href: getLocalizedPath('/') },
{ key: 'products', label: t.nav.products, href: getLocalizedPath('/products') },
{ key: 'news', label: t.nav.news, href: getLocalizedPath('/news') },
{ key: 'support', label: t.nav.support, href: getLocalizedPath('/support') },
{ key: 'about', label: t.nav.about, href: getLocalizedPath('/about') },
];
// ===== 渲染部分 =====
return (
<div
className="min-h-screen bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50"
data-oid="ix8o8.a"
>
{/* Navigation */}
<nav
className="fixed top-0 left-0 w-full z-50 bg-white/80 backdrop-blur-md border-b border-white/20 shadow-sm"
data-oid="kjq3ona"
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" data-oid="f.sioe_">
<div className="flex justify-between items-center h-16" data-oid="z6_7ffb">
{/* Logo */}
<div className="flex items-center" data-oid="ley_3l4">
<div className="flex-shrink-0" data-oid="xxe8q3g">
<div
className="w-10 h-10 bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg flex items-center justify-center"
data-oid="ite7jiz"
>
<span
className="text-white font-bold text-lg"
data-oid="mhid:-."
>
T
</span>
</div>
</div>
<div className="ml-3" data-oid="63:8m7i">
<span
className="text-xl font-semibold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
data-oid=".ibqqs5"
>
TechCorp
</span>
</div>
</div>
{/* Desktop Navigation */}
<div className="hidden md:block" data-oid="0kkpz_p">
<div className="ml-10 flex items-baseline space-x-8" data-oid="9.msh5.">
{navItems.map((item) => (
<a
key={item.key}
href={item.href}
className={`px-3 py-2 text-sm font-medium transition-colors duration-200 rounded-md ${item.key === 'news' ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50'}`}
data-oid="fyiy-or"
>
{item.label}
</a>
))}
</div>
</div>
{/* Language Selector & Mobile Menu */}
<div className="flex items-center space-x-4" data-oid="508vpv_">
{/* Language Selector */}
<div className="relative" data-oid="z.:g.bg">
<select
value={language}
onChange={(e) => handleLanguageChange(e.target.value)}
className="appearance-none bg-white/80 border border-gray-200 rounded-md px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
data-oid="4j_n-jy"
>
{languages.map((lang) => (
<option
key={lang.code}
value={lang.code}
data-oid="di4nvwi"
>
{lang.flag} {lang.label}
</option>
))}
</select>
</div>
{/* Mobile menu button */}
<div className="md:hidden" data-oid="_qroycv">
<button
onClick={() => setIsMenuOpen(!isMenuOpen)}
className="text-gray-700 hover:text-blue-600 p-2"
data-oid="81ah:12"
>
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="_c15l09"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
data-oid="g-3fzyz"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</nav>
{/* Mobile Navigation */}
{isMenuOpen && (
<div className="md:hidden" data-oid="-hdh49s">
<div
className="px-2 pt-2 pb-3 space-y-1 bg-white/90 backdrop-blur-md rounded-lg mt-2"
data-oid="ng:mz.0"
>
{navItems.map((item) => (
<a
key={item.key}
href={item.href}
className={`block px-3 py-2 text-base font-medium transition-colors duration-200 ${item.key === 'news' ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600'}`}
data-oid="o3t.zfn"
>
{item.label}
</a>
))}
</div>
</div>
)}
{/* Hero Section */}
<section className="pt-24 pb-16 px-4 sm:px-6 lg:px-8" data-oid="fd3mhvl">
<div className="max-w-7xl mx-auto text-center" data-oid="uos3o3k">
<h1
className="text-4xl md:text-6xl font-bold text-gray-900 mb-6"
data-oid="akgu.es"
>
{language === 'en'
? 'News & Insights'
: language === 'zh-CN'
? '新闻资讯'
: '新聞資訊'}
</h1>
<p className="text-xl text-gray-600 max-w-3xl mx-auto mb-8" data-oid="l6x3xja">
{language === 'en'
? 'Stay updated with the latest news, insights, and developments from TechCorp and the industry.'
: language === 'zh-CN'
? '了解 TechCorp 和行业的最新新闻、见解和发展动态。'
: '了解 TechCorp 和行業的最新新聞、見解和發展動態。'}
</p>
{/* 搜索栏 */}
<div className="max-w-2xl mx-auto mb-8" data-oid="p-b.2rx">
<div className="relative" data-oid="yk5othk">
<div
className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"
data-oid="zdq1v9j"
>
<svg
className="h-5 w-5 text-gray-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="my-.mv6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
data-oid=".helhue"
/>
</svg>
</div>
<input
type="text"
placeholder={
language === 'en'
? 'Search news and articles...'
: language === 'zh-CN'
? '搜索新闻和文章...'
: '搜尋新聞和文章...'
}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="block w-full pl-10 pr-3 py-4 border border-gray-300 rounded-full leading-5 bg-white/80 backdrop-blur-sm placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-lg"
data-oid="u:i8n-v"
/>
</div>
</div>
{/* 统计信息 */}
<div
className="grid grid-cols-2 md:grid-cols-4 gap-4 max-w-4xl mx-auto"
data-oid="wz4.x:v"
>
<div
className="bg-white/60 backdrop-blur-sm rounded-lg p-4 border border-white/20"
data-oid="3eg1s68"
>
<div className="text-2xl font-bold text-blue-600" data-oid="p611rv2">
{newsList.length}
</div>
<div className="text-sm text-gray-600" data-oid="zqsp9j3">
{language === 'en'
? 'Articles'
: language === 'zh-CN'
? '文章'
: '文章'}
</div>
</div>
<div
className="bg-white/60 backdrop-blur-sm rounded-lg p-4 border border-white/20"
data-oid="5sh9vz5"
>
<div className="text-2xl font-bold text-purple-600" data-oid="kn8ai1b">
4
</div>
<div className="text-sm text-gray-600" data-oid="1qgtipk">
{language === 'en'
? 'Categories'
: language === 'zh-CN'
? '分类'
: '分類'}
</div>
</div>
<div
className="bg-white/60 backdrop-blur-sm rounded-lg p-4 border border-white/20"
data-oid="0r._io2"
>
<div className="text-2xl font-bold text-green-600" data-oid="dtk6.ey">
{language === 'en'
? 'Weekly'
: language === 'zh-CN'
? '每周'
: '每週'}
</div>
<div className="text-sm text-gray-600" data-oid="fv5.803">
{language === 'en'
? 'Updates'
: language === 'zh-CN'
? '更新'
: '更新'}
</div>
</div>
<div
className="bg-white/60 backdrop-blur-sm rounded-lg p-4 border border-white/20"
data-oid="s_9xcei"
>
<div className="text-2xl font-bold text-orange-600" data-oid="v.gx3.5">
2024
</div>
<div className="text-sm text-gray-600" data-oid=":632am2">
{language === 'en'
? 'Latest'
: language === 'zh-CN'
? '最新'
: '最新'}
</div>
</div>
</div>
</div>
</section>
{/* 筛选和排序控制 */}
<section className="pb-8 px-4 sm:px-6 lg:px-8" data-oid="p6x::it">
<div className="max-w-7xl mx-auto" data-oid="7udx8v5">
{/* 分类筛选 */}
<div className="flex flex-wrap justify-center gap-4 mb-6" data-oid="kdkqxck">
{newsCategories.map((category) => (
<button
key={category}
onClick={() => setSelectedCategory(category)}
className={`px-6 py-3 rounded-full font-medium transition-all duration-300 flex items-center gap-2 ${selectedCategory === category ? 'bg-gradient-to-r from-blue-600 to-purple-600 text-white shadow-lg transform scale-105' : 'bg-white/60 text-gray-700 hover:bg-white/80 hover:shadow-md'}`}
data-oid="e12ok5."
>
<span data-oid="0ft1-.3">
{categoryIcons[category as keyof typeof categoryIcons]}
</span>
{language === 'en'
? category.charAt(0).toUpperCase() + category.slice(1)
: category === 'all'
? '全部'
: category === 'company'
? language === 'zh-CN'
? '公司'
: '公司'
: category === 'product'
? language === 'zh-CN'
? '产品'
: '產品'
: category === 'industry'
? language === 'zh-CN'
? '行业'
: '行業'
: category === 'technology'
? language === 'zh-CN'
? '技术'
: '技術'
: category}
</button>
))}
</div>
{/* 工具栏 */}
<div
className="flex flex-col sm:flex-row justify-between items-center gap-4 mb-6"
data-oid="hmcq4lw"
>
<div className="flex items-center gap-4" data-oid="xteqfhi">
{/* 结果计数 */}
<span className="text-gray-600" data-oid="rcfaqnx">
{language === 'en'
? `${filteredNews.length} articles found`
: language === 'zh-CN'
? `找到 ${filteredNews.length} 篇文章`
: `找到 ${filteredNews.length} 篇文章`}
</span>
</div>
<div className="flex items-center gap-4" data-oid="a40z.kj">
{/* 排序选择 */}
<select
value={sortBy}
onChange={(e) => setSortBy(e.target.value as any)}
className="bg-white/60 border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
data-oid="s1l84aw"
>
<option value="date" data-oid="ma16.sa">
{language === 'en'
? 'Sort by Date'
: language === 'zh-CN'
? '按日期排序'
: '按日期排序'}
</option>
<option value="title" data-oid="z:_-er5">
{language === 'en'
? 'Sort by Title'
: language === 'zh-CN'
? '按标题排序'
: '按標題排序'}
</option>
<option value="category" data-oid="9r05zl_">
{language === 'en'
? 'Sort by Category'
: language === 'zh-CN'
? '按分类排序'
: '按分類排序'}
</option>
</select>
{/* 视图切换 */}
<div className="flex bg-white/60 rounded-lg p-1" data-oid=".9.-joq">
<button
onClick={() => setViewMode('grid')}
className={`p-2 rounded ${viewMode === 'grid' ? 'bg-blue-600 text-white' : 'text-gray-600 hover:text-blue-600'}`}
data-oid="1rzmg:h"
>
<svg
className="w-4 h-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="g2fsv5v"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"
data-oid="k1ja7pk"
/>
</svg>
</button>
<button
onClick={() => setViewMode('list')}
className={`p-2 rounded ${viewMode === 'list' ? 'bg-blue-600 text-white' : 'text-gray-600 hover:text-blue-600'}`}
data-oid="-xx519h"
>
<svg
className="w-4 h-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="hxiccnk"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 10h16M4 14h16M4 18h16"
data-oid="f-5y_so"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</section>
{/* News Display */}
<section className="pb-20 px-4 sm:px-6 lg:px-8" data-oid="yj.t:zb">
<div className="max-w-7xl mx-auto" data-oid="9lxpa:.">
{filteredNews.length === 0 ? (
/* 无结果状态 */
<div className="text-center py-20" data-oid="6ha07bo">
<div className="text-8xl mb-4 animate-bounce" data-oid="n0g518k">
📰
</div>
<h3
className="text-2xl font-bold text-gray-900 mb-4"
data-oid="zbo8c:w"
>
{language === 'en'
? 'No articles found'
: language === 'zh-CN'
? '未找到文章'
: '未找到文章'}
</h3>
<p
className="text-lg text-gray-600 mb-8 max-w-md mx-auto"
data-oid="05r_x_1"
>
{language === 'en'
? 'Try adjusting your search terms or clearing the filters to see more results.'
: language === 'zh-CN'
? '尝试调整您的搜索词或清除筛选条件以查看更多结果。'
: '嘗試調整您的搜尋詞或清除篩選條件以查看更多結果。'}
</p>
<div
className="flex flex-col sm:flex-row gap-4 justify-center"
data-oid="ejotqxe"
>
<button
onClick={() => {
setSearchTerm('');
setSelectedCategory('all');
}}
className="bg-gradient-to-r from-blue-600 to-purple-600 text-white px-8 py-3 rounded-full font-semibold hover:from-blue-700 hover:to-purple-700 transition-all duration-300 transform hover:scale-105 shadow-lg hover:shadow-xl"
data-oid="-kmrn_u"
>
{language === 'en'
? 'Clear All Filters'
: language === 'zh-CN'
? '清除所有筛选'
: '清除所有篩選'}
</button>
</div>
</div>
) : (
<div
className={
viewMode === 'grid'
? 'grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8'
: 'space-y-8'
}
data-oid="b4v:cw1"
>
{filteredNews.map((news, index) => {
const localizedData = getLocalizedNewsData(news);
console.log(news.id);
if (viewMode === 'grid') {
return (
/* 网格视图 */
<article
key={news.id}
className="group bg-white/70 backdrop-blur-sm rounded-2xl overflow-hidden hover:bg-white/90 transition-all duration-500 transform hover:-translate-y-3 hover:shadow-2xl border border-white/30 hover:border-blue-200 flex flex-col h-full"
data-oid="xkkvdh8"
>
<a
href={getLocalizedPath(`/news/${news.id}`)}
className="flex flex-col h-full"
data-oid="38qwv:-"
>
{/* 新闻图片区域 */}
<div
className="relative h-56 overflow-hidden flex-shrink-0"
data-oid="o0gtg4p"
>
<img
src={
news.image ||
newsImages[index % newsImages.length]
}
alt={localizedData.title}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
data-oid="n.kn9sv"
/>
{/* 分类标签 */}
<div
className="absolute top-4 left-4"
data-oid="9omsz4u"
>
<span
className="bg-gradient-to-r from-blue-600 to-purple-600 text-white px-3 py-2 rounded-full text-xs font-bold flex items-center gap-2 shadow-lg backdrop-blur-sm"
data-oid="xmjdncz"
>
<span
className="text-sm"
data-oid="bzrf51d"
>
{
categoryIcons[
news.category as keyof typeof categoryIcons
]
}
</span>
{language === 'en'
? (news.category || '').charAt(0).toUpperCase() + (news.category || '').slice(1)
: news.category === 'company'
? language === 'zh-CN'
? '公司'
: '公司'
: news.category === 'product'
? language === 'zh-CN'
? '产品'
: '產品'
: news.category === 'industry'
? language === 'zh-CN'
? '行业'
: '行業'
: news.category ===
'technology'
? language === 'zh-CN'
? '技术'
: '技術'
: news.category}
</span>
</div>
{/* 阅读时间 */}
<div
className="absolute top-4 right-4"
data-oid="fe6oah1"
>
<span
className="bg-black/50 text-white px-3 py-1 rounded-full text-xs font-medium backdrop-blur-sm"
data-oid="tols.si"
>
📖 {news.readTime}
</span>
</div>
{/* 悬停叠加层 */}
<div
className="absolute inset-0 bg-gradient-to-t from-black/40 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500"
data-oid="04-21q:"
></div>
</div>
{/* 新闻内容区域 */}
<div
className="p-6 flex flex-col flex-grow"
data-oid="bfb-s0x"
>
<div className="flex-grow" data-oid="8h328-n">
<div className="mb-4" data-oid="uc-07mc">
<h3
className="text-xl font-bold text-gray-900 mb-3 group-hover:text-blue-600 transition-colors duration-300 line-clamp-2"
data-oid="aa9:_e9"
>
{localizedData.title}
</h3>
<p
className="text-gray-600 text-sm leading-relaxed line-clamp-3"
data-oid="q0qzozn"
>
{localizedData.summary}
</p>
</div>
{/* 标签 */}
<div
className="flex flex-wrap gap-2 mb-6"
data-oid=":qu5urc"
>
{(localizedData.tags ?? [])
.slice(0, 3)
.map((tag, tagIndex) => (
<span
key={tagIndex}
className="bg-gradient-to-r from-blue-50 to-purple-50 text-blue-700 px-3 py-1 rounded-full text-xs font-medium border border-blue-100 hover:from-blue-100 hover:to-purple-100 transition-colors duration-300"
data-oid="hn:50_d"
>
{tag}
</span>
))}
</div>
</div>
{/* 日期和操作区域 */}
<div
className="flex items-center justify-between mt-auto"
data-oid="xvj1w8l"
>
<div data-oid="ruz:d:-">
<span
className="text-sm text-gray-500"
data-oid="p9kvpe3"
>
📅 {formatDate(news.date)}
</span>
</div>
<a
href={getLocalizedPath(
`/news/${news.id}`,
)}
className="group/btn bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white px-6 py-2.5 rounded-xl font-semibold transition-all duration-300 transform hover:scale-105 shadow-lg hover:shadow-xl text-sm"
data-oid="54_egn7"
>
<span
className="flex items-center gap-2"
data-oid="og.if8u"
>
{language === 'en'
? 'Read More'
: language === 'zh-CN'
? '阅读更多'
: '閱讀更多'}
<svg
className="w-4 h-4 transition-transform duration-300 group-hover/btn:translate-x-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="2rw5m7f"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5l7 7-7 7"
data-oid="5:bp52c"
/>
</svg>
</span>
</a>
</div>
</div>
</a>
</article>
);
} else {
return (
/* 列表视图 */
<article
key={news.id}
className="group bg-white/70 backdrop-blur-sm rounded-2xl overflow-hidden hover:bg-white/90 transition-all duration-500 hover:shadow-2xl border border-white/30 hover:border-blue-200"
data-oid="m_wkg-f"
>
<a
href={getLocalizedPath(`/news/${news.id}`)}
className="block"
data-oid="l4m.dxp"
>
<div
className="flex flex-col lg:flex-row"
data-oid="vyocvg2"
>
{/* 图片区域 */}
<div
className="lg:w-2/5 relative h-64 lg:h-auto overflow-hidden"
data-oid="lscupha"
>
<img
src={
news.image ||
newsImages[
index % newsImages.length
]
}
alt={localizedData.title}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
data-oid="fm92t3m"
/>
{/* 分类标签 */}
<div
className="absolute top-6 left-6"
data-oid="q4g3mus"
>
<span
className="bg-gradient-to-r from-blue-600 to-purple-600 text-white px-4 py-2 rounded-full text-sm font-bold flex items-center gap-2 shadow-lg backdrop-blur-sm"
data-oid="1y_3r9-"
>
<span data-oid="z02miz:">
{
categoryIcons[
news.category as keyof typeof categoryIcons
]
}
</span>
{language === 'en'
? (news.category || '').charAt(0).toUpperCase() + (news.category || '').slice(1)
: news.category === 'company'
? language === 'zh-CN'
? '公司'
: '公司'
: news.category === 'product'
? language === 'zh-CN'
? '产品'
: '產品'
: news.category ===
'industry'
? language === 'zh-CN'
? '行业'
: '行業'
: news.category ===
'technology'
? language === 'zh-CN'
? '技术'
: '技術'
: news.category}
</span>
</div>
{/* 阅读时间 */}
<div
className="absolute top-6 right-6"
data-oid="2fuz102"
>
<span
className="bg-black/50 text-white px-3 py-2 rounded-full text-sm font-medium backdrop-blur-sm"
data-oid="ek9l72j"
>
📖 {news.readTime}
</span>
</div>
</div>
{/* 内容区域 */}
<div
className="lg:w-3/5 p-8 flex flex-col justify-between"
data-oid="f.cwtd_"
>
<div data-oid="av49ggo">
<div
className="mb-6"
data-oid="uz9hk.e"
>
<h3
className="text-3xl font-bold text-gray-900 mb-4 group-hover:text-blue-600 transition-colors duration-300"
data-oid="8lq9.30"
>
{localizedData.title}
</h3>
<p
className="text-gray-600 text-lg leading-relaxed mb-4"
data-oid="m4i7q:l"
>
{localizedData.summary}
</p>
<div
className="text-sm text-gray-500 mb-4"
data-oid="fr55vys"
>
📅 {formatDate(news.date)}
</div>
</div>
{/* 标签 */}
<div
className="flex flex-wrap gap-3 mb-8"
data-oid="r67b665"
>
{localizedData.tags.map(
(tag, tagIndex) => (
<span
key={tagIndex}
className="bg-gradient-to-r from-blue-50 to-purple-50 text-blue-700 px-4 py-2 rounded-full text-sm font-medium border border-blue-100 hover:from-blue-100 hover:to-purple-100 transition-colors duration-300"
data-oid="22c:89g"
>
🏷 {tag}
</span>
),
)}
</div>
</div>
{/* 操作区域 */}
<div
className="flex flex-col sm:flex-row gap-4"
data-oid="wxl:ot5"
>
<button
className="group/share border-2 border-blue-600 text-blue-600 px-8 py-3 rounded-xl font-semibold hover:bg-blue-600 hover:text-white transition-all duration-300 transform hover:scale-105 text-sm"
data-oid="6k:8ftu"
>
<span
className="flex items-center justify-center gap-2"
data-oid="rkapgpd"
>
<svg
className="w-5 h-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="yw6geds"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.367 2.684 3 3 0 00-5.367-2.684z"
data-oid="a0:yl:q"
/>
</svg>
{language === 'en'
? 'Share'
: language === 'zh-CN'
? '分享'
: '分享'}
</span>
</button>
<a
href={getLocalizedPath(
`/news/${news.id}`,
)}
className="group/read bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white px-8 py-3 rounded-xl font-semibold transition-all duration-300 transform hover:scale-105 shadow-lg hover:shadow-xl text-sm"
data-oid="90mz6ve"
>
<span
className="flex items-center justify-center gap-2"
data-oid="a71x415"
>
{language === 'en'
? 'Read Full Article'
: language === 'zh-CN'
? '阅读全文'
: '閱讀全文'}
<svg
className="w-5 h-5 transition-transform duration-300 group-hover/read:translate-x-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="hp-l7f3"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M13 7l5 5m0 0l-5 5m5-5H6"
data-oid="c681z_t"
/>
</svg>
</span>
</a>
</div>
</div>
</div>
</a>
</article>
);
}
})}
</div>
)}
</div>
</section>
{/* CTA Section */}
<section
className="py-20 px-4 sm:px-6 lg:px-8 bg-gradient-to-r from-blue-600 to-purple-600"
data-oid="9-8jy-3"
>
<div className="max-w-4xl mx-auto text-center text-white" data-oid="dw79oh8">
<h2 className="text-3xl md:text-4xl font-bold mb-6" data-oid="bz-rhu5">
{language === 'en'
? 'Stay Updated'
: language === 'zh-CN'
? '保持更新'
: '保持更新'}
</h2>
<p className="text-xl mb-8 opacity-90" data-oid="8ixgmdh">
{language === 'en'
? 'Subscribe to our newsletter and never miss important updates and insights.'
: language === 'zh-CN'
? '订阅我们的新闻通讯,不要错过重要的更新和见解。'
: '訂閱我們的新聞通訊,不要錯過重要的更新和見解。'}
</p>
<div
className="flex flex-col sm:flex-row gap-4 justify-center"
data-oid=":1jd:t0"
>
<button
className="bg-white text-blue-600 px-8 py-3 rounded-full font-semibold hover:bg-gray-100 transition-all duration-300 transform hover:scale-105"
data-oid="j8.zt50"
>
{language === 'en'
? 'Subscribe Newsletter'
: language === 'zh-CN'
? '订阅新闻'
: '訂閱新聞'}
</button>
<button
className="border-2 border-white text-white px-8 py-3 rounded-full font-semibold hover:bg-white hover:text-blue-600 transition-all duration-300 transform hover:scale-105"
data-oid="jrtu1_a"
>
{language === 'en'
? 'Follow Us'
: language === 'zh-CN'
? '关注我们'
: '關注我們'}
</button>
</div>
</div>
</section>
{/* 回到顶部按钮 */}
{showScrollTop && (
<button
onClick={scrollToTop}
className="fixed bottom-8 right-8 bg-gradient-to-r from-blue-600 to-purple-600 text-white p-3 rounded-full shadow-lg hover:shadow-xl transition-all duration-300 transform hover:scale-110 z-40"
data-oid="9mnso1a"
>
<svg
className="w-6 h-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
data-oid="1dpfcqq"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M5 10l7-7m0 0l7 7m-7-7v18"
data-oid="-efjx3n"
/>
</svg>
</button>
)}
{/* Footer */}
<footer
className="bg-gray-900 text-white py-12 px-4 sm:px-6 lg:px-8"
data-oid="v.yyp6l"
>
<div className="max-w-7xl mx-auto" data-oid="4me6hqo">
<div className="grid grid-cols-1 md:grid-cols-4 gap-8" data-oid="n2pgqw-">
<div data-oid="6xjcyaz">
<div className="flex items-center mb-4" data-oid="t96uews">
<div
className="w-8 h-8 bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg flex items-center justify-center mr-3"
data-oid="6y05wrb"
>
<span className="text-white font-bold" data-oid="e_b300o">
T
</span>
</div>
<span className="text-xl font-semibold" data-oid=":86qu55">
TechCorp
</span>
</div>
<p className="text-gray-400" data-oid="8-fyky3">
{t.footer.description}
</p>
</div>
<div data-oid="uyyjvb5">
<h3 className="text-lg font-semibold mb-4" data-oid="f87eu7u">
{t.footer.sections.products.title}
</h3>
<ul className="space-y-2 text-gray-400" data-oid="xrq:es7">
{t.footer.sections.products.items.map((item, index) => (
<li key={index} data-oid="iae5dvo">
<a
href={getLocalizedPath(item.href)}
className="hover:text-white transition-colors"
data-oid=".phmv_-"
>
{item.label}
</a>
</li>
))}
</ul>
</div>
<div data-oid="kt9yuvu">
<h3 className="text-lg font-semibold mb-4" data-oid="is4s-k:">
{t.footer.sections.support.title}
</h3>
<ul className="space-y-2 text-gray-400" data-oid="5cruobe">
{t.footer.sections.support.items.map((item, index) => (
<li key={index} data-oid="eyaap5k">
<a
href={getLocalizedPath(item.href)}
className="hover:text-white transition-colors"
data-oid="2:m52s3"
>
{item.label}
</a>
</li>
))}
</ul>
</div>
<div data-oid="co06mui">
<h3 className="text-lg font-semibold mb-4" data-oid="l-di38e">
{t.footer.sections.social.title}
</h3>
<div className="flex space-x-4" data-oid="_eewkbd">
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
data-oid="snmef_q"
>
<span className="sr-only" data-oid="xg8szj5">
</span>
💬
</a>
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
data-oid="i8.snop"
>
<span className="sr-only" data-oid="5nm9bcc">
</span>
📱
</a>
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
data-oid="7az3bt4"
>
<span className="sr-only" data-oid="gnbjgfc">
</span>
📧
</a>
</div>
</div>
</div>
<div
className="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400"
data-oid="tinbwrk"
>
<p data-oid="k.u6jmw">&copy; 2024 TechCorp. {t.footer.copyright}</p>
</div>
</div>
</footer>
</div>
);
}