"use client"; import { useEffect, useState, useCallback } from "react"; import { Folder, FolderOpen, Home, ChevronRight, ChevronDown, Search } from "lucide-react"; import Modal from "../ui/Modal"; import Button from "../ui/Button"; interface TreeFolder { id: string; name: string; children?: TreeFolder[]; _count?: { files: number }; } interface MoveModalProps { isOpen: boolean; onClose: () => void; /** Appelée avec "root" ou l'id du dossier cible. */ onSelect: (folderId: string) => void; /** Dossier (et son sous-arbre) à masquer — pour le déplacement d'un dossier. */ excludeId?: string; title?: string; itemName?: string; /** Emplacement actuel (désactivé dans la liste) */ currentFolderId?: string | null; } function matches(node: TreeFolder, q: string): boolean { if (!q) return true; if (node.name.toLowerCase().includes(q)) return true; return (node.children ?? []).some((c) => matches(c, q)); } export default function MoveModal({ isOpen, onClose, onSelect, excludeId, title = "Déplacer vers", itemName, currentFolderId, }: MoveModalProps) { const [tree, setTree] = useState([]); const [expanded, setExpanded] = useState>(new Set()); const [loading, setLoading] = useState(false); const [query, setQuery] = useState(""); const [chosen, setChosen] = useState(null); useEffect(() => { if (!isOpen) return; setLoading(true); setQuery(""); setChosen(null); fetch("/api/folders?tree=true") .then((r) => (r.ok ? r.json() : [])) .then((data) => { const t: TreeFolder[] = Array.isArray(data) ? data : []; setTree(t); setExpanded(new Set(t.filter((n) => n.children?.length).map((n) => n.id))); }) .catch(() => setTree([])) .finally(() => setLoading(false)); }, [isOpen]); const toggle = useCallback((id: string) => { setExpanded((prev) => { const next = new Set(prev); next.has(id) ? next.delete(id) : next.add(id); return next; }); }, []); const q = query.trim().toLowerCase(); const current = currentFolderId ?? undefined; function renderNode(node: TreeFolder, depth: number): React.ReactNode { if (node.id === excludeId) return null; if (!matches(node, q)) return null; const kids = node.children ?? []; const hasKids = kids.length > 0; const isOpen = q ? true : expanded.has(node.id); const isCurrent = node.id === current; const isChosen = node.id === chosen; return (
{hasKids && isOpen &&
{kids.map((c) => renderNode(c, depth + 1))}
}
); } const rootIsCurrent = current === "root" || current === null; return ( } >
setQuery(e.target.value)} placeholder="Filtrer les dossiers…" className="field pl-9" />
{loading ? (
{[0, 1, 2].map((i) =>
)}
) : ( tree.map((n) => renderNode(n, 0)) )} {!loading && q && tree.every((n) => !matches(n, q)) && (

Aucun dossier ne correspond

)}
); }