Spaces:
Build error
Build error
| 'use client'; | |
| import * as React from 'react'; | |
| import { Folder, FolderOpen, ChevronRight } from 'lucide-react'; | |
| import { | |
| Collapsible, | |
| CollapsibleContent, | |
| CollapsibleTrigger, | |
| } from '@/components/ui/collapsible'; | |
| import { cn } from '@/lib/utils'; | |
| import type { Folder as FolderType } from '@/app/api/files/route'; | |
| interface FolderTreeProps { | |
| rootFolder: FolderType; | |
| currentPath: string; | |
| onSelectFolder: (path: string) => void; | |
| } | |
| export function FolderTree({ rootFolder, currentPath, onSelectFolder }: FolderTreeProps) { | |
| const subFolders = rootFolder.children.filter( | |
| (child): child is FolderType => child.type === 'folder' | |
| ); | |
| return ( | |
| <nav className="p-2"> | |
| {subFolders.map((folder) => ( | |
| <RecursiveFolder | |
| key={folder.id} | |
| folder={folder} | |
| currentPath={currentPath} | |
| onSelectFolder={onSelectFolder} | |
| level={0} | |
| /> | |
| ))} | |
| </nav> | |
| ); | |
| } | |
| interface RecursiveFolderProps { | |
| folder: FolderType; | |
| currentPath: string; | |
| onSelectFolder: (path: string) => void; | |
| level: number; | |
| } | |
| function RecursiveFolder({ folder, currentPath, onSelectFolder, level }: RecursiveFolderProps) { | |
| const [isOpen, setIsOpen] = React.useState( | |
| currentPath.startsWith(`${folder.path}`) | |
| ); | |
| React.useEffect(() => { | |
| setIsOpen(currentPath.startsWith(`${folder.path}`)); | |
| }, [currentPath, folder.path]); | |
| const subFolders = folder.children.filter( | |
| (child): child is FolderType => child.type === 'folder' | |
| ); | |
| const isActive = currentPath === folder.path; | |
| const Icon = isOpen ? FolderOpen : Folder; | |
| return ( | |
| <Collapsible open={isOpen} onOpenChange={setIsOpen} className="space-y-1"> | |
| <CollapsibleTrigger | |
| className={cn( | |
| 'w-full text-left flex items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium transition-colors hover:bg-accent', | |
| isActive && 'bg-primary/10 text-primary' | |
| )} | |
| onClick={() => onSelectFolder(folder.path)} | |
| > | |
| <ChevronRight | |
| className={cn( | |
| 'h-4 w-4 transform transition-transform duration-200', | |
| isOpen && 'rotate-90', | |
| subFolders.length === 0 && 'invisible' | |
| )} | |
| /> | |
| <Icon className="h-4 w-4" /> | |
| <span>{folder.name}</span> | |
| </CollapsibleTrigger> | |
| <CollapsibleContent> | |
| <div className="pl-6 space-y-1 border-l border-dashed ml-3"> | |
| {subFolders.map((subFolder) => ( | |
| <RecursiveFolder | |
| key={subFolder.id} | |
| folder={subFolder} | |
| currentPath={currentPath} | |
| onSelectFolder={onSelectFolder} | |
| level={level + 1} | |
| /> | |
| ))} | |
| </div> | |
| </CollapsibleContent> | |
| </Collapsible> | |
| ); | |
| } | |