diff --git a/frontends/nextjs/src/components/nerd-mode-ide/FileTree.tsx b/frontends/nextjs/src/components/nerd-mode-ide/FileTree.tsx new file mode 100644 index 000000000..dd18e0f58 --- /dev/null +++ b/frontends/nextjs/src/components/nerd-mode-ide/FileTree.tsx @@ -0,0 +1,37 @@ +import type { FileNode } from '@/lib/nerd-mode-ide' +import { FileTreeNode } from './FileTreeNode' + +interface FileTreeProps { + nodes: FileNode[] + selectedFileId: string | null + activeFolderId: string | null + onToggleFolder: (nodeId: string) => void + onSelectFile: (nodeId: string) => void + onSelectFolder: (nodeId: string) => void +} + +export function FileTree({ + nodes, + selectedFileId, + activeFolderId, + onToggleFolder, + onSelectFile, + onSelectFolder, +}: FileTreeProps) { + return ( +
+ {nodes.map((node) => ( + + ))} +
+ ) +} diff --git a/frontends/nextjs/src/components/nerd-mode-ide/FileTreeNode.tsx b/frontends/nextjs/src/components/nerd-mode-ide/FileTreeNode.tsx new file mode 100644 index 000000000..1369bdae1 --- /dev/null +++ b/frontends/nextjs/src/components/nerd-mode-ide/FileTreeNode.tsx @@ -0,0 +1,79 @@ +import ChevronRightIcon from '@mui/icons-material/ChevronRight' +import DescriptionOutlinedIcon from '@mui/icons-material/DescriptionOutlined' +import ExpandMoreIcon from '@mui/icons-material/ExpandMore' +import FolderOutlinedIcon from '@mui/icons-material/FolderOutlined' +import FolderOpenOutlinedIcon from '@mui/icons-material/FolderOpenOutlined' +import type { FileNode } from '@/lib/nerd-mode-ide' + +interface FileTreeNodeProps { + node: FileNode + level: number + selectedFileId: string | null + activeFolderId: string | null + onToggleFolder: (nodeId: string) => void + onSelectFile: (nodeId: string) => void + onSelectFolder: (nodeId: string) => void +} + +export function FileTreeNode({ + node, + level, + selectedFileId, + activeFolderId, + onToggleFolder, + onSelectFile, + onSelectFolder, +}: FileTreeNodeProps) { + const isSelected = node.type === 'file' + ? selectedFileId === node.id + : activeFolderId === node.id + const paddingLeft = `${level * 16}px` + + return ( +
+
{ + if (node.type === 'folder') { + onToggleFolder(node.id) + onSelectFolder(node.id) + } else { + onSelectFile(node.id) + } + }} + > + {node.type === 'folder' ? ( + <> + {node.expanded ? : } + {node.expanded ? : } + + ) : ( + <> +
+ + + )} + {node.name} +
+ {node.type === 'folder' && node.expanded && node.children && node.children.length > 0 && ( +
+ {node.children.map((child) => ( + + ))} +
+ )} +
+ ) +}