import { useEffect, useState } from 'react'; import { Modal } from './Modal'; import { CloudDownloadIcon } from '../icons'; import type { RemoteVault } from '../vault/registry'; type SyncRemoteVaultModalProps = { /** The remote vault to sync, or null when the modal is closed. */ target: RemoteVault | null; onClose: () => void; /** Clone the vault into `path`. Rejects on failure (surfaced in the modal). */ onConfirm: (path: string) => Promise; }; export function SyncRemoteVaultModal({ target, onClose, onConfirm, }: SyncRemoteVaultModalProps) { const [path, setPath] = useState(''); const [error, setError] = useState(null); const [syncing, setSyncing] = useState(false); // Reset state each time a new target opens the modal. useEffect(() => { if (target) { setPath(''); setError(null); setSyncing(false); } }, [target]); const handleSelectDirectory = async () => { try { const result = await window.textile?.vault?.showOpenDialog(); if (result && !result.canceled && result.filePaths.length > 0) { setPath(result.filePaths[0]!); setError(null); } } catch { // Dialog may be unavailable in browser dev environment. } }; const handleConfirm = async () => { if (!path.trim()) { setError('Please select a directory'); return; } setError(null); setSyncing(true); try { await onConfirm(path.trim()); onClose(); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } finally { setSyncing(false); } }; return ( {} : onClose} ariaLabel="Sync Remote Vault dialog" title="Sync Remote Vault" panelClassName="w-full max-w-md" bodyClassName="flex min-h-0 flex-1 flex-col gap-4 p-5" >
{target?.name ?? ''}
Sync into directory
{path || 'No directory selected'}
{error &&

{error}

}
); }