import React, { useState, useRef } from 'react'; import { Button } from '@/components/ui/button.tsx'; import { Input } from '@/components/ui/input.tsx'; import { Card } from '@/components/ui/card.tsx'; import { Separator } from '@/components/ui/separator.tsx'; import { Upload, FilePlus, FolderPlus, Trash2, Edit3, X, Check, AlertCircle, FileText, Folder } from 'lucide-react'; import { cn } from '@/lib/utils.ts'; interface FileManagerOperationsProps { currentPath: string; sshSessionId: string | null; onOperationComplete: () => void; onError: (error: string) => void; onSuccess: (message: string) => void; } export function FileManagerOperations({ currentPath, sshSessionId, onOperationComplete, onError, onSuccess }: FileManagerOperationsProps) { const [showUpload, setShowUpload] = useState(false); const [showCreateFile, setShowCreateFile] = useState(false); const [showCreateFolder, setShowCreateFolder] = useState(false); const [showDelete, setShowDelete] = useState(false); const [showRename, setShowRename] = useState(false); const [uploadFile, setUploadFile] = useState(null); const [newFileName, setNewFileName] = useState(''); const [newFolderName, setNewFolderName] = useState(''); const [deletePath, setDeletePath] = useState(''); const [deleteIsDirectory, setDeleteIsDirectory] = useState(false); const [renamePath, setRenamePath] = useState(''); const [renameIsDirectory, setRenameIsDirectory] = useState(false); const [newName, setNewName] = useState(''); const [isLoading, setIsLoading] = useState(false); const fileInputRef = useRef(null); const handleFileUpload = async () => { if (!uploadFile || !sshSessionId) return; setIsLoading(true); try { const content = await uploadFile.text(); const { uploadSSHFile } = await import('@/ui/main-axios.ts'); await uploadSSHFile(sshSessionId, currentPath, uploadFile.name, content); onSuccess(`File "${uploadFile.name}" uploaded successfully`); setShowUpload(false); setUploadFile(null); onOperationComplete(); } catch (error: any) { onError(error?.response?.data?.error || 'Failed to upload file'); } finally { setIsLoading(false); } }; const handleCreateFile = async () => { if (!newFileName.trim() || !sshSessionId) return; setIsLoading(true); try { const { createSSHFile } = await import('@/ui/main-axios.ts'); await createSSHFile(sshSessionId, currentPath, newFileName.trim()); onSuccess(`File "${newFileName.trim()}" created successfully`); setShowCreateFile(false); setNewFileName(''); onOperationComplete(); } catch (error: any) { onError(error?.response?.data?.error || 'Failed to create file'); } finally { setIsLoading(false); } }; const handleCreateFolder = async () => { if (!newFolderName.trim() || !sshSessionId) return; setIsLoading(true); try { const { createSSHFolder } = await import('@/ui/main-axios.ts'); await createSSHFolder(sshSessionId, currentPath, newFolderName.trim()); onSuccess(`Folder "${newFolderName.trim()}" created successfully`); setShowCreateFolder(false); setNewFolderName(''); onOperationComplete(); } catch (error: any) { onError(error?.response?.data?.error || 'Failed to create folder'); } finally { setIsLoading(false); } }; const handleDelete = async () => { if (!deletePath || !sshSessionId) return; setIsLoading(true); try { const { deleteSSHItem } = await import('@/ui/main-axios.ts'); await deleteSSHItem(sshSessionId, deletePath, deleteIsDirectory); onSuccess(`${deleteIsDirectory ? 'Folder' : 'File'} deleted successfully`); setShowDelete(false); setDeletePath(''); setDeleteIsDirectory(false); onOperationComplete(); } catch (error: any) { onError(error?.response?.data?.error || 'Failed to delete item'); } finally { setIsLoading(false); } }; const handleRename = async () => { if (!renamePath || !newName.trim() || !sshSessionId) return; setIsLoading(true); try { const { renameSSHItem } = await import('@/ui/main-axios.ts'); await renameSSHItem(sshSessionId, renamePath, newName.trim()); onSuccess(`${renameIsDirectory ? 'Folder' : 'File'} renamed successfully`); setShowRename(false); setRenamePath(''); setRenameIsDirectory(false); setNewName(''); onOperationComplete(); } catch (error: any) { onError(error?.response?.data?.error || 'Failed to rename item'); } finally { setIsLoading(false); } }; const openFileDialog = () => { fileInputRef.current?.click(); }; const handleFileSelect = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { setUploadFile(file); } }; const resetStates = () => { setShowUpload(false); setShowCreateFile(false); setShowCreateFolder(false); setShowDelete(false); setShowRename(false); setUploadFile(null); setNewFileName(''); setNewFolderName(''); setDeletePath(''); setDeleteIsDirectory(false); setRenamePath(''); setRenameIsDirectory(false); setNewName(''); }; if (!sshSessionId) { return (

Connect to SSH to use file operations

); } return (
{/* Operation Buttons */}
{/* Current Path Display */}
Current Path: {currentPath}
{/* Upload File Modal */} {showUpload && (

Upload File

Maximum file size: 100MB (JSON) / 200MB (Binary)

{uploadFile ? (

{uploadFile.name}

{(uploadFile.size / 1024).toFixed(2)} KB

) : (

Click to select a file

)}
)} {/* Create File Modal */} {showCreateFile && (

Create New File

setNewFileName(e.target.value)} placeholder="Enter file name (e.g., example.txt)" className="bg-[#23232a] border-2 border-[#434345] text-white" onKeyDown={(e) => e.key === 'Enter' && handleCreateFile()} />
)} {/* Create Folder Modal */} {showCreateFolder && (

Create New Folder

setNewFolderName(e.target.value)} placeholder="Enter folder name" className="bg-[#23232a] border-2 border-[#434345] text-white" onKeyDown={(e) => e.key === 'Enter' && handleCreateFolder()} />
)} {/* Delete Modal */} {showDelete && (

Delete Item

Warning: This action cannot be undone
setDeletePath(e.target.value)} placeholder="Enter full path to item (e.g., /path/to/file.txt)" className="bg-[#23232a] border-2 border-[#434345] text-white" />
setDeleteIsDirectory(e.target.checked)} className="rounded border-[#434345] bg-[#23232a]" />
)} {/* Rename Modal */} {showRename && (

Rename Item

setRenamePath(e.target.value)} placeholder="Enter current path to item" className="bg-[#23232a] border-2 border-[#434345] text-white" />
setNewName(e.target.value)} placeholder="Enter new name" className="bg-[#23232a] border-2 border-[#434345] text-white" onKeyDown={(e) => e.key === 'Enter' && handleRename()} />
setRenameIsDirectory(e.target.checked)} className="rounded border-[#434345] bg-[#23232a]" />
)}
); }