用户个人中心、兴趣小组
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>