mirror of
https://github.com/Jerryplusy/AI-powered-switches.git
synced 2025-07-04 21:29:18 +00:00
能跑了
This commit is contained in:
parent
97947273ed
commit
fdeaa05612
@ -12,9 +12,11 @@
|
|||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"framer-motion": "^12.14.0",
|
"framer-motion": "^12.14.0",
|
||||||
|
"next-themes": "^0.4.6",
|
||||||
"prettierrc": "0.0.0-5",
|
"prettierrc": "0.0.0-5",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^7.6.1",
|
"react-router-dom": "^7.6.1",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"recharts": "^2.15.3",
|
"recharts": "^2.15.3",
|
||||||
|
26
src/frontend/pnpm-lock.yaml
generated
26
src/frontend/pnpm-lock.yaml
generated
@ -35,6 +35,9 @@ importers:
|
|||||||
framer-motion:
|
framer-motion:
|
||||||
specifier: ^12.14.0
|
specifier: ^12.14.0
|
||||||
version: 12.15.0(@emotion/is-prop-valid@1.3.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 12.15.0(@emotion/is-prop-valid@1.3.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
next-themes:
|
||||||
|
specifier: ^0.4.6
|
||||||
|
version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
prettierrc:
|
prettierrc:
|
||||||
specifier: 0.0.0-5
|
specifier: 0.0.0-5
|
||||||
version: 0.0.0-5(prettier@1.19.1)
|
version: 0.0.0-5(prettier@1.19.1)
|
||||||
@ -44,6 +47,9 @@ importers:
|
|||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^19.1.0
|
specifier: ^19.1.0
|
||||||
version: 19.1.0(react@19.1.0)
|
version: 19.1.0(react@19.1.0)
|
||||||
|
react-icons:
|
||||||
|
specifier: ^5.5.0
|
||||||
|
version: 5.5.0(react@19.1.0)
|
||||||
react-router-dom:
|
react-router-dom:
|
||||||
specifier: ^7.6.1
|
specifier: ^7.6.1
|
||||||
version: 7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
@ -4438,6 +4444,12 @@ packages:
|
|||||||
neo-async@2.6.2:
|
neo-async@2.6.2:
|
||||||
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
|
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
|
||||||
|
|
||||||
|
next-themes@0.4.6:
|
||||||
|
resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
||||||
|
|
||||||
no-case@3.0.4:
|
no-case@3.0.4:
|
||||||
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
||||||
|
|
||||||
@ -5271,6 +5283,11 @@ packages:
|
|||||||
react-error-overlay@6.1.0:
|
react-error-overlay@6.1.0:
|
||||||
resolution: {integrity: sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==}
|
resolution: {integrity: sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==}
|
||||||
|
|
||||||
|
react-icons@5.5.0:
|
||||||
|
resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '*'
|
||||||
|
|
||||||
react-is@16.13.1:
|
react-is@16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
||||||
@ -12021,6 +12038,11 @@ snapshots:
|
|||||||
|
|
||||||
neo-async@2.6.2: {}
|
neo-async@2.6.2: {}
|
||||||
|
|
||||||
|
next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.1.0
|
||||||
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
|
||||||
no-case@3.0.4:
|
no-case@3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
lower-case: 2.0.2
|
lower-case: 2.0.2
|
||||||
@ -12881,6 +12903,10 @@ snapshots:
|
|||||||
|
|
||||||
react-error-overlay@6.1.0: {}
|
react-error-overlay@6.1.0: {}
|
||||||
|
|
||||||
|
react-icons@5.5.0(react@19.1.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.1.0
|
||||||
|
|
||||||
react-is@16.13.1: {}
|
react-is@16.13.1: {}
|
||||||
|
|
||||||
react-is@17.0.2: {}
|
react-is@17.0.2: {}
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Routes, Route } from 'react-router-dom';
|
//import { Button, HStack } from '@chakra-ui/react';
|
||||||
import Dashboard from './pages/Dashboard';
|
//import { Routes, Route } from 'react-router-dom';
|
||||||
import Configuration from './pages/Configuration';
|
//import Dashboard from './pages/Dashboard';
|
||||||
import Header from './components/Header';
|
//import Configuration from './pages/Configuration';
|
||||||
|
//import Header from './components/Header';
|
||||||
|
//import { Box, Button } from '@chakra-ui/react';
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (//待扩展
|
||||||
<>
|
<>
|
||||||
<Header />
|
|
||||||
<Routes>
|
|
||||||
<Route path="/" element={<Dashboard />} />
|
|
||||||
<Route path="/config" element={<Configuration />} />
|
|
||||||
</Routes>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**备用
|
||||||
|
* <Routes>
|
||||||
|
* <Route path="/" element={<Dashboard />} />
|
||||||
|
* <Route path="/config" element={<Configuration />} />
|
||||||
|
* </Routes>
|
||||||
|
*/
|
||||||
export default App;
|
export default App;
|
90
src/frontend/src/components/ui/color-mode.jsx
Normal file
90
src/frontend/src/components/ui/color-mode.jsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
export function ColorModeProvider(props) {
|
||||||
|
return (
|
||||||
|
<ThemeProvider attribute='class' disableTransitionOnChange {...props} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useColorMode() {
|
||||||
|
const { resolvedTheme, setTheme, forcedTheme } = useTheme()
|
||||||
|
const colorMode = forcedTheme || resolvedTheme
|
||||||
|
const toggleColorMode = () => {
|
||||||
|
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
colorMode: colorMode,
|
||||||
|
setColorMode: setTheme,
|
||||||
|
toggleColorMode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useColorModeValue(light, dark) {
|
||||||
|
const { colorMode } = useColorMode()
|
||||||
|
return colorMode === 'dark' ? dark : light
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ColorModeIcon() {
|
||||||
|
const { colorMode } = useColorMode()
|
||||||
|
return colorMode === 'dark' ? <LuMoon /> : <LuSun />
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ColorModeButton = React.forwardRef(
|
||||||
|
function ColorModeButton(props, ref) {
|
||||||
|
const { toggleColorMode } = useColorMode()
|
||||||
|
return (
|
||||||
|
<ClientOnly fallback={<Skeleton boxSize='8' />}>
|
||||||
|
<IconButton
|
||||||
|
onClick={toggleColorMode}
|
||||||
|
variant='ghost'
|
||||||
|
aria-label='Toggle color mode'
|
||||||
|
size='sm'
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
css={{
|
||||||
|
_icon: {
|
||||||
|
width: '5',
|
||||||
|
height: '5',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ColorModeIcon />
|
||||||
|
</IconButton>
|
||||||
|
</ClientOnly>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export const LightMode = React.forwardRef(function LightMode(props, ref) {
|
||||||
|
return (
|
||||||
|
<Span
|
||||||
|
color='fg'
|
||||||
|
display='contents'
|
||||||
|
className='chakra-theme light'
|
||||||
|
colorPalette='gray'
|
||||||
|
colorScheme='light'
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const DarkMode = React.forwardRef(function DarkMode(props, ref) {
|
||||||
|
return (
|
||||||
|
<Span
|
||||||
|
color='fg'
|
||||||
|
display='contents'
|
||||||
|
className='chakra-theme dark'
|
||||||
|
colorPalette='gray'
|
||||||
|
colorScheme='dark'
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
12
src/frontend/src/components/ui/provider.jsx
Normal file
12
src/frontend/src/components/ui/provider.jsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { ChakraProvider, defaultSystem } from '@chakra-ui/react'
|
||||||
|
import { ColorModeProvider } from './color-mode'
|
||||||
|
|
||||||
|
export function Provider(props) {
|
||||||
|
return (
|
||||||
|
<ChakraProvider value={defaultSystem}>
|
||||||
|
<ColorModeProvider {...props} />
|
||||||
|
</ChakraProvider>
|
||||||
|
)
|
||||||
|
}
|
43
src/frontend/src/components/ui/toaster.jsx
Normal file
43
src/frontend/src/components/ui/toaster.jsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Toaster as ChakraToaster,
|
||||||
|
Portal,
|
||||||
|
Spinner,
|
||||||
|
Stack,
|
||||||
|
Toast,
|
||||||
|
createToaster,
|
||||||
|
} from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const toaster = createToaster({
|
||||||
|
placement: 'bottom-end',
|
||||||
|
pauseOnPageIdle: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const Toaster = () => {
|
||||||
|
return (
|
||||||
|
<Portal>
|
||||||
|
<ChakraToaster toaster={toaster} insetInline={{ mdDown: '4' }}>
|
||||||
|
{(toast) => (
|
||||||
|
<Toast.Root width={{ md: 'sm' }}>
|
||||||
|
{toast.type === 'loading' ? (
|
||||||
|
<Spinner size='sm' color='blue.solid' />
|
||||||
|
) : (
|
||||||
|
<Toast.Indicator />
|
||||||
|
)}
|
||||||
|
<Stack gap='1' flex='1' maxWidth='100%'>
|
||||||
|
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
|
||||||
|
{toast.description && (
|
||||||
|
<Toast.Description>{toast.description}</Toast.Description>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
{toast.action && (
|
||||||
|
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
|
||||||
|
)}
|
||||||
|
{toast.closable && <Toast.CloseTrigger />}
|
||||||
|
</Toast.Root>
|
||||||
|
)}
|
||||||
|
</ChakraToaster>
|
||||||
|
</Portal>
|
||||||
|
)
|
||||||
|
}
|
35
src/frontend/src/components/ui/tooltip.jsx
Normal file
35
src/frontend/src/components/ui/tooltip.jsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Tooltip as ChakraTooltip, Portal } from '@chakra-ui/react'
|
||||||
|
import * as React from 'react'
|
||||||
|
|
||||||
|
export const Tooltip = React.forwardRef(function Tooltip(props, ref) {
|
||||||
|
const {
|
||||||
|
showArrow,
|
||||||
|
children,
|
||||||
|
disabled,
|
||||||
|
portalled = true,
|
||||||
|
content,
|
||||||
|
contentProps,
|
||||||
|
portalRef,
|
||||||
|
...rest
|
||||||
|
} = props
|
||||||
|
|
||||||
|
if (disabled) return children
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ChakraTooltip.Root {...rest}>
|
||||||
|
<ChakraTooltip.Trigger asChild>{children}</ChakraTooltip.Trigger>
|
||||||
|
<Portal disabled={!portalled} container={portalRef}>
|
||||||
|
<ChakraTooltip.Positioner>
|
||||||
|
<ChakraTooltip.Content ref={ref} {...contentProps}>
|
||||||
|
{showArrow && (
|
||||||
|
<ChakraTooltip.Arrow>
|
||||||
|
<ChakraTooltip.ArrowTip />
|
||||||
|
</ChakraTooltip.Arrow>
|
||||||
|
)}
|
||||||
|
{content}
|
||||||
|
</ChakraTooltip.Content>
|
||||||
|
</ChakraTooltip.Positioner>
|
||||||
|
</Portal>
|
||||||
|
</ChakraTooltip.Root>
|
||||||
|
)
|
||||||
|
})
|
@ -1,14 +1,14 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import {ChakraProvider} from '@chakra-ui/react';
|
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
import {Provider} from './components/ui/provider'
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
root.render(
|
root.render(
|
||||||
<ChakraProvider value={}>
|
<Provider>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<App />
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</ChakraProvider>
|
</Provider>
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user