blob: f7506ac8563bdee401d86c2f6e2aacec0ebfff76 [file] [log] [blame]
22301008d5fbb782025-06-18 16:28:43 +08001import React, { useState, useEffect } from 'react'
2import { useParams, useNavigate } from 'react-router-dom'
3import { ArrowLeft, ThumbsUp, MessageCircle, Share2, BookmarkPlus, Heart, Eye } from 'lucide-react'
4import '../style/PostDetail.css'
5
6export default function PostDetail() {
7 const { id } = useParams()
8 const navigate = useNavigate()
9 const [post, setPost] = useState(null)
10 const [loading, setLoading] = useState(true)
11 const [error, setError] = useState(null)
12 const [liked, setLiked] = useState(false)
13 const [bookmarked, setBookmarked] = useState(false)
14 const [likeCount, setLikeCount] = useState(0)
15 useEffect(() => {
16 fetchPostDetail()
17 }, [id])
18
19 const fetchPostDetail = async () => {
20 setLoading(true)
21 setError(null)
22 try {
23 // 根据ID获取帖子详情,使用本地服务器地址
24 const response = await fetch(`http://127.0.0.1:5000/post/${id}`)
25 if (!response.ok) {
26 throw new Error('帖子不存在或已被删除')
27 }
28 const data = await response.json()
29 setPost(data)
30 setLikeCount(data.heat || 0)
31 } catch (error) {
32 console.error('获取帖子详情失败:', error)
33 setError(error.message)
34 } finally {
35 setLoading(false)
36 }
37 }
38
39 const handleBack = () => {
40 navigate(-1)
41 }
42
43 const handleLike = async () => {
44 try {
45 // 模拟点赞API调用
46 const newLiked = !liked
47 setLiked(newLiked)
48 setLikeCount(prev => newLiked ? prev + 1 : prev - 1)
49
50 // 实际项目中这里应该调用后端API
51 // await fetch(`/post/${id}/like`, { method: 'POST' })
52 } catch (error) {
53 console.error('点赞失败:', error)
54 // 回滚状态
55 setLiked(!liked)
56 setLikeCount(prev => liked ? prev + 1 : prev - 1)
57 }
58 }
59
60 const handleBookmark = () => {
61 setBookmarked(!bookmarked)
62 // 实际项目中这里应该调用后端API保存收藏状态
63 }
64
65 const handleShare = () => {
66 // 分享功能
67 if (navigator.share) {
68 navigator.share({
69 title: post?.title,
70 text: post?.content,
71 url: window.location.href,
72 })
73 } else {
74 // 复制链接到剪贴板
75 navigator.clipboard.writeText(window.location.href)
76 alert('链接已复制到剪贴板')
77 }
78 }
79
80 if (loading) {
81 return (
82 <div className="post-detail">
83 <div className="loading-container">
84 <div className="loading-spinner"></div>
85 <p>加载中...</p>
86 </div>
87 </div>
88 )
89 }
90
91 if (error) {
92 return (
93 <div className="post-detail">
94 <div className="error-container">
95 <h2>😔 出错了</h2>
96 <p>{error}</p>
97 <button onClick={handleBack} className="back-btn">
98 <ArrowLeft size={20} />
99 返回
100 </button>
101 </div>
102 </div>
103 )
104 }
105
106 if (!post) {
107 return (
108 <div className="post-detail">
109 <div className="error-container">
110 <h2>😔 帖子不存在</h2>
111 <p>该帖子可能已被删除或不存在</p>
112 <button onClick={handleBack} className="back-btn">
113 <ArrowLeft size={20} />
114 返回
115 </button>
116 </div>
117 </div>
118 )
119 }
120
121 return (
122 <div className="post-detail">
123 {/* 顶部导航栏 */}
124 <header className="post-header">
125 <button onClick={handleBack} className="back-btn">
126 <ArrowLeft size={20} />
127 返回
128 </button>
129 <div className="header-actions">
130 <button onClick={handleShare} className="action-btn">
131 <Share2 size={20} />
132 </button>
133 <button
134 onClick={handleBookmark}
135 className={`action-btn ${bookmarked ? 'active' : ''}`}
136 >
137 <BookmarkPlus size={20} />
138 </button>
139 </div>
140 </header>
141
142 {/* 主要内容区 */}
143 <main className="post-content">
144 {/* 帖子标题 */}
145 <h1 className="post-title">{post.title}</h1>
146
147 {/* 作者信息和元数据 */}
148 <div className="post-meta">
149 <div className="author-info">
150 <div className="avatar">
151 {post.author ? post.author.charAt(0).toUpperCase() : 'U'}
152 </div>
153 <div className="author-details">
154 <span className="author-name">{post.author || '匿名用户'}</span>
155 <span className="post-date">
156 {post.create_time ? new Date(post.create_time).toLocaleDateString('zh-CN') : '未知时间'}
157 </span>
158 </div>
159 </div>
160 <div className="post-stats">
161 <span className="stat-item">
162 <Eye size={16} />
163 {post.views || 0}
164 </span>
165 <span className="stat-item">
166 <Heart size={16} />
167 {likeCount}
168 </span>
169 </div>
170 </div>
171
172 {/* 标签 */}
173 {post.tags && post.tags.length > 0 && (
174 <div className="post-tags">
175 {post.tags.map((tag, index) => (
176 <span key={index} className="tag">{tag}</span>
177 ))}
178 </div>
179 )}
180
181 {/* 帖子正文 */}
182 <div className="post-body">
183 <p>{post.content}</p>
184 </div>
185
186 {/* 类别信息 */}
187 {post.category && (
188 <div className="post-category">
189 <span className="category-label">分类:</span>
190 <span className="category-name">{post.category}</span>
191 </div>
192 )}
193 </main>
194
195 {/* 底部操作栏 */}
196 <footer className="post-footer">
197 <div className="action-bar">
198 <button
199 onClick={handleLike}
200 className={`action-button ${liked ? 'liked' : ''}`}
201 >
202 <ThumbsUp size={20} />
203 <span>{likeCount}</span>
204 </button>
205
206 <button className="action-button">
207 <MessageCircle size={20} />
208 <span>评论</span>
209 </button>
210
211 <button onClick={handleShare} className="action-button">
212 <Share2 size={20} />
213 <span>分享</span>
214 </button>
215
216 <button
217 onClick={handleBookmark}
218 className={`action-button ${bookmarked ? 'bookmarked' : ''}`}
219 >
220 <BookmarkPlus size={20} />
221 <span>收藏</span>
222 </button>
223 </div>
224 </footer>
225 </div>
226 )
227}