"use client"; import { ChevronDown, ChevronRight, Folder, FolderOpen, Home } from "lucide-react"; import { useCallback, useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; import type { FolderDisplay } from "./FolderNode"; interface FolderPickerDialogProps { open: boolean; onOpenChange: (open: boolean) => void; folders: FolderDisplay[]; title: string; description?: string; disabledFolderIds?: Set; onSelect: (folderId: number | null) => void; } export function FolderPickerDialog({ open, onOpenChange, folders, title, description, disabledFolderIds, onSelect, }: FolderPickerDialogProps) { const [selectedId, setSelectedId] = useState(null); const [expandedIds, setExpandedIds] = useState>(new Set()); const handleOpenChange = useCallback( (next: boolean) => { if (next) { setSelectedId(null); setExpandedIds(new Set()); } onOpenChange(next); }, [onOpenChange] ); const foldersByParent = useMemo(() => { const map: Record = {}; for (const f of folders) { const key = f.parentId ?? "root"; if (!map[key]) map[key] = []; map[key].push(f); } return map; }, [folders]); const toggleExpand = useCallback((id: number) => { setExpandedIds((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }, []); const handleConfirm = useCallback(() => { onSelect(selectedId); onOpenChange(false); }, [selectedId, onSelect, onOpenChange]); function renderPickerLevel(parentId: number | null, depth: number): React.ReactNode[] { const key = parentId ?? "root"; const children = (foldersByParent[key] ?? []) .slice() .sort((a, b) => a.position.localeCompare(b.position)); return children.flatMap((f) => { const isDisabled = disabledFolderIds?.has(f.id) ?? false; const isExpanded = expandedIds.has(f.id); const hasChildren = (foldersByParent[f.id] ?? []).length > 0; const isSelected = selectedId === f.id; const FolderIcon = isExpanded ? FolderOpen : Folder; return [ ) : ( )} {f.name} , ...(isExpanded ? renderPickerLevel(f.id, depth + 1) : []), ]; }); } return (
{title} {description && ( {description} )}
{renderPickerLevel(null, 1)}
); }