mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-08-10 04:37:59 +00:00
feat: 布局调整&添加首页
This commit is contained in:
parent
10d6e23815
commit
7eb02a0dc2
@ -2,11 +2,15 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #1677ff;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--joy-palette-text-primary, var(--joy-palette-neutral-800, #25252D));
|
color: var(--joy-palette-text-primary, var(--joy-palette-neutral-800, #25252D));
|
||||||
font-family: var(--joy-fontFamily-body, var(--joy-Josefin Sans, sans-serif));
|
font-family: var(--joy-fontFamily-body, var(--joy-Josefin Sans, sans-serif));
|
||||||
font-size: var(--joy-fontSize-md, 1rem);
|
font-size: var(--joy-fontSize-md, 1rem);
|
||||||
line-height: var(--joy-lineHeight-md, 1.5);
|
line-height: var(--joy-lineHeight-md, 1.5);
|
||||||
background-color: var(--joy-palette-background-body);
|
background-color: var(--joy-palette-background-body);
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import './globals.css'
|
import './globals.css'
|
||||||
import Header from '@/components/header';
|
|
||||||
import LeftSider from '@/components/leftSider';
|
import LeftSider from '@/components/leftSider';
|
||||||
import { CssVarsProvider, ThemeProvider } from '@mui/joy/styles';
|
import { CssVarsProvider, ThemeProvider } from '@mui/joy/styles';
|
||||||
import { joyTheme } from './defaultTheme';
|
import { joyTheme } from './defaultTheme';
|
||||||
@ -16,10 +15,9 @@ export default function RootLayout({
|
|||||||
<ThemeProvider theme={joyTheme}>
|
<ThemeProvider theme={joyTheme}>
|
||||||
<CssVarsProvider theme={joyTheme} defaultMode="light">
|
<CssVarsProvider theme={joyTheme} defaultMode="light">
|
||||||
<div className='min-h-screen flex flex-col'>
|
<div className='min-h-screen flex flex-col'>
|
||||||
<Header />
|
|
||||||
<div className="flex flex-1 flex-row">
|
<div className="flex flex-1 flex-row">
|
||||||
<LeftSider />
|
<LeftSider />
|
||||||
<div className='flex-1'>{children}</div>
|
<div className='flex-1 overflow-auto'>{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CssVarsProvider>
|
</CssVarsProvider>
|
||||||
|
@ -1,9 +1,270 @@
|
|||||||
import Image from 'next/image'
|
"use client";
|
||||||
|
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import { Collapse } from 'antd';
|
||||||
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||||
|
import { Box, Slider, Input, Tabs, TabList, Typography, TabPanel, Tab, RadioGroup, Radio, tabClasses, useColorScheme, radioClasses } from '@/lib/mui';
|
||||||
|
import { sendGetRequest } from '@/utils/request';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import ChatBoxComp from '@/components/chatBox';
|
||||||
|
import useAgentChat from '@/hooks/useAgentChat';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const [temperatureNum, setTemperatureNum] = useState(3);
|
||||||
|
const [tokenSize, setTokenSize] = useState(0);
|
||||||
|
const { mode, setMode } = useColorScheme();
|
||||||
|
|
||||||
|
const { handleChatSubmit, history } = useAgentChat({
|
||||||
|
queryAgentURL: `/api/agents/query`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleGetD = () => {
|
||||||
|
sendGetRequest('/v1/chat/dialogue/list', {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log(mode, 'mode', radioClasses, 'radioClasses')
|
||||||
|
useEffect(() => {
|
||||||
|
handleGetD();
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='p-6 w-full h-full text-sm flex flex-col gap-4'>
|
||||||
Hello GPT
|
<ReactMarkdown linkTarget={'_blank'}>
|
||||||
|
[DB-GPT](https://github.com/csunny/DB-GPT) 是一个开源的以数据库为基础的GPT实验项目,使用本地化的GPT大模型与您的数据和环境进行交互,无数据泄露风险,100% 私密,100% 安全。
|
||||||
|
</ReactMarkdown>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
'& .ant-collapse': {
|
||||||
|
backgroundColor: 'var(--joy-palette-background-level1)',
|
||||||
|
color: 'var(--joy-palette-neutral-plainColor)'
|
||||||
|
},
|
||||||
|
'& .ant-collapse>.ant-collapse-item >.ant-collapse-header, & .ant-collapse .ant-collapse-content': {
|
||||||
|
color: 'var(--joy-palette-neutral-plainColor)'
|
||||||
|
},
|
||||||
|
'& .ant-collapse .ant-collapse-content>.ant-collapse-content-box': {
|
||||||
|
paddingTop: 0
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Collapse
|
||||||
|
collapsible="header"
|
||||||
|
defaultActiveKey={['1']}
|
||||||
|
ghost
|
||||||
|
bordered
|
||||||
|
expandIcon={({ isActive }) => (
|
||||||
|
<div className={`text-2xl cursor-pointer ${isActive ? 'rotate-0' : 'rotate-90'}`}>
|
||||||
|
<ArrowDropDownIcon />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
expandIconPosition="end"
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
label: 'This panel can only be collapsed by clicking text',
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
className="p-4 border"
|
||||||
|
sx={{
|
||||||
|
borderColor: 'var(--joy-palette-background-level2)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex flex-row justify-between items-center'>
|
||||||
|
<span>Temperature</span>
|
||||||
|
<Input
|
||||||
|
size='sm'
|
||||||
|
type="number"
|
||||||
|
value={temperatureNum / 10}
|
||||||
|
onChange={(e) => {
|
||||||
|
console.log(Number(e.target.value) * 10, '===')
|
||||||
|
setTemperatureNum(Number(e.target.value) * 10);
|
||||||
|
}}
|
||||||
|
slotProps={{
|
||||||
|
input: {
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
step: 0.1,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Slider
|
||||||
|
color="info"
|
||||||
|
value={temperatureNum}
|
||||||
|
max={10}
|
||||||
|
onChange={(e, value) => {
|
||||||
|
console.log(e, 'e', value, 'v')
|
||||||
|
setTemperatureNum(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
className="p-4 border border-t-0"
|
||||||
|
sx={{
|
||||||
|
borderColor: 'var(--joy-palette-background-level2)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex flex-row justify-between items-center'>
|
||||||
|
<span>Maximum output token size</span>
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
type="number"
|
||||||
|
value={tokenSize}
|
||||||
|
onChange={(e) => {
|
||||||
|
setTokenSize(Number(e.target.value));
|
||||||
|
}}
|
||||||
|
slotProps={{
|
||||||
|
input: {
|
||||||
|
min: 0,
|
||||||
|
max: 1024,
|
||||||
|
step: 64,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Slider
|
||||||
|
color="info"
|
||||||
|
value={tokenSize}
|
||||||
|
max={1024}
|
||||||
|
step={64}
|
||||||
|
onChange={(e, value) => {
|
||||||
|
console.log(e, 'e', value, 'v')
|
||||||
|
setTokenSize(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Tabs
|
||||||
|
className='w-full'
|
||||||
|
aria-label="Pricing plan"
|
||||||
|
defaultValue={0}
|
||||||
|
sx={(theme) => ({
|
||||||
|
'--Tabs-gap': '0px',
|
||||||
|
borderRadius: 'unset',
|
||||||
|
boxShadow: 'sm',
|
||||||
|
overflow: 'auto',
|
||||||
|
WebkitBoxShadow: 'none'
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<TabList
|
||||||
|
sx={{
|
||||||
|
'--ListItem-radius': '0px',
|
||||||
|
borderRadius: 0,
|
||||||
|
bgcolor: 'background.body',
|
||||||
|
[`& .${tabClasses.root}`]: {
|
||||||
|
fontWeight: 'lg',
|
||||||
|
flex: 'unset',
|
||||||
|
position: 'relative',
|
||||||
|
[`&.${tabClasses.selected}`]: {
|
||||||
|
border: '1px solid var(--joy-palette-background-level2)',
|
||||||
|
borderTopLeftRadius: '8px',
|
||||||
|
borderTopRightRadius: '8px',
|
||||||
|
},
|
||||||
|
[`&.${tabClasses.selected}:before`]: {
|
||||||
|
content: '""',
|
||||||
|
display: 'block',
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: -4,
|
||||||
|
width: '100%',
|
||||||
|
height: 6,
|
||||||
|
bgcolor: mode == 'dark' ? '#000' : 'var(--joy-palette-background-surface)',
|
||||||
|
},
|
||||||
|
[`&.${tabClasses.focusVisible}`]: {
|
||||||
|
outlineOffset: '-3px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tab sx={{ py: 1.5 }}>Documents Chat</Tab>
|
||||||
|
<Tab>SQL Generation & Diagnostics</Tab>
|
||||||
|
<Tab>Plugin Mode</Tab>
|
||||||
|
</TabList>
|
||||||
|
<TabPanel
|
||||||
|
value={0}
|
||||||
|
sx={{
|
||||||
|
p: 3,
|
||||||
|
border: '1px solid var(--joy-palette-background-level2)',
|
||||||
|
borderBottomLeftRadius: '8px',
|
||||||
|
borderBottomRightRadius: '8px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RadioGroup
|
||||||
|
orientation="horizontal"
|
||||||
|
defaultValue="LLM native dialogue"
|
||||||
|
name="radio-buttons-group"
|
||||||
|
className='gap-3 p-3'
|
||||||
|
sx={{
|
||||||
|
backgroundColor: 'var(--joy-palette-background-level1)',
|
||||||
|
'& .MuiRadio-radio': {
|
||||||
|
borderColor: '#707070'
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box className="px-2 py-1 border rounded" sx={{ borderColor: 'var(--joy-palette-background-level2)' }}>
|
||||||
|
<Radio value="LLM native dialogue" label="LLM native dialogue" variant="outlined"
|
||||||
|
sx={{
|
||||||
|
borderColor: 'var(--joy-palette-neutral-outlinedHoverColor)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box className="px-2 py-1 border rounded" sx={{ borderColor: 'var(--joy-palette-background-level2)' }}>
|
||||||
|
<Radio value="Default documents" label="Default documents" variant="outlined" />
|
||||||
|
</Box>
|
||||||
|
<Box className="px-2 py-1 border rounded" sx={{ borderColor: 'var(--joy-palette-background-level2)' }}>
|
||||||
|
<Radio value="New documents" label="New documents" variant="outlined" />
|
||||||
|
</Box>
|
||||||
|
<Box className="px-2 py-1 border rounded" sx={{ borderColor: 'var(--joy-palette-background-level2)' }}>
|
||||||
|
<Radio value="Chat with url" label="Chat with url" variant="outlined" />
|
||||||
|
</Box>
|
||||||
|
</RadioGroup>
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value={1} sx={{ p: 3 }}>
|
||||||
|
<Typography level="inherit">
|
||||||
|
Best for professional developers building enterprise or data-rich
|
||||||
|
applications.
|
||||||
|
</Typography>
|
||||||
|
<Typography textColor="primary.400" fontSize="xl3" fontWeight="xl" my={1}>
|
||||||
|
$15{' '}
|
||||||
|
<Typography fontSize="sm" textColor="text.secondary" fontWeight="md">
|
||||||
|
/ dev / month
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value={2} sx={{ p: 3 }}>
|
||||||
|
<Typography level="inherit">
|
||||||
|
The most advanced features for data-rich applications, as well as the
|
||||||
|
highest priority for support.
|
||||||
|
</Typography>
|
||||||
|
<Typography textColor="primary.400" fontSize="xl3" fontWeight="xl" my={1}>
|
||||||
|
<Typography
|
||||||
|
fontSize="xl"
|
||||||
|
borderRadius="sm"
|
||||||
|
px={0.5}
|
||||||
|
mr={0.5}
|
||||||
|
sx={(theme) => ({
|
||||||
|
...theme.variants.soft.danger,
|
||||||
|
color: 'danger.400',
|
||||||
|
verticalAlign: 'text-top',
|
||||||
|
textDecoration: 'line-through',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
$49
|
||||||
|
</Typography>
|
||||||
|
$37*{' '}
|
||||||
|
<Typography fontSize="sm" textColor="text.secondary" fontWeight="md">
|
||||||
|
/ dev / month
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
|
</TabPanel>
|
||||||
|
</Tabs>
|
||||||
|
</Box>
|
||||||
|
<ChatBoxComp messages={history} onSubmit={handleChatSubmit}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,6 @@ const ChatBoxComp = ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexBasis: '100%',
|
flexBasis: '100%',
|
||||||
maxWidth: '700px',
|
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
maxHeight: '100%',
|
maxHeight: '100%',
|
||||||
|
@ -1,14 +1,40 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Box, List, ListItem, ListItemButton, ListItemDecorator, ListItemContent } from '@/lib/mui';
|
import Image from 'next/image';
|
||||||
|
import { Box, List, ListItem, ListItemButton, ListItemDecorator, ListItemContent, Typography, Button, useColorScheme } from '@/lib/mui';
|
||||||
import SmartToyRoundedIcon from '@mui/icons-material/SmartToyRounded'; // Icons import
|
import SmartToyRoundedIcon from '@mui/icons-material/SmartToyRounded'; // Icons import
|
||||||
import StorageRoundedIcon from '@mui/icons-material/StorageRounded';
|
import StorageRoundedIcon from '@mui/icons-material/StorageRounded';
|
||||||
|
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
||||||
|
import WbSunnyIcon from '@mui/icons-material/WbSunny';
|
||||||
|
|
||||||
|
const mockHistory = [{
|
||||||
|
id: 1,
|
||||||
|
summary: "chat1",
|
||||||
|
history: [{
|
||||||
|
from: 'human',
|
||||||
|
message: 'Hello'
|
||||||
|
}, {
|
||||||
|
from: 'agent',
|
||||||
|
message: 'Hello! How can I assist you today?'
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
summary: "天气",
|
||||||
|
history: [{
|
||||||
|
from: 'human',
|
||||||
|
message: '讲个笑话'
|
||||||
|
}, {
|
||||||
|
from: 'agent',
|
||||||
|
message: '当然!这是一个经典的笑话:xxx'
|
||||||
|
}]
|
||||||
|
}];
|
||||||
|
|
||||||
const LeftSider = () => {
|
const LeftSider = () => {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
console.log(pathname, 'router')
|
const { mode, setMode } = useColorScheme();
|
||||||
|
const [chatSelect, setChatSelect] = useState();
|
||||||
const menus = useMemo(() => {
|
const menus = useMemo(() => {
|
||||||
return [{
|
return [{
|
||||||
label: 'Agents',
|
label: 'Agents',
|
||||||
@ -23,52 +49,161 @@ const LeftSider = () => {
|
|||||||
}];
|
}];
|
||||||
}, [pathname]);
|
}, [pathname]);
|
||||||
|
|
||||||
|
const handleChangeTheme = () => {
|
||||||
|
if (mode === 'light') {
|
||||||
|
setMode('dark');
|
||||||
|
} else {
|
||||||
|
setMode('light');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={[
|
sx={{
|
||||||
{
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
borderRight: '1px solid',
|
||||||
|
borderColor: 'divider',
|
||||||
|
maxHeight: '100vh',
|
||||||
|
position: 'sticky',
|
||||||
|
left: '0px',
|
||||||
|
top: '0px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 2,
|
||||||
|
gap: 2,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex items-center justify-center gap-3'>
|
||||||
|
<Image
|
||||||
|
src="/databerry-logo-icon.png"
|
||||||
|
width="200"
|
||||||
|
height="200"
|
||||||
|
className='w-12'
|
||||||
|
alt="Databerry"
|
||||||
|
/>
|
||||||
|
<Typography component="h1" fontWeight="xl">
|
||||||
|
DB-GPT
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
px: 2
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button variant="outlined" color="primary" className='w-full'>+ 新建对话</Button>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
p: 2,
|
p: 2,
|
||||||
borderRight: '1px solid',
|
|
||||||
borderColor: 'divider',
|
|
||||||
display: {
|
display: {
|
||||||
xs: 'none',
|
xs: 'none',
|
||||||
sm: 'initial',
|
sm: 'initial',
|
||||||
},
|
},
|
||||||
},
|
maxHeight: '100%',
|
||||||
]}
|
overflow: 'auto',
|
||||||
>
|
}}
|
||||||
<List size="sm" sx={{ '--ListItem-radius': '8px' }}>
|
>
|
||||||
<ListItem nested>
|
<List size="sm" sx={{ '--ListItem-radius': '8px' }}>
|
||||||
<List
|
<ListItem nested>
|
||||||
size="sm"
|
<List
|
||||||
aria-labelledby="nav-list-browse"
|
size="sm"
|
||||||
sx={{
|
aria-labelledby="nav-list-browse"
|
||||||
'& .JoyListItemButton-root': { p: '8px' },
|
sx={{
|
||||||
}}
|
'& .JoyListItemButton-root': { p: '8px' },
|
||||||
>
|
}}
|
||||||
{menus.map((each) => (
|
>
|
||||||
<Link key={each.route} href={each.route}>
|
{mockHistory.map((each, index) => (
|
||||||
<ListItem>
|
<ListItem key={index}>
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
selected={each.active}
|
selected={chatSelect === each.id}
|
||||||
variant={each.active ? 'soft' : 'plain'}
|
variant={chatSelect === each.id ? 'soft' : 'plain'}
|
||||||
|
onClick={() => {
|
||||||
|
setChatSelect(each.id);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<ListItemDecorator
|
<ListItemContent>{each.summary}</ListItemContent>
|
||||||
sx={{
|
|
||||||
color: each.active ? 'inherit' : 'neutral.500',
|
|
||||||
'--ListItemDecorator-size': '26px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{each.icon}
|
|
||||||
</ListItemDecorator>
|
|
||||||
<ListItemContent>{each.label}</ListItemContent>
|
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</Link>
|
))}
|
||||||
))}
|
</List>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
</Box>
|
||||||
|
<div className='flex flex-col justify-between flex-1'>
|
||||||
|
<div></div>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 2,
|
||||||
|
borderTop: '1px solid',
|
||||||
|
borderColor: 'divider',
|
||||||
|
display: {
|
||||||
|
xs: 'none',
|
||||||
|
sm: 'initial',
|
||||||
|
},
|
||||||
|
position: 'sticky',
|
||||||
|
bottom: 0,
|
||||||
|
zIndex: 100,
|
||||||
|
background: 'var(--joy-palette-background-body)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<List size="sm" sx={{ '--ListItem-radius': '8px' }}>
|
||||||
|
<ListItem nested>
|
||||||
|
<List
|
||||||
|
size="sm"
|
||||||
|
aria-labelledby="nav-list-browse"
|
||||||
|
sx={{
|
||||||
|
'& .JoyListItemButton-root': { p: '8px' },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{menus.map((each) => (
|
||||||
|
<Link key={each.route} href={each.route}>
|
||||||
|
<ListItem>
|
||||||
|
<ListItemButton
|
||||||
|
color="neutral"
|
||||||
|
selected={each.active}
|
||||||
|
variant={each.active ? 'soft' : 'plain'}
|
||||||
|
>
|
||||||
|
<ListItemDecorator
|
||||||
|
sx={{
|
||||||
|
color: each.active ? 'inherit' : 'neutral.500',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{each.icon}
|
||||||
|
</ListItemDecorator>
|
||||||
|
<ListItemContent>{each.label}</ListItemContent>
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<ListItemButton
|
||||||
|
onClick={handleChangeTheme}
|
||||||
|
>
|
||||||
|
<ListItemDecorator>
|
||||||
|
{mode === 'dark' ? (
|
||||||
|
<DarkModeIcon fontSize="small"/>
|
||||||
|
) : (
|
||||||
|
<WbSunnyIcon fontSize="small"/>
|
||||||
|
)}
|
||||||
|
</ListItemDecorator>
|
||||||
|
<ListItemContent>Theme</ListItemContent>
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
</ListItem>
|
</Box>
|
||||||
</List>
|
</div>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
31
datacenter/utils/request.ts
Normal file
31
datacenter/utils/request.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
axios.defaults.baseURL = 'http://30.183.153.244:5000';
|
||||||
|
|
||||||
|
axios.defaults.timeout = 10000;
|
||||||
|
|
||||||
|
axios.interceptors.response.use(
|
||||||
|
response => response.data,
|
||||||
|
err => Promise.reject(err)
|
||||||
|
);
|
||||||
|
|
||||||
|
export const sendGetRequest = (url: string, qs?: { [key: string]: any }) => {
|
||||||
|
if (qs) {
|
||||||
|
const str = Object.keys(qs)
|
||||||
|
.filter(k => qs[k] !== undefined && qs[k] !== '')
|
||||||
|
.map(k => `${k}=${qs[k]}`)
|
||||||
|
.join('&');
|
||||||
|
if (str) {
|
||||||
|
url += `?${str}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axios.get(url, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": 'text/plain'
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
console.log(res, 'res');
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err, 'err');
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user