This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { Typography, Card, Avatar, Tag, Space, Button, Divider, Input, message, Upload, Tooltip } from 'antd';
|
||||
import { Typography, Card, Avatar, Tag, Space, Button, Divider, Input, message, Upload, Tooltip, Grid } from 'antd';
|
||||
import { UserOutlined, ClockCircleOutlined, EyeOutlined, CheckCircleFilled, LeftOutlined, UploadOutlined, EditOutlined } from '@ant-design/icons';
|
||||
import { getTopicDetail, createReply, uploadMedia } from '../api';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
@@ -17,11 +17,14 @@ import 'katex/dist/katex.min.css';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { TextArea } = Input;
|
||||
const { useBreakpoint } = Grid;
|
||||
|
||||
const ForumDetail = () => {
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const { user } = useAuth();
|
||||
const screens = useBreakpoint();
|
||||
const isMobile = !screens.md;
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [topic, setTopic] = useState(null);
|
||||
@@ -156,7 +159,7 @@ const ForumDetail = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '80px 20px 40px', minHeight: '100vh', maxWidth: 1000, margin: '0 auto' }}>
|
||||
<div style={{ padding: isMobile ? '60px 10px 20px' : '80px 20px 40px', minHeight: '100vh', maxWidth: 1000, margin: '0 auto' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
|
||||
<Button
|
||||
type="text"
|
||||
@@ -167,21 +170,15 @@ const ForumDetail = () => {
|
||||
返回列表
|
||||
</Button>
|
||||
|
||||
{/* Debug Info: Remove in production */}
|
||||
{/* <div style={{ color: 'red', fontSize: 10 }}>
|
||||
User ID: {user?.id} ({typeof user?.id})<br/>
|
||||
Topic Author: {topic.author} ({typeof topic.author})<br/>
|
||||
Match: {String(topic.author) === String(user?.id) ? 'Yes' : 'No'}
|
||||
</div> */}
|
||||
|
||||
{user && String(topic.author) === String(user.id) && (
|
||||
<Button
|
||||
type="primary"
|
||||
ghost
|
||||
icon={<EditOutlined />}
|
||||
onClick={() => setEditModalVisible(true)}
|
||||
size={isMobile ? 'small' : 'middle'}
|
||||
>
|
||||
编辑帖子
|
||||
{isMobile ? '编辑' : '编辑帖子'}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@@ -194,17 +191,17 @@ const ForumDetail = () => {
|
||||
backdropFilter: 'blur(10px)',
|
||||
marginBottom: 30
|
||||
}}
|
||||
styles={{ body: { padding: '30px' } }}
|
||||
styles={{ body: { padding: isMobile ? '15px' : '30px' } }}
|
||||
>
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
{topic.is_pinned && <Tag color="red" style={{ marginRight: 10 }}>置顶</Tag>}
|
||||
{topic.product_info && <Tag color="blue">{topic.product_info.name}</Tag>}
|
||||
<Title level={2} style={{ color: '#fff', margin: '10px 0' }}>{topic.title}</Title>
|
||||
<Title level={isMobile ? 3 : 2} style={{ color: '#fff', margin: '10px 0', wordBreak: 'break-word' }}>{topic.title}</Title>
|
||||
|
||||
<Space size="large" style={{ color: '#888', marginTop: 10 }}>
|
||||
<Space size={isMobile ? 'small' : 'large'} style={{ color: '#888', marginTop: 10, flexWrap: 'wrap' }}>
|
||||
<Space>
|
||||
<Avatar src={topic.author_info?.avatar_url} icon={<UserOutlined />} />
|
||||
<span style={{ color: '#ccc' }}>{topic.author_info?.nickname}</span>
|
||||
<Avatar src={topic.author_info?.avatar_url} icon={<UserOutlined />} size={isMobile ? 'small' : 'default'} />
|
||||
<span style={{ color: '#ccc', fontSize: isMobile ? 12 : 14 }}>{topic.author_info?.nickname}</span>
|
||||
{topic.is_verified_owner && (
|
||||
<Tooltip title="已验证购买过相关产品">
|
||||
<CheckCircleFilled style={{ color: '#00b96b' }} />
|
||||
@@ -213,11 +210,11 @@ const ForumDetail = () => {
|
||||
</Space>
|
||||
<Space>
|
||||
<ClockCircleOutlined />
|
||||
<span>{new Date(topic.created_at).toLocaleString()}</span>
|
||||
<span style={{ fontSize: isMobile ? 12 : 14 }}>{new Date(topic.created_at).toLocaleString()}</span>
|
||||
</Space>
|
||||
<Space>
|
||||
<EyeOutlined />
|
||||
<span>{topic.view_count} 阅读</span>
|
||||
<span style={{ fontSize: isMobile ? 12 : 14 }}>{topic.view_count} 阅读</span>
|
||||
</Space>
|
||||
</Space>
|
||||
</div>
|
||||
@@ -253,7 +250,7 @@ const ForumDetail = () => {
|
||||
|
||||
{/* Replies List */}
|
||||
<div style={{ marginBottom: 30 }}>
|
||||
<Title level={4} style={{ color: '#fff', marginBottom: 20 }}>
|
||||
<Title level={isMobile ? 5 : 4} style={{ color: '#fff', marginBottom: 20 }}>
|
||||
{topic.replies?.length || 0} 条回复
|
||||
</Title>
|
||||
|
||||
@@ -266,18 +263,19 @@ const ForumDetail = () => {
|
||||
marginBottom: 16,
|
||||
borderRadius: 8
|
||||
}}
|
||||
styles={{ body: { padding: isMobile ? '15px' : '24px' } }}
|
||||
>
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Avatar src={reply.author_info?.avatar_url} icon={<UserOutlined />} />
|
||||
<div style={{ display: 'flex', gap: isMobile ? 10 : 16 }}>
|
||||
<Avatar src={reply.author_info?.avatar_url} icon={<UserOutlined />} size={isMobile ? 'small' : 'default'} />
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
|
||||
<Space>
|
||||
<Text style={{ color: '#aaa', fontWeight: 'bold' }}>{reply.author_info?.nickname}</Text>
|
||||
<Space size={isMobile ? 'small' : 'middle'} align="center">
|
||||
<Text style={{ color: '#aaa', fontWeight: 'bold', fontSize: isMobile ? 13 : 14 }}>{reply.author_info?.nickname}</Text>
|
||||
<Text style={{ color: '#666', fontSize: 12 }}>{new Date(reply.created_at).toLocaleString()}</Text>
|
||||
</Space>
|
||||
<Text style={{ color: '#444' }}>#{index + 1}</Text>
|
||||
<Text style={{ color: '#444', fontSize: 12 }}>#{index + 1}</Text>
|
||||
</div>
|
||||
<div style={{ color: '#eee' }}>
|
||||
<div style={{ color: '#eee', fontSize: isMobile ? 14 : 16 }}>
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkMath, remarkGfm]}
|
||||
rehypePlugins={[rehypeKatex, rehypeRaw]}
|
||||
@@ -298,6 +296,7 @@ const ForumDetail = () => {
|
||||
background: 'rgba(20,20,20,0.8)',
|
||||
border: '1px solid rgba(255,255,255,0.1)'
|
||||
}}
|
||||
styles={{ body: { padding: isMobile ? '15px' : '24px' } }}
|
||||
>
|
||||
<Title level={5} style={{ color: '#fff', marginBottom: 16 }}>发表回复</Title>
|
||||
{user ? (
|
||||
@@ -309,7 +308,7 @@ const ForumDetail = () => {
|
||||
placeholder="友善回复,分享你的见解... (支持 Markdown)"
|
||||
style={{ marginBottom: 16, background: '#111', border: '1px solid #333', color: '#fff' }}
|
||||
/>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', justifyContent: 'space-between', alignItems: isMobile ? 'stretch' : 'center', gap: isMobile ? 10 : 0 }}>
|
||||
<Upload
|
||||
beforeUpload={handleReplyUpload}
|
||||
showUploadList={false}
|
||||
@@ -321,14 +320,15 @@ const ForumDetail = () => {
|
||||
style={{
|
||||
color: '#fff',
|
||||
background: 'rgba(255,255,255,0.1)',
|
||||
border: '1px solid rgba(255,255,255,0.2)'
|
||||
border: '1px solid rgba(255,255,255,0.2)',
|
||||
width: isMobile ? '100%' : 'auto'
|
||||
}}
|
||||
>
|
||||
插入图片/视频
|
||||
</Button>
|
||||
</Upload>
|
||||
|
||||
<Button type="primary" onClick={handleSubmitReply} loading={submitting}>
|
||||
<Button type="primary" onClick={handleSubmitReply} loading={submitting} style={{ width: isMobile ? '100%' : 'auto' }}>
|
||||
提交回复
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user