Ver código fonte

✨ feat(dashboard): 实现快捷操作卡片导航功能

- 添加快捷操作卡片点击事件处理函数,支持跳转到对应管理页面
- 为每个快捷操作卡片添加导航链接:用户管理→/admin/users,系统设置→/admin/settings,数据备份→/admin/backup,日志查看→/admin/logs

✅ test(dashboard): 添加快捷操作导航测试用例

- 验证快捷操作卡片存在性和可点击性
- 测试各快捷操作卡片的导航跳转功能
- 验证所有快捷操作卡片描述文本正确显示
yourname 2 meses atrás
pai
commit
e1ad6f0d1c

+ 45 - 0
src/client/__integration_tests__/admin/dashboard.test.tsx

@@ -121,4 +121,49 @@ describe('DashboardPage 集成测试', () => {
     const progressElements = document.querySelectorAll('[role="progressbar"]');
     expect(progressElements.length).toBeGreaterThan(0);
   });
+
+  it('应该正确处理快捷操作导航', async () => {
+    const user = userEvent.setup();
+    render(<DashboardPage />);
+
+    // 验证快捷操作卡片存在
+    expect(screen.getByText('用户管理')).toBeInTheDocument();
+    expect(screen.getByText('系统设置')).toBeInTheDocument();
+    expect(screen.getByText('数据备份')).toBeInTheDocument();
+    expect(screen.getByText('日志查看')).toBeInTheDocument();
+
+    // 点击用户管理卡片
+    const userManagementCard = screen.getByText('用户管理').closest('.cursor-pointer');
+    await user.click(userManagementCard!);
+    expect(mockNavigate).toHaveBeenCalledWith('/admin/users');
+
+    // 点击系统设置卡片
+    const settingsCard = screen.getByText('系统设置').closest('.cursor-pointer');
+    await user.click(settingsCard!);
+    expect(mockNavigate).toHaveBeenCalledWith('/admin/settings');
+
+    // 点击数据备份卡片
+    const backupCard = screen.getByText('数据备份').closest('.cursor-pointer');
+    await user.click(backupCard!);
+    expect(mockNavigate).toHaveBeenCalledWith('/admin/backup');
+
+    // 点击日志查看卡片
+    const logsCard = screen.getByText('日志查看').closest('.cursor-pointer');
+    await user.click(logsCard!);
+    expect(mockNavigate).toHaveBeenCalledWith('/admin/logs');
+  });
+
+  it('应该正确渲染所有导航元素', async () => {
+    render(<DashboardPage />);
+
+    // 验证所有快捷操作卡片都包含正确的描述
+    expect(screen.getByText('查看和管理所有用户')).toBeInTheDocument();
+    expect(screen.getByText('配置系统参数')).toBeInTheDocument();
+    expect(screen.getByText('执行数据备份操作')).toBeInTheDocument();
+    expect(screen.getByText('查看系统日志')).toBeInTheDocument();
+
+    // 验证所有快捷操作卡片都存在
+    const quickActionCards = screen.getAllByText(/用户管理|系统设置|数据备份|日志查看/);
+    expect(quickActionCards.length).toBe(4); // 4个快捷操作卡片
+  });
 });

+ 37 - 4
src/client/admin/pages/Dashboard.tsx

@@ -1,4 +1,5 @@
 import React from 'react';
+import { useNavigate } from 'react-router';
 import { Users, Bell, Eye, TrendingUp, TrendingDown, Activity } from 'lucide-react';
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/client/components/ui/card';
 import { Badge } from '@/client/components/ui/badge';
@@ -6,6 +7,7 @@ import { Progress } from '@/client/components/ui/progress';
 
 // 仪表盘页面
 export const DashboardPage = () => {
+  const navigate = useNavigate();
   const stats = [
     {
       title: '活跃用户',
@@ -93,6 +95,25 @@ export const DashboardPage = () => {
     },
   ];
 
+  const handleQuickActionClick = (action: string) => {
+    switch (action) {
+      case 'users':
+        navigate('/admin/users');
+        break;
+      case 'settings':
+        navigate('/admin/settings');
+        break;
+      case 'backup':
+        navigate('/admin/backup');
+        break;
+      case 'logs':
+        navigate('/admin/logs');
+        break;
+      default:
+        break;
+    }
+  };
+
   return (
     <div className="space-y-6">
       <div>
@@ -205,25 +226,37 @@ export const DashboardPage = () => {
         </CardHeader>
         <CardContent>
           <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
-            <Card className="hover:shadow-md transition-all cursor-pointer">
+            <Card
+              className="hover:shadow-md transition-all cursor-pointer"
+              onClick={() => handleQuickActionClick('users')}
+            >
               <CardHeader className="pb-3">
                 <CardTitle className="text-base">用户管理</CardTitle>
                 <CardDescription>查看和管理所有用户</CardDescription>
               </CardHeader>
             </Card>
-            <Card className="hover:shadow-md transition-all cursor-pointer">
+            <Card
+              className="hover:shadow-md transition-all cursor-pointer"
+              onClick={() => handleQuickActionClick('settings')}
+            >
               <CardHeader className="pb-3">
                 <CardTitle className="text-base">系统设置</CardTitle>
                 <CardDescription>配置系统参数</CardDescription>
               </CardHeader>
             </Card>
-            <Card className="hover:shadow-md transition-all cursor-pointer">
+            <Card
+              className="hover:shadow-md transition-all cursor-pointer"
+              onClick={() => handleQuickActionClick('backup')}
+            >
               <CardHeader className="pb-3">
                 <CardTitle className="text-base">数据备份</CardTitle>
                 <CardDescription>执行数据备份操作</CardDescription>
               </CardHeader>
             </Card>
-            <Card className="hover:shadow-md transition-all cursor-pointer">
+            <Card
+              className="hover:shadow-md transition-all cursor-pointer"
+              onClick={() => handleQuickActionClick('logs')}
+            >
               <CardHeader className="pb-3">
                 <CardTitle className="text-base">日志查看</CardTitle>
                 <CardDescription>查看系统日志</CardDescription>