import { useRef, useState, type ReactElement } from 'react'; import { useVault } from '../contexts/vault-context.js'; type Step = 1 | 2 | 3; export function VaultSetup(): ReactElement { const vault = useVault(); const [step, setStep] = useState(1); const [password, setPassword] = useState(''); const [confirm, setConfirm] = useState(''); const [serverUrl, setServerUrl] = useState(''); const [apiKey, setApiKey] = useState(''); const [localError, setLocalError] = useState(null); const [loading, setLoading] = useState(false); const [uploadError, setUploadError] = useState(null); const fileInputRef = useRef(null); function handleStep1(e: React.FormEvent) { e.preventDefault(); if (password.length < 8) { setLocalError('Password must be at least 8 characters.'); return; } if (password !== confirm) { setLocalError('Passwords do not match.'); return; } setLocalError(null); setStep(2); } function handleStep2(e: React.FormEvent) { e.preventDefault(); setLocalError(null); setStep(3); } async function handleStep3(e: React.FormEvent) { e.preventDefault(); setLoading(true); await vault.create(password, serverUrl, apiKey); setLoading(false); } async function handleFileChange(e: React.ChangeEvent) { const file = e.target.files?.[0]; if (!file) return; setUploadError(null); try { await vault.upload(file); } catch { setUploadError('Failed to upload vault. Please try again.'); } if (fileInputRef.current) fileInputRef.current.value = ''; } return (

Setup Vault

{uploadError &&

{uploadError}

}

{step === 1 && (

Step 1: Choose master password

setPassword(e.target.value)} autoFocus />
setConfirm(e.target.value)} />
{localError &&

{localError}

}
)} {step === 2 && (

Step 2: Server connection

setServerUrl(e.target.value)} autoFocus />
setApiKey(e.target.value)} />
{localError &&

{localError}

}
)} {step === 3 && (

Step 3: Confirm

Server URL: {serverUrl || '(none)'}

API key: {apiKey ? '••••••••' : '(none)'}

{vault.error &&

{vault.error}

}
)}
); }