2
0

Dashboard.tsx 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import { useNavigate } from 'react-router';
  2. import { Users, Bell, Eye, TrendingUp, TrendingDown, Activity } from 'lucide-react';
  3. import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/client/components/ui/card';
  4. import { Progress } from '@/client/components/ui/progress';
  5. // 仪表盘页面
  6. export const DashboardPage = () => {
  7. const navigate = useNavigate();
  8. const stats = [
  9. {
  10. title: '活跃用户',
  11. value: '112,893',
  12. icon: Users,
  13. color: 'text-blue-500',
  14. bgColor: 'bg-blue-50',
  15. trend: 12.5,
  16. trendDirection: 'up',
  17. description: '较昨日增长 12.5%',
  18. },
  19. {
  20. title: '系统消息',
  21. value: '93',
  22. icon: Bell,
  23. color: 'text-yellow-500',
  24. bgColor: 'bg-yellow-50',
  25. trend: 0,
  26. trendDirection: 'neutral',
  27. description: '其中 5 条未读',
  28. },
  29. {
  30. title: '在线用户',
  31. value: '1,128',
  32. icon: Eye,
  33. color: 'text-purple-500',
  34. bgColor: 'bg-purple-50',
  35. trend: 32.1,
  36. trendDirection: 'up',
  37. description: '当前在线率 32.1%',
  38. },
  39. ];
  40. const recentActivities = [
  41. {
  42. id: 1,
  43. user: '张三',
  44. action: '登录系统',
  45. time: '2分钟前',
  46. status: 'success',
  47. },
  48. {
  49. id: 2,
  50. user: '李四',
  51. action: '创建了新用户',
  52. time: '5分钟前',
  53. status: 'info',
  54. },
  55. {
  56. id: 3,
  57. user: '王五',
  58. action: '删除了用户',
  59. time: '10分钟前',
  60. status: 'warning',
  61. },
  62. {
  63. id: 4,
  64. user: '赵六',
  65. action: '修改了配置',
  66. time: '15分钟前',
  67. status: 'info',
  68. },
  69. ];
  70. const systemMetrics = [
  71. {
  72. name: 'CPU使用率',
  73. value: 65,
  74. color: 'bg-green-500',
  75. },
  76. {
  77. name: '内存使用率',
  78. value: 78,
  79. color: 'bg-blue-500',
  80. },
  81. {
  82. name: '磁盘使用率',
  83. value: 45,
  84. color: 'bg-purple-500',
  85. },
  86. {
  87. name: '网络使用率',
  88. value: 32,
  89. color: 'bg-orange-500',
  90. },
  91. ];
  92. const handleQuickActionClick = (action: string) => {
  93. switch (action) {
  94. case 'users':
  95. navigate('/admin/users');
  96. break;
  97. case 'settings':
  98. navigate('/admin/settings');
  99. break;
  100. case 'backup':
  101. navigate('/admin/backup');
  102. break;
  103. case 'logs':
  104. navigate('/admin/logs');
  105. break;
  106. default:
  107. break;
  108. }
  109. };
  110. return (
  111. <div className="space-y-6">
  112. <div>
  113. <h1 className="text-3xl font-bold tracking-tight">仪表盘</h1>
  114. <p className="text-muted-foreground">
  115. 欢迎回来!这里是系统概览和关键指标。
  116. </p>
  117. </div>
  118. {/* 统计卡片 */}
  119. <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
  120. {stats.map((stat, index) => {
  121. const Icon = stat.icon;
  122. return (
  123. <Card key={index} className="transition-all duration-300 hover:shadow-lg">
  124. <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
  125. <CardTitle className="text-sm font-medium">
  126. {stat.title}
  127. </CardTitle>
  128. <div className={`p-2 rounded-full ${stat.bgColor}`}>
  129. <Icon className={`h-4 w-4 ${stat.color}`} />
  130. </div>
  131. </CardHeader>
  132. <CardContent>
  133. <div className="text-2xl font-bold">{stat.value}</div>
  134. <div className="flex items-center space-x-2">
  135. {stat.trendDirection === 'up' && (
  136. <TrendingUp className="h-4 w-4 text-green-500" />
  137. )}
  138. {stat.trendDirection === 'down' && (
  139. <TrendingDown className="h-4 w-4 text-red-500" />
  140. )}
  141. <p className="text-xs text-muted-foreground">{stat.description}</p>
  142. </div>
  143. </CardContent>
  144. </Card>
  145. );
  146. })}
  147. </div>
  148. <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-7">
  149. {/* 系统性能 */}
  150. <Card className="lg:col-span-4">
  151. <CardHeader>
  152. <CardTitle>系统性能</CardTitle>
  153. <CardDescription>
  154. 当前系统各项资源的使用情况
  155. </CardDescription>
  156. </CardHeader>
  157. <CardContent>
  158. <div className="space-y-4">
  159. {systemMetrics.map((metric, index) => (
  160. <div key={index} className="space-y-2">
  161. <div className="flex justify-between text-sm">
  162. <span className="font-medium">{metric.name}</span>
  163. <span className="text-muted-foreground">{metric.value}%</span>
  164. </div>
  165. <Progress value={metric.value} className="h-2" />
  166. </div>
  167. ))}
  168. </div>
  169. </CardContent>
  170. </Card>
  171. {/* 最近活动 */}
  172. <Card className="lg:col-span-3">
  173. <CardHeader>
  174. <CardTitle>最近活动</CardTitle>
  175. <CardDescription>
  176. 系统最新操作记录
  177. </CardDescription>
  178. </CardHeader>
  179. <CardContent>
  180. <div className="space-y-4">
  181. {recentActivities.map((activity) => (
  182. <div key={activity.id} className="flex items-center space-x-4">
  183. <div className="flex-shrink-0">
  184. <div className={`p-2 rounded-full ${
  185. activity.status === 'success' ? 'bg-green-100' :
  186. activity.status === 'warning' ? 'bg-yellow-100' : 'bg-blue-100'
  187. }`}>
  188. <Activity className={`h-4 w-4 ${
  189. activity.status === 'success' ? 'text-green-600' :
  190. activity.status === 'warning' ? 'text-yellow-600' : 'text-blue-600'
  191. }`} />
  192. </div>
  193. </div>
  194. <div className="flex-1 space-y-1">
  195. <p className="text-sm font-medium">
  196. {activity.user} {activity.action}
  197. </p>
  198. <p className="text-sm text-muted-foreground">
  199. {activity.time}
  200. </p>
  201. </div>
  202. </div>
  203. ))}
  204. </div>
  205. </CardContent>
  206. </Card>
  207. </div>
  208. {/* 快捷操作 */}
  209. <Card>
  210. <CardHeader>
  211. <CardTitle>快捷操作</CardTitle>
  212. <CardDescription>
  213. 常用的管理功能
  214. </CardDescription>
  215. </CardHeader>
  216. <CardContent>
  217. <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
  218. <Card
  219. className="hover:shadow-md transition-all cursor-pointer"
  220. onClick={() => handleQuickActionClick('users')}
  221. >
  222. <CardHeader className="pb-3">
  223. <CardTitle className="text-base">用户管理</CardTitle>
  224. <CardDescription>查看和管理所有用户</CardDescription>
  225. </CardHeader>
  226. </Card>
  227. <Card
  228. className="hover:shadow-md transition-all cursor-pointer"
  229. onClick={() => handleQuickActionClick('settings')}
  230. >
  231. <CardHeader className="pb-3">
  232. <CardTitle className="text-base">系统设置</CardTitle>
  233. <CardDescription>配置系统参数</CardDescription>
  234. </CardHeader>
  235. </Card>
  236. <Card
  237. className="hover:shadow-md transition-all cursor-pointer"
  238. onClick={() => handleQuickActionClick('backup')}
  239. >
  240. <CardHeader className="pb-3">
  241. <CardTitle className="text-base">数据备份</CardTitle>
  242. <CardDescription>执行数据备份操作</CardDescription>
  243. </CardHeader>
  244. </Card>
  245. <Card
  246. className="hover:shadow-md transition-all cursor-pointer"
  247. onClick={() => handleQuickActionClick('logs')}
  248. >
  249. <CardHeader className="pb-3">
  250. <CardTitle className="text-base">日志查看</CardTitle>
  251. <CardDescription>查看系统日志</CardDescription>
  252. </CardHeader>
  253. </Card>
  254. </div>
  255. </CardContent>
  256. </Card>
  257. </div>
  258. );
  259. };