'use client'
import { useCallback, useState, useEffect } from 'react'
import Tree, { useTreeState } from 'react-hyper-tree'
const Icons = ({ open, ...props }) => {
if (open) {
return <div {...props}> {'v'} </div>
} else {
return <div {...props}> {'>'} </div>
}
}
const getTree = async () =>
fetch('http://127.0.0.1:2000/api/tree')
.then(res => res.json())
.then(data => data.tree)
const getFileContent = async (path: string) =>
fetch(`http://127.0.0.1:2000/api/file/${path}`)
.then(res => res.json())
.then(data => data.content)
export default function Page() {
const [checked, setChecked] = useState(false)
const [data, setData] = useState<any[]>([])
const [content, setContent] = useState<string | null>(null)
const [file, setFile] = useState<string | null>(null)
useEffect(() => {
getTree().then(tree => setData(tree))
if (!file) {
setFile('repo/readme.md')
}
getFileContent(file).then(content => setContent(content))
}, [file])
const filter = useCallback(
data => {
if (checked) {
return true
} else {
return data.data.name.toLowerCase().at(0) !== '.'
}
},
[checked],
)
const { required, handlers } = useTreeState({
id: 'tree',
data: data,
filter,
defaultOpened: true,
multipleSelect: false,
})
const renderNode = useCallback(({ node, onToggle }) => {
return (
<div className='flex' key={node.data.title}>
<div className='flex' onClick={onToggle}>
{node.hasChildren() ? <Icons open={node.options.opened} /> : null}
<span className='ml-2' onClick={() => setFile(node.data.path)}>
{' '}
{node.data.name}
</span>
</div>
</div>
)
}, [])
return (
<div className='flex m-10'>
<div className='m-5'>
<div className='form-control w-44 text-black'>
<label className='label cursor-pointer'>
<span className='label-text'>Show hidden files</span>
<input
type='checkbox'
checked={checked}
className='checkbox checkbox-primary'
onClick={() => setChecked(!checked)}
onChange={() => {}}
/>
</label>
</div>
<Tree
{...required}
{...handlers}
draggable={false}
depthGap={20}
disableLines={false}
disableHorizontalLines={false}
disableVerticalLines={false}
verticalLineTopOffset={-17}
verticalLineOffset={5}
renderNode={renderNode}
/>
</div>
{data ? (
<div className='mockup-code m-5'>
<pre>
<code>{`${content}`}</code>
</pre>
</div>
) : null}
</div>
)
}