Dashboard.tsx 8.3 KB

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