File size: 2,762 Bytes
a5871f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

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