用户个人中心、兴趣小组

Change-Id: I0e2f3f4ad586f237505613238cbb7bebb6118b63
diff --git a/src/pages/InterestGroup/GroupFilters.jsx b/src/pages/InterestGroup/GroupFilters.jsx
index c93b495..c6c3a52 100644
--- a/src/pages/InterestGroup/GroupFilters.jsx
+++ b/src/pages/InterestGroup/GroupFilters.jsx
@@ -1,58 +1,58 @@
-import React from 'react';
-import { useGroupStore } from '../../context/useGroupStore';
+// import React from 'react';
+// import { useGroupStore } from '../../context/useGroupStore';
 
-const GroupFilters = () => {
-  const { 
-    category, setCategory, 
-    name, setName, 
-    sortBy, setSortBy,
-    handleSearch
-  } = useGroupStore();
+// const GroupFilters = () => {
+//   const { 
+//     category, setCategory, 
+//     name, setName, 
+//     sortBy, setSortBy,
+//     handleSearch
+//   } = useGroupStore();
 
-  const handleSortChange = (e) => {
-    const sortValueMap = {
-      'member_count': 'member_count',
-      'name': 'groupName',
-      'category': 'category'
-    };
-    const backendValue = sortValueMap[e.target.value] || 'member_count';
-    setSortBy(backendValue);
-  };
+//   const handleSortChange = (e) => {
+//     const sortValueMap = {
+//       'member_count': 'member_count',
+//       'name': 'groupName',
+//       'category': 'category'
+//     };
+//     const backendValue = sortValueMap[e.target.value] || 'member_count';
+//     setSortBy(backendValue);
+//   };
 
-  return (
-    <div className="filter-search-sort-container">
-      <div className="filter">
-        <label>分类:</label>
-        <select onChange={(e) => setCategory(e.target.value)} value={category}>
-          <option value="">全部</option>
-          <option value="影视">影视</option>
-          <option value="游戏">游戏</option>
-          <option value="学习">学习</option>
-          <option value="体育">体育</option>
-          <option value="其他">其他</option>
-        </select>
-      </div>
+//   return (
+//     <div className="filter-search-sort-container">
+//       <div className="filter">
+//         <label>分类:</label>
+//         <select onChange={(e) => setCategory(e.target.value)} value={category}>
+//           <option value="">全部</option>
+//           <option value="影视">影视</option>
+//           <option value="游戏">游戏</option>
+//           <option value="学习">学习</option>
+//           <option value="体育">体育</option>
+//           <option value="其他">其他</option>
+//         </select>
+//       </div>
 
-      <div className="sort">
-        <label>排序:</label>
-        <select onChange={handleSortChange} value={sortBy}>
-          <option value="member_count">按成员数排序</option>
-          <option value="name">按名称排序</option>
-          <option value="category">按分类排序</option>
-        </select>
-      </div>
+//       <div className="sort">
+//         <label>排序:</label>
+//         <select onChange={handleSortChange} value={sortBy}>
+//           <option value="member_count">按成员数排序</option>
+//           <option value="name">按名称排序</option>
+//           <option value="category">按分类排序</option>
+//         </select>
+//       </div>
 
-      <div className="search">
-        <input
-          type="text"
-          value={name}
-          onChange={(e) => setName(e.target.value)}
-          placeholder="输入小组名称搜索"
-        />
-        <button onClick={handleSearch}>搜索</button>
-      </div>
-    </div>
-  );
-};
+//       <div className="search">
+//         <input
+//           type="text"
+//           value={name}
+//           onChange={(e) => setName(e.target.value)}
+//           placeholder="输入小组名称搜索"
+//         />
+//         <button onClick={handleSearch}>搜索</button>
+//       </div>
+//     </div>
+//   );
+// };
 
