baima_home_main/app/news/page.tsx

140 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState, useEffect } from 'react'
import { motion } from 'framer-motion'
import { Calendar, Eye, ArrowRight, Loader2 } from 'lucide-react'
import { Card, CardContent } from '@/components/ui/card'
import Link from 'next/link'
type News = {
id: number
title: string
category: string
excerpt: string
createdAt: string
views: number
}
const categories = ["全部", "公司新闻", "荣誉获奖", "产品发布", "媒体报道", "行业洞察"]
export default function NewsPage() {
const [news, setNews] = useState<News[]>([])
const [isLoading, setIsLoading] = useState(true)
const [activeCategory, setActiveCategory] = useState("全部")
useEffect(() => {
const fetchNews = async () => {
try {
const url = activeCategory === "全部"
? '/api/news'
: `/api/news?category=${encodeURIComponent(activeCategory)}`
const res = await fetch(url)
if (res.ok) {
const data = await res.json()
setNews(data.news)
}
} catch (error) {
console.error('加载新闻失败', error)
} finally {
setIsLoading(false)
}
}
fetchNews()
}, [activeCategory])
return (
<div className="min-h-screen bg-white pt-24 pb-20">
<div className="container mx-auto px-4 md:px-6">
{/* Header */}
<div className="text-center mb-16">
<h1 className="text-4xl md:text-5xl font-black text-[#0A1931] mb-4">
</h1>
<p className="text-lg text-gray-500 max-w-2xl mx-auto">
</p>
</div>
{/* Category Filter */}
<div className="flex flex-wrap justify-center gap-2 mb-12">
{categories.map((category) => (
<button
key={category}
onClick={() => setActiveCategory(category)}
className={`px-6 py-2 rounded-full text-sm font-bold transition-all ${
activeCategory === category
? 'bg-[#FF6600] text-white shadow-lg'
: 'bg-gray-100 text-gray-500 hover:bg-gray-200'
}`}
>
{category}
</button>
))}
</div>
{/* Loading State */}
{isLoading ? (
<div className="flex justify-center items-center py-20">
<Loader2 className="w-8 h-8 animate-spin text-[#FF6600]" />
</div>
) : news.length === 0 ? (
<div className="text-center py-20 text-gray-400 font-medium">
</div>
) : (
/* News Grid */
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{news.map((item, index) => (
<motion.div
key={item.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
<Link href="#" className="group block h-full">
<Card className="h-full border-0 shadow-lg hover:shadow-xl transition-all duration-300 overflow-hidden card-hover">
{/* Placeholder Color Block */}
<div className="h-40 bg-gradient-to-br from-[#0A1931] to-[#185ADB] flex items-center justify-center">
<span className="text-white/10 text-6xl font-black">{item.id}</span>
</div>
<CardContent className="p-6">
<div className="flex items-center justify-between mb-4">
<span className="text-xs font-bold text-[#FF6600] bg-orange-50 px-3 py-1 rounded-full">
{item.category}
</span>
<div className="flex items-center text-xs text-gray-400 font-mono">
<Calendar className="w-3 h-3 mr-1" />
{new Date(item.createdAt).toLocaleDateString()}
</div>
</div>
<h3 className="text-lg font-bold text-[#0A1931] mb-3 group-hover:text-[#FF6600] transition-colors line-clamp-2">
{item.title}
</h3>
<p className="text-sm text-gray-500 mb-6 line-clamp-3 leading-relaxed">
{item.excerpt}
</p>
<div className="flex items-center justify-between pt-4 border-t border-gray-100">
<div className="flex items-center text-xs text-gray-400">
<Eye className="w-3 h-3 mr-1" />
{item.views}
</div>
<span className="flex items-center text-sm font-bold text-[#FF6600] group-hover:translate-x-1 transition-transform">
<ArrowRight className="ml-1 w-4 h-4" />
</span>
</div>
</CardContent>
</Card>
</Link>
</motion.div>
))}
</div>
)}
</div>
</div>
)
}