import { TargetedEvent, TargetedKeyboardEvent } from "preact"; import { useEffect, useRef } from "preact/hooks"; import { EncryptionModalProps } from "./welcome-types.ts"; import { useFocusTrap } from "../../utils/useFocusTrap.ts"; /** * EncryptionModal Component * Modal banner for setting up encryption password or changing PIN * Appears at top of screen until password is set or skipped * * @param showModal - Whether modal is visible * @param tempPassword - Current password input value * @param passwordError - Error message to display * @param isChangeMode - Whether modal is in change PIN mode * @param onPasswordChange - Handler for password input changes * @param onSetPassword - Handler to validate and set password * @param onSkip - Handler to skip encryption setup * @param onClose - Handler to close change PIN modal * * TODO: Future enhancements * - Add password strength indicator * - Add password visibility toggle * - Add "Remember this device" checkbox * - Add password requirements tooltip * - Add biometric authentication option * - Add password confirmation field */ export default function EncryptionModal({ showModal, tempPassword, passwordError, isChangeMode = false, showRemovePinConfirm = false, persistAcrossDevices, onPasswordChange, onSetPassword, onSkip, onClose, onRemovePinConfirm, onPersistAcrossDevicesChange, }: EncryptionModalProps) { const inputRef = useRef(null); const modalRef = useRef(null); // Enable focus trap for keyboard navigation useFocusTrap(showModal, modalRef); useEffect(() => { if (showModal && inputRef.current) { inputRef.current.focus(); } }, [showModal]); if (!showModal) return null; const handleCheckboxChange = (e: TargetedEvent) => { onPersistAcrossDevicesChange(e.currentTarget.checked); }; const handlePasswordInput = ( e: TargetedEvent, ) => { onPasswordChange(e.currentTarget.value); }; const handleKeyDown = (e: TargetedKeyboardEvent) => { if (e.key === "Enter") { e.preventDefault(); if (tempPassword.length >= 4) { onSetPassword(); } } }; const handleSubmit = (e: TargetedEvent) => { e.preventDefault(); if (tempPassword.length >= 4) { onSetPassword(); } }; const handleCancel = () => { if (isChangeMode) { onClose?.(); } else { // Clear the input when skipping initial encryption setup onPasswordChange(""); onSkip(); } }; const handleBackdropClick = ( e: TargetedEvent, ) => { if (e.currentTarget === e.target) { if (isChangeMode) { onClose?.(); } else { onSkip(); } } }; const handleInputBlur = () => { if (tempPassword.length === 0 && !isChangeMode) { onSkip(); } }; const isPasswordValid = tempPassword.length >= 4; return ( <> {/* Main Change PIN Modal */} {/* Confirmation Dialog for PIN Removal */} {showRemovePinConfirm && onRemovePinConfirm && onSkip && ( )} ); }