blob: a68f20c110f9f39b05c73500477e1d4231c79b05 [file] [log] [blame]
223010093a876cc2025-04-14 16:22:20 +08001import React, { useEffect, useState } from 'react';
2import axios from 'axios';
3import './InterestGroup.css';
4import Header from '../../components/Header'; // 导入 Header 组件
5
Krishya2283d882025-05-27 22:25:19 +08006
223010093a876cc2025-04-14 16:22:20 +08007
8const InterestGroup = () => {
9 const [groups, setGroups] = useState([]);
10 const [loading, setLoading] = useState(true);
11 const [error, setError] = useState(null);
12 const [category, setCategory] = useState('');
13 const [name, setName] = useState('');
14 const [page, setPage] = useState(1);
15 const [size, setSize] = useState(10);
16 const [totalPages, setTotalPages] = useState(1);
17 const [sortBy, setSortBy] = useState('member_count'); // 默认按照成员数排序
223010092303fe12025-04-15 21:26:56 +080018 const [joinStatus, setJoinStatus] = useState({}); // 存储每个小组的加入状态
223010093a876cc2025-04-14 16:22:20 +080019
20 useEffect(() => {
21 // 请求兴趣小组列表
22 const fetchGroups = async () => {
23 try {
24 setLoading(true);
25 setError(null);
Krishya2283d882025-05-27 22:25:19 +080026 const response = await axios.get(`/echo/groups`, {
223010093a876cc2025-04-14 16:22:20 +080027 params: {
28 category,
29 name,
30 page,
31 size,
32 sort_by: sortBy
33 }
34 });
35
36 if (response.data.status === 'success') {
37 setGroups(response.data.items);
38 setTotalPages(response.data.total_pages); // 更新总页数
39 } else {
40 setError('获取兴趣小组列表失败');
41 }
42 } catch (err) {
43 setError('请求失败,请稍后再试');
44 } finally {
45 setLoading(false);
46 }
47 };
48
49 fetchGroups();
50 }, [category, name, page, size, sortBy]);
51
52 const handleCategoryChange = (e) => {
53 setCategory(e.target.value);
54 setPage(1); // 重置为第一页
55 };
56
57 const handleSearchChange = (e) => {
58 setName(e.target.value);
59 setPage(1); // 重置为第一页
60 };
61
62 const handleSortChange = (e) => {
63 setSortBy(e.target.value);
64 };
65
66 const handlePageChange = (newPage) => {
67 if (newPage > 0 && newPage <= totalPages) {
68 setPage(newPage);
69 }
70 };
71
223010092303fe12025-04-15 21:26:56 +080072 // 加入兴趣小组
73 const handleJoinGroup = async (groupId) => {
74 const userId = 1; // 假设用户ID为1,可以根据实际情况获取
75
76 try {
Krishya2283d882025-05-27 22:25:19 +080077 const response = await axios.post(`/echo/groups/${groupId}/join`, {
223010092303fe12025-04-15 21:26:56 +080078 user_id: userId
79 });
80
81 if (response.data.status === 'success') {
82 setJoinStatus(prevState => ({
83 ...prevState,
84 [groupId]: '加入成功'
85 }));
86 } else {
87 setJoinStatus(prevState => ({
88 ...prevState,
89 [groupId]: '加入失败'
90 }));
91 }
92 } catch (error) {
93 setJoinStatus(prevState => ({
94 ...prevState,
95 [groupId]: '请求失败,请稍后再试'
96 }));
97 }
98 };
99
Krishyac0f7e9b2025-04-22 15:28:28 +0800100 const handleSearch = () => {
101 // 触发搜索逻辑,通过修改 name 状态重新请求数据
102 setPage(1);
103 };
104
223010093a876cc2025-04-14 16:22:20 +0800105 return (
106 <div className="interest-group-container">
107 {/* Header 组件放在页面最上方 */}
108 <Header />
Krishyac0f7e9b2025-04-22 15:28:28 +0800109 <div className="interest-group-card">
110 {/* <h1>兴趣小组列表</h1> */}
111 {/* 水平排列的筛选、搜索和排序容器 */}
112 <div className="filter-search-sort-container">
113 {/* 分类筛选 */}
114 <div className="filter">
115 <label>分类:</label>
116 <select onChange={handleCategoryChange} value={category} style={{ width: '150px' }}>
117 <option value="">全部</option>
118 <option value="影视">影视</option>
119 <option value="游戏">游戏</option>
120 <option value="学习">学习</option>
121 <option value="体育">体育</option>
122 <option value="其他">其他</option>
123 </select>
124 </div>
223010093a876cc2025-04-14 16:22:20 +0800125
Krishyac0f7e9b2025-04-22 15:28:28 +0800126 {/* 排序 */}
127 <div className="sort">
128 <label>排序:</label>
129 <select onChange={handleSortChange} value={sortBy} style={{ width: '150px' }}>
130 <option value="member_count">按成员数排序</option>
131 <option value="name">按名称排序</option>
132 <option value="category">按分类排序</option>
133 </select>
134 </div>
223010093a876cc2025-04-14 16:22:20 +0800135
Krishyac0f7e9b2025-04-22 15:28:28 +0800136 {/* 搜索框 */}
137 <div className="search">
138 <input
139 type="text"
140 value={name}
141 onChange={handleSearchChange}
142 placeholder="输入小组名称搜索"
143 />
144 <button onClick={handleSearch} style={{ backgroundColor: '#BA929A', color: 'white' , padding: '5px 10px'}}>搜索</button>
145 </div>
223010093a876cc2025-04-14 16:22:20 +0800146 </div>
223010093a876cc2025-04-14 16:22:20 +0800147
Krishyac0f7e9b2025-04-22 15:28:28 +0800148 {/* 加载中提示 */}
149 {loading && <p>加载中...</p>}
150
151 {/* 错误提示 */}
152 {error && <p className="error">{error}</p>}
153
154 {/* 小组列表 */}
155 {!loading && !error && (
156 <div className="group-list">
157 {groups.map((group) => (
158 <div className="group-item" key={group.group_id}>
159 <div className="group-content">
160 <img
161 style={{ width: '40%', height: '40%'}}
162 src={group.cover_image}
163 alt={group.name}
164 className="group-cover"
165 />
166 <div
167 className="group-info-right"
168 style={{
169 display: 'flex',
170 flexDirection: 'column',
171 alignItems: 'flex-start',
172 gap: '4px', // 控制元素之间的垂直间距
173 }}
174 >
175 <h3 style={{ margin: 0 }}>{group.name}</h3>
176 <p style={{ color: '#BA929A', margin: 0 }}>{group.member_count}人加入了小组</p>
177 <button
178 onClick={() => handleJoinGroup(group.group_id)}
179 disabled={joinStatus[group.group_id] === '加入成功'}
180 style={{
181 background: 'none',
182 color: '#007bff',
183 padding: 0,
184 marginTop: '4px',
185 /*左对齐*/
186 textAlign: 'left',
187 marginLeft: '0',
188 cursor: joinStatus[group.group_id] === '加入成功' ? 'default' : 'pointer',
189 }}
190 >
191 {joinStatus[group.group_id] === '加入成功' ? '已加入' : '+加入小组'}
192 </button>
193 </div>
194
195 </div>
196 <div className="group-description">
197 <p>{group.description}</p>
198 </div>
199 <p>分类:{group.category}</p>
200
201 </div>
202 ))}
203 </div>
204 )}
205
206 {/* 分页 */}
207 <div className="pagination">
208 <button onClick={() => handlePageChange(page - 1)} disabled={page <= 1}>
209 上一页
210 </button>
211 <span> {page} / {totalPages} 页</span>
212 <button
213 onClick={() => handlePageChange(page + 1)}
214 disabled={page >= totalPages}
215 >
216 下一页
217 </button>
218 </div>
223010093a876cc2025-04-14 16:22:20 +0800219 </div>
220 </div>
221 );
222};
223
Krishyac0f7e9b2025-04-22 15:28:28 +0800224export default InterestGroup;