mirror of
https://github.com/Jerryplusy/AI-powered-switches.git
synced 2025-07-04 13:19:20 +00:00
Compare commits
2 Commits
8c71a4c83c
...
c186b8f3bb
Author | SHA1 | Date | |
---|---|---|---|
c186b8f3bb | |||
1dbd840d36 |
43
src/frontend/src/components/pages/dashboard/FeatureCard.jsx
Normal file
43
src/frontend/src/components/pages/dashboard/FeatureCard.jsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { Box, Button, Text } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 特性卡片
|
||||||
|
* @param title 标题
|
||||||
|
* @param description 描述
|
||||||
|
* @param buttonText 按钮文字
|
||||||
|
* @param to 转向
|
||||||
|
* @param disabled 按钮是否可用
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const FeatureCard = ({ title, description, buttonText, to, disabled }) => (
|
||||||
|
<Box
|
||||||
|
p={6}
|
||||||
|
bg={'whiteAlpha.100'}
|
||||||
|
borderRadius={'xl'}
|
||||||
|
border={'1px solid'}
|
||||||
|
borderColor={'whiteAlpha.300'}
|
||||||
|
transition={'all 0.2s'}
|
||||||
|
_hover={{ transform: 'translateY(-4px)' }}
|
||||||
|
>
|
||||||
|
<Text fontSize={'xl'} fontWeight={'bold'} color={'white'} mb={2}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
<Text color={'gray.300'} mb={4}>
|
||||||
|
{description}
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
colorScheme={'blue'}
|
||||||
|
variant={'solid'}
|
||||||
|
isDisabled={disabled}
|
||||||
|
onClick={() => {
|
||||||
|
if (to) window.location.href = to;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default FeatureCard;
|
31
src/frontend/src/components/pages/dashboard/StatCard.jsx
Normal file
31
src/frontend/src/components/pages/dashboard/StatCard.jsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { Box, Stat } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态卡片
|
||||||
|
* @param title 标题
|
||||||
|
* @param value 内容
|
||||||
|
* @param suffix 交换机数目
|
||||||
|
* @param isTime 扫描时间
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const StatCard = ({ title, value, suffix, isTime }) => (
|
||||||
|
<Box
|
||||||
|
p={6}
|
||||||
|
bg={'whiteAlpha.100'}
|
||||||
|
borderRadius={'xl'}
|
||||||
|
border={'1px solid'}
|
||||||
|
borderColor={'whiteAlpha.300'}
|
||||||
|
transition={'all 0.2s'}
|
||||||
|
_hover={{ transform: 'translateY(-4px)' }}
|
||||||
|
>
|
||||||
|
<Stat.Root colorPalette={'teal'}>
|
||||||
|
<Stat.Label>{title}</Stat.Label>
|
||||||
|
<Stat.ValueText>{`${value}${suffix ? ` ${suffix}` : ''}`}</Stat.ValueText>
|
||||||
|
{isTime && <Stat.HelpText>{`上次扫描时间`}</Stat.HelpText>}
|
||||||
|
</Stat.Root>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default StatCard;
|
@ -25,6 +25,14 @@ const defaultConfig = {
|
|||||||
authKey: '',
|
authKey: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接地址配置组件
|
||||||
|
* @param isOpen 打开状态
|
||||||
|
* @param onClose 关闭状态
|
||||||
|
* @param onSave 保存状态
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
const ConnectionConfigModal = ({ isOpen, onClose, onSave }) => {
|
const ConnectionConfigModal = ({ isOpen, onClose, onSave }) => {
|
||||||
const [config, setConfig] = useState(defaultConfig);
|
const [config, setConfig] = useState(defaultConfig);
|
||||||
const [saved, setSaved] = useState(false);
|
const [saved, setSaved] = useState(false);
|
||||||
@ -84,6 +92,7 @@ const ConnectionConfigModal = ({ isOpen, onClose, onSave }) => {
|
|||||||
top={3}
|
top={3}
|
||||||
right={3}
|
right={3}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
|
_hover={{ bg: 'rgba(255, 0, 0, 0.3)' }}
|
||||||
>
|
>
|
||||||
<IoClose size={20} color={'white'} />
|
<IoClose size={20} color={'white'} />
|
||||||
</Button>
|
</Button>
|
||||||
@ -124,6 +133,7 @@ const ConnectionConfigModal = ({ isOpen, onClose, onSave }) => {
|
|||||||
borderColor={'whiteAlpha.500'}
|
borderColor={'whiteAlpha.500'}
|
||||||
color={'white'}
|
color={'white'}
|
||||||
onClick={handleClear}
|
onClick={handleClear}
|
||||||
|
_hover={{ bg: 'rgba(0, 0, 255, 0.3)' }}
|
||||||
>
|
>
|
||||||
清除配置
|
清除配置
|
||||||
</Button>
|
</Button>
|
||||||
@ -134,6 +144,7 @@ const ConnectionConfigModal = ({ isOpen, onClose, onSave }) => {
|
|||||||
borderColor={'whiteAlpha.500'}
|
borderColor={'whiteAlpha.500'}
|
||||||
color={'white'}
|
color={'white'}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
|
_hover={{ bg: 'rgba(0, 0, 255, 0.3)' }}
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
@ -146,6 +157,7 @@ const ConnectionConfigModal = ({ isOpen, onClose, onSave }) => {
|
|||||||
isDisabled={saved}
|
isDisabled={saved}
|
||||||
position={'relative'}
|
position={'relative'}
|
||||||
width={'80px'}
|
width={'80px'}
|
||||||
|
_hover={{ bg: 'rgba(0, 0, 255, 0.3)' }}
|
||||||
>
|
>
|
||||||
<AnimatePresence initial={false} mode={'wait'}>
|
<AnimatePresence initial={false} mode={'wait'}>
|
||||||
{saved ? (
|
{saved ? (
|
||||||
|
@ -8,7 +8,7 @@ import { Box } from '@chakra-ui/react';
|
|||||||
*/
|
*/
|
||||||
const PageContainer = ({ children }) => {
|
const PageContainer = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<Box pt={'60px'} px={6}>
|
<Box pt={'80px'} px={6}>
|
||||||
{children}
|
{children}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -1,19 +1,117 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Box, Text } from '@chakra-ui/react';
|
import { Box, Text, VStack, HStack, SimpleGrid, Badge } from '@chakra-ui/react';
|
||||||
import DocumentTitle from '@/components/system/pages/DocumentTitle';
|
import DocumentTitle from '@/components/system/pages/DocumentTitle';
|
||||||
import PageContainer from '@/components/system/PageContainer';
|
import PageContainer from '@/components/system/PageContainer';
|
||||||
import DashboardBackground from '@/components/system/pages/DashboardBackground';
|
import DashboardBackground from '@/components/system/pages/DashboardBackground';
|
||||||
import FadeInWrapper from '@/components/system/layout/FadeInWrapper';
|
import FadeInWrapper from '@/components/system/layout/FadeInWrapper';
|
||||||
|
import FeatureCard from '@/components/pages/dashboard/FeatureCard';
|
||||||
|
import StatCard from '@/components/pages/dashboard/StatCard';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制台页面
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
|
const [stats, setStats] = useState({
|
||||||
|
totalDevices: 0,
|
||||||
|
onlineDevices: 0,
|
||||||
|
lastScan: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DocumentTitle title={'控制台'}>
|
<DocumentTitle title={'控制台'}>
|
||||||
<DashboardBackground />
|
<DashboardBackground />
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<FadeInWrapper delay={0.1} yOffset={-5}>
|
<FadeInWrapper delay={0.3} yOffset={-5}>
|
||||||
<Box p={6}>
|
<VStack spacing={8} align={'stretch'}>
|
||||||
<Text fontSize={'xl'}>控制台奇怪的功能+1</Text>
|
<Box
|
||||||
|
p={4}
|
||||||
|
bg={'whiteAlpha.100'}
|
||||||
|
borderRadius={'xl'}
|
||||||
|
border={'1px solid'}
|
||||||
|
borderColor={'whiteAlpha.300'}
|
||||||
|
mx={4}
|
||||||
|
transition={'all 0.2s'}
|
||||||
|
_hover={{ transform: 'translateY(-4px)' }}
|
||||||
|
>
|
||||||
|
<Text fontSize={'3xl'} fontWeight={'bold'} color={'teal.300'}>
|
||||||
|
{`欢迎使用智能交换机管理系统`}
|
||||||
|
</Text>
|
||||||
|
<Text mt={2} fontSize={'lg'} color={'gray.300'}>
|
||||||
|
{`实时监控您的网络设备状态,快速配置并掌控全局网络环境`}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
<SimpleGrid columns={{ base: 1, md: 3 }} gap={'10px'} mx={4}>
|
||||||
|
<StatCard title={'已发现设备'} value={stats.totalDevices} />
|
||||||
|
<StatCard
|
||||||
|
title={'在线设备'}
|
||||||
|
value={stats.onlineDevices}
|
||||||
|
suffix={`/ ${stats.totalDevices}`}
|
||||||
|
/>
|
||||||
|
<StatCard title={'最近扫描'} value={stats.lastScan} isTime />
|
||||||
|
</SimpleGrid>
|
||||||
|
|
||||||
|
<FadeInWrapper delay={0.3} yOffset={-5}>
|
||||||
|
<Box
|
||||||
|
p={6}
|
||||||
|
bg={'whiteAlpha.100'}
|
||||||
|
borderRadius={'xl'}
|
||||||
|
border={'1px solid'}
|
||||||
|
borderColor={'whiteAlpha.300'}
|
||||||
|
mx={4}
|
||||||
|
transition={'all 0.2s'}
|
||||||
|
_hover={{ transform: 'translateY(-4px)' }}
|
||||||
|
>
|
||||||
|
<Text fontSize={'xl'} fontWeight={'bold'} mb={4} color={'white'}>
|
||||||
|
{`网络健康状态`}
|
||||||
|
</Text>
|
||||||
|
<HStack spacing={4}>
|
||||||
|
<Badge colorScheme={'green'} variant={'solid'} p={2} borderRadius={'lg'}>
|
||||||
|
{`网络连接正常`}
|
||||||
|
</Badge>
|
||||||
|
<Badge colorScheme={'blue'} variant={'solid'} p={2} borderRadius={'lg'}>
|
||||||
|
{`交换机正常运行`}
|
||||||
|
</Badge>
|
||||||
|
<Badge colorScheme={'yellow'} variant={'solid'} p={2} borderRadius={'lg'}>
|
||||||
|
{`流量监控未启动`}
|
||||||
|
</Badge>
|
||||||
|
</HStack>
|
||||||
|
</Box>
|
||||||
|
</FadeInWrapper>
|
||||||
|
|
||||||
|
<FadeInWrapper delay={0.4} yOffset={-5}>
|
||||||
|
<SimpleGrid columns={{ base: 1, md: 2 }} gap={'10px'} mx={4}>
|
||||||
|
<FeatureCard
|
||||||
|
title={'网络扫描'}
|
||||||
|
description={'快速扫描指定子网,发现可用设备,展示设备 IP/MAC 和开放端口信息'}
|
||||||
|
buttonText={'立即扫描'}
|
||||||
|
to={'/scan'}
|
||||||
|
/>
|
||||||
|
<FeatureCard
|
||||||
|
title={'设备管理'}
|
||||||
|
description={'查看已记录的交换机设备信息,未来支持编辑、备注、批量管理'}
|
||||||
|
buttonText={'管理设备'}
|
||||||
|
to={'/devices'}
|
||||||
|
/>
|
||||||
|
<FeatureCard
|
||||||
|
title={'命令配置'}
|
||||||
|
description={'输入自然语言命令,自动生成设备配置,支持一键应用到交换机'}
|
||||||
|
buttonText={'前往配置'}
|
||||||
|
to={'/config'}
|
||||||
|
/>
|
||||||
|
<FeatureCard
|
||||||
|
title={'流量监控'}
|
||||||
|
description={'未来将支持实时监控每台设备上下行带宽,帮助掌握网络流量变化'}
|
||||||
|
buttonText={'敬请期待'}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</SimpleGrid>
|
||||||
|
</FadeInWrapper>
|
||||||
|
</VStack>
|
||||||
</FadeInWrapper>
|
</FadeInWrapper>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</DocumentTitle>
|
</DocumentTitle>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user