add prompt js page
This commit is contained in:
parent
d53c18606e
commit
3da62fd254
@ -4,6 +4,9 @@ import { App as ContainerApp } from './pages/container';
|
||||
import { App as PanelApp } from './pages/panel';
|
||||
import { App as PublishApp } from './pages/publish';
|
||||
import { App as CodeEditorApp } from './pages/code-editor';
|
||||
import { App as MapApp } from './pages/map';
|
||||
import { App as PromptApp } from './pages/prompt';
|
||||
|
||||
import '@abearxiong/container/dist/container.css';
|
||||
|
||||
export const App = () => {
|
||||
@ -20,6 +23,8 @@ export const App = () => {
|
||||
<Route path='/panel/*' element={<PanelApp />} />
|
||||
<Route path='/publish/*' element={<PublishApp />} />
|
||||
<Route path='/code-editor' element={<CodeEditorApp />} />
|
||||
<Route path='/map/*' element={<MapApp />} />
|
||||
<Route path='/prompt/*' element={<PromptApp />} />
|
||||
<Route path='/404' element={<div>404</div>} />
|
||||
<Route path='*' element={<div>404</div>} />
|
||||
</Routes>
|
||||
|
BIN
src/assets/fonts/D-DIN/D-DIN-Bold.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DIN-Bold.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DIN-Italic.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DIN-Italic.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DIN.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DIN.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DINCondensed-Bold.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DINCondensed-Bold.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DINCondensed.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DINCondensed.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DINExp-Bold.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DINExp-Bold.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DINExp-Italic.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DINExp-Italic.woff
Normal file
Binary file not shown.
BIN
src/assets/fonts/D-DIN/D-DINExp.woff
Normal file
BIN
src/assets/fonts/D-DIN/D-DINExp.woff
Normal file
Binary file not shown.
64
src/assets/fonts/D-DIN/font.css
Normal file
64
src/assets/fonts/D-DIN/font.css
Normal file
@ -0,0 +1,64 @@
|
||||
/* #### Generated By: http://www.cufonfonts.com #### */
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('D-DIN.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN-Italic';
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
src: url('D-DIN-Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN-Bold';
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
src: url('D-DIN-Bold.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN Condensed';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('D-DINCondensed.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN Exp';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('D-DINExp.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN Exp-Italic';
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
src: url('D-DINExp-Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN Condensed-Bold';
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
src: url('D-DINCondensed-Bold.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'D-DIN Exp-Bold';
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
src: url('D-DINExp-Bold.woff') format('woff');
|
||||
}
|
Binary file not shown.
BIN
src/assets/fonts/Montserrat/Montserrat-VariableFont_wght.ttf
Normal file
BIN
src/assets/fonts/Montserrat/Montserrat-VariableFont_wght.ttf
Normal file
Binary file not shown.
16
src/assets/fonts/Montserrat/font.css
Normal file
16
src/assets/fonts/Montserrat/font.css
Normal file
@ -0,0 +1,16 @@
|
||||
/* #### Generated By: http://www.cufonfonts.com #### */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
src: url('Montserrat-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Montserrat-Italic';
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
src: url('Montserrat-Italic-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
BIN
src/assets/fonts/Orbitron/Orbitron-VariableFont_wght.ttf
Normal file
BIN
src/assets/fonts/Orbitron/Orbitron-VariableFont_wght.ttf
Normal file
Binary file not shown.
6
src/assets/fonts/Orbitron/font.css
Normal file
6
src/assets/fonts/Orbitron/font.css
Normal file
@ -0,0 +1,6 @@
|
||||
@font-face {
|
||||
font-family: 'Orbitron';
|
||||
font-style: normal;
|
||||
font-weight: 400 900;
|
||||
src: url('Orbitron-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
3
src/assets/fonts/font.css
Normal file
3
src/assets/fonts/font.css
Normal file
@ -0,0 +1,3 @@
|
||||
@import "./D-DIN/font.css";
|
||||
@import "./Montserrat/font.css";
|
||||
@import "./Orbitron/font.css";
|
@ -1,3 +1,5 @@
|
||||
@import './fonts/font.css';
|
||||
|
||||
.scrollbar {
|
||||
/* 整个滚动条 */
|
||||
&::-webkit-scrollbar {
|
||||
@ -14,7 +16,7 @@
|
||||
/* 滚动条滑块(竖向:vertical 横向:horizontal) */
|
||||
&::-webkit-scrollbar-thumb {
|
||||
cursor: pointer;
|
||||
background-color: black;
|
||||
background-color: #c1c1c1;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
@ -12,4 +12,7 @@
|
||||
h3 {
|
||||
@apply text-lg font-bold;
|
||||
}
|
||||
.layout-menu {
|
||||
@apply bg-gray-900 p-2 text-white flex justify-between h-12;
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,35 @@ body {
|
||||
#root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.w-tc-editor, .w-tc-editor > textarea {
|
||||
/* 整个滚动条 */
|
||||
&::-webkit-scrollbar {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
/* 滚动条有滑块的轨道部分 */
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background-color: transparent;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* 滚动条滑块(竖向:vertical 横向:horizontal) */
|
||||
&::-webkit-scrollbar-thumb {
|
||||
cursor: pointer;
|
||||
background-color: #c1c1c1;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 滚动条滑块hover */
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #999999;
|
||||
}
|
||||
|
||||
/* 同时有垂直和水平滚动条时交汇的部分 */
|
||||
&::-webkit-scrollbar-corner {
|
||||
display: block; /* 修复交汇时出现的白块 */
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import CodeEditor from '@uiw/react-textarea-code-editor';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
@ -7,29 +8,35 @@ type Props = {
|
||||
onChange?: (data: string) => void;
|
||||
readonly?: boolean;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
language?: string;
|
||||
listen?: boolean;
|
||||
};
|
||||
export const TextArea = (props: Props) => {
|
||||
const [code, setCode] = useState<string>('');
|
||||
useEffect(() => {
|
||||
setCode(props.value || '');
|
||||
}, []);
|
||||
}, [props.value]);
|
||||
const _onChange = (value: string) => {
|
||||
setCode(value);
|
||||
props.onChange && props.onChange(value);
|
||||
if (props.onChange) {
|
||||
props.onChange(value);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className={clsx('min-h-16 max-h-52 overflow-scroll p-1 ', props.className)}>
|
||||
<div className={clsx('min-h-16 max-h-52 overflow-scroll scrollbar p-1 ', props.className)}>
|
||||
<CodeEditor
|
||||
value={code}
|
||||
language='js'
|
||||
className='border rounded-sm'
|
||||
className='border rounded-sm '
|
||||
readOnly={props.readonly}
|
||||
placeholder='Please enter JS code.'
|
||||
onChange={(evn) => _onChange(evn.target.value)}
|
||||
padding={10}
|
||||
style={{
|
||||
backgroundColor: '#f5f5f5',
|
||||
// backgroundColor: '#f5f5f5',
|
||||
fontFamily: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace',
|
||||
...props.style,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Button, Input, message, Modal, Table } from 'antd';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Fragment, useEffect, useMemo, useState } from 'react';
|
||||
import { TextArea } from '../components/TextArea';
|
||||
import { useContainerStore } from '../store';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { Form } from 'antd';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { EditOutlined, SettingOutlined, LinkOutlined, SaveOutlined, DeleteOutlined, LeftOutlined } from '@ant-design/icons';
|
||||
import clsx from 'clsx';
|
||||
const FormModal = () => {
|
||||
const [form] = Form.useForm();
|
||||
const containerStore = useContainerStore(
|
||||
@ -22,8 +24,6 @@ const FormModal = () => {
|
||||
const open = containerStore.showEdit;
|
||||
if (open) {
|
||||
form.setFieldsValue(containerStore.formData || {});
|
||||
} else {
|
||||
form.resetFields();
|
||||
}
|
||||
}, [containerStore.showEdit]);
|
||||
const onFinish = async (values: any) => {
|
||||
@ -59,7 +59,12 @@ const FormModal = () => {
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='code' label='code'>
|
||||
<TextArea value={containerStore.formData.code} />
|
||||
<TextArea
|
||||
value={containerStore.formData.code}
|
||||
style={{
|
||||
height: '200px',
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label=' ' colon={false}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
@ -85,111 +90,122 @@ export const ContainerList = () => {
|
||||
getList: state.getList,
|
||||
loading: state.loading,
|
||||
publishData: state.publishData,
|
||||
updateData: state.updateData,
|
||||
formData: state.formData,
|
||||
};
|
||||
}),
|
||||
);
|
||||
const [codeEdit, setCodeEdit] = useState(false);
|
||||
const [code, setCode] = useState('');
|
||||
useEffect(() => {
|
||||
containerStore.getList();
|
||||
}, []);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
render: (text: string) => {
|
||||
return (
|
||||
<div
|
||||
className='w-40 truncate cursor-pointer'
|
||||
title={text}
|
||||
onClick={() => {
|
||||
copy(text);
|
||||
message.success('copy success');
|
||||
}}>
|
||||
{text}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Title',
|
||||
dataIndex: 'title',
|
||||
},
|
||||
{
|
||||
title: 'Code',
|
||||
dataIndex: 'code',
|
||||
width: '40%',
|
||||
render: (text: string, record: any) => {
|
||||
return <TextArea value={text} readonly />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Source',
|
||||
dataIndex: 'source',
|
||||
},
|
||||
{
|
||||
title: 'Operation',
|
||||
dataIndex: 'operation',
|
||||
render: (text: string, record: any) => {
|
||||
return (
|
||||
<div className='flex gap-2'>
|
||||
<Button
|
||||
type='primary'
|
||||
onClick={() => {
|
||||
containerStore.setFormData(record);
|
||||
containerStore.setShowEdit(true);
|
||||
}}>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
navicate('/container/preview/' + record.id);
|
||||
}}>
|
||||
Preview
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
containerStore.publishData(record);
|
||||
}}>
|
||||
Publish
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
onClick={() => {
|
||||
containerStore.deleteData(record.id);
|
||||
}}>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
const onAdd = () => {
|
||||
containerStore.setFormData({});
|
||||
containerStore.setShowEdit(true);
|
||||
};
|
||||
return (
|
||||
<div className='w-full h-full flex flex-col'>
|
||||
<div className='mb-2 w-full p-2 bg-white rounded-lg'>
|
||||
<Button
|
||||
className='w-20 '
|
||||
type='primary'
|
||||
onClick={() => {
|
||||
containerStore.setFormData({});
|
||||
containerStore.setShowEdit(true);
|
||||
}}>
|
||||
Add
|
||||
</Button>
|
||||
<div className='flex flex-grow overflow-hidden h-full'>
|
||||
<div className='flex-grow overflow-auto scrollbar bg-gray-100'>
|
||||
<div className='flex flex-wrap gap-x-10 gap-y-4 rounded pt-10 justify-center'>
|
||||
{containerStore.list.length > 0 &&
|
||||
containerStore.list.map((item) => {
|
||||
return (
|
||||
<Fragment key={item.id}>
|
||||
<div
|
||||
className='flex text-sm gap flex-col w-[400px] max-h-[400px] bg-white p-4 rounded-lg'
|
||||
key={item.id}
|
||||
onClick={() => {
|
||||
setCode(item.code);
|
||||
containerStore.setFormData(item);
|
||||
setCodeEdit(true);
|
||||
}}>
|
||||
<div className='px-4 cursor-pointer'>
|
||||
<div
|
||||
className='font-bold'
|
||||
onClick={(e) => {
|
||||
copy(item.code);
|
||||
e.stopPropagation();
|
||||
message.success('copy code success');
|
||||
}}>
|
||||
{item.title || '-'}
|
||||
</div>
|
||||
<div className='font-light'>{item.description ? item.description : '-'}</div>
|
||||
</div>
|
||||
<div className='w-full text-xs'>
|
||||
<TextArea className='max-h-[240px] scrollbar' value={item.code} readonly />
|
||||
</div>
|
||||
<div className='flex mt-2 '>
|
||||
<Button.Group>
|
||||
<Button onClick={() => containerStore.publishData(item)} icon={<SettingOutlined />}></Button>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
containerStore.setFormData(item);
|
||||
containerStore.setShowEdit(true);
|
||||
setCodeEdit(false);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
icon={<EditOutlined />}></Button>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
// navicate('/container/preview/' + item.id);
|
||||
window.open('/container/preview/' + item.id);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
icon={<LinkOutlined />}></Button>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
containerStore.deleteData(item.id);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
icon={<DeleteOutlined />}></Button>
|
||||
</Button.Group>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
{new Array(4).fill(0).map((_, index) => {
|
||||
return <div key={index} className='w-[400px]'></div>;
|
||||
})}
|
||||
{containerStore.list.length == 0 && (
|
||||
<div className='text-center' key={'no-data'}>
|
||||
No Data
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={clsx('bg-gray-100 border-l border-bg-slate-300 w-[600px] flex-shrink-0', !codeEdit && 'hidden')}>
|
||||
<div className='bg-white p-2'>
|
||||
<div className='mt-2 ml-2 flex gap-2'>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setCodeEdit(false);
|
||||
containerStore.setFormData({});
|
||||
}}
|
||||
icon={<LeftOutlined />}></Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
console.log('save', containerStore.formData);
|
||||
containerStore.updateData({ ...containerStore.formData, code });
|
||||
}}
|
||||
icon={<SaveOutlined />}></Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='h-[94%] p-2 rounded-2 shadow-sm'>
|
||||
<TextArea
|
||||
value={code}
|
||||
onChange={(value) => {
|
||||
setCode(value);
|
||||
}}
|
||||
className='h-full max-h-full scrollbar'
|
||||
style={{ overflow: 'auto' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-grow overflow-scroll'>
|
||||
<Table
|
||||
pagination={false}
|
||||
scroll={{
|
||||
y: 600,
|
||||
}}
|
||||
loading={containerStore.loading}
|
||||
dataSource={containerStore.list}
|
||||
rowKey='id'
|
||||
columns={columns}
|
||||
/>
|
||||
</div>
|
||||
<div className='h-2'></div>
|
||||
<FormModal />
|
||||
</div>
|
||||
);
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
import { ContainerList } from './edit/List';
|
||||
import { Main } from './layouts';
|
||||
import { Preview } from './preview';
|
||||
import { Preview, PreviewWrapper } from './preview';
|
||||
export const App = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route element={<Main />}>
|
||||
<Route path='/' element={<Navigate to='/container/edit/list' />}></Route>
|
||||
<Route path='edit/list' element={<ContainerList />} />
|
||||
<Route path='preview/:id' element={<Preview />} />
|
||||
|
||||
<Route path='preview/:id/wrapper' element={<PreviewWrapper />} />
|
||||
<Route path='/' element={<div>Home</div>} />
|
||||
</Route>
|
||||
<Route path='preview/:id' element={<Preview />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
@ -1,15 +1,41 @@
|
||||
import { Outlet } from 'react-router';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import { Outlet, useLocation } from 'react-router';
|
||||
import { useContainerStore } from '../store';
|
||||
import { useEffect } from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
|
||||
export const Main = () => {
|
||||
const containerStore = useContainerStore(
|
||||
useShallow((state) => {
|
||||
return {
|
||||
setFormData: state.setFormData,
|
||||
setShowEdit: state.setShowEdit,
|
||||
};
|
||||
}),
|
||||
);
|
||||
const location = useLocation();
|
||||
const isEdit = location.pathname.includes('edit/list');
|
||||
return (
|
||||
<div className='flex w-full h-full flex-col bg-gray-200'>
|
||||
<div className='h-12 bg-white p-2 mb-2'>Container</div>
|
||||
<div className='flex w-full h-full flex-col'>
|
||||
<div className='layout-menu'>
|
||||
Container
|
||||
<Button
|
||||
className={!isEdit ? 'hidden' : ''}
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
console.log('add');
|
||||
containerStore.setFormData({});
|
||||
containerStore.setShowEdit(true);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className='flex'
|
||||
style={{
|
||||
height: 'calc(100vh - 4rem)',
|
||||
height: 'calc(100vh - 3rem)',
|
||||
}}>
|
||||
<div className='flex-grow overflow-hidden mx-2'>
|
||||
<div className='flex-grow overflow-hidden'>
|
||||
<div className='w-full h-full rounded-lg'>
|
||||
<Outlet />
|
||||
</div>
|
||||
|
@ -57,6 +57,75 @@ export const Preview = () => {
|
||||
const containerRef = useRef<Container | null>(null);
|
||||
const [data, setData] = useState<any>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) return;
|
||||
fetch();
|
||||
}, []);
|
||||
const fetch = async () => {
|
||||
const res = await query.post({
|
||||
path: 'container',
|
||||
key: 'get',
|
||||
id,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
const data = res.data;
|
||||
// setData([data]);
|
||||
console.log('data', data);
|
||||
const code = {
|
||||
id: data.id,
|
||||
title: data.title,
|
||||
codeId: data.id,
|
||||
code: data.code,
|
||||
data: data.data,
|
||||
};
|
||||
init([code]);
|
||||
} else {
|
||||
message.error(res.msg || 'Failed to fetch data');
|
||||
}
|
||||
};
|
||||
const refresh = (data: any) => {
|
||||
if (!data.id) return;
|
||||
const code = {
|
||||
id: data.id,
|
||||
title: data.title,
|
||||
codeId: data.id,
|
||||
code: data.code,
|
||||
data: data.data,
|
||||
hash: '',
|
||||
};
|
||||
init([code], true);
|
||||
};
|
||||
useListener(id, { refresh: refresh });
|
||||
const init = async (data: any[], replace: boolean = false) => {
|
||||
// console.log('data', data, ref.current);
|
||||
if (containerRef.current) {
|
||||
const container = containerRef.current;
|
||||
console.log('data', data, container.data);
|
||||
container.updateData(data);
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 2000);
|
||||
});
|
||||
console.log('update---data', data, container.data);
|
||||
container.destroy(id!);
|
||||
container.renderId(id!);
|
||||
return;
|
||||
}
|
||||
console.log('data', containerRef.current);
|
||||
const container = new Container({
|
||||
root: ref.current!,
|
||||
data: data as any,
|
||||
showChild: false,
|
||||
});
|
||||
container.renderId(id!);
|
||||
containerRef.current = container;
|
||||
};
|
||||
return <div className='mx-auto border bg-gray-200 h-full w-full' ref={ref}></div>;
|
||||
};
|
||||
export const PreviewWrapper = () => {
|
||||
const params = useParams<{ id: string }>();
|
||||
const id = params.id;
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const containerRef = useRef<Container | null>(null);
|
||||
useEffect(() => {
|
||||
if (!id) return;
|
||||
fetch();
|
||||
@ -121,13 +190,13 @@ export const Preview = () => {
|
||||
};
|
||||
return (
|
||||
<div className='w-full h-full bg-gray-200'>
|
||||
<div className='text-center mb-10 font-bold text-4xl mt-4 '>Preview</div>
|
||||
<div className='text-center mb-4 pt-2 font-bold text-4xl '>Preview</div>
|
||||
<div
|
||||
className='flex '
|
||||
style={{
|
||||
height: 'calc(100% - 32px)',
|
||||
}}>
|
||||
<div className='mx-auto border bg-white h-h-full w-[80%] h-[80%]' ref={ref}></div>
|
||||
<div className='mx-auto border bg-white h-h-full w-[80%] h-[80%] overflow-y-auto' ref={ref}></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
16
src/pages/map/index.tsx
Normal file
16
src/pages/map/index.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
export const App = () => {
|
||||
const serverList = ['container', 'panel', 'publish', 'code-editor', 'map'];
|
||||
return (
|
||||
<div className='p-2 w-full h-full bg-gray-200'>
|
||||
<div className='flex flex-col w-1/2 m-auto bg-white p-4 border rounded-md shadow-md'>
|
||||
{serverList.map((item) => {
|
||||
return (
|
||||
<div key={item} className='flex flex-col'>
|
||||
<div>{item}</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
57
src/pages/prompt/index.tsx
Normal file
57
src/pages/prompt/index.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import { Button, Form, Input } from 'antd';
|
||||
import { TextArea } from '../container/components/TextArea';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export const App = () => {
|
||||
const [form] = Form.useForm();
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
const onSave = () => {
|
||||
//
|
||||
};
|
||||
const isEdit = form.getFieldValue('id');
|
||||
return (
|
||||
<div className='w-full h-full felx flex-col bg-gray-200'>
|
||||
<h1 className='text-center py-4'>Prompt JS Code Generate</h1>
|
||||
<div className='py-2 px-4 w-3/4 min-w-[600px] mx-auto border shadow rounded bg-white'>
|
||||
<Form form={form} onFinish={onFinish} className='mt-4' labelCol={{ span: 4 }}>
|
||||
<Form.Item name='id' hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='title' label='Title'>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='description' label='Description'>
|
||||
<Input.TextArea rows={4} />
|
||||
</Form.Item>
|
||||
<Form.Item name='code' label='Code'>
|
||||
<TextArea className='max-h-full' style={{ minHeight: 300 }} />
|
||||
</Form.Item>
|
||||
<Form.Item label=' ' colon={false}>
|
||||
<div className='flex gap-2'>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
Generate
|
||||
</Button>
|
||||
<Button htmlType='reset'>Reset</Button>
|
||||
<Button
|
||||
type='primary'
|
||||
onClick={() => {
|
||||
//
|
||||
}}>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
className={clsx(isEdit ? 'block' : 'hidden')}
|
||||
onClick={() => {
|
||||
//
|
||||
}}>
|
||||
Preview
|
||||
</Button>
|
||||
</div>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user