Merge remote-tracking branch 'origin/new-page-framework' into llm_framework

This commit is contained in:
aries_ckt 2023-06-27 16:50:57 +08:00
commit 6012ecc8c6
14 changed files with 1207 additions and 391 deletions

View File

@ -1,65 +1,76 @@
"use client"; 'use client'
import { useSearchParams } from 'next/navigation' import { useSearchParams } from 'next/navigation'
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react'
import { Table, Popover } from 'antd'; import { Table } from '@/lib/mui'
import moment from 'moment'; import { Popover } from 'antd'
const ChunkList = () => { const ChunkList = () => {
const spaceName = useSearchParams().get('spacename'); const spaceName = useSearchParams().get('spacename')
const documentId = useSearchParams().get('documentid'); const documentId = useSearchParams().get('documentid')
const [chunkList, setChunkList] = useState<any>([]); const [chunkList, setChunkList] = useState<any>([])
useEffect(() => { useEffect(() => {
async function fetchChunks() { async function fetchChunks() {
const res = await fetch(`http://localhost:8000/knowledge/${spaceName}/chunk/list`, { const res = await fetch(
method: 'POST', `http://localhost:8000/knowledge/${spaceName}/chunk/list`,
headers: { {
'Content-Type': 'application/json', method: 'POST',
}, headers: {
body: JSON.stringify({ 'Content-Type': 'application/json'
document_id: documentId },
}), body: JSON.stringify({
}); document_id: documentId
const data = await res.json(); })
if (data.success) {
setChunkList(data.data);
}
} }
fetchChunks(); )
}, []); const data = await res.json()
return ( if (data.success) {
<div className='p-4'> setChunkList(data.data)
<Table }
columns={[ }
{ fetchChunks()
title: 'Name', }, [])
dataIndex: 'doc_name', return (
key: 'doc_name', <div className="p-4">
align: 'center', <Table sx={{ '& thead th:nth-child(1)': { width: '40%' } }}>
}, <thead>
{ <tr>
title: 'Content', <th>Name</th>
dataIndex: 'content', <th>Content</th>
key: 'content', <th>Meta Data</th>
align: 'center', </tr>
render: (text: string, label: any) => { </thead>
return <Popover content={text} trigger="hover">{text.length < 10 ? `${text.slice(0, 10)}...` : text}</Popover>; <tbody>
} {chunkList.map((row: any) => (
}, <tr key={row.id}>
{ <td>{row.doc_name}</td>
title: 'Meta Data', <td>
dataIndex: 'meta_info', {
key: 'meta_info', <Popover content={row.content} trigger="hover">
align: 'center', {row.content.length > 10
render: (text: string, label: any) => { ? `${row.content.slice(0, 10)}...`
return <Popover content={JSON.stringify(text || '{}', null, 2)} trigger="hover">{text.length < 10 ? `${text.slice(0, 10)}...` : text}</Popover>; : row.content}
} </Popover>
}, }
]} </td>
dataSource={chunkList} <td>
/> {
</div> <Popover
) content={JSON.stringify(row.meta_info || '{}', null, 2)}
trigger="hover"
>
{row.meta_info.length > 10
? `${row.meta_info.slice(0, 10)}...`
: row.meta_info}
</Popover>
}
</td>
</tr>
))}
</tbody>
</Table>
</div>
)
} }
export default ChunkList; export default ChunkList

View File

