"use client"; import { useState, useEffect } from "react"; import { FolderOpen, Folder, ChevronRight, Home, ArrowLeft, HardDrive } from "lucide-react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; interface DirectoryEntry { name: string; path: string; } interface BrowseResult { success: boolean; currentPath: string; parentPath: string | null; directories: DirectoryEntry[]; drives?: string[]; error?: string; } interface FileBrowserDialogProps { open: boolean; onOpenChange: (open: boolean) => void; onSelect: (path: string) => void; title?: string; description?: string; } export function FileBrowserDialog({ open, onOpenChange, onSelect, title = "Select Project Directory", description = "Navigate to your project folder", }: FileBrowserDialogProps) { const [currentPath, setCurrentPath] = useState(""); const [parentPath, setParentPath] = useState(null); const [directories, setDirectories] = useState([]); const [drives, setDrives] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const browseDirectory = async (dirPath?: string) => { setLoading(true); setError(""); try { // Get server URL from environment or default const serverUrl = process.env.NEXT_PUBLIC_SERVER_URL || "http://localhost:3008"; const response = await fetch(`${serverUrl}/api/fs/browse`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ dirPath }), }); const result: BrowseResult = await response.json(); if (result.success) { setCurrentPath(result.currentPath); setParentPath(result.parentPath); setDirectories(result.directories); setDrives(result.drives || []); } else { setError(result.error || "Failed to browse directory"); } } catch (err) { setError(err instanceof Error ? err.message : "Failed to load directories"); } finally { setLoading(false); } }; // Load home directory on mount useEffect(() => { if (open && !currentPath) { browseDirectory(); } }, [open]); const handleSelectDirectory = (dir: DirectoryEntry) => { browseDirectory(dir.path); }; const handleGoToParent = () => { if (parentPath) { browseDirectory(parentPath); } }; const handleGoHome = () => { browseDirectory(); }; const handleSelectDrive = (drivePath: string) => { browseDirectory(drivePath); }; const handleSelect = () => { if (currentPath) { onSelect(currentPath); onOpenChange(false); } }; return ( {title} {description}
{/* Drives selector (Windows only) */} {drives.length > 0 && (
Drives:
{drives.map((drive) => ( ))}
)} {/* Current path breadcrumb */}
{parentPath && ( )}
{currentPath || "Loading..."}
{/* Directory list */}
{loading && (
Loading directories...
)} {error && (
{error}
)} {!loading && !error && directories.length === 0 && (
No subdirectories found
)} {!loading && !error && directories.length > 0 && (
{directories.map((dir) => ( ))}
)}
Click on a folder to navigate. Select the current folder or navigate to a subfolder.
); }