-export default GroupFilters;
\ No newline at end of file
+// export default GroupFilters;
\ No newline at end of file
diff --git a/src/pages/InterestGroup/GroupItem.jsx b/src/pages/InterestGroup/GroupItem.jsx
index 736f88d..ea2253f 100644
--- a/src/pages/InterestGroup/GroupItem.jsx
+++ b/src/pages/InterestGroup/GroupItem.jsx
@@ -1,97 +1,3 @@
-// import React, { useState, useEffect } from 'react';
-// import { useGroupStore } from '../../context/useGroupStore';
-// import { useUser } from '../../context/UserContext';
-// import CreatePostForm from './CreatePostForm';
-// import axios from 'axios'; // 新增
-
-// const GroupItem = ({ group }) => {
-//   const { handleJoinGroup, joinStatus, setJoinStatus } = useGroupStore(); // 假设你有 setJoinStatus 方法
-//   const { user } = useUser();
-
-//   const userId = user?.userId;
-//   const groupId = group.groupId;
-
-//   const [isMember, setIsMember] = useState(false);
-
-//   useEffect(() => {
-//     setIsMember(joinStatus[groupId] === '加入成功');
-//   }, [joinStatus, groupId]);
-
-//   const [showCreatePost, setShowCreatePost] = useState(false);
-
-//   // 退出小组函数(新增)
-//   const handleLeaveGroup = async () => {
-//     try {
-//       const res = await axios.post(`/echo/groups/${groupId}/leave`, {
-//         user_id: userId,
-//       });
-//       if (res.data.status === 'success') {
-//         setJoinStatus(groupId, '未加入'); // 更新全局状态(需确保 useGroupStore 中有此方法)
-//         setIsMember(false); // 本地状态也更新
-//       } else {
-//         alert(res.data.message || '退出失败');
-//       }
-//     } catch (error) {
-//       console.error('退出小组失败:', error);
-//       alert('退出小组失败');
-//     }
-//   };
-
-//   return (
-//     <div className="group-item">
-//       <div className="group-content">
-//         <img
-//           style={{ width: '40%', height: '40%' }}
-//           src={group.coverImage || 'https://picsum.photos/200/200'}
-//           alt={group.groupName}
-//           className="group-cover"
-//         />
-//         <div className="group-info-right">
-//           <h3>{group.groupName}</h3>
-//           <p style={{ color: '#BA929A' }}>{group.memberCount || 0}人加入了小组</p>
-
-//           {/* 加入/退出按钮逻辑 */}
-//           {userId && (
-//             <button
-//               onClick={() => {
-//                 if (isMember) {
-//                   handleLeaveGroup(); // 已加入 -> 退出
-//                 } else {
-//                   handleJoinGroup(groupId, userId); // 未加入 -> 加入
-//                 }
-//               }}
-//             >
-//               {isMember ? '退出小组' : '+加入小组'}
-//             </button>
-//           )}
-//           {!userId && <button disabled>请登录</button>}
-
-//           {/* 发布帖子按钮 */}
-//           {userId && isMember && (
-//             <button onClick={() => setShowCreatePost(!showCreatePost)}>
-//               +发布帖子
-//             </button>
-//           )}
-//         </div>
-//       </div>
-
-//       <div className="group-description">
-//         <p>{group.description}</p>
-//       </div>
-//       <p>分类:{group.category}</p>
-
-//       {showCreatePost && (
-//         <CreatePostForm 
-//           groupId={groupId}
-//           onClose={() => setShowCreatePost(false)}
-//         />
-//       )}
-//     </div>
-//   );
-// };
-
-// export default GroupItem;
-
 import React, { useState, useEffect } from 'react';
 import { useGroupStore } from '../../context/useGroupStore';
 import { useUser } from '../../context/UserContext';