@ -1,84 +1,74 @@
"use client"; 'use client'
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation' import { useRouter, useSearchParams } from 'next/navigation'
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react'
import { Table, Button } from 'antd'; import { Button, Table } from '@/lib/mui'
import moment from 'moment'; import moment from 'moment'
const Documents = () => { const Documents = () => {
const router = useRouter(); const router = useRouter()
const spaceName = useSearchParams().get('name'); const spaceName = useSearchParams().get('name')
const [documents, setDocuments] = useState<any>([]); const [documents, setDocuments] = useState<any>([])
useEffect(() => { useEffect(() => {
async function fetchDocuments() { async function fetchDocuments() {
const res = await fetch(`http://localhost:8000/knowledge/${spaceName}/document/list`, { const res = await fetch(
method: 'POST', `http://localhost:8000/knowledge/${spaceName}/document/list`,
headers: { {
'Content-Type': 'application/json', method: 'POST',
}, headers: {
body: JSON.stringify({}), 'Content-Type': 'application/json'
}); },
const data = await res.json(); body: JSON.stringify({})
if (data.success) {
setDocuments(data.data);
}
} }
fetchDocuments(); )
}, []); const data = await res.json()
return ( if (data.success) {
<div className='p-4'> setDocuments(data.data)
<Table }
columns={[ }
{ fetchDocuments()
title: 'Name', }, [])
dataIndex: 'doc_name', return (
key: 'doc_name', <div className="p-4">
align: 'center', <Table sx={{ '& thead th:nth-child(1)': { width: '40%' } }}>
}, <thead>
{ <tr>
title: 'Type', <th>Name</th>
dataIndex: 'doc_type', <th>Type</th>
key: 'doc_type', <th>Size</th>
align: 'center', <th>Last Synch</th>
}, <th>Status</th>
{ <th>Operation</th>
title: 'Size', </tr>
dataIndex: 'chunk_size', </thead>
key: 'chunk_size', <tbody>
align: 'center', {documents.map((row: any) => (
}, <tr key={row.id}>
{ <td>{row.doc_name}</td>
title: 'Last Synch', <td>{row.doc_type}</td>
dataIndex: 'last_sync', <td>{row.chunk_size}</td>
key: 'last_sync', <td>{moment(row.last_sync).format('YYYY-MM-DD HH:MM:SS')}</td>
align: 'center', <td>{row.status}</td>
render: (text: string) => moment(text).format('YYYY-MM-DD HH:MM:SS') <td>
}, {
{ <Button
title: 'Status', variant="outlined"
dataIndex: 'status', onClick={() => {
key: 'status', router.push(
align: 'center', `/datastores/documents/chunklist?spacename=${spaceName}&documentid=${row.id}`
}, )
{ }}
title: 'Operation', >
dataIndex: 'operation', Detail of Chunks
key: 'operation', </Button>
align: 'center', }
render: (_: any, label: any) => { </td>
return ( </tr>
<Button onClick={() => { ))}
router.push(`/datastores/documents/chunklist?spacename=${spaceName}&documentid=${label.id}`) </tbody>
}}>Detail of Chunks</Button> </Table>
) </div>
} )
},
]}
dataSource={documents}
/>
</div>
)
} }
export default Documents; export default Documents

View File

