diff --git a/src/components/documents/folder-tree-sidebar.tsx b/src/components/documents/folder-tree-sidebar.tsx new file mode 100644 index 00000000..f1e90319 --- /dev/null +++ b/src/components/documents/folder-tree-sidebar.tsx @@ -0,0 +1,161 @@ +'use client'; + +import { useState } from 'react'; +import { ChevronRight, Folder, FolderOpen, Inbox } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { cn } from '@/lib/utils'; +import { useDocumentFolders, type FolderNode } from '@/hooks/use-document-folders'; + +interface FolderTreeSidebarProps { + /** Currently-selected folder id, or `null` for root, or `undefined` + * for "All documents" (no folder filter). */ + selectedFolderId: string | null | undefined; + onSelect: (folderId: string | null | undefined) => void; + /** Slot below the tree for a "New folder" affordance from the parent. */ + footer?: React.ReactNode; +} + +/** + * Collapsed-by-default tree. Each row shows a chevron that toggles its + * children; clicking the row label selects the folder. The "All + * documents" + "Root" pseudo-rows at the top let reps filter to the + * full set or to docs without a folder. + * + * Designed for unlimited depth — only the top level renders by default + * so deep trees don't blow out the page; reps drill in by expanding. + */ +export function FolderTreeSidebar({ + selectedFolderId, + onSelect, + footer, +}: FolderTreeSidebarProps) { + const { data: tree = [], isLoading } = useDocumentFolders(); + + return ( + + ); +} + +function PseudoRow({ + label, + icon: Icon, + active, + onClick, +}: { + label: string; + icon: typeof Inbox; + active: boolean; + onClick: () => void; +}) { + return ( + + ); +} + +function FolderRow({ + node, + depth, + selectedFolderId, + onSelect, +}: { + node: FolderNode; + depth: number; + selectedFolderId: string | null | undefined; + onSelect: (folderId: string | null) => void; +}) { + const [open, setOpen] = useState(false); + const hasChildren = node.children.length > 0; + const isActive = selectedFolderId === node.id; + + return ( + <> +
+ + +
+ {open + ? node.children.map((child) => ( + + )) + : null} + + ); +}