blob: 8a8d67bd13a5e779313f939961ef5a68a25413b4 [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
6const API_BASE = process.env.REACT_APP_API_BASE;
7
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);
26 const response = await axios.get(`${API_BASE}/echo/groups`, {
27 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 {
77 const response = await axios.post(`${API_BASE}/echo/groups/${groupId}/join`, {
78 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
223010093a876cc2025-04-14 16:22:20 +0800100 return (
101 <div className="interest-group-container">
102 {/* Header 组件放在页面最上方 */}
103 <Header />
104
105 <h1>兴趣小组列表</h1>
106 {/* 分类筛选 */}
107 <div className="filter">
108 <label>分类:</label>
109 <select onChange={handleCategoryChange} value={category}>
110 <option value="">全部</option>
111 <option value="影视">影视</option>
112 <option value="游戏">游戏</option>
113 <option value="学习">学习</option>
114 <option value="体育">体育</option>
115 <option value="其他">其他</option>
116 </select>
117 </div>
118
119 {/* 搜索框 */}
120 <div className="search">
121 <label>搜索:</label>
122 <input
123 type="text"
124 value={name}
125 onChange={handleSearchChange}
126 placeholder="输入小组名称搜索"
127 />
128 </div>
129
130 {/* 排序 */}
131 <div className="sort">
132 <label>排序:</label>
133 <select onChange={handleSortChange} value={sortBy}>
134 <option value="member_count">按成员数排序</option>
135 <option value="name">按名称排序</option>
136 <option value="category">按分类排序</option>
137 </select>
138 </div>
139
140 {/* 加载中提示 */}
141 {loading && <p>加载中...</p>}
142
143 {/* 错误提示 */}
144 {error && <p className="error">{error}</p>}
145
146 {/* 小组列表 */}
147 {!loading && !error && (
148 <div className="group-list">
149 {groups.map((group) => (
150 <div className="group-item" key={group.group_id}>
151 <img
152 src={group.cover_image}
153 alt={group.name}
154 className="group-cover"
155 />
156 <div className="group-info">
157 <h2>{group.name}</h2>
158 <p>{group.description}</p>
159 <p>成员数:{group.member_count}</p>
160 <p>分类:{group.category}</p>
223010092303fe12025-04-15 21:26:56 +0800161 {/* 加入小组按钮 */}
162 <button
163 onClick={() => handleJoinGroup(group.group_id)}
164 disabled={joinStatus[group.group_id] === '加入成功'}
165 >
166 {joinStatus[group.group_id] === '加入成功' ? '已加入' : '加入小组'}
167 </button>
168 {/* 显示加入状态 */}
169 {joinStatus[group.group_id] && <p>{joinStatus[group.group_id]}</p>}
223010093a876cc2025-04-14 16:22:20 +0800170 </div>
171 </div>
172 ))}
173 </div>
174 )}
175
176 {/* 分页 */}
177 <div className="pagination">
178 <button onClick={() => handlePageChange(page - 1)} disabled={page <= 1}>
179 上一页
180 </button>
181 <span> {page} / {totalPages} 页</span>
182 <button
183 onClick={() => handlePageChange(page + 1)}
184 disabled={page >= totalPages}
185 >
186 下一页
187 </button>
188 </div>
189 </div>
190 );
191};
192
193export default InterestGroup;