blob: 2d6a3a51d5b9e554f17205de429a00e28fa50189 [file] [log] [blame]
223011339e292152025-06-08 00:34:37 +08001import React, { useState, useEffect } from "react";
wht338fc032025-06-09 17:16:22 +08002import HomeIcon from "@mui/icons-material/Home";
956303669a32fc2c2025-06-02 19:45:53 +08003import MovieIcon from "@mui/icons-material/Movie";
TRM-codingfa3ffdf2025-06-09 22:47:42 +08004import TvIcon from "@mui/icons-material/Tv";
956303669a32fc2c2025-06-02 19:45:53 +08005import MusicNoteIcon from "@mui/icons-material/MusicNote";
TRM-codingfa3ffdf2025-06-09 22:47:42 +08006import AnimationIcon from "@mui/icons-material/Animation";
956303669a32fc2c2025-06-02 19:45:53 +08007import SportsEsportsIcon from "@mui/icons-material/SportsEsports";
8import SportsMartialArtsIcon from "@mui/icons-material/SportsMartialArts";
9import PersonIcon from "@mui/icons-material/Person";
10import AccountCircleIcon from "@mui/icons-material/AccountCircle";
wht338fc032025-06-09 17:16:22 +080011import ForumIcon from "@mui/icons-material/Forum";
12import HelpIcon from "@mui/icons-material/Help";
TRM-codingfa3ffdf2025-06-09 22:47:42 +080013import "./SharedStyles.css";
wht338fc032025-06-09 17:16:22 +080014import { useNavigate } from "react-router-dom";
223011330f9623f2025-06-06 00:22:05 +080015import { API_BASE_URL } from "./config";
956303669a32fc2c2025-06-02 19:45:53 +080016
17const navItems = [
TRM-codingfa3ffdf2025-06-09 22:47:42 +080018 { label: "首页", icon: <HomeIcon className="emerald-nav-icon" />, path: "/home", type: "home" },
19 { label: "电影", icon: <MovieIcon className="emerald-nav-icon" />, path: "/movie", type: "movie" },
20 { label: "剧集", icon: <TvIcon className="emerald-nav-icon" />, path: "/tv", type: "tv" },
21 { label: "音乐", icon: <MusicNoteIcon className="emerald-nav-icon" />, path: "/music", type: "music" },
22 { label: "动漫", icon: <AnimationIcon className="emerald-nav-icon" />, path: "/anime", type: "anime" },
23 { label: "游戏", icon: <SportsEsportsIcon className="emerald-nav-icon" />, path: "/game", type: "game" },
24 { label: "体育", icon: <SportsMartialArtsIcon className="emerald-nav-icon" />, path: "/sport", type: "sport" },
25 { label: "资料", icon: <PersonIcon className="emerald-nav-icon" />, path: "/info", type: "info" },
26 { label: "论坛", icon: <ForumIcon className="emerald-nav-icon" />, path: "/forum", type: "forum" },
27 { label: "发布", icon: <AccountCircleIcon className="emerald-nav-icon" />, path: "/publish", type: "publish" },
28 { label: "求种", icon: <HelpIcon className="emerald-nav-icon" />, path: "/begseed", type: "help" },
956303669a32fc2c2025-06-02 19:45:53 +080029];
30
TRM-codingfa3ffdf2025-06-09 22:47:42 +080031// 剧集地区标签
956303669a32fc2c2025-06-02 19:45:53 +080032const areaTabs = [
TRM-codingfa3ffdf2025-06-09 22:47:42 +080033 { label: "华语剧集", value: "chinese" },
34 { label: "港台剧集", value: "hk_tw" },
35 { label: "欧美剧集", value: "western" },
36 { label: "日韩剧集", value: "jp_kr" },
37 { label: "其他剧集", value: "others" }
9563036699e95ae32025-06-02 21:42:11 +080038];
39
956303669a32fc2c2025-06-02 19:45:53 +080040export default function TVPage() {
41 const navigate = useNavigate();
223011339e292152025-06-08 00:34:37 +080042 const [searchText, setSearchText] = React.useState('');
wht338fc032025-06-09 17:16:22 +080043 const [userInfo, setUserInfo] = useState({ avatar_url: '', username: '' });
44 const [userPT, setUserPT] = useState({ magic: 0, ratio: 0, upload: 0, download: 0 });
956303669a32fc2c2025-06-02 19:45:53 +080045 const [activeTab, setActiveTab] = React.useState(0);
rhjc6a4ee02025-06-06 00:45:18 +080046 const [tvList, setTvList] = React.useState([]);
47
wht338fc032025-06-09 17:16:22 +080048 useEffect(() => {
49 const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
50 const userId = match ? match[2] : null;
51 if (!userId) return;
52 fetch(`${API_BASE_URL}/api/get-userpt?userid=${encodeURIComponent(userId)}`)
53 .then(res => res.json())
54 .then(data => {
55 setUserInfo({ avatar_url: data.user.avatar_url, username: data.user.username });
56 setUserPT({
57 magic: data.magic_value || data.magic || 0,
58 ratio: data.share_ratio || data.share || 0,
59 upload: data.upload_amount || data.upload || 0,
60 download: data.download_amount || data.download || 0,
61 });
62 })
63 .catch(err => console.error('Fetching user profile failed', err));
64 }, []);
223011339e292152025-06-08 00:34:37 +080065
rhjc6a4ee02025-06-06 00:45:18 +080066 React.useEffect(() => {
67 // 假设后端接口为 /api/tvs?area=大陆
68 const area = areaTabs[activeTab].label;
223011330f9623f2025-06-06 00:22:05 +080069 fetch(`${API_BASE_URL}/api/get-seed-list-by-tag?tag=${encodeURIComponent(area)}`)
rhjc6a4ee02025-06-06 00:45:18 +080070 .then(res => res.json())
71 .then(data => setTvList(data))
72 .catch(() => setTvList([]));
73 }, [activeTab]);
956303669a32fc2c2025-06-02 19:45:53 +080074
wht338fc032025-06-09 17:16:22 +080075 // 搜索按钮处理
76 const handleSearch = () => {
77 const area = areaTabs[activeTab].label;
78 fetch(`${API_BASE_URL}/api/search-seeds?tag=${encodeURIComponent(area)}&keyword=${encodeURIComponent(searchText)}`)
79 .then(res => res.json())
80 .then(data => {
81 console.log('搜索返回数据:', data);
82 setTvList(data);
83 })
84 .catch(() => setTvList([]));
85 };
223011339e292152025-06-08 00:34:37 +080086
wht338fc032025-06-09 17:16:22 +080087 const tvTypesList = [
88 ["华语剧集(大陆)", "欧美剧集", "日韩剧集", "港台剧集", "其他"], // 大陆
89 ["港台都市", "港台爱情", "港台悬疑", "港台其他"], // 港台
90 ["欧美悬疑", "欧美历史", "欧美其他"], // 欧美
91 ["日韩青春", "日韩家庭", "日韩其他"], // 日韩
92 ["其他类型1", "其他类型2"] // 其他
93 ];
956303669a32fc2c2025-06-02 19:45:53 +080094 const tvTypes = tvTypesList[activeTab] || [];
956303669a32fc2c2025-06-02 19:45:53 +080095 return (
TRM-codingfa3ffdf2025-06-09 22:47:42 +080096 <div className="emerald-home-container">
97 {/* 流星雨背景效果 */}
98 <div className="meteor-shower">
99 <div className="meteor">💫</div>
100 <div className="meteor">⭐</div>
101 <div className="meteor">✨</div>
102 <div className="meteor">🌟</div>
103 <div className="meteor">💫</div>
104 <div className="meteor">⭐</div>
105 <div className="meteor">✨</div>
106 <div className="meteor">🌟</div>
107 <div className="meteor">💫</div>
108 <div className="meteor">⭐</div>
956303669a32fc2c2025-06-02 19:45:53 +0800109 </div>
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800110
111 {/* 浮动园林装饰元素 */}
112 <div className="floating-garden-elements">
113 <div className="garden-element">🌿</div>
114 <div className="garden-element">🦋</div>
115 <div className="garden-element">🌺</div>
116 <div className="garden-element">🌸</div>
956303669a32fc2c2025-06-02 19:45:53 +0800117 </div>
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800118
119 <div className="emerald-content">
120 {/* NeuraFlux用户栏 */}
121 <div className="emerald-user-bar">
122 <div className="emerald-user-avatar" onClick={() => navigate('/user')}>
123 {userInfo.avatar_url ? (
124 <img src={userInfo.avatar_url} alt="用户头像" style={{ width: 38, height: 38, borderRadius: '50%', objectFit: 'cover' }} />
rhjc6a4ee02025-06-06 00:45:18 +0800125 ) : (
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800126 <AccountCircleIcon style={{ fontSize: 38, color: 'white' }} />
rhjc6a4ee02025-06-06 00:45:18 +0800127 )}
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800128 </div>
129 <div className="emerald-brand-section">
130 <div className="emerald-brand-icon">⚡</div>
131 <div className="emerald-user-label">NeuraFlux</div>
132 </div>
133 <div className="emerald-user-stats">
134 <span className="emerald-stat-item">
135 魔力值: <span className="emerald-stat-value">{userPT.magic}</span>
136 </span>
137 <span className="emerald-stat-item">
138 分享率: <span className="emerald-stat-value">{userPT.ratio}</span>
139 </span>
140 <span className="emerald-stat-item">
141 上传: <span className="emerald-stat-value">{userPT.upload}GB</span>
142 </span>
143 <span className="emerald-stat-item">
144 下载: <span className="emerald-stat-value">{userPT.download}GB</span>
145 </span>
146 </div>
147 </div> {/* NeuraFlux导航栏 */}
148 <nav className="emerald-nav-bar">
149 {navItems.map((item) => (
150 <div
151 key={item.label}
152 className={`emerald-nav-item ${item.label === "剧集" ? "active" : ""}`}
153 data-type={item.type}
154 onClick={() => navigate(item.path)}
155 >
156 {item.icon}
157 <span className="emerald-nav-label">{item.label}</span>
158 </div>
159 ))}
160 </nav>
161
162 {/* 剧集内容区域 */}
163 <div className="emerald-content-section">
164 <h1 className="emerald-page-title">📺 剧集资源</h1>
165 <p style={{ textAlign: 'center', color: '#2d5016', fontSize: '18px', marginBottom: '30px' }}>
166 欢迎来到NeuraFlux剧集频道,这里有最新最热门的电视剧、综艺、纪录片资源
167 </p>
168
169 {/* 搜索栏 */}
170 <div style={{
171 display: 'flex',
172 justifyContent: 'center',
173 marginBottom: '30px',
174 gap: '15px'
175 }}>
176 <input
177 type="text"
178 placeholder="搜索剧集资源..."
179 value={searchText}
180 onChange={(e) => setSearchText(e.target.value)}
181 style={{
182 padding: '12px 20px',
183 borderRadius: '20px',
184 border: '2px solid rgba(144, 238, 144, 0.3)',
185 background: 'rgba(240, 255, 240, 0.5)',
186 fontSize: '16px',
187 width: '300px',
188 fontFamily: 'Lora, serif'
189 }}
190 />
191 <button
192 onClick={handleSearch}
193 style={{
194 padding: '12px 24px',
195 borderRadius: '20px',
196 border: 'none',
197 background: 'linear-gradient(135deg, #2d5016 0%, #90ee90 100%)',
198 color: 'white',
199 fontSize: '16px',
200 cursor: 'pointer',
201 fontFamily: 'Lora, serif'
202 }}
203 >
204 搜索
205 </button>
206 </div> {/* 地区分类标签 */}
207 <div style={{
208 display: 'flex',
209 justifyContent: 'center',
210 marginBottom: '30px',
211 gap: '15px',
212 flexWrap: 'wrap'
213 }}>
214 {areaTabs.map((tab, index) => (
215 <button
216 key={tab.value}
217 onClick={() => setActiveTab(index)}
218 style={{
219 padding: '10px 20px',
220 borderRadius: '15px',
221 border: '2px solid rgba(144, 238, 144, 0.3)',
222 background: activeTab === index
223 ? 'linear-gradient(135deg, #90ee90 0%, #2d5016 100%)'
224 : 'rgba(240, 255, 240, 0.3)',
225 color: activeTab === index ? 'white' : '#2d5016',
226 fontSize: '14px',
227 cursor: 'pointer',
228 fontFamily: 'Lora, serif',
229 transition: 'all 0.3s ease'
230 }}
231 >
232 {tab.label}
233 </button>
234 ))}
235 </div>
236
237 {/* 剧集列表 */}
238 <div className="emerald-table-section">
239 <table className="emerald-table">
240 <thead>
241 <tr>
242 <th>剧集类型</th>
243 <th>标题</th>
244 <th>发布者</th>
245 <th>大小</th>
246 <th>热度</th>
247 <th>折扣倍率</th>
248 </tr>
249 </thead>
250 <tbody>
251 {tvList.length > 0 ? (
252 tvList.map((item, index) => (
253 <tr key={item.id || index}>
254 <td>{item.seedtag}</td>
255 <td>
256 <a href={`/torrent/${item.seedid}`}>
257 {item.title}
258 </a>
259 </td>
260 <td>{item.username}</td>
261 <td>{item.seedsize}</td>
262 <td>{item.downloadtimes}</td>
263 <td>{item.discount == null ? 1 : item.discount}</td>
264 </tr>
265 ))
266 ) : (
267 tvTypes.map((type, index) => (
268 <tr key={type}>
269 <td>{type}</td>
270 <td>
271 <a href={`/torrent/${type}`}>
272 种子{index + 1}
273 </a>
274 </td>
275 <td>发布者{index + 1}</td>
276 <td>--</td>
277 <td>--</td>
278 <td>1</td>
279 </tr>
280 ))
281 )}
282 </tbody>
283 </table>
284 </div>
285 </div>
956303669a32fc2c2025-06-02 19:45:53 +0800286 </div>
956303669a32fc2c2025-06-02 19:45:53 +0800287 </div>
288 );
289}
290
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800291// Pagination组件暂时不使用
956303669a32fc2c2025-06-02 19:45:53 +0800292function Pagination() {
293 const [page, setPage] = React.useState(3);
294 const total = 5;
295 return (
296 <div className="pagination">
297 <button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page === 1}>上一页</button>
298 <span className="page-num">{page}/{total}</span>
299 <button onClick={() => setPage(p => Math.min(total, p + 1))} disabled={page === total}>下一页</button>
300 <span className="page-info">第 <b>{page}</b> 页</span>
301 </div>
302 );
303}