embedwith/bunapp/App.jsx

136 lines
3.9 KiB
JavaScript

import React, { StrictMode, useState, useMemo } from 'react'
import { createRoot } from 'react-dom/client'
import { useUnstrictEffect as useEffect } from './useUnstrictEffect'
const ApiTest = function ({ path, method, params }) {
const [ submit_enabled, setSubmitEnabled ] = useState(true)
const [ result, setResult ] = useState(null)
const func_click_submit = useMemo(() => {
return () => {
setSubmitEnabled(false)
let endpoint_full
let body
if (method === 'GET') {
endpoint_full = path + '?' + new URLSearchParams({
p: JSON.stringify(params),
}).toString()
}
else if (method === 'POST') {
endpoint_full = path
body = JSON.stringify(params)
}
else {
throw `bad method : ${method}`
}
fetch(endpoint_full, { method, body }).then(async (resp) => {
const resp_json = await resp.json()
setResult(resp_json)
return
}).catch(console.error).finally(() => {
setSubmitEnabled(true)
return
})
return
}
}, [])
const jsx_btn_submit = (<button disabled={submit_enabled === false} onClick={func_click_submit}>{'do request'}</button>)
return (
<div>
<div style={{ fontSize: `${2.5*8}px`, fontWeight: 'bold', padding: `8px` }}>{'Input'}</div>
<div style={{ whiteSpace: 'pre-wrap' }}>
{JSON.stringify({ path, method, params }, null, 2)}
</div>
<div style={{height: `${2*8}px` }} />
{jsx_btn_submit}
<div style={{height: `${2*8}px` }} />
<div style={{ fontSize: `${2.5*8}px`, fontWeight: 'bold', padding: `8px` }}>{'Output'}</div>
<div style={{ whiteSpace: 'pre-wrap' }}>
{JSON.stringify(result, null, 2)}
</div>
</div>
)
}
const HEIGHT_PANEL_HEADER = `${8*8}px`
const DemoStash = function () {
return (
<div style={{
position: 'absolute', top: '0px', left: '0px', right: '0px', bottom: '0px',
}}>
<div style={{ height: HEIGHT_PANEL_HEADER, fontSize: `${3 * 8}px`, fontWeight: 'bold', padding: `${2*8}px` }}>{'/stash'}</div>
<div style={{ position: 'absolute', top: HEIGHT_PANEL_HEADER, left: '0px', bottom: '0px', right: '0px', overflow: 'auto' }}>
<ApiTest path={'/stash'} method={'POST'} params={{ collection_name: 'misc', documents: ['hello', 'world'], wait_for_result: true }} />
</div>
</div>
)
}
const DemoSearch = function () {
return (
<div style={{
position: 'absolute', top: '0px', left: '0px', right: '0px', bottom: '0px',
}}>
<div style={{ height: HEIGHT_PANEL_HEADER, fontSize: `${3 * 8}px`, fontWeight: 'bold', padding: `${2*8}px` }}>{'/search'}</div>
<div style={{ position: 'absolute', top: HEIGHT_PANEL_HEADER, left: '0px', bottom: '0px', right: '0px', overflow: 'auto' }}>
<ApiTest path={'/search'} method={'POST'} params={{ collection_name: 'misc', query: 'hello!', limit: 10 }} />
</div>
</div>
)
}
const App = function () {
return (
<div style={{ height: '100%', width: '100%', overflow: 'hidden', display: 'flex', backgroundColor: '#000', color: '#FFF', fontFamily: 'monospace', fontSize: `${2*8}px`, lineHeight: `${2*8}px` }}>
<div style={{flex: '0 0 50%', position: 'relative', border: '1px solid #EEE', boxSizing: 'border-box'}}><DemoStash /></div>
<div style={{flex: '0 0 50%', position: 'relative', border: '1px solid #EEE', boxSizing: 'border-box'}}><DemoSearch /></div>
</div>
)
}
const render_app = function () {
const elem_appstyles = document.createElement('style')
elem_appstyles.innerHTML = `
html, body {
height: 100%;
width: 100%;
overflow: hidden;
margin: 0px;
padding: 0px;
border: 0px;
}
`.trim()
document.head.appendChild(elem_appstyles)
const elem_root = document.createElement('div')
elem_root.style = 'height:100%; width:100%;'
document.body.appendChild(elem_root)
const func_render_app = () => {
const react_root = createRoot(elem_root)
react_root.render((
<StrictMode>
<App />
</StrictMode>
))
return
}
func_render_app()
return {}
}
export { render_app }