blob: 51635c2c5be53579eeeded7ceea9b8807e8f6570 [file] [log] [blame]
// src/components/CreatePost.jsx
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import UploadPage from './UploadPage'
import { createPost } from '../api/posts'
import '../style/CreatePost.css'
export default function CreatePost() {
const navigate = useNavigate()
const [step, setStep] = useState('upload') // 'upload' | 'detail'
const [files, setFiles] = useState([]) // 本地 File 对象列表
const [mediaUrls, setMediaUrls] = useState([]) // 上传后得到的 URL 列表
// 详情表单字段
const [title, setTitle] = useState('')
const [content, setContent] = useState('')
const [topicId, setTopicId] = useState('')
const [status, setStatus] = useState('published')
const [error, setError] = useState(null)
// 静态话题数据
const TOPICS = [
{ id: 1, name: '世俱杯环球评大会' },
{ id: 2, name: '我的REDmentor' },
{ id: 3, name: '我染上了拼豆' },
// …更多静态话题…
]
// 上传页面回调 —— 上传完成后切换到“填写详情”步骤
const handleUploadComplete = async uploadedFiles => {
setFiles(uploadedFiles)
// TODO: 改成真实上传逻辑,拿到真正的 media_urls
const urls = await Promise.all(
uploadedFiles.map(f => URL.createObjectURL(f))
)
setMediaUrls(urls)
setStep('detail')
}
// 发布按钮
const handleSubmit = async () => {
if (!title.trim() || !content.trim()) {
setError('标题和正文必填')
return
}
setError(null)
try {
await createPost({
user_id: 1,
topic_id: topicId || undefined,
title: title.trim(),
content: content.trim(),
media_urls: mediaUrls,
status
})
// 发布成功后跳转回首页
navigate('/home', { replace: true })
} catch (e) {
setError(e.message)
}
}
// 渲染上传页
if (step === 'upload') {
return <UploadPage onComplete={handleUploadComplete} />
}
// 渲染详情页
return (
<div className="create-post">
<h2>填写帖子内容</h2>
{error && <div className="error">{error}</div>}
{/* 已上传媒体预览 */}
<div className="preview-media">
{mediaUrls.map((url, i) => (
<div key={i} className="preview-item">
{files[i].type.startsWith('image/') ? (
<img src={url} alt={`预览 ${i}`} />
) : (
<video src={url} controls />
)}
</div>
))}
</div>
{/* 标题 */}
<label className="form-label">
标题(最多20字)
<input
type="text"
maxLength={20}
value={title}
onChange={e => setTitle(e.target.value)}
placeholder="填写标题会有更多赞哦~"
/>
<span className="char-count">{title.length}/20</span>
</label>
{/* 正文 */}
<label className="form-label">
正文(最多1000字)
<textarea
maxLength={1000}
value={content}
onChange={e => setContent(e.target.value)}
placeholder="输入正文描述,真诚有价值的分享予人温暖"
/>
<span className="char-count">{content.length}/1000</span>
</label>
{/* 话题选择 */}
<label className="form-label">
选择话题(可选)
<select
value={topicId}
onChange={e => setTopicId(e.target.value)}
>
<option value="">不添加话题</option>
{TOPICS.map(t => (
<option key={t.id} value={t.id}>
#{t.name}
</option>
))}
</select>
</label>
{/* 发布状态 */}
<div className="status-group">
<label>
<input
type="radio"
name="status"
value="published"
checked={status === 'published'}
onChange={() => setStatus('published')}
/>
立即发布
</label>
<label>
<input
type="radio"
name="status"
value="draft"
checked={status === 'draft'}
onChange={() => setStatus('draft')}
/>
存为草稿
</label>
</div>
{/* 操作按钮 */}
<div className="btn-group">
<button className="btn btn-primary" onClick={handleSubmit}>
发布
</button>
<button className="btn btn-secondary" onClick={() => setStep('upload')}>
上一步
</button>
</div>
</div>
)
}