import { Ionicons } from "@expo/vector-icons"; import { BottomSheetBackdrop, type BottomSheetBackdropProps, BottomSheetModal, BottomSheetView, } from "@gorhom/bottom-sheet"; import type React from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Platform, TouchableOpacity, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import type { AccountSecurityType } from "@/utils/secureCredentials"; import { Button } from "./Button"; import { Text } from "./common/Text"; import { PinInput } from "./inputs/PinInput"; interface SaveAccountModalProps { visible: boolean; onClose: () => void; onSave: (securityType: AccountSecurityType, pinCode?: string) => void; username: string; } interface SecurityOption { type: AccountSecurityType; titleKey: string; descriptionKey: string; icon: keyof typeof Ionicons.glyphMap; } const SECURITY_OPTIONS: SecurityOption[] = [ { type: "none", titleKey: "save_account.no_protection", descriptionKey: "save_account.no_protection_desc", icon: "flash-outline", }, { type: "pin", titleKey: "save_account.pin_code", descriptionKey: "save_account.pin_code_desc", icon: "keypad-outline", }, { type: "password", titleKey: "save_account.password", descriptionKey: "save_account.password_desc", icon: "lock-closed-outline", }, ]; export const SaveAccountModal: React.FC = ({ visible, onClose, onSave, username, }) => { const { t } = useTranslation(); const insets = useSafeAreaInsets(); const bottomSheetModalRef = useRef(null); const [selectedType, setSelectedType] = useState("none"); const [pinCode, setPinCode] = useState(""); const [pinError, setPinError] = useState(null); const isAndroid = Platform.OS === "android"; const snapPoints = useMemo( () => (isAndroid ? ["100%"] : ["70%"]), [isAndroid], ); useEffect(() => { if (visible) { bottomSheetModalRef.current?.present(); } else { bottomSheetModalRef.current?.dismiss(); } }, [visible]); const handleSheetChanges = useCallback( (index: number) => { if (index === -1) { resetState(); onClose(); } }, [onClose], ); const resetState = () => { setSelectedType("none"); setPinCode(""); setPinError(null); }; const renderBackdrop = useCallback( (props: BottomSheetBackdropProps) => ( ), [], ); const handleOptionSelect = (type: AccountSecurityType) => { setSelectedType(type); setPinCode(""); setPinError(null); }; const handleSave = () => { if (selectedType === "pin") { if (pinCode.length !== 4) { setPinError(t("pin.enter_4_digits") || "Enter 4 digits"); return; } onSave("pin", pinCode); } else { onSave(selectedType); } resetState(); }; const handleCancel = () => { resetState(); onClose(); }; const canSave = () => { if (selectedType === "pin") { return pinCode.length === 4; } return true; }; return ( {/* Header */} {t("save_account.title")} {username} {/* PIN Entry Step */} {selectedType === "pin" ? ( {t("pin.setup_pin")} {pinError && ( {pinError} )} ) : ( /* Security Options */ {t("save_account.security_option")} {SECURITY_OPTIONS.map((option, index) => ( handleOptionSelect(option.type)} className={`flex-row items-center p-4 ${ index < SECURITY_OPTIONS.length - 1 ? "border-b border-neutral-700" : "" }`} > {t(option.titleKey)} {t(option.descriptionKey)} {selectedType === option.type && ( )} ))} )} {/* Buttons */} ); };