blob: c1109a0d0f53c85ee68716cf687f3febc694b33c [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'); // 默认按照成员数排序
18
19 useEffect(() => {
20 // 请求兴趣小组列表
21 const fetchGroups = async () => {
22 try {
23 setLoading(true);
24 setError(null);
25 const response = await axios.get(`${API_BASE}/echo/groups`, {
26 params: {
27 category,
28 name,
29 page,
30 size,
31 sort_by: sortBy
32 }
33 });
34
35 if (response.data.status === 'success') {
36 setGroups(response.data.items);
37 setTotalPages(response.data.total_pages); // 更新总页数
38 } else {
39 setError('获取兴趣小组列表失败');
40 }
41 } catch (err) {
42 setError('请求失败,请稍后再试');
43 } finally {
44 setLoading(false);
45 }
46 };
47
48 fetchGroups();
49 }, [category, name, page, size, sortBy]);
50
51 const handleCategoryChange = (e) => {
52 setCategory(e.target.value);
53 setPage(1); // 重置为第一页
54 };
55
56 const handleSearchChange = (e) => {
57 setName(e.target.value);
58 setPage(1); // 重置为第一页
59 };
60
61 const handleSortChange = (e) => {
62 setSortBy(e.target.value);
63 };
64
65 const handlePageChange = (newPage) => {
66 if (newPage > 0 && newPage <= totalPages) {
67 setPage(newPage);
68 }
69 };
70
71 return (
72 <div className="interest-group-container">
73 {/* Header 组件放在页面最上方 */}
74 <Header />
75
76 <h1>兴趣小组列表</h1>
77 {/* 分类筛选 */}
78 <div className="filter">
79 <label>分类:</label>
80 <select onChange={handleCategoryChange} value={category}>
81 <option value="">全部</option>
82 <option value="影视">影视</option>
83 <option value="游戏">游戏</option>
84 <option value="学习">学习</option>
85 <option value="体育">体育</option>
86 <option value="其他">其他</option>
87 </select>
88 </div>
89
90 {/* 搜索框 */}
91 <div className="search">
92 <label>搜索:</label>
93 <input
94 type="text"
95 value={name}
96 onChange={handleSearchChange}
97 placeholder="输入小组名称搜索"
98 />
99 </div>
100
101 {/* 排序 */}
102 <div className="sort">
103 <label>排序:</label>
104 <select onChange={handleSortChange} value={sortBy}>
105 <option value="member_count">按成员数排序</option>
106 <option value="name">按名称排序</option>
107 <option value="category">按分类排序</option>
108 </select>
109 </div>
110
111 {/* 加载中提示 */}
112 {loading && <p>加载中...</p>}
113
114 {/* 错误提示 */}
115 {error && <p className="error">{error}</p>}
116
117 {/* 小组列表 */}
118 {!loading && !error && (
119 <div className="group-list">
120 {groups.map((group) => (
121 <div className="group-item" key={group.group_id}>
122 <img
123 src={group.cover_image}
124 alt={group.name}
125 className="group-cover"
126 />
127 <div className="group-info">
128 <h2>{group.name}</h2>
129 <p>{group.description}</p>
130 <p>成员数:{group.member_count}</p>
131 <p>分类:{group.category}</p>
132 </div>
133 </div>
134 ))}
135 </div>
136 )}
137
138 {/* 分页 */}
139 <div className="pagination">
140 <button onClick={() => handlePageChange(page - 1)} disabled={page <= 1}>
141 上一页
142 </button>
143 <span> {page} / {totalPages} 页</span>
144 <button
145 onClick={() => handlePageChange(page + 1)}
146 disabled={page >= totalPages}
147 >
148 下一页
149 </button>
150 </div>
151 </div>
152 );
153};
154
155export default InterestGroup;