import { useModalSearchParams } from '@/hooks/useModalSearchParams' import { Modal } from '@/shared/Modal/Modal' import { MODAL_PARAMS_KEYS } from '@/types/modal' import { Box, Stack, Typography } from '@mui/material' import { StyledButton, StyledSettingContainer, StyledSynchedText } from './styled' import { SectionTitle } from '@/shared/SectionTitle/SectionTitle' import { CheckmarkIcon } from '@/assets' import { Input } from '@/shared/Input/Input' import { ChangeEvent, FC, useEffect, useState } from 'react' import { Checkbox } from '@/shared/Checkbox/Checkbox' import { useEnqueueSnackbar } from '@/hooks/useEnqueueSnackbar' import { swicCall } from '@/modules/swic' import { useParams } from 'react-router-dom' import { dbi } from '@/modules/db' import { usePassword } from '@/hooks/usePassword' import { useAppSelector } from '@/store/hooks/redux' import { selectKeys } from '@/store' import { isValidPassphase, isWeakPassphase } from '@/modules/keys' import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner' type ModalSettingsProps = { isSynced: boolean } export const ModalSettings: FC = ({ isSynced }) => { const { getModalOpened, createHandleCloseReplace } = useModalSearchParams() const { npub = '' } = useParams<{ npub: string }>() const keys = useAppSelector(selectKeys) const notify = useEnqueueSnackbar() const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.SETTINGS) const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.SETTINGS) const { hidePassword, inputProps } = usePassword() const [enteredPassword, setEnteredPassword] = useState('') const [isPasswordInvalid, setIsPasswordInvalid] = useState(false) const [isChecked, setIsChecked] = useState(false) const [isLoading, setIsLoading] = useState(false) useEffect(() => setIsChecked(isSynced), [isModalOpened, isSynced]) useEffect(() => { return () => { if (isModalOpened) { // modal closed hidePassword() } } }, [hidePassword, isModalOpened]) const isNpubExists = npub.trim().length && keys.some((key) => key.npub === npub) if (isModalOpened && !isNpubExists) { handleCloseModal() return null } const handlePasswordChange = (e: ChangeEvent) => { const password = e.target.value setIsPasswordInvalid(!!password && !isValidPassphase(password)) setEnteredPassword(password) } const onClose = () => { handleCloseModal() setEnteredPassword('') setIsPasswordInvalid(false) } const handleChangeCheckbox = (e: unknown, checked: boolean) => { setIsChecked(checked) } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setIsPasswordInvalid(false) if (!isValidPassphase(enteredPassword)) { return setIsPasswordInvalid(true) } try { setIsLoading(true) await swicCall('saveKey', npub, enteredPassword) notify('Key saved', 'success') dbi.addSynced(npub) // Sync npub setEnteredPassword('') setIsPasswordInvalid(false) setIsLoading(false) } catch (error) { setIsPasswordInvalid(false) setIsLoading(false) } } return ( Cloud sync {isSynced && ( Synched )} Use this key on multiple devices {isPasswordInvalid ? ( Password must include 6+ English letters, numbers or punctuation marks. ) : !!enteredPassword && isWeakPassphase(enteredPassword) ? ( Weak password ) : !!enteredPassword && !isPasswordInvalid ? ( Good password ) : isSynced ? ( To change your password, type a new one and sync. ) : ( This key will be encrypted and stored on our server. You can use the password to download this key onto another device. )} Sync {isLoading && } ) }