@ -1,233 +1,239 @@
'use client' 'use client'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import type { ProFormInstance } from '@ant-design/pro-components'; import type { ProFormInstance } from '@ant-design/pro-components'
import React, { useState, useRef, useEffect } from 'react' import React, { useState, useRef, useEffect } from 'react'
import { message } from 'antd'
import { import {
ProCard, Modal,
ProForm, Button,
ProFormCheckbox, Table,
ProFormDatePicker, Sheet,
ProFormDateRangePicker, Stack,
ProFormSelect, Box,
ProFormText, Input,
ProFormTextArea, styled
StepsForm } from '@/lib/mui'
} from '@ant-design/pro-components'
import { Button, Modal, Table, message } from 'antd' const Item = styled(Sheet)(({ theme }) => ({
width: '33%',
backgroundColor:
theme.palette.mode === 'dark' ? theme.palette.background.level1 : '#fff',
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: 'center',
borderRadius: 4,
color: theme.vars.palette.text.secondary
}))
const stepsOfAddingSpace = [
'Knowledge Space Configuration',
'Choose a Datasource type',
'Setup the Datasource'
]
const Index = () => { const Index = () => {
const router = useRouter(); const router = useRouter()
const formRef = useRef<ProFormInstance>(); const formRef = useRef<ProFormInstance>()
const [knowledgeSpaceList, setKnowledgeSpaceList] = useState<any>([]); const [activeStep, setActiveStep] = useState<number>(0)
const [knowledgeSpaceList, setKnowledgeSpaceList] = useState<any>([])
const [isAddKnowledgeSpaceModalShow, setIsAddKnowledgeSpaceModalShow] = const [isAddKnowledgeSpaceModalShow, setIsAddKnowledgeSpaceModalShow] =
useState<boolean>(false); useState<boolean>(false)
const [knowledgeSpaceName, setKnowledgeSpaceName] = useState<string>(''); const [knowledgeSpaceName, setKnowledgeSpaceName] = useState<string>('')
const [webPageUrl, setWebPageUrl] = useState<string>(''); const [webPageUrl, setWebPageUrl] = useState<string>('')
useEffect(() => { useEffect(() => {
async function fetchData() { async function fetchData() {
const res = await fetch('http://localhost:8000/knowledge/space/list', { const res = await fetch('http://localhost:8000/knowledge/space/list', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, },
body: JSON.stringify({}), body: JSON.stringify({})
}); })
const data = await res.json(); const data = await res.json()
if (data.success) { if (data.success) {
setKnowledgeSpaceList(data.data); setKnowledgeSpaceList(data.data)
} }
} }
fetchData(); fetchData()
}, []); }, [])
return ( return (
<> <>
<div className="page-header p-4"> <div className="page-header p-4">
<div className="page-header-title">Knowledge Spaces</div> <div className="page-header-title">Knowledge Spaces</div>
<Button onClick={() => setIsAddKnowledgeSpaceModalShow(true)} type='default'> <Button
onClick={() => setIsAddKnowledgeSpaceModalShow(true)}
variant="outlined"
>
+ New Knowledge Space + New Knowledge Space
</Button> </Button>
</div> </div>
<div className="page-body p-4"> <div className="page-body p-4">
<Table <Table sx={{ '& thead th:nth-child(1)': { width: '40%' } }}>
columns={[ <thead>
{ <tr>
title: 'Name', <th>Name</th>
dataIndex: 'name', <th>Provider</th>
key: 'name', <th>Owner</th>
align: 'center', </tr>
render: (text: string) => { </thead>
return <a href='javascript:;' onClick={() => router.push(`/datastores/documents?name=${text}`)}>{text}</a> <tbody>
} {knowledgeSpaceList.map((row: any) => (
}, <tr key={row.id}>
{ <td>
title: 'Provider', {
dataIndex: 'vector_type', <a
key: 'vector_type', href="javascript:;"
align: 'center', onClick={() =>
}, router.push(`/datastores/documents?name=${row.name}`)
{ }
title: 'Owner', >
dataIndex: 'owner', {row.name}
key: 'owner', </a>
align: 'center', }
}, </td>
]} <td>{row.vector_type}</td>
dataSource={knowledgeSpaceList} <td>{row.owner}</td>
/> </tr>
))}
</tbody>
</Table>
</div> </div>
<Modal <Modal
title="Add Knowledge Space" title="Add Knowledge Space"
footer={null} sx={{
width={900} display: 'flex',
justifyContent: 'center',
alignItems: 'center',
'z-index': 1000
}}
open={isAddKnowledgeSpaceModalShow} open={isAddKnowledgeSpaceModalShow}
onOk={() => console.log('ok')} onClose={() => setIsAddKnowledgeSpaceModalShow(false)}
onCancel={() => setIsAddKnowledgeSpaceModalShow(false)}
> >
<ProCard> <Sheet
<StepsForm<{ variant="outlined"
name: string sx={{
}> width: 800,
formRef={formRef} borderRadius: 'md',
onFinish={async () => { p: 3,
message.success('success') boxShadow: 'lg'
}} }}
formProps={{ >
validateMessages: { <Box sx={{ width: '100%' }}>
required: 'This is required' <Stack spacing={2} direction="row">
} {stepsOfAddingSpace.map((item: any, index: number) => (
}} <Item
submitter={{ key={item}
render: (props) => { sx={{ fontWeight: activeStep === index ? 'bold' : '' }}
if (props.step === 0) { >
return ( {item}
<Button type="default" onClick={async () => { </Item>
if (knowledgeSpaceName === '') { ))}
props.onSubmit?.() </Stack>
} else { </Box>
const res = await fetch('http://localhost:8000/knowledge/space/add', { {activeStep === 0 ? (
method: 'POST', <>
headers: { <Box sx={{ margin: '30px auto' }}>
'Content-Type': 'application/json', Knowledge Space Name:
}, <Input
body: JSON.stringify({ placeholder="Please input the name"
name: knowledgeSpaceName, onChange={(e: any) => setKnowledgeSpaceName(e.target.value)}
vector_type: "Chroma", />
owner: "keting", </Box>
desc: "test1" <Button
}), variant="outlined"
}); onClick={async () => {
const data = await res.json(); if (knowledgeSpaceName === '') {
if (data.success) { message.error('please input the name')
props.onSubmit?.(); return
message.success('success'); }
const res = await fetch('http://localhost:8000/knowledge/space/list', { const res = await fetch(
method: 'POST', 'http://localhost:8000/knowledge/space/add',
headers: { {
'Content-Type': 'application/json', method: 'POST',
}, headers: {
body: JSON.stringify({}), 'Content-Type': 'application/json'
}); },
const data = await res.json(); body: JSON.stringify({
if (data.success) { name: knowledgeSpaceName,
setKnowledgeSpaceList(data.data); vector_type: 'Chroma',
} owner: 'keting',
} else { desc: 'test1'
message.error(data.err_msg || 'failed'); })
} }
} )
}}> const data = await res.json()
Next {'>'} if (data.success) {
</Button> message.success('success')
); setActiveStep(1)
} else if (props.step === 1) { const res = await fetch(
return ( 'http://localhost:8000/knowledge/space/list',
<Button type="default" onClick={() => props.onSubmit?.()}> {
Web Page {'>'}
</Button>
);
}
return [
<Button key="gotoTwo" onClick={() => props.onPre?.()}>
Previous {'<'}
</Button>,
<Button
type="default"
key="goToTree"
onClick={async () => {
props.onSubmit?.();
const res = await fetch(`http://localhost:8000/knowledge/${knowledgeSpaceName}/document/add`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify({})
doc_name: webPageUrl,
doc_type: 'URL'
}),
});
const data = await res.json();
if (data.success) {
props.onSubmit?.();
message.success('success');
setIsAddKnowledgeSpaceModalShow(false);
} else {
message.error(data.err_msg || 'failed');
} }
}} )
> const data = await res.json()
Finish if (data.success) {
</Button>, setKnowledgeSpaceList(data.data)
]; }
}, } else {
}} message.error(data.err_msg || 'failed')
> }
<StepsForm.StepForm<{ }}
name: string >
}> Next
name="base" </Button>
title="Knowledge Space Configuration" </>
onFinish={async () => { ) : activeStep === 1 ? (
console.log(formRef.current?.getFieldsValue()) <>
return true <Box sx={{ margin: '30px auto' }}>
}} <Button variant="outlined" onClick={() => setActiveStep(2)}>
> Web Page
<ProFormText </Button>
name="name" </Box>
label="Knowledge Space Name" </>
width="lg" ) : (
placeholder="Please input the name" <>
rules={[{ required: true }]} <Box sx={{ margin: '30px auto' }}>
onChange={(e: any) => setKnowledgeSpaceName(e.target.value)} Web Page URL:
/> <Input
</StepsForm.StepForm> placeholder="Please input the Web Page URL"
<StepsForm.StepForm<{ onChange={(e: any) => setWebPageUrl(e.target.value)}
checkbox: string />
}> </Box>
name="checkbox" <Button
title="Choose a Datasource type" onClick={async () => {
onFinish={async () => { const res = await fetch(
console.log(formRef.current?.getFieldsValue()) `http://localhost:8000/knowledge/${knowledgeSpaceName}/document/add`,
return true {
}} method: 'POST',
> headers: {
</StepsForm.StepForm> 'Content-Type': 'application/json'
<StepsForm.StepForm },
name="time" body: JSON.stringify({
title="Setup the Datasource" doc_name: webPageUrl,
> doc_type: 'URL'
<ProFormText })
name="webPageUrl" }
label="Web Page URL" )
width="lg" const data = await res.json()
placeholder="Please input the Web Page URL" if (data.success) {
rules={[{ required: true }]} message.success('success')
onChange={(e: any) => setWebPageUrl(e.target.value)} setIsAddKnowledgeSpaceModalShow(false)
/> } else {
</StepsForm.StepForm> message.error(data.err_msg || 'failed')
</StepsForm> }
</ProCard> }}
>
Finish
</Button>
</>
)}
</Sheet>
</Modal> </Modal>
<style jsx>{` <style jsx>{`
.page-header { .page-header {
@ -235,7 +241,7 @@ const Index = () => {
justify-content: space-between; justify-content: space-between;
.page-header-title { .page-header-title {
font-size: 30px; font-size: 30px;
font-weight: bold font-weight: bold;
} }
} }
.datasource-type-wrap { .datasource-type-wrap {

View File

@ -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);
} }

View File

@ -1,25 +1,27 @@
"use client" "use client"
import './globals.css' import './globals.css'
import Header from '@/components/header'; import './nprogress.css';
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';
import TopProgressBar from '@/components/topProgressBar';
export default function RootLayout({ export default function RootLayout({
children, children,
}: { }: {
children: React.ReactNode children: React.ReactNode
}) { }) {
return ( return (
<html lang="en" className="min-h-full font-sans"> <html lang="en" className="min-h-full font-sans">
<body className={`min-h-screen font-sans`}> <body className={`min-h-screen font-sans`}>
<ThemeProvider theme={joyTheme}> <ThemeProvider theme={joyTheme}>
<CssVarsProvider theme={joyTheme} defaultMode="light"> <CssVarsProvider theme={joyTheme} defaultMode="light">
<TopProgressBar />
<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>

View File

@ -0,0 +1,32 @@
/* Make clicks pass-through */
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: var(--joy-palette-primary-500, #096BDE);
position: fixed;
z-index: 10031;
top: 0;
left: 0;
width: 100%;
height: 3px;
}
/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px var(--joy-palette-primary-500, #096BDE), 0 0 5px var(--joy-palette-primary-500, #096BDE);
opacity: 1;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}

View File

@ -1,9 +1,267 @@
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', {
})
}
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) => {
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) => {
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) => {
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>
) )
} }

