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