first commit
This commit is contained in:
183
src/components/Home/NewsSection.tsx
Normal file
183
src/components/Home/NewsSection.tsx
Normal file
@@ -0,0 +1,183 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { Calendar, ArrowRight } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { formatDate } from '../../lib/utils';
|
||||
|
||||
/**
|
||||
* NewsSection 组件 - 最新动态区域
|
||||
*/
|
||||
|
||||
// 模拟新闻数据
|
||||
const newsItems = [
|
||||
{
|
||||
id: 1,
|
||||
category: 'company',
|
||||
title: '示例集团荣获"2025年度优秀企业"称号',
|
||||
excerpt: '在近日举办的年度企业评选活动中,示例集团凭借其卓越的经营业绩和社会责任表现,荣获"2025年度优秀企业"称号。',
|
||||
date: '2025-12-20',
|
||||
image: '/images/news-award.jpg',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
category: 'industry',
|
||||
title: '金融科技创新论坛圆满落幕,示例集团分享行业洞察',
|
||||
excerpt: '示例集团受邀参加金融科技创新论坛,与行业专家共同探讨金融科技发展趋势,分享公司在数字化转型方面的实践经验。',
|
||||
date: '2025-12-15',
|
||||
image: '/images/news-tech.jpg',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
category: 'achievement',
|
||||
title: '示例集团完成新一轮战略融资,估值突破百亿',
|
||||
excerpt: '示例集团宣布完成新一轮战略融资,本轮融资由知名投资机构领投,估值突破百亿元人民币,标志着公司发展进入新阶段。',
|
||||
date: '2025-12-10',
|
||||
image: '/images/news-company.jpg',
|
||||
},
|
||||
];
|
||||
|
||||
// 新闻分类映射
|
||||
const categoryMap: Record<string, { label: string; color: string }> = {
|
||||
company: { label: '公司动态', color: 'bg-primary/10 text-primary' },
|
||||
industry: { label: '行业资讯', color: 'bg-accent/20 text-accent-dark' },
|
||||
achievement: { label: '荣誉资质', color: 'bg-green-100 text-green-700' },
|
||||
};
|
||||
|
||||
/**
|
||||
* 新闻卡片组件
|
||||
*/
|
||||
const NewsCard: React.FC<{
|
||||
news: typeof newsItems[0];
|
||||
index: number;
|
||||
}> = ({ news, index }) => {
|
||||
const category = categoryMap[news.category] || categoryMap.company;
|
||||
|
||||
return (
|
||||
<motion.article
|
||||
className="group bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden hover:shadow-lg transition-shadow duration-300"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: index * 0.1, duration: 0.5 }}
|
||||
whileHover={{ y: -5 }}
|
||||
>
|
||||
{/* 图片区域 */}
|
||||
<div className="aspect-[16/9] bg-gradient-to-br from-primary/5 to-primary-light/10 relative overflow-hidden">
|
||||
{news.image ? (
|
||||
<img
|
||||
src={news.image}
|
||||
alt=""
|
||||
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
|
||||
loading="lazy"
|
||||
/>
|
||||
) : (
|
||||
<div className="text-primary/20">
|
||||
<svg
|
||||
className="w-16 h-16 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={1}
|
||||
d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
{/* 分类标签 */}
|
||||
<span
|
||||
className={`absolute top-4 left-4 px-3 py-1 text-xs font-medium rounded-full ${category.color}`}
|
||||
>
|
||||
{category.label}
|
||||
</span>
|
||||
{/* 图片遮罩 */}
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||
</div>
|
||||
|
||||
{/* 内容区域 */}
|
||||
<div className="p-6">
|
||||
{/* 日期 */}
|
||||
<div className="flex items-center gap-2 text-sm text-gray-500 mb-3">
|
||||
<Calendar size={14} />
|
||||
<time dateTime={news.date}>{formatDate(news.date, 'YYYY年MM月DD日')}</time>
|
||||
</div>
|
||||
|
||||
{/* 标题 */}
|
||||
<h3 className="text-lg font-semibold text-primary-dark mb-3 line-clamp-2 group-hover:text-primary transition-colors">
|
||||
{news.title}
|
||||
</h3>
|
||||
|
||||
{/* 摘要 */}
|
||||
<p className="text-gray-600 text-sm leading-relaxed line-clamp-3 mb-4">
|
||||
{news.excerpt}
|
||||
</p>
|
||||
|
||||
{/* 了解更多链接 */}
|
||||
<Link
|
||||
to={`/news/${news.id}`}
|
||||
className="inline-flex items-center gap-2 text-sm font-medium text-primary group-hover:text-primary-light transition-colors"
|
||||
>
|
||||
阅读全文
|
||||
<motion.span
|
||||
initial={{ x: 0 }}
|
||||
whileHover={{ x: 5 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<ArrowRight size={16} />
|
||||
</motion.span>
|
||||
</Link>
|
||||
</div>
|
||||
</motion.article>
|
||||
);
|
||||
};
|
||||
|
||||
export const NewsSection: React.FC = () => {
|
||||
return (
|
||||
<section
|
||||
id="news"
|
||||
className="py-20 lg:py-28 bg-background"
|
||||
aria-labelledby="news-heading"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* 标题区域 */}
|
||||
<motion.div
|
||||
className="flex flex-col md:flex-row md:items-end md:justify-between gap-4 mb-12"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<div>
|
||||
<h2
|
||||
id="news-heading"
|
||||
className="text-3xl md:text-4xl font-bold text-primary-dark"
|
||||
>
|
||||
新闻资讯
|
||||
</h2>
|
||||
<p className="mt-2 text-lg text-gray-600">
|
||||
了解示例集团最新动态
|
||||
</p>
|
||||
</div>
|
||||
<Link
|
||||
to="/news"
|
||||
className="inline-flex items-center gap-2 text-primary font-medium hover:text-primary-light transition-colors"
|
||||
>
|
||||
查看更多新闻
|
||||
<ArrowRight size={18} />
|
||||
</Link>
|
||||
</motion.div>
|
||||
|
||||
{/* 新闻卡片网格 */}
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{newsItems.map((news, index) => (
|
||||
<NewsCard key={news.id} news={news} index={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewsSection;
|
||||
Reference in New Issue
Block a user