blob: 1764f5c498f577837f4e49cc29940d989c08fdb1 [file] [log] [blame]
ZBD7e88c222025-05-07 21:07:12 +08001// src/pages/Home.jsx
2import React, { useState, useEffect } from 'react';
3import {
4 Table, TableHead, TableRow, TableCell, TableBody,
5 Typography, Box, Container, Paper, Tooltip, IconButton, Chip
6} from '@mui/material';
7import DownloadIcon from '@mui/icons-material/Download';
8import StarBorderIcon from '@mui/icons-material/StarBorder';
9
10function Home() {
11 const [torrents, setTorrents] = useState([]);
12
13 useEffect(() => {
14 setTorrents([
15 { title: 'Ubuntu 22.04 LTS', size: '3.2 GB', seeders: 1200, leechers: 300, date: '2025-04-01', tags: ['Linux', 'ISO'] },
16 { title: 'LibreOffice 7.5.2', size: '320 MB', seeders: 450, leechers: 50, date: '2025-03-28', tags: ['办公'] },
17 { title: 'Movie.Title.1080p.BluRay', size: '2.5 GB', seeders: 900, leechers: 200, date: '2025-04-05', tags: ['电影', '高清'] },
18 ]);
19 }, []);
20
21 return (
22 <Box sx={styles.mainContainer}>
23 <Container maxWidth="lg">
24 <Typography variant="h4" sx={styles.title}>
25 🎬 资源列表 · Mini-Tracker
26 </Typography>
27
28 <Paper sx={styles.paper}>
29 <Table size="small">
30 <TableHead>
31 <TableRow>
32 <TableCell sx={styles.header}>名称</TableCell>
33 <TableCell sx={styles.header}>标签</TableCell>
34 <TableCell sx={styles.header}>大小</TableCell>
35 <TableCell sx={styles.header}>做种者</TableCell>
36 <TableCell sx={styles.header}>下载者</TableCell>
37 <TableCell sx={styles.header}>上传时间</TableCell>
38 <TableCell sx={styles.header}>操作</TableCell>
39 </TableRow>
40 </TableHead>
41 <TableBody>
42 {torrents.map((t, i) => (
43 <TableRow key={i} sx={styles.row}>
44 <TableCell sx={styles.cell}>{t.title}</TableCell>
45 <TableCell sx={styles.cell}>
46 {t.tags.map(tag => (
47 <Chip key={tag} label={tag} size="small" sx={styles.chip} />
48 ))}
49 </TableCell>
50 <TableCell sx={styles.cell}>{t.size}</TableCell>
51 <TableCell sx={styles.cell}>{t.seeders}</TableCell>
52 <TableCell sx={styles.cell}>{t.leechers}</TableCell>
53 <TableCell sx={styles.cell}>{t.date}</TableCell>
54 <TableCell sx={styles.cell}>
55 <Tooltip title="下载种子">
56 <IconButton color="success" size="small">
57 <DownloadIcon fontSize="small" />
58 </IconButton>
59 </Tooltip>
60 <Tooltip title="收藏">
61 <IconButton color="warning" size="small">
62 <StarBorderIcon fontSize="small" />
63 </IconButton>
64 </Tooltip>
65 </TableCell>
66 </TableRow>
67 ))}
68 </TableBody>
69 </Table>
70 </Paper>
71 </Container>
72
73 {/* 柔和深蓝渐变背景 */}
74 <div style={styles.background}></div>
75
76 {/* 舒缓漂浮的柔和粒子 */}
77 <div style={styles.bubbles}>
78 {[...Array(40)].map((_, i) => (
79 <div key={i} style={{ ...styles.bubble, ...bubbleAnimation(i) }} />
80 ))}
81 </div>
82
83 {/* 动画 Keyframes */}
84 <style>{animationCSS}</style>
85 </Box>
86 );
87}
88
89export default Home;
90
91// 样式对象
92const styles = {
93 mainContainer: {
94 minHeight: '100vh',
95 bgcolor: '#0d1b2a',
96 color: '#e0e0e0',
97 py: 5,
98 position: 'relative',
99 overflow: 'hidden',
100 },
101 title: {
102 mb: 3,
103 fontFamily: '"Fira Code", monospace',
104 color: '#a3cef1',
105 textAlign: 'center',
106 fontSize: '2rem',
107 fontWeight: 'bold',
108 },
109 paper: {
110 bgcolor: '#1b263b',
111 p: 2,
112 borderRadius: 3,
113 boxShadow: 3,
114 backdropFilter: 'blur(6px)',
115 border: '1px solid rgba(255, 255, 255, 0.08)',
116 },
117 header: {
118 fontWeight: 'bold',
119 color: '#b0ccee',
120 fontFamily: '"Fira Code", monospace',
121 borderBottom: '1px solid #3a4a6b',
122 },
123 cell: {
124 fontFamily: '"Fira Code", monospace',
125 color: '#e0e0e0',
126 fontSize: '0.85rem',
127 padding: '8px 12px',
128 },
129 chip: {
130 mr: 0.5,
131 backgroundColor: '#2e3b53',
132 color: '#81c784',
133 fontSize: '0.75rem',
134 },
135 row: {
136 '&:nth-of-type(odd)': { bgcolor: '#19263e' },
137 '&:hover': { bgcolor: '#26354f' },
138 },
139 background: {
140 position: 'absolute',
141 top: 0, left: 0,
142 width: '100%', height: '100%',
143 background: 'linear-gradient(45deg, #0d1b2a, #122b44, rgb(28, 102, 158))',
144 backgroundSize: '400% 400%',
145 animation: 'bgShift 30s ease infinite',
146 zIndex: -1,
147 },
148 bubbles: {
149 position: 'absolute',
150 top: 0, left: 0,
151 width: '100%', height: '100%',
152 zIndex: 0,
153 overflow: 'hidden',
154 },
155 bubble: {
156 position: 'absolute',
157 width: '6px',
158 height: '6px',
159 borderRadius: '50%',
160 backgroundColor: 'rgba(163, 206, 241, 0.4)',
161 animation: 'bubbleFloat 8s ease-in-out infinite',
162 },
163};
164
165const animationCSS = `
166@keyframes bgShift {
167 0% { background-position: 0% 50%; }
168 50% { background-position: 100% 50%; }
169 100% { background-position: 0% 50%; }
170}
171@keyframes bubbleFloat {
172 0% { transform: translateY(100%); opacity: 0; }
173 50% { opacity: 0.5; }
174 100% { transform: translateY(-100%); opacity: 0; }
175}
176`;
177
178function bubbleAnimation(i) {
179 const delay = Math.random() * 6;
180 const left = Math.random() * 100;
181 const size = 4 + Math.random() * 8;
182 const top = Math.random() * 100;
183 return {
184 left: `${left}%`,
185 top: `${top}%`,
186 width: `${size}px`,
187 height: `${size}px`,
188 animationDelay: `${delay}s`,
189 };
190}