View File

@ -34,7 +34,7 @@ const ChatBoxComp = ({
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [firstMsg, setFirstMsg] = useState<Message>(); const [firstMsg, setFirstMsg] = useState<Message>();
const [hideTemplateMessages, setHideTemplateMessages] = useState(false); const [hideTemplateMessages, setHideTemplateMessages] = useState(false);
console.log(messages, 'mmm');
const methods = useForm<z.infer<typeof Schema>>({ const methods = useForm<z.infer<typeof Schema>>({
resolver: zodResolver(Schema), resolver: zodResolver(Schema),
defaultValues: {}, defaultValues: {},
@ -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%',

View File

@ -1,16 +1,47 @@
"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: 'Home',
icon: <SmartToyRoundedIcon fontSize="small" />,
route: '/',
active: pathname === '/',
}, {
label: 'Agents', label: 'Agents',
icon: <SmartToyRoundedIcon fontSize="small" />, icon: <SmartToyRoundedIcon fontSize="small" />,
route: '/agents', route: '/agents',
@ -23,52 +54,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>
) )
}; };

View File

@ -0,0 +1,59 @@
import Router from 'next/router';
import NProgress from 'nprogress';
let timer: any;
let state: any;
let activeRequests = 0;
const delay = 250;
function load() {
if (state === 'loading') {
return;
}
state = 'loading';
timer = setTimeout(function () {
NProgress.start();
}, delay); // only show progress bar if it takes longer than the delay
}
function stop() {
if (activeRequests > 0) {
return;
}
state = 'stop';
clearTimeout(timer);
NProgress.done();
}
Router.events.on('routeChangeStart', load);
Router.events.on('routeChangeComplete', stop);
Router.events.on('routeChangeError', stop);
const originalFetch = window.fetch;
window.fetch = async function (...args) {
if (activeRequests === 0) {
load();
}
activeRequests++;
try {
const response = await originalFetch(...args);
return response;
} catch (error) {
return Promise.reject(error);
} finally {
activeRequests -= 1;
if (activeRequests === 0) {
stop();
}
}
};
export default function TopProgressBar() {
return null;
}

View File

@ -68,7 +68,6 @@ import {
signal: ctrl.signal, signal: ctrl.signal,
async onopen(response) { async onopen(response) {
console.log('onopen', response);
if ( if (
response.ok && response.ok &&
response.headers.get('content-type') === EventStreamContentType response.headers.get('content-type') === EventStreamContentType
@ -91,7 +90,6 @@ import {
throw new RetriableError(); throw new RetriableError();
}, },
onerror(err) { onerror(err) {
console.log('on error', err, Object.keys(err));
throw new Error(err); throw new Error(err);
// if (err instanceof FatalError) { // if (err instanceof FatalError) {
// ctrl.abort(); // ctrl.abort();

View File

@ -17,7 +17,8 @@
"@mui/icons-material": "^5.11.16", "@mui/icons-material": "^5.11.16",
"@mui/joy": "5.0.0-alpha.72", "@mui/joy": "5.0.0-alpha.72",
"@mui/lab": "5.0.0-alpha.124", "@mui/lab": "5.0.0-alpha.124",
"@mui/material": "^5.11.14", "@mui/material": "^5.13.6",
"@mui/styled-engine-sc": "^5.12.0",
"@mui/utils": "^5.11.13", "@mui/utils": "^5.11.13",
"@prisma/client": "^4.12.0", "@prisma/client": "^4.12.0",
"@types/node": "20.3.1", "@types/node": "20.3.1",
@ -33,16 +34,21 @@
"moment": "^2.29.4", "moment": "^2.29.4",
"next": "13.4.7", "next": "13.4.7",
"next-auth": "^4.20.1", "next-auth": "^4.20.1",
"nprogress": "^0.2.0",
"postcss": "8.4.24", "postcss": "8.4.24",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hook-form": "^7.43.8", "react-hook-form": "^7.43.8",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"styled-components": "^5.3.11",
"swr": "^2.1.1", "swr": "^2.1.1",
"tailwindcss": "3.3.2", "tailwindcss": "3.3.2",
"typescript": "5.1.3", "typescript": "5.1.3",
"zod": "^3.19.1" "zod": "^3.19.1"
},
"devDependencies": {
"@types/nprogress": "^0.2.0"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@ -706,6 +712,17 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@babel/helper-annotate-as-pure": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
"integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
"dependencies": {
"@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": { "node_modules/@babel/helper-compilation-targets": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz",
@ -985,6 +1002,20 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@babel/plugin-syntax-jsx": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
"integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": { "node_modules/@babel/plugin-transform-modules-commonjs": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz",
@ -1272,6 +1303,11 @@
} }
} }
}, },
"node_modules/@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"node_modules/@emotion/unitless": { "node_modules/@emotion/unitless": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz", "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz",
@ -1638,7 +1674,7 @@
}, },
"node_modules/@mui/material": { "node_modules/@mui/material": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/material/-/material-5.13.6.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.6.tgz",
"integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==", "integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
@ -1657,6 +1693,10 @@
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
}, },
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.5.0", "@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0", "@emotion/styled": "^11.3.0",
@ -1730,6 +1770,31 @@
} }
} }
}, },
"node_modules/@mui/styled-engine-sc": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz",
"integrity": "sha512-3MgYoY2YG5tx0E5oKqvCv94oL0ABVBr+qpcyvciXW/v0wzPG6bXvuZV80GHYlJfasgnnRa1AbRWf5a9FcX8v6g==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"prop-types": "^15.8.1"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"peerDependencies": {
"@types/styled-components": "^5.1.14",
"styled-components": "^5.3.1"
},
"peerDependenciesMeta": {
"@types/styled-components": {
"optional": true
}
}
},
"node_modules/@mui/system": { "node_modules/@mui/system": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz", "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz",
@ -2202,6 +2267,12 @@
"resolved": "https://registry.npmmirror.com/@types/node/-/node-20.3.1.tgz", "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.3.1.tgz",
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg=="
}, },
"node_modules/@types/nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/@types/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==",
"dev": true
},
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz",
@ -2727,6 +2798,21 @@
"@babel/core": "^7.0.0-0" "@babel/core": "^7.0.0-0"
} }
}, },
"node_modules/babel-plugin-styled-components": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz",
"integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-module-imports": "^7.22.5",
"@babel/plugin-syntax-jsx": "^7.22.5",
"lodash": "^4.17.21",
"picomatch": "^2.3.1"
},
"peerDependencies": {
"styled-components": ">= 2"
}
},
"node_modules/babel-plugin-transform-replace-object-assign": { "node_modules/babel-plugin-transform-replace-object-assign": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz",
@ -2926,6 +3012,14 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001507", "version": "1.0.30001507",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz",
@ -3144,6 +3238,24 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
"engines": {
"node": ">=4"
}
},
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/cssesc": { "node_modules/cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@ -5670,6 +5782,11 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
},
"node_modules/oauth": { "node_modules/oauth": {
"version": "0.9.15", "version": "0.9.15",
"resolved": "https://registry.npmmirror.com/oauth/-/oauth-0.9.15.tgz", "resolved": "https://registry.npmmirror.com/oauth/-/oauth-0.9.15.tgz",
@ -7409,6 +7526,59 @@
"inline-style-parser": "0.1.1" "inline-style-parser": "0.1.1"
} }
}, },
"node_modules/styled-components": {
"version": "5.3.11",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz",
"integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==",
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/styled-components"
},
"peerDependencies": {
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0",
"react-is": ">= 16.8.0"
}
},
"node_modules/styled-components/node_modules/@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"node_modules/styled-components/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"engines": {
"node": ">=4"
}
},
"node_modules/styled-components/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/styled-jsx": { "node_modules/styled-jsx": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz", "resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz",
@ -8690,6 +8860,14 @@
"jsesc": "^2.5.1" "jsesc": "^2.5.1"
} }
}, },
"@babel/helper-annotate-as-pure": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
"integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
"requires": {
"@babel/types": "^7.22.5"
}
},
"@babel/helper-compilation-targets": { "@babel/helper-compilation-targets": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz",
@ -8900,6 +9078,14 @@
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.5.tgz",
"integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==" "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q=="
}, },
"@babel/plugin-syntax-jsx": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
"integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
"requires": {
"@babel/helper-plugin-utils": "^7.22.5"
}
},
"@babel/plugin-transform-modules-commonjs": { "@babel/plugin-transform-modules-commonjs": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz",
@ -9124,6 +9310,11 @@
"@emotion/utils": "^1.2.1" "@emotion/utils": "^1.2.1"
} }
}, },
"@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"@emotion/unitless": { "@emotion/unitless": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz", "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz",
@ -9369,7 +9560,7 @@
}, },
"@mui/material": { "@mui/material": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/material/-/material-5.13.6.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.6.tgz",
"integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==", "integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==",
"requires": { "requires": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
@ -9414,6 +9605,15 @@
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
} }
}, },
"@mui/styled-engine-sc": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz",
"integrity": "sha512-3MgYoY2YG5tx0E5oKqvCv94oL0ABVBr+qpcyvciXW/v0wzPG6bXvuZV80GHYlJfasgnnRa1AbRWf5a9FcX8v6g==",
"requires": {
"@babel/runtime": "^7.21.0",
"prop-types": "^15.8.1"
}
},
"@mui/system": { "@mui/system": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz", "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz",
@ -9711,6 +9911,12 @@
"resolved": "https://registry.npmmirror.com/@types/node/-/node-20.3.1.tgz", "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.3.1.tgz",
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg=="
}, },
"@types/nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/@types/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==",
"dev": true
},
"@types/parse-json": { "@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz",
@ -10134,6 +10340,18 @@
"@babel/helper-define-polyfill-provider": "^0.4.0" "@babel/helper-define-polyfill-provider": "^0.4.0"
} }
}, },
"babel-plugin-styled-components": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz",
"integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-module-imports": "^7.22.5",
"@babel/plugin-syntax-jsx": "^7.22.5",
"lodash": "^4.17.21",
"picomatch": "^2.3.1"
}
},
"babel-plugin-transform-replace-object-assign": { "babel-plugin-transform-replace-object-assign": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz",
@ -10290,6 +10508,11 @@
"resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz",
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="
}, },
"camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="
},
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001507", "version": "1.0.30001507",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz",
@ -10474,6 +10697,21 @@
"which": "^2.0.1" "which": "^2.0.1"
} }
}, },
"css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="
},
"css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"requires": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"cssesc": { "cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@ -12544,6 +12782,11 @@
} }
} }
}, },
"nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
},
"oauth": { "oauth": {
"version": "0.9.15", "version": "0.9.15",
"resolved": "https://registry.npmmirror.com/oauth/-/oauth-0.9.15.tgz", "resolved": "https://registry.npmmirror.com/oauth/-/oauth-0.9.15.tgz",
@ -13839,6 +14082,43 @@
"inline-style-parser": "0.1.1" "inline-style-parser": "0.1.1"
} }
}, },
"styled-components": {
"version": "5.3.11",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz",
"integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"dependencies": {
"@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"styled-jsx": { "styled-jsx": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz", "resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz",

View File

@ -18,7 +18,8 @@
"@mui/icons-material": "^5.11.16", "@mui/icons-material": "^5.11.16",
"@mui/joy": "5.0.0-alpha.72", "@mui/joy": "5.0.0-alpha.72",
"@mui/lab": "5.0.0-alpha.124", "@mui/lab": "5.0.0-alpha.124",
"@mui/material": "^5.11.14", "@mui/material": "^5.13.6",
"@mui/styled-engine-sc": "^5.12.0",
"@mui/utils": "^5.11.13", "@mui/utils": "^5.11.13",
"@prisma/client": "^4.12.0", "@prisma/client": "^4.12.0",
"@types/node": "20.3.1", "@types/node": "20.3.1",
@ -34,15 +35,20 @@
"moment": "^2.29.4", "moment": "^2.29.4",
"next": "13.4.7", "next": "13.4.7",
"next-auth": "^4.20.1", "next-auth": "^4.20.1",
"nprogress": "^0.2.0",
"postcss": "8.4.24", "postcss": "8.4.24",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hook-form": "^7.43.8", "react-hook-form": "^7.43.8",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"styled-components": "^5.3.11",
"swr": "^2.1.1", "swr": "^2.1.1",
"tailwindcss": "3.3.2", "tailwindcss": "3.3.2",
"typescript": "5.1.3", "typescript": "5.1.3",
"zod": "^3.19.1" "zod": "^3.19.1"
},
"devDependencies": {
"@types/nprogress": "^0.2.0"
} }
} }

View 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');
})
}