@@ -99,7 +5,7 @@
 import axios from 'axios';
 
 const GroupItem = ({ group }) => {
-  const { handleJoinGroup, joinStatus, setJoinStatus } = useGroupStore();
+  const { handleJoinGroup, joinStatus, setJoinStatus,fetchGroupList } = useGroupStore();
   const { user } = useUser();
 
   const userId = user?.userId;
@@ -126,7 +32,8 @@
     try {
       const res = await axios.get(`/echo/groups/${groupId}/members`);
       const isMember = res.data.members.some(member => member.user_id === userId);
-      setJoinStatus(groupId, isMember ? '加入成功' : '未加入');
+      setIsMember(isMember);
+      // setJoinStatus(groupId, isMember ? '加入成功' : '未加入');
     } catch (error) {
       console.error('检查成员状态失败:', error);
     }
@@ -141,7 +48,8 @@
         user_id: userId,
       });
       if (res.data.status === 'success') {
-        setJoinStatus(groupId, '未加入');
+          fetchGroupList(); // 刷新小组列表
+        // setJoinStatus(groupId, '未加入');
         setIsMember(false);
         // 可选:刷新小组成员计数
         group.memberCount = (group.memberCount || 0) - 1;
diff --git a/src/pages/InterestGroup/InterestGroup.css b/src/pages/InterestGroup/InterestGroup.css
index 91b21da..f819038 100644
--- a/src/pages/InterestGroup/InterestGroup.css
+++ b/src/pages/InterestGroup/InterestGroup.css
@@ -204,4 +204,82 @@
   margin-top: 40px;
   /* padding: 24px 32px; */
   padding: 3% 3%
-}    
\ No newline at end of file
+}    
+
+.create-group-btn {
+  background-color: #f2d0c9; /* 浅粉色 */
+  color: #4e342e; /* 深棕色 */
+  border: none;
+  padding: 10px 20px;
+  margin: 20px 0;
+  border-radius: 8px;
+  font-size: 16px;
+  cursor: pointer;
+  transition: background-color 0.3s ease;
+}
+
+.create-group-btn:hover {
+  background-color: #e4b5ae;
+}
+
+.modal-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(50, 30, 20, 0.5); /* 米棕半透明 */
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1000;
+}
+
+.modal-content {
+  background-color: #fffaf5; /* 淡米色 */
+  padding: 30px;
+  border-radius: 12px;
+  width: 400px;
+  box-shadow: 0 5px 15px rgba(0,0,0,0.2);
+}
+
+.modal-content h2 {
+  margin-bottom: 15px;
+  color: #4e342e;
+}
+
+.modal-content input,
+.modal-content textarea {
+  width: 100%;
+  padding: 10px;
+  margin: 8px 0;
+  border: 1px solid #d3c0b0;
+  border-radius: 6px;
+  font-size: 14px;
+}
+
+.modal-buttons {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+  margin-top: 15px;
+}
+
+.modal-buttons button {
+  padding: 8px 16px;
+  border: none;
+  border-radius: 6px;
+  font-weight: bold;
+  cursor: pointer;
+  font-size: 14px;
+}
+
+.modal-buttons button:first-child {
+  background-color: #d7a29e; /* 粉棕 */
+  color: white;
+}
+
+.modal-buttons button:last-child {
+  background-color: #c5b8af; /* 米色灰棕 */
+  color: white;
+}
diff --git a/src/pages/InterestGroup/InterestGroup.jsx b/src/pages/InterestGroup/InterestGroup.jsx
index b89cf57..0b5b002 100644
--- a/src/pages/InterestGroup/InterestGroup.jsx
+++ b/src/pages/InterestGroup/InterestGroup.jsx
@@ -1,23 +1,217 @@
-import React, { useEffect } from 'react';
+// // import React, { useEffect } from 'react';
+// // import Header from '../../components/Header';
+// // import { useGroupStore } from '../../context/useGroupStore';
+// // // import GroupFilters from './GroupFilters';
+// // import GroupList from './GroupList';
+// // import GroupPagination from './GroupPagination';
+// // import './InterestGroup.css';
+// // const InterestGroup = () => {
+// //   const { fetchGroupList, setPage, handleSearch } = useGroupStore();
+
+// //   // 初始化加载
+// //   useEffect(() => {
+// //     fetchGroupList();
+// //   }, [fetchGroupList]);
+
+// //   return (
+// //     <div className="interest-group-container">
+// //       <Header />
+// //       <div className="interest-group-card">
+// //         {/* <GroupFilters /> */}
+// //         <GroupList />
+// //         <GroupPagination />
+// //       </div>
+// //     </div>
+// //   );
+// // };
+
+// // export default InterestGroup;
+
+// import React, { useEffect, useState } from 'react';
+// import Header from '../../components/Header';
+// import { useGroupStore } from '../../context/useGroupStore';
+// import GroupList from './GroupList';
+// import GroupPagination from './GroupPagination';
+// import './InterestGroup.css';
+// import axios from 'axios';
+
+// const InterestGroup = () => {
+//   const { fetchGroupList } = useGroupStore();
+
+//   const [showModal, setShowModal] = useState(false);
+//   const [groupName, setGroupName] = useState('');
+//   const [groupDescription, setGroupDescription] = useState('');
+
+//   useEffect(() => {
+//     fetchGroupList();
+//   }, [fetchGroupList]);
+
+//   const handleCreateGroup = async () => {
+//   try {
+//     const res = await axios.post('http://localhost:3011/echo/groups/createGroup', {
+//       user_id: 1,
+//       group_name: groupName,               // ✅ 改为 snake_case
+//       description: groupDescription,
+//       time: new Date().toISOString(),
+//       category: '默认分类',
+//       cover_image: 'https://picsum.photos/300/200',
+//     });
+
+//     if (res.status === 200 && res.data.status === 'success') {
+//       alert('小组创建成功');
+//       setShowModal(false);
+//       setGroupName('');
+//       setGroupDescription('');
+//       fetchGroupList();
+//     } else {
+//       alert('创建失败: ' + res.data.message);
+//     }
+//   } catch (error) {
+//     alert('创建失败,请检查网络或输入');
+//     console.error(error);
+//   }
+// };
+
+
+//   // const handleCreateGroup = async () => {
+//   //   try {
+//   //     const res = await axios.post('/createGroup', {
+//   //       groupName,
+//   //       description: groupDescription,
+//   //     });
+//   //     if (res.status === 200) {
+//   //       alert('小组创建成功');
+//   //       setShowModal(false);
+//   //       setGroupName('');
+//   //       setGroupDescription('');
+//   //       fetchGroupList(); // 刷新列表
+//   //     }
+//   //   } catch (error) {
+//   //     alert('创建失败,请重试');
+//   //   }
+//   // };
+
+//   return (
+//     <div className="interest-group-container">
+//       <Header />
+//       <div className="interest-group-card">
+//         <button className="create-group-btn" onClick={() => setShowModal(true)}>
+//           创建小组
+//         </button>
+
+//         {showModal && (
+//           <div className="modal-overlay">
+//             <div className="modal-content">
+//               <h2>创建新小组</h2>
+//               <input
+//                 type="text"
+//                 placeholder="小组名称"
+//                 value={groupName}
+//                 onChange={(e) => setGroupName(e.target.value)}
+//               />
+//               <textarea
+//                 placeholder="小组简介"
+//                 value={groupDescription}
+//                 onChange={(e) => setGroupDescription(e.target.value)}
+//               />
+//               <div className="modal-buttons">
+//                 <button onClick={handleCreateGroup}>确定</button>
+//                 <button onClick={() => setShowModal(false)}>取消</button>
+//               </div>
+//             </div>
+//           </div>
+//         )}
+
+//         <GroupList />
+//         <GroupPagination />
+//       </div>
+//     </div>
+//   );
+// };
+
+// export default InterestGroup;
+
+
+import React, { useEffect, useState } from 'react';
 import Header from '../../components/Header';
 import { useGroupStore } from '../../context/useGroupStore';
