import { useState, useEffect, useCallback } from 'react'; import { Play, Square, Trash2, FolderOpen, ChevronRight, ChevronDown, Settings, Server, Plus, X, Folder, ArrowUp, Loader2 } from 'lucide-react'; const API_URL = import.meta.env.VITE_API_URL || 'http://100.105.142.13:3001'; const RECENT_DIRS_KEY = 'claude-webui-recent-dirs'; const MAX_RECENT_DIRS = 10; // Load recent directories from localStorage function loadRecentDirs() { try { const stored = localStorage.getItem(RECENT_DIRS_KEY); return stored ? JSON.parse(stored) : {}; } catch { return {}; } } // Save recent directories to localStorage function saveRecentDirs(dirs) { try { localStorage.setItem(RECENT_DIRS_KEY, JSON.stringify(dirs)); } catch (e) { console.error('Failed to save recent dirs:', e); } } // Add a directory to recent list for a host function addRecentDir(hostId, path) { const recent = loadRecentDirs(); const hostRecent = recent[hostId] || []; // Remove if already exists, then add to front const filtered = hostRecent.filter(p => p !== path); const updated = [path, ...filtered].slice(0, MAX_RECENT_DIRS); recent[hostId] = updated; saveRecentDirs(recent); return updated; } export function Sidebar({ open, onToggle, selectedProject, onSelectProject, selectedHost, onSelectHost, sessionActive, activeHost, onStartSession, onStopSession, onClearMessages, resumeSession, onToggleResume }) { const [hosts, setHosts] = useState([]); const [recentDirs, setRecentDirs] = useState([]); const [showBrowser, setShowBrowser] = useState(false); const [browserPath, setBrowserPath] = useState('~'); const [browserDirs, setBrowserDirs] = useState([]); const [browserLoading, setBrowserLoading] = useState(false); const [browserError, setBrowserError] = useState(null); const [dropdownOpen, setDropdownOpen] = useState(false); // Fetch hosts on mount useEffect(() => { fetch(`${API_URL}/api/hosts`) .then(res => res.json()) .then(data => { setHosts(data.hosts || []); if (!selectedHost && data.defaultHost) { onSelectHost(data.defaultHost); } }) .catch(console.error); }, []); // Load recent directories when host changes useEffect(() => { if (!selectedHost) return; const recent = loadRecentDirs(); setRecentDirs(recent[selectedHost] || []); }, [selectedHost]); // Handle selecting a directory (from dropdown or browser) const handleSelectDir = useCallback((path) => { onSelectProject(path); const updated = addRecentDir(selectedHost, path); setRecentDirs(updated); setDropdownOpen(false); setShowBrowser(false); }, [selectedHost, onSelectProject]); // Browse directories on host const browsePath = useCallback(async (path) => { if (!selectedHost) return; setBrowserLoading(true); setBrowserError(null); try { const res = await fetch(`${API_URL}/api/browse?host=${selectedHost}&path=${encodeURIComponent(path)}`); const data = await res.json(); if (data.error) { setBrowserError(data.error); return; } setBrowserPath(data.currentPath); setBrowserDirs(data.directories || []); } catch (err) { setBrowserError(err.message); } finally { setBrowserLoading(false); } }, [selectedHost]); // Open browser const openBrowser = useCallback(() => { setShowBrowser(true); setDropdownOpen(false); browsePath('~'); }, [browsePath]); // Get display name for path const getDisplayName = (path) => { const parts = path.split('/'); return parts[parts.length - 1] || path; }; return ( ); }