import { IconFolder, IconUpload, IconTrash, IconDownload } from "@tabler/icons-react"; import { useState, useRef } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Modal, Button, Table, Spinner, Badge } from "react-bootstrap"; import { getWgClientFiles, uploadWgClientFile, deleteWgClientFile, downloadWgClientFile } from "src/api/backend"; import { showError, showSuccess } from "src/notifications"; import { Loading } from "src/components"; interface Props { resolve: (value: boolean) => void; clientId: number; clientName: string; ipv4Address: string; } function formatBytes(bytes: number | null): string { if (bytes === null || bytes === 0) return "0 B"; const k = 1024; const sizes = ["B", "KB", "MB", "GB", "TB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`; } export default function WireGuardFileManagerModal({ resolve, clientId, clientName, ipv4Address }: Props) { const [visible, setVisible] = useState(true); const queryClient = useQueryClient(); const fileInputRef = useRef(null); const { data: files, isLoading } = useQuery({ queryKey: ["wg-client-files", clientId], queryFn: () => getWgClientFiles(clientId) }); const uploadMutation = useMutation({ mutationFn: (file: File) => uploadWgClientFile(clientId, file), onSuccess: () => { showSuccess("File uploaded and encrypted successfully!"); queryClient.invalidateQueries({ queryKey: ["wg-client-files", clientId] }); if (fileInputRef.current) fileInputRef.current.value = ""; }, onError: (err: any) => { showError(err.message || "Failed to upload file"); } }); const deleteMutation = useMutation({ mutationFn: (filename: string) => deleteWgClientFile(clientId, filename), onSuccess: () => { showSuccess("File deleted successfully!"); queryClient.invalidateQueries({ queryKey: ["wg-client-files", clientId] }); }, onError: (err: any) => { showError(err.message || "Failed to delete file"); } }); const onClose = () => { setVisible(false); resolve(false); }; const handleFileSelect = (e: React.ChangeEvent) => { if (e.target.files && e.target.files.length > 0) { uploadMutation.mutate(e.target.files[0]); } }; const handleDownload = (filename: string) => { downloadWgClientFile(clientId, filename); }; const handleDelete = (filename: string) => { if (window.confirm(`Are you sure you want to completely delete "${filename}"?`)) { deleteMutation.mutate(filename); } }; return ( Secure File Manager
Client: {clientName}

Storage Partition: /data/wg_clients/{ipv4Address}/

AES-256-CBC End-to-End Encryption Active
Encrypted Files
{isLoading ? ( ) : files && files.length > 0 ? ( files.map((file) => ( )) ) : ( )}
Filename Encrypted Size Last Modified Actions
{file.name} {formatBytes(file.size)} {new Date(file.modified).toLocaleString()}
No files found. The partition is empty.
); }