-import GroupFilters from './GroupFilters';
 import GroupList from './GroupList';
 import GroupPagination from './GroupPagination';
 import './InterestGroup.css';
-const InterestGroup = () => {
-  const { fetchGroupList, setPage, handleSearch } = useGroupStore();
+import axios from 'axios';
 
-  // 初始化加载
+const InterestGroup = () => {
+  const { fetchGroupList } = useGroupStore();
+
+  const [showModal, setShowModal] = useState(false);
+  const [groupName, setGroupName] = useState('');
+  const [groupDescription, setGroupDescription] = useState('');
+
   useEffect(() => {
     fetchGroupList();
   }, [fetchGroupList]);
 
+  const handleCreateGroup = async () => {
+    try {
+      // ✅ 修改请求体字段名,使用驼峰命名法
+      const res = await axios.post('http://localhost:3011/echo/groups/createGroup', {
+        userId: 1,                 // 改为驼峰命名 userId
+        groupName: groupName,      // 改为驼峰命名 groupName
+        description: groupDescription,
+        // 移除time字段,使用后端生成的时间
+        memberCount: 1,            // 添加初始成员数
+        category: '默认分类',
+        coverImage: 'https://picsum.photos/300/200',  // 改为驼峰命名 coverImage
+      });
+
+      if (res.status === 200 && res.data.status === 'success') {
+        alert('小组创建成功');
+        setShowModal(false);
+        setGroupName('');
+        setGroupDescription('');
+        fetchGroupList(); // 刷新列表
+      } else {
+        // 显示后端返回的详细错误信息
+        alert('创建失败: ' + res.data.message);
+      }
+    } catch (error) {
+      // 处理网络错误或其他异常
+      alert('创建失败,请检查网络连接或输入内容');
+      console.error('创建小组错误:', error);
+    }
+  };
+
   return (
     <div className="interest-group-container">
       <Header />
       <div className="interest-group-card">
-        <GroupFilters />
+        <button className="create-group-btn" onClick={() => setShowModal(true)}>
+          创建小组
+        </button>
+
+        {showModal && (
+          <div className="modal-overlay">
+            <div className="modal-content">
+              <h2>创建新小组</h2>
+              <input
+                type="text"
+                placeholder="小组名称"
+                value={groupName}
+                onChange={(e) => setGroupName(e.target.value)}
+              />
+              <textarea
+                placeholder="小组简介"
+                value={groupDescription}
+                onChange={(e) => setGroupDescription(e.target.value)}
+              />
+              <div className="modal-buttons">
+                <button onClick={handleCreateGroup}>确定</button>
+                <button onClick={() => setShowModal(false)}>取消</button>
+              </div>
+            </div>
+          </div>
+        )}
+
         <GroupList />
         <GroupPagination />
       </div>