// // import React, { useState } from 'react';
// // import axios from 'axios';
// // import { useNavigate } from 'react-router-dom';
// // import './CreateMoment.css';
// // import Header from '../../components/Header';

// // const API_BASE = process.env.REACT_APP_API_BASE;
// // const USER_ID = 456;

// // const CreateMoment = () => {
// //   const [title, setTitle] = useState('');
// //   const [content, setContent] = useState('');
// //   const [previewUrls, setPreviewUrls] = useState([]);
// //   const [images, setImages] = useState([]);
// //   const navigate = useNavigate();

// //   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(file => uploadImageToServer(file))
// //       );
// //       setImages(uploaded);
// //     } catch (err) {
// //       console.error('图片上传失败：', err);
// //       alert('有图片上传失败，请重试');
// //     }
// //   };

// //   const uploadImageToServer = async (file) => {
// //     const formData = new FormData();
// //     formData.append('file', file);
// //     const res = await axios.post(`${API_BASE}/upload`, formData, {
// //       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}/CreateMoment`,
// //         {
// //           title: title.trim() || undefined,
// //           friend_content: content.trim(),
// //           images
// //         }
// //       );
// //       navigate('/friend-moments');
// //     } catch (err) {
// //       console.error('发布失败：', err);
// //       alert('发布失败，请稍后重试');
// //     }
// //   };

// //   return (
// //     <div className="create-feed-page">
// //       <Header/>
// //       <div className="cf-header">
// //         <button onClick={() => navigate(-1)} style={{padding : '5px 10px', backgroundColor: '#BA929A', color: 'white'}}>返回</button>
// //         <h3>发布新动态</h3>
// //       </div>

// //       <div className="cf-form">
// //         <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}
// //         />
// //         <div className="cf-preview">
// //           {previewUrls.map((url, i) => (
// //             <img key={i} src={url} alt={`预览 ${i}`} />
// //           ))}
// //         </div>
// //         <button className="cf-submit-btn" onClick={handleSubmit}>
// //           发布
// //         </button>
// //       </div>
// //     </div>
// //   );
// // };

// // export default CreateMoment;
// import React, { useState } from 'react';
// import axios from 'axios';
// import { useNavigate } from 'react-router-dom';
// import './CreateMoment.css';
// import Header from '../../components/Header';

// const API_BASE = process.env.REACT_APP_API_BASE;
// const USER_ID = 456;

// const CreateMoment = ({ onClose, fetchFeeds }) => {
//     const [title, setTitle] = useState('');
//     const [content, setContent] = useState('');
//     const [previewUrls, setPreviewUrls] = useState([]);
//     const [images, setImages] = useState([]);
//     const navigate = useNavigate();

//     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(file => uploadImageToServer(file))
//             );
//             setImages(uploaded);
//         } catch (err) {
//             console.error('图片上传失败：', err);
//             alert('有图片上传失败，请重试');
//         }
//     };

//     const uploadImageToServer = async (file) => {
//         const formData = new FormData();
//         formData.append('file', file);
//         const res = await axios.post(`${API_BASE}/upload`, formData, {
//             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}/CreateMoment`,
//                 {
//                     title: title.trim() || undefined,
//                     friend_content: content.trim(),
//                     images
//                 }
//             );
//             onClose();
//             fetchFeeds();
//         } catch (err) {
//             console.error('发布失败：', err);
//             alert('发布失败，请稍后重试');
//         }
//     };

//     return (
//         <div className="create-feed-page">
//             <div className="cf-header">
//                 <button onClick={onClose} style={{ padding: '5px 10px', backgroundColor: '#BA929A', color: 'white' }}>
//                     返回
//                 </button>
//                 <h3>发布新动态</h3>
//             </div>
//             <div className="cf-form">
//                 <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}
//                 />
//                 <div className="cf-preview">
//                     {previewUrls.map((url, i) => (
//                         <img key={i} src={url} alt={`预览 ${i}`} />
//                     ))}
//                 </div>
//                 <button className="cf-submit-btn" onClick={handleSubmit}>
//                     发布
//                 </button>
//             </div>
//         </div>
//     );
// };

// export default CreateMoment;
    
