blob: fdf101c337d1decdbd391b4f5ea31dd01a289c2c [file] [log] [blame]
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './FriendMoments.css';
import Header from '../../components/Header';
import { Edit } from '@icon-park/react';
const API_BASE = process.env.REACT_APP_API_BASE;
const USER_ID = 456;
const FriendMoments = () => {
const [feeds, setFeeds] = useState([]);
const [filteredFeeds, setFilteredFeeds] = useState([]);
const [query, setQuery] = useState('');
// Modal state & form fields
const [showModal, setShowModal] = useState(false);
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const [previewUrls, setPreviewUrls] = useState([]);
const [images, setImages] = useState([]);
// 拉取好友动态列表
const fetchFeeds = async () => {
try {
const res = await axios.get(`${API_BASE}/echo/users/${USER_ID}/feeds`);
setFeeds(res.data.feeds);
setFilteredFeeds(res.data.feeds);
} catch (err) {
console.error('获取动态列表失败:', err);
}
};
useEffect(() => {
fetchFeeds();
}, []);
// 搜索处理
const handleSearch = () => {
const q = query.trim().toLowerCase();
if (!q) return;
setFilteredFeeds(
feeds.filter(f => (f.title || '').toLowerCase().includes(q))
);
};
const handleReset = () => {
setQuery('');
setFilteredFeeds(feeds);
};
// 对话框内:本地预览 & 上传
const handleImageChange = async (e) => {
const files = Array.from(e.target.files);
if (!files.length) return;
setPreviewUrls(files.map(f => URL.createObjectURL(f)));
try {
const uploaded = await Promise.all(files.map(f => uploadImageToServer(f)));
setImages(uploaded);
} catch (err) {
console.error('图片上传失败', err);
alert('图片上传失败,请重试');
}
};
const uploadImageToServer = async (file) => {
const fd = new FormData();
fd.append('file', file);
const res = await axios.post(`${API_BASE}/upload`, fd, {
headers: {'Content-Type':'multipart/form-data'}
});
return res.data.url;
};
// 对话框内:提交新动态
const handleSubmit = async () => {
if (!content.trim()) {
alert('内容不能为空');
return;
}
try {
await axios.post(
`${API_BASE}/echo/users/${USER_ID}/createFeed`,
{ title: title.trim() || undefined, friend_content: content.trim(), images }
);
// 重置表单
setTitle('');
setContent('');
setImages([]);
setPreviewUrls([]);
setShowModal(false);
fetchFeeds();
} catch (err) {
console.error('发布失败', err);
alert('发布失败,请稍后重试');
}
};
// 删除动态
const handleDelete = async (feedId) => {
if (!window.confirm('确定要删除这条动态吗?')) return;
try {
await axios.delete(`${API_BASE}/echo/users/me/feed/${feedId}`);
fetchFeeds();
} catch (err) {
console.error('删除失败', err);
alert('删除失败');
}
};
return (
<div className="friend-moments-container">
<Header />
<div className="fm-header">
<button className="create-btn" onClick={() => setShowModal(true)}>
<Edit theme="outline" size="18" style={{ marginRight: '6px' }} />
创建动态
</button>
<div className="f-search-bar">
<input
className="search-input"
type="text"
value={query}
onChange={e => setQuery(e.target.value)}
placeholder="输入要搜索的动态"
/>
<button className="search-btn" onClick={handleSearch}>搜索</button>
<button className="search-btn" onClick={handleReset}>重置</button>
</div>
</div>
<div className="feed-list">
{filteredFeeds.map(feed => (
<div className="feed-item" key={feed.feed_id}>
{feed.title && <h4>{feed.title}</h4>}
<p>{feed.friend_content}</p>
{feed.images?.length > 0 && (
<div className="feed-images">
{feed.images.map((url, i) => (
<img key={i} src={url} alt={`动态图${i}`} />
))}
</div>
)}
<div className="feed-footer">
<span className="feed-date">
{new Date(feed.created_at).toLocaleString()}
</span>
{feed.is_mine && (
<button className="delete-btn" onClick={() => handleDelete(feed.feed_id)}>
删除
</button>
)}
</div>
</div>
))}
</div>
{/* Modal 对话框 */}
{showModal && (
<div className="modal-overlay" onClick={() => setShowModal(false)}>
<div className="modal-dialog" onClick={e => e.stopPropagation()}>
<h3>发布新动态</h3>
<input
type="text"
placeholder="标题"
value={title}
onChange={e => setTitle(e.target.value)}
/>
<textarea
placeholder="写下你的内容..."
value={content}
onChange={e => setContent(e.target.value)}
/>
{/* <input
type="file"
accept="image/*"
multiple
onChange={handleImageChange}
/> */}
<label className="file-label">
选择图片
<input
type="file"
accept="image/*"
multiple
onChange={handleImageChange}
style={{ display: 'none' }}
/>
</label>
<div className="cf-preview">
{previewUrls.map((url, i) => (
<img key={i} src={url} alt={`预览${i}`} />
))}
</div>
<div className="modal-actions">
<button className="btn cancel" onClick={() => setShowModal(false)}>
取消
</button>
<button className="btn submit" onClick={handleSubmit}>
发布
</button>
</div>
</div>
</div>
)}
</div>
);
};
export default FriendMoments;