'use client'; import { useState } from 'react'; import { Lock, Loader2, AlertCircle } from 'lucide-react'; import { useAuth } from '@/lib/contexts/AuthContext'; interface IdentityUnlockPromptProps { onUnlock?: () => void; onCancel?: () => void; } /** * IdentityUnlockPrompt Modal Component * * Prompts the user to unlock their cryptographic identity by entering their password. * This is required when the user's private key is not available in memory (e.g., after * page refresh or when the session expires). * * Requirements: US-2.3, US-5.1 */ export function IdentityUnlockPrompt({ onUnlock, onCancel }: IdentityUnlockPromptProps) { const { unlockIdentity } = useAuth(); const [password, setPassword] = useState(''); const [error, setError] = useState(null); const [isUnlocking, setIsUnlocking] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!password.trim()) { setError('Please enter your password'); return; } setError(null); setIsUnlocking(true); try { await unlockIdentity(password); // Success! Call the onUnlock callback if provided if (onUnlock) { onUnlock(); } } catch (err) { console.error('[IdentityUnlockPrompt] Failed to unlock identity:', err); setError('Incorrect password. Please try again.'); } finally { setIsUnlocking(false); } }; const handleCancel = () => { setPassword(''); setError(null); if (onCancel) { onCancel(); } }; return ( <>
e.stopPropagation()} > {/* Drag indicator - only visible on mobile */}
{/* Header */}

Identity Required

{/* Description */}

Enter your password to unlock your identity

{/* Form */}
{ setPassword(e.target.value); setError(null); }} disabled={isUnlocking} placeholder="Enter your password" autoFocus style={{ width: '100%', padding: '12px 14px', borderRadius: '8px', border: error ? '2px solid var(--error)' : '1px solid var(--border)', background: 'var(--background)', color: 'var(--foreground)', fontSize: '15px', outline: 'none', transition: 'border-color 0.2s' }} onFocus={(e) => { if (!error) { e.target.style.borderColor = 'var(--accent)'; } }} onBlur={(e) => { if (!error) { e.target.style.borderColor = 'var(--border)'; } }} />
{/* Error Message */} {error && (
{error}
)} {/* Buttons */}
{/* Info Note */}

Your password never leaves this device

); }