diff --git a/.idea/AI-powered-switches.iml b/.idea/AI-powered-switches.iml index 4e1a7e9..b7e68da 100644 --- a/.idea/AI-powered-switches.iml +++ b/.idea/AI-powered-switches.iml @@ -11,6 +11,5 @@ - - + \ No newline at end of file diff --git a/README.md b/README.md index dd8d7c9..bfae63b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ - Framer-motion - chakra-ui - HTML5 - ### 项目分工 - **后端api,人工智能算法** : `3`(主要) & `log_out` & `Jerry`(maybe) 使用python - **前端管理后台设计**:`Jerry`使用react @@ -19,7 +18,9 @@ ### 各部分说明 -[网页管理前端](https://github.com/Jerryplusy/AI-powered-switches/blob/main/src/frontend/README.md) +[网页管理前端如下](https://github.com/Jerryplusy/AI-powered-switches/blob/main/src/frontend/README.md) + +![img](./src/frontend/src/resources/img.png) [逻辑处理后端](https://github.com/Jerryplusy/AI-powered-switches/blob/main/src/backend/README.md) diff --git a/src/frontend/public/index.html b/src/frontend/public/index.html index 8428f1b..be441da 100644 --- a/src/frontend/public/index.html +++ b/src/frontend/public/index.html @@ -8,4 +8,4 @@
- + \ No newline at end of file diff --git a/src/frontend/src/components/CommandInput.jsx b/src/frontend/src/components/CommandInput.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/frontend/src/components/ConfigForm.jsx b/src/frontend/src/components/ConfigForm.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/frontend/src/components/NetworkStatusChart.jsx b/src/frontend/src/components/NetworkStatusChart.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/frontend/src/components/pages/welcome/BackgroundBlur.jsx b/src/frontend/src/components/pages/welcome/BackgroundBlur.jsx index f92455b..e2771ad 100644 --- a/src/frontend/src/components/pages/welcome/BackgroundBlur.jsx +++ b/src/frontend/src/components/pages/welcome/BackgroundBlur.jsx @@ -1,13 +1,16 @@ import { Box, Image } from '@chakra-ui/react'; +import { motion } from 'framer-motion'; import image from '@/resources/welcome/image/background.png'; +const MotionBox = motion(Box); + /** * 带高斯模糊的背景 * @returns {JSX.Element} * @constructor */ const BackgroundBlur = () => ( - ( height={'100%'} filter={'blur(6px)'} zIndex={0} + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + transition={{ duration: 0.4, ease: 'easeInOut' }} > - + ); export default BackgroundBlur; diff --git a/src/frontend/src/components/pages/welcome/DashboardCard.jsx b/src/frontend/src/components/pages/welcome/DashboardCard.jsx index 3672168..921e4e6 100644 --- a/src/frontend/src/components/pages/welcome/DashboardCard.jsx +++ b/src/frontend/src/components/pages/welcome/DashboardCard.jsx @@ -12,7 +12,7 @@ const DashboardCard = () => { const navigate = useNavigate(); return ( - navigate('/dashboard')} /> + navigate('/dashboard')} /> ); }; diff --git a/src/frontend/src/components/pages/welcome/GithubCard.jsx b/src/frontend/src/components/pages/welcome/GithubCard.jsx index 03121ba..863cb77 100644 --- a/src/frontend/src/components/pages/welcome/GithubCard.jsx +++ b/src/frontend/src/components/pages/welcome/GithubCard.jsx @@ -13,6 +13,7 @@ const GithubCard = () => { window.open('https://github.com/Jerryplusy/AI-powered-switches', '_blank')} /> diff --git a/src/frontend/src/components/pages/welcome/WelcomeContent.jsx b/src/frontend/src/components/pages/welcome/WelcomeContent.jsx index 1400d38..b350722 100644 --- a/src/frontend/src/components/pages/welcome/WelcomeContent.jsx +++ b/src/frontend/src/components/pages/welcome/WelcomeContent.jsx @@ -9,10 +9,10 @@ import FadeInWrapper from '@/components/system/layout/FadeInWrapper'; */ const WelcomeContent = () => { return ( - + - - + + 智能网络交换机
管理系统 @@ -20,8 +20,8 @@ const WelcomeContent = () => {
- - + + 助力大型网络交换机配置及网络流量管理,方便的管控网络,让网络配置不再困难 diff --git a/src/frontend/src/components/system/Header.jsx b/src/frontend/src/components/system/Header.jsx deleted file mode 100644 index 985db0c..0000000 --- a/src/frontend/src/components/system/Header.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { Box, Flex, Heading, Spacer, Button, Card } from '@chakra-ui/react'; -import { useNavigate } from 'react-router-dom'; -import NavButton from '@/components/ui/NavButton'; - -const Header = () => { - const navigate = useNavigate(); - return ( - - - 网络管理后台 - - navigate('/')}> - 返回欢迎页 - - - - ); -}; - -export default Header; diff --git a/src/frontend/src/components/system/PageContainer.jsx b/src/frontend/src/components/system/PageContainer.jsx new file mode 100644 index 0000000..857c974 --- /dev/null +++ b/src/frontend/src/components/system/PageContainer.jsx @@ -0,0 +1,17 @@ +import { Box } from '@chakra-ui/react'; + +/** + * 解决导航栏占位问题 + * @param children + * @returns {JSX.Element} + * @constructor + */ +const PageContainer = ({ children }) => { + return ( + + {children} + + ); +}; + +export default PageContainer; diff --git a/src/frontend/src/components/system/layout/AppShell.jsx b/src/frontend/src/components/system/layout/AppShell.jsx index baef4f6..3f56f27 100644 --- a/src/frontend/src/components/system/layout/AppShell.jsx +++ b/src/frontend/src/components/system/layout/AppShell.jsx @@ -2,6 +2,7 @@ import { Outlet, useLocation } from 'react-router-dom'; import PageTransition from './PageTransition'; import { Box } from '@chakra-ui/react'; import { AnimatePresence } from 'framer-motion'; +import GithubTransitionCard from '@/components/system/layout/github/GithubTransitionCard'; /** * 应用加壳 @@ -13,8 +14,9 @@ const AppShell = () => { return ( + - + diff --git a/src/frontend/src/components/system/layout/GithubNavTransition.jsx b/src/frontend/src/components/system/layout/GithubNavTransition.jsx deleted file mode 100644 index df77d68..0000000 --- a/src/frontend/src/components/system/layout/GithubNavTransition.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import { useLocation } from 'react-router-dom'; -import { motion, AnimatePresence } from 'framer-motion'; -import { Box, Text, Image } from '@chakra-ui/react'; -import githubIcon from '@/resources/welcome/image/github.svg'; - -/** - * GitHub图标变换=>导航栏 - * @returns {JSX.Element} - * @constructor - */ -const GithubNavTransition = () => { - const { pathname } = useLocation(); - const isDashboard = pathname.startsWith('/dashboard'); - - return ( - - - window.open('https://github.com/Jerryplusy/AI-powered-switches', '_blank')} - > - - {isDashboard && ( - - GitHub 项目主页 - - )} - - - - ); -}; - -export default GithubNavTransition; diff --git a/src/frontend/src/components/system/layout/github/GithubTransitionCard.jsx b/src/frontend/src/components/system/layout/github/GithubTransitionCard.jsx new file mode 100644 index 0000000..fd18391 --- /dev/null +++ b/src/frontend/src/components/system/layout/github/GithubTransitionCard.jsx @@ -0,0 +1,103 @@ +import { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { AnimatePresence, motion } from 'framer-motion'; +import { Button, HStack } from '@chakra-ui/react'; +import web from '@/resources/icon/web.svg'; +import githubIcon from '@/resources/welcome/image/github.svg'; +import FadeInWrapper from '@/components/system/layout/FadeInWrapper'; +import MotionCard from '@/components/ui/MotionCard'; + +const navItems = [ + { label: '面板', path: '/dashboard' }, + { label: '网络', path: '/dashboard/network' }, + { label: '交换机', path: '/dashboard/switch' }, +]; + +/** + * 导航栏&github按钮组件 + * @returns {JSX.Element} + * @constructor + */ +const GithubTransitionCard = () => { + const { pathname } = useLocation(); + const navigate = useNavigate(); + const isDashboard = pathname.startsWith('/dashboard'); + const [showNavButtons, setShowNavButtons] = useState(false); + + useEffect(() => { + setShowNavButtons(false); + const timer = setTimeout(() => { + if (isDashboard) setShowNavButtons(true); + }, 400); + return () => clearTimeout(timer); + }, [isDashboard]); + + return ( + + + + { + if (!isDashboard) { + window.open('https://github.com/Jerryplusy/AI-powered-switches', '_blank'); + } + }} + justifyContent={isDashboard ? 'flex-start' : 'center'} + alignItems={'center'} + flexDirection={'row'} + w={'100%'} + px={isDashboard ? 4 : 3} + py={isDashboard ? 3 : 2} + noHover={isDashboard} + > + {isDashboard && showNavButtons && ( + + {navItems.map((item) => ( + + ))} + + )} + + + + + ); +}; + +export default GithubTransitionCard; diff --git a/src/frontend/src/components/system/pages/DashboardBackground.jsx b/src/frontend/src/components/system/pages/DashboardBackground.jsx new file mode 100644 index 0000000..4a3f6e8 --- /dev/null +++ b/src/frontend/src/components/system/pages/DashboardBackground.jsx @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from 'react'; +import { Box } from '@chakra-ui/react'; +import { motion } from 'framer-motion'; + +const MotionBox = motion(Box); + +/** + * 控制台背景 + * @returns {JSX.Element} + * @constructor + */ +const DashboardBackground = () => { + const [mousePos, setMousePos] = useState({ x: 0, y: 0 }); + + useEffect(() => { + const handleMouseMove = (e) => { + setMousePos({ x: e.clientX, y: e.clientY }); + }; + window.addEventListener('mousemove', handleMouseMove); + return () => window.removeEventListener('mousemove', handleMouseMove); + }, []); + + const spotlight = { + background: `radial-gradient( + circle at ${mousePos.x}px ${mousePos.y}px, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0.02) 120px, + transparent 240px + )`, + }; + + return ( + + ); +}; + +export default DashboardBackground; diff --git a/src/frontend/src/components/system/pages/DocumentTitle.jsx b/src/frontend/src/components/system/pages/DocumentTitle.jsx new file mode 100644 index 0000000..0c68a6b --- /dev/null +++ b/src/frontend/src/components/system/pages/DocumentTitle.jsx @@ -0,0 +1,10 @@ +import { useEffect } from 'react'; + +const DocumentTitle = ({ title, children }) => { + useEffect(() => { + document.title = title || '网络管理后台'; + }, [title]); + return children; +}; + +export default DocumentTitle; diff --git a/src/frontend/src/components/ui/MotionCard.jsx b/src/frontend/src/components/ui/MotionCard.jsx index e05080c..02aafee 100644 --- a/src/frontend/src/components/ui/MotionCard.jsx +++ b/src/frontend/src/components/ui/MotionCard.jsx @@ -4,19 +4,28 @@ import { motion } from 'framer-motion'; const MotionBox = motion(Box); /** - * 带有动作效果的卡片 + * 卡片组件 * @param icon 可选图标 * @param text 文字 - * @param onClick 点击执行操作 + * @param onClick 点击执行函数 + * @param hasBlurBackground 是否模糊背景 + * @param noHover 是否禁用 hover 动画 + * @param children 子组件 + * @param props * @returns {JSX.Element} * @constructor */ -const MotionCard = ({ icon, text, onClick }) => ( +const MotionCard = ({ + icon, + text, + onClick, + hasBlurBackground = false, + disableHover = false, + children, + ...props +}) => ( ( px={4} py={2} borderRadius={'md'} - cursor={'pointer'} + cursor={onClick ? 'pointer' : 'default'} onClick={onClick} - transition={{ duration: 0.1 }} + transition={'all 0.2s ease'} + overflow={'hidden'} + _hover={ + disableHover + ? {} + : { + _before: { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + bg: 'whiteAlpha.100', + zIndex: 1, + }, + } + } + {...props} > - {icon && } - {text} + {hasBlurBackground && ( + + )} + {icon && } + {text && ( + + {text} + + )} + {children} ); diff --git a/src/frontend/src/components/ui/color-mode.jsx b/src/frontend/src/components/ui/color-mode.jsx index b2d1cd6..47ba63d 100644 --- a/src/frontend/src/components/ui/color-mode.jsx +++ b/src/frontend/src/components/ui/color-mode.jsx @@ -1,90 +1,86 @@ -'use client' +'use client'; -import { ClientOnly, IconButton, Skeleton, Span } from '@chakra-ui/react' -import { ThemeProvider, useTheme } from 'next-themes' +import { ClientOnly, IconButton, Skeleton, Span } from '@chakra-ui/react'; +import { ThemeProvider, useTheme } from 'next-themes'; -import * as React from 'react' -import { LuMoon, LuSun } from 'react-icons/lu' +import * as React from 'react'; +import { LuMoon, LuSun } from 'react-icons/lu'; export function ColorModeProvider(props) { - return ( - - ) + return ; } export function useColorMode() { - const { resolvedTheme, setTheme, forcedTheme } = useTheme() - const colorMode = forcedTheme || resolvedTheme + const { resolvedTheme, setTheme, forcedTheme } = useTheme(); + const colorMode = forcedTheme || resolvedTheme; const toggleColorMode = () => { - setTheme(resolvedTheme === 'dark' ? 'light' : 'dark') - } + setTheme(resolvedTheme === 'dark' ? 'light' : 'dark'); + }; return { colorMode: colorMode, setColorMode: setTheme, toggleColorMode, - } + }; } export function useColorModeValue(light, dark) { - const { colorMode } = useColorMode() - return colorMode === 'dark' ? dark : light + const { colorMode } = useColorMode(); + return colorMode === 'dark' ? dark : light; } export function ColorModeIcon() { - const { colorMode } = useColorMode() - return colorMode === 'dark' ? : + const { colorMode } = useColorMode(); + return colorMode === 'dark' ? : ; } -export const ColorModeButton = React.forwardRef( - function ColorModeButton(props, ref) { - const { toggleColorMode } = useColorMode() - return ( - }> - - - - - ) - }, -) +export const ColorModeButton = React.forwardRef(function ColorModeButton(props, ref) { + const { toggleColorMode } = useColorMode(); + return ( + }> + + + + + ); +}); export const LightMode = React.forwardRef(function LightMode(props, ref) { return ( - ) -}) + ); +}); export const DarkMode = React.forwardRef(function DarkMode(props, ref) { return ( - ) -}) + ); +}); diff --git a/src/frontend/src/pages/Dashboard.jsx b/src/frontend/src/pages/Dashboard.jsx index 1a153ed..80c3282 100644 --- a/src/frontend/src/pages/Dashboard.jsx +++ b/src/frontend/src/pages/Dashboard.jsx @@ -1,13 +1,19 @@ import React from 'react'; import { Box, Text } from '@chakra-ui/react'; +import DocumentTitle from '@/components/system/pages/DocumentTitle'; +import PageContainer from '@/components/system/PageContainer'; +import DashboardBackground from '@/components/system/pages/DashboardBackground'; const Dashboard = () => { return ( - <> - - 控制台奇怪的功能+1 - - + + + + + 控制台奇怪的功能+1 + + + ); }; diff --git a/src/frontend/src/pages/Welcome.jsx b/src/frontend/src/pages/Welcome.jsx index 5e4e1d9..826e498 100644 --- a/src/frontend/src/pages/Welcome.jsx +++ b/src/frontend/src/pages/Welcome.jsx @@ -1,7 +1,6 @@ import { Box } from '@chakra-ui/react'; import BackgroundBlur from '@/components/pages/welcome/BackgroundBlur'; import WelcomeContent from '@/components/pages/welcome/WelcomeContent'; -import GithubCard from '@/components/pages/welcome/GithubCard'; /** * 欢迎页 @@ -13,7 +12,7 @@ const Welcome = () => { - + {/**/} diff --git a/src/frontend/src/resources/icon/web.svg b/src/frontend/src/resources/icon/web.svg new file mode 100644 index 0000000..817a917 --- /dev/null +++ b/src/frontend/src/resources/icon/web.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/resources/img.png b/src/frontend/src/resources/img.png new file mode 100644 index 0000000..f9ab032 Binary files /dev/null and b/src/frontend/src/resources/img.png differ