blob: c68185819b0e07d6a699f8d4c537eae9565c99de [file] [log] [blame]
TRM-codingd1cbf672025-06-18 15:15:08 +08001// src/components/HomeFeed.jsx
2
9563036698c2ae422025-06-20 12:54:31 +08003import React, { useState, useEffect } from 'react'
TRM-coding29174c22025-06-18 23:56:51 +08004import { useNavigate } from 'react-router-dom'
TRM-codingd1cbf672025-06-18 15:15:08 +08005import { ThumbsUp } from 'lucide-react'
6import { fetchPosts, fetchPost } from '../api/posts_wzy'
7import '../style/HomeFeed.css'
8
9const categories = [
10 '推荐','穿搭','美食','彩妆','影视',
11 '职场','情感','家居','游戏','旅行','健身'
12]
13
14export default function HomeFeed() {
TRM-coding29174c22025-06-18 23:56:51 +080015 const navigate = useNavigate()
TRM-codingd1cbf672025-06-18 15:15:08 +080016 const [activeCat, setActiveCat] = useState('推荐')
17 const [items, setItems] = useState([])
18 const [loading, setLoading] = useState(true)
19 const [error, setError] = useState(null)
20
21 useEffect(() => {
9563036698c2ae422025-06-20 12:54:31 +080022 async function loadPosts() {
TRM-codingd1cbf672025-06-18 15:15:08 +080023 try {
24 const list = await fetchPosts() // [{id, title, heat, created_at}, …]
25 // 为了拿到 media_urls 和 user_id,这里再拉详情
26 const detailed = await Promise.all(
27 list.map(async p => {
28 const d = await fetchPost(p.id)
29 return {
30 id: d.id,
31 title: d.title,
32 author: `作者 ${d.user_id}`,
33 avatar: `https://i.pravatar.cc/40?img=${d.user_id}`,
34 img: d.media_urls?.[0] || '', // 用第一张媒体作为封面
35 likes: d.heat
36 }
37 })
38 )
39 setItems(detailed)
40 } catch (e) {
41 setError(e.message)
42 } finally {
43 setLoading(false)
44 }
45 }
9563036698c2ae422025-06-20 12:54:31 +080046 loadPosts()
47 }, [])
TRM-codingd1cbf672025-06-18 15:15:08 +080048
49 return (
50 <div className="home-feed">
51 {/* 顶部分类 */}
52 <nav className="feed-tabs">
53 {categories.map(cat => (
54 <button
55 key={cat}
56 className={cat === activeCat ? 'tab active' : 'tab'}
9563036698c2ae422025-06-20 12:54:31 +080057 onClick={() => setActiveCat(cat)}
TRM-codingd1cbf672025-06-18 15:15:08 +080058 >
59 {cat}
60 </button>
61 ))}
9563036698c2ae422025-06-20 12:54:31 +080062 </nav>
63
64 {/* 状态提示 */}
TRM-codingd1cbf672025-06-18 15:15:08 +080065 {loading ? (
66 <div className="loading">加载中…</div>
67 ) : error ? (
68 <div className="error">加载失败:{error}</div>
69 ) : (
70 /* 瀑布流卡片区 */
71 <div className="feed-grid">
9563036698c2ae422025-06-20 12:54:31 +080072 {items.map(item => (
73 <div key={item.id} className="feed-card">
74 <img className="card-img" src={item.img} alt={item.title} />
75 <h3 className="card-title">{item.title}</h3>
76 <div className="card-footer">
77 <div className="card-author">
78 <img className="avatar" src={item.avatar} alt={item.author} />
79 <span className="username">{item.author}</span>
80 </div>
81 <div className="card-likes">
82 <ThumbsUp size={16} />
83 <span className="likes-count">{item.likes}</span>
TRM-codingd1cbf672025-06-18 15:15:08 +080084 </div>
85 </div>
9563036698c2ae422025-06-20 12:54:31 +080086 </div>
87 ))}
TRM-codingd1cbf672025-06-18 15:15:08 +080088 </div>
89 )}
90 </div>
91 )
92}