import React, { useEffect, useState } from "react"; import FolderSection from "@/components/cloud-storage/folder-section"; import FilesSection from "@/components/cloud-storage/files-section"; import { apiRequest } from "@/lib/queryClient"; import { Breadcrumbs } from "./bread-crumb"; export default function FolderPanel({ folderId, onClose, onViewChange, }) { const [currentFolderId, setCurrentFolderId] = useState(folderId ?? null); const [path, setPath] = useState([]); const [isLoadingPath, setIsLoadingPath] = useState(false); // When the panel opens to a different initial folder, sync and notify parent useEffect(() => { setCurrentFolderId(folderId ?? null); onViewChange?.(folderId ?? null); }, [folderId, onViewChange]); // notify parent when viewed folder changes useEffect(() => { onViewChange?.(currentFolderId); }, [currentFolderId, onViewChange]); // whenever currentFolderId changes we load the ancestor path useEffect(() => { let mounted = true; async function buildPath(fid) { setIsLoadingPath(true); try { // We'll build path from root -> ... -> current. Since we don't know // if backend provides a single endpoint for ancestry, we'll fetch // current folder and walk parents until null. If fid is null then path is empty. if (fid == null) { if (mounted) setPath([]); return; } const collected = []; let cursor = fid; // keep a safety cap to avoid infinite loop in case of cycles const MAX_DEPTH = 50; let depth = 0; while (cursor != null && depth < MAX_DEPTH) { const res = await apiRequest("GET", `/api/cloud-storage/folders/${cursor}`); const json = await res.json(); if (!res.ok) throw new Error(json?.message || "Failed to fetch folder"); const folder = json?.data ?? json ?? null; // normalize const meta = { id: folder?.id ?? null, name: folder?.name ?? null, parentId: folder?.parentId ?? null, }; // prepend (we are walking up) then continue with parent collected.push(meta); cursor = meta.parentId; depth += 1; } // collected currently top-down from current -> root. We need root->...->current const rootToCurrent = collected.slice().reverse(); // we don't include the root (null) as an explicit item; Breadcrumbs shows "My Cloud Storage" if (mounted) setPath(rootToCurrent); } catch (err) { console.error("buildPath error", err); if (mounted) setPath([]); } finally { if (mounted) setIsLoadingPath(false); } } buildPath(currentFolderId); return () => { mounted = false; }; }, [currentFolderId]); // handler when child folder is clicked inside FolderSection function handleChildSelect(childFolderId) { // if user re-clicks current folder id as toggle, we still want to navigate into it. setCurrentFolderId(childFolderId); onViewChange?.(childFolderId); // keep page in sync } // navigate via breadcrumb (id may be null for root) function handleNavigateTo(id) { setCurrentFolderId(id); onViewChange?.(id); } return (