blob: c1ce2311f1862d06f47831897f3e8e2f25fd36a4 [file] [log] [blame]
956303669a32fc2c2025-06-02 19:45:53 +08001import React, { useState } from "react";
2import MovieIcon from "@mui/icons-material/Movie";
3import EmailIcon from "@mui/icons-material/Email";
4import MusicNoteIcon from "@mui/icons-material/MusicNote";
5import EmojiPeopleIcon from "@mui/icons-material/EmojiPeople";
6import SportsEsportsIcon from "@mui/icons-material/SportsEsports";
7import SportsMartialArtsIcon from "@mui/icons-material/SportsMartialArts";
8import PersonIcon from "@mui/icons-material/Person";
9import AccountCircleIcon from "@mui/icons-material/AccountCircle";
10import "./App.css";
11import { useNavigate } from "react-router-dom";
223011330f9623f2025-06-06 00:22:05 +080012import { API_BASE_URL } from "./config";
2230113338fd3882025-06-06 23:33:57 +080013import ForumIcon from "@mui/icons-material/Forum";
956303669a32fc2c2025-06-02 19:45:53 +080014
15const navItems = [
16 { label: "电影", icon: <MovieIcon />, path: "/movie" },
17 { label: "剧集", icon: <EmailIcon />, path: "/tv" },
18 { label: "音乐", icon: <MusicNoteIcon />, path: "/music" },
19 { label: "动漫", icon: <EmojiPeopleIcon />, path: "/anime" },
20 { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },
21 { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },
22 { label: "资料", icon: <PersonIcon />, path: "/info" },
2230113338fd3882025-06-06 23:33:57 +080023 { label: "论坛", icon: <ForumIcon />, path: "/forum" },
9563036699e95ae32025-06-02 21:42:11 +080024 { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option
956303669a32fc2c2025-06-02 19:45:53 +080025];
26
rhjc6a4ee02025-06-06 00:45:18 +080027const gameTypesList = [
28 ["PC"],
29 ["主机"],
30 ["移动"],
31 ["掌机"],
32 ["视频"]
33];
956303669a32fc2c2025-06-02 19:45:53 +080034
35const areaTabs = [
36 { label: "PC", icon: <MovieIcon fontSize="small" /> },
37 { label: "主机", icon: <EmailIcon fontSize="small" /> },
38 { label: "移动", icon: <PersonIcon fontSize="small" /> },
39 { label: "掌机", icon: <EmojiPeopleIcon fontSize="small" /> },
40 { label: "视频", icon: <PersonIcon fontSize="small" /> },
41];
42
43export default function GamePage() {
44 const navigate = useNavigate();
45 const [activeTab, setActiveTab] = useState(0);
rhjc6a4ee02025-06-06 00:45:18 +080046 const [gameList, setGameList] = useState([]);
47
48 const gameTypes = gameTypesList[activeTab] || [];
49
50 React.useEffect(() => {
51 const area = areaTabs[activeTab].label;
223011330f9623f2025-06-06 00:22:05 +080052 fetch(`${API_BASE_URL}/api/get-seed-list-by-tag?tag=${encodeURIComponent(area)}`)
rhjc6a4ee02025-06-06 00:45:18 +080053 .then(res => res.json())
54 .then(data => setGameList(data))
55 .catch(() => setGameList([]));
56 }, [activeTab]);
956303669a32fc2c2025-06-02 19:45:53 +080057
58 return (
59 <div className="container">
60 {/* 预留顶部空间用于放图片 */}
61 <div style={{ height: 80 }} />
62 <div
63 className="user-bar"
64 style={{
65 position: "fixed",
66 top: 18,
67 right: 42,
68 zIndex: 100,
69 display: "flex",
70 alignItems: "center",
71 background: "#e0f3ff",
72 borderRadius: 12,
73 padding: "6px 18px",
74 boxShadow: "0 2px 8px #b2d8ea",
75 minWidth: 320,
76 minHeight: 48,
77 width: 420,
78 }}
79 >
80 <div
81 style={{ cursor: "pointer", marginRight: 16 }}
82 onClick={() => navigate("/user")}
83 >
84 <AccountCircleIcon
85 style={{
86 fontSize: 38,
87 color: "#1a237e",
88 background: "#e0f3ff",
89 borderRadius: "50%",
90 }}
91 />
92 </div>
93 <div style={{ color: "#222", fontWeight: 500, marginRight: 24 }}>
94 用户栏
95 </div>
96 <div
97 style={{
98 display: "flex",
99 gap: 28,
100 flex: 1,
101 justifyContent: "flex-end",
102 alignItems: "center",
103 }}
104 >
105 <span style={{ color: "#1976d2", fontWeight: 500 }}>
106 魔力值: <b>12345</b>
107 </span>
108 <span style={{ color: "#1976d2", fontWeight: 500 }}>
109 分享率: <b>2.56</b>
110 </span>
111 <span style={{ color: "#1976d2", fontWeight: 500 }}>
112 上传量: <b>100GB</b>
113 </span>
114 <span style={{ color: "#1976d2", fontWeight: 500 }}>
115 下载量: <b>50GB</b>
116 </span>
117 </div>
118 </div>
119 {/* 下方内容整体下移,留出与音乐界面一致的间距 */}
120 <div style={{ height: 32 }} />
121 <nav className="nav-bar card">
122 {navItems.map((item) => (
123 <div
124 key={item.label}
125 className={item.label === "游戏" ? "nav-item active" : "nav-item"}
126 onClick={() => navigate(item.path)}
127 >
128 {item.icon}
129 <span>{item.label}</span>
130 </div>
131 ))}
132 </nav>
133 <div className="search-section card">
134 <input className="search-input" placeholder="输入搜索关键词" />
135 <button className="search-btn">
136 <span role="img" aria-label="search">
137 🔍
138 </span>
139 </button>
140 </div>
141 <div
142 className="area-tabs"
143 style={{
144 display: "flex",
145 justifyContent: "center",
146 gap: 24,
147 margin: "18px 0",
148 }}
149 >
150 {areaTabs.map((tab, idx) => (
151 <div
152 key={tab.label}
153 className={activeTab === idx ? "area-tab active" : "area-tab"}
154 onClick={() => setActiveTab(idx)}
155 >
156 {tab.icon} <span>{tab.label}</span>
157 </div>
158 ))}
159 </div>
160 <div className="table-section">
9563036699e95ae32025-06-02 21:42:11 +0800161 <table className="game-table">
956303669a32fc2c2025-06-02 19:45:53 +0800162 <thead>
163 <tr>
164 <th>游戏类型</th>
165 <th>标题</th>
166 <th>发布者</th>
167 </tr>
168 </thead>
169 <tbody>
rhjc6a4ee02025-06-06 00:45:18 +0800170 {gameList.length > 0 ? (
171 gameList.map((item, idx) => (
172 <tr key={item.id || idx}>
173 <td>
174 <a href={`/torrent/${item.seedid}`} style={{ color: "#1a237e", textDecoration: "none" }}>
175 {item.seedtag}
176 </a>
177 </td>
178 <td>
179 <a href={`/torrent/${item.seedid}`} style={{ color: "#1a237e", textDecoration: "none" }}>
180 {item.title}
181 </a>
182 </td>
183 <td>{item.user.username}</td>
184 </tr>
185 ))
186 ) : (
187 gameTypes.map((type, idx) => (
188 <tr key={type}>
189 <td>
190 <a href={`/torrent/${type}`} style={{ color: "#1a237e", textDecoration: "none" }}>
191 {type}
192 </a>
193 </td>
194 <td>
195 <a href={`/torrent/${type}`} style={{ color: "#1a237e", textDecoration: "none" }}>
196 种子{idx + 1}
197 </a>
198 </td>
199 <td></td>
200 </tr>
201 ))
202 )}
956303669a32fc2c2025-06-02 19:45:53 +0800203 </tbody>
204 </table>
205 </div>
206 <div style={{ height: 32 }} />
207 <Pagination />
208 </div>
209 );
210}
211
212function Pagination() {
213 const [page, setPage] = React.useState(3);
214 const total = 5;
215 return (
216 <div className="pagination">
217 <button
218 onClick={() => setPage((p) => Math.max(1, p - 1))}
219 disabled={page === 1}
220 >
221 上一页
222 </button>
223 <span className="page-num">
224 {page}/{total}
225 </span>
226 <button
227 onClick={() => setPage((p) => Math.min(total, p + 1))}
228 disabled={page === total}
229 >
230 下一页
231 </button>
232 <span className="page-info">
233 <b>{page}</b>
234 </span>
235 </div>
236 );
237}