update pages
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Alert, Button, CircularProgress, Grid, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material';
|
||||
import { CopyToClipboard } from '@nymproject/react';
|
||||
import { useSnackbar } from 'notistack';
|
||||
import { WordTiles } from '../components';
|
||||
import { TPages } from '../types';
|
||||
import { MnemonicInput } from '../components/textfields';
|
||||
import { SignInContext } from '../context';
|
||||
import { createPassword } from '../../../requests';
|
||||
|
||||
export const CreateMnemonic = ({
|
||||
page,
|
||||
onNext,
|
||||
onPrev,
|
||||
onComplete,
|
||||
}: {
|
||||
page: TPages;
|
||||
onNext: () => void;
|
||||
onPrev: () => void;
|
||||
onComplete: () => void;
|
||||
}) => {
|
||||
const [toggle, setToggle] = useState('new');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const { password, mnemonic, mnemonicWords, error, generateMnemonic, validateMnemonic, setMnemonic, setError } =
|
||||
useContext(SignInContext);
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const handleUseExisting = async () => {
|
||||
setIsLoading(true);
|
||||
setError(undefined);
|
||||
try {
|
||||
await validateMnemonic();
|
||||
await createPassword({ password, mnemonic });
|
||||
enqueueSnackbar('Password successfully created', { variant: 'success' });
|
||||
onComplete();
|
||||
} catch (e) {
|
||||
setError(e as string);
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setError(undefined);
|
||||
if (toggle === 'new') {
|
||||
generateMnemonic();
|
||||
} else {
|
||||
setMnemonic('');
|
||||
}
|
||||
}, [toggle]);
|
||||
|
||||
return (
|
||||
<Grid container spacing={4} justifyContent="center" id={page}>
|
||||
<Grid item xs={12}>
|
||||
<Typography sx={{ color: 'common.white', fontWeight: 600 }} textAlign="center">
|
||||
Write down your mnemonic
|
||||
</Typography>
|
||||
</Grid>
|
||||
{toggle === 'new' && (
|
||||
<Grid item xs={7}>
|
||||
<Alert
|
||||
icon={false}
|
||||
sx={{ bgcolor: '#18263B', color: '#50ABFF' }}
|
||||
action={mnemonic && <CopyToClipboard value={mnemonic} tooltip="Copy your mnemonic phrase" />}
|
||||
>
|
||||
<Typography>Please store your mnemonic in a safe place</Typography>
|
||||
<Typography fontWeight={600} textTransform="uppercase">
|
||||
This is the only way to access your wallet!
|
||||
</Typography>
|
||||
</Alert>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={7}>
|
||||
<ToggleButtonGroup
|
||||
fullWidth
|
||||
value={toggle}
|
||||
exclusive
|
||||
onChange={(_: React.MouseEvent<HTMLElement>, value: string) => {
|
||||
setToggle(value);
|
||||
}}
|
||||
>
|
||||
<ToggleButton value="new">Create new mnemonic</ToggleButton>
|
||||
<ToggleButton value="existing">Use existing mnemonic</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
<Grid item xs={toggle === 'new' ? 12 : 7}>
|
||||
{toggle === 'new' && <WordTiles mnemonicWords={mnemonicWords} showIndex />}
|
||||
{toggle === 'existing' && (
|
||||
<MnemonicInput mnemonic={mnemonic} onUpdateMnemonic={(mnc) => setMnemonic(mnc)} error={error} />
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid container item spacing={2} justifyContent="center">
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="outlined"
|
||||
disableElevation
|
||||
size="large"
|
||||
onClick={() => {
|
||||
setError(undefined);
|
||||
onPrev();
|
||||
}}
|
||||
sx={{
|
||||
color: 'common.white',
|
||||
border: '1px solid white',
|
||||
'&:hover': { border: '1px solid white' },
|
||||
width: 250,
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disableElevation
|
||||
size="large"
|
||||
onClick={toggle === 'new' ? onNext : handleUseExisting}
|
||||
sx={{ width: 250 }}
|
||||
>
|
||||
{isLoading ? <CircularProgress size={20} color="inherit" /> : 'Verify mnemonic'}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,14 +1,19 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, FormControl, Grid, IconButton, Stack, TextField } from '@mui/material';
|
||||
import { VisibilityOff, Visibility } from '@mui/icons-material';
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { Button, FormControl, Grid, Stack } from '@mui/material';
|
||||
import { TPages } from '../types';
|
||||
import { Subtitle, Title, PasswordStrength } from '../components';
|
||||
import { PasswordInput } from '../components/textfields';
|
||||
import { SignInContext } from '../context';
|
||||
|
||||
export const CreatePassword = ({ page, onPrev, onNext }: { page: TPages; onNext: () => void; onPrev: () => void }) => {
|
||||
const [password, setPassword] = useState<string>('');
|
||||
const [confirmedPassword, setConfirmedPassword] = useState<string>();
|
||||
const [showConfirmedPassword, setShowConfirmedPassword] = useState(false);
|
||||
const { password, setPassword } = useContext(SignInContext);
|
||||
const [confirmedPassword, setConfirmedPassword] = useState<string>('');
|
||||
const [isStrongPassword, setIsStrongPassword] = useState(false);
|
||||
|
||||
const handleOnPrev = () => {
|
||||
setPassword('');
|
||||
onPrev();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -20,33 +25,25 @@ export const CreatePassword = ({ page, onPrev, onNext }: { page: TPages; onNext:
|
||||
<FormControl fullWidth>
|
||||
<Stack spacing={2}>
|
||||
<>
|
||||
<PasswordInput password={password} onUpdatePassword={(pswd) => setPassword(pswd)} />
|
||||
<PasswordStrength password={password} />
|
||||
<PasswordInput password={password} onUpdatePassword={(pswd) => setPassword(pswd)} label="Password" />
|
||||
<PasswordStrength password={password} onChange={(isStrong) => setIsStrongPassword(isStrong)} />
|
||||
</>
|
||||
<TextField
|
||||
<PasswordInput
|
||||
password={confirmedPassword}
|
||||
onUpdatePassword={(pswd) => setConfirmedPassword(pswd)}
|
||||
label="Confirm password"
|
||||
value={confirmedPassword}
|
||||
onChange={(e) => setConfirmedPassword(e.target.value)}
|
||||
type={showConfirmedPassword ? 'input' : 'password'}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<IconButton onClick={() => setShowConfirmedPassword((show) => !show)}>
|
||||
{showConfirmedPassword ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={password !== confirmedPassword || password.length === 0}
|
||||
disabled={password !== confirmedPassword || password.length === 0 || !isStrongPassword}
|
||||
onClick={onNext}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
size="large"
|
||||
onClick={onPrev}
|
||||
onClick={handleOnPrev}
|
||||
sx={{
|
||||
color: 'common.white',
|
||||
border: '1px solid white',
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { Alert, Button, FormControl, Grid, Stack, ToggleButton, ToggleButtonGroup } from '@mui/material';
|
||||
import { ClientContext } from 'src/context/main';
|
||||
import { Subtitle } from '../components';
|
||||
import { Subtitle, MnemonicInput, PasswordInput } from '../components';
|
||||
import { TPages } from '../types';
|
||||
import { MnemonicInput, PasswordInput } from '../components/textfields';
|
||||
|
||||
type TToggle = 'mnemonic' | 'password';
|
||||
|
||||
export const ExistingAccount: React.FC<{ page: TPages; onPrev: () => void; onCreatePassword: () => void }> = ({
|
||||
onPrev,
|
||||
onCreatePassword,
|
||||
}) => {
|
||||
const [toggle, setToggle] = useState('mnemonic');
|
||||
const [toggle, setToggle] = useState<TToggle>('mnemonic');
|
||||
const [password, setPassword] = useState('');
|
||||
const [mnemonic, setMnemonic] = useState('');
|
||||
const { setError, logIn } = useContext(ClientContext);
|
||||
const { setError, logIn, error } = useContext(ClientContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -38,7 +39,7 @@ export const ExistingAccount: React.FC<{ page: TPages; onPrev: () => void; onCre
|
||||
fullWidth
|
||||
value={toggle}
|
||||
exclusive
|
||||
onChange={(e: React.MouseEvent<HTMLElement>, value: string) => {
|
||||
onChange={(_: React.MouseEvent<HTMLElement>, value: TToggle) => {
|
||||
setError(undefined);
|
||||
setToggle(value);
|
||||
}}
|
||||
@@ -49,13 +50,23 @@ export const ExistingAccount: React.FC<{ page: TPages; onPrev: () => void; onCre
|
||||
<FormControl fullWidth>
|
||||
<Stack spacing={2}>
|
||||
{toggle === 'mnemonic' && (
|
||||
<MnemonicInput mnemonic={mnemonic} onUpdateMnemonic={(mnc) => setMnemonic(mnc)} />
|
||||
<MnemonicInput mnemonic={mnemonic} onUpdateMnemonic={(mnc) => setMnemonic(mnc)} error={error} />
|
||||
)}
|
||||
{toggle === 'password' && (
|
||||
<PasswordInput password={password} onUpdatePassword={(pswd) => setPassword(pswd)} />
|
||||
<PasswordInput
|
||||
password={password}
|
||||
onUpdatePassword={(pswd) => setPassword(pswd)}
|
||||
label="Password"
|
||||
error={error}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Button variant="contained" size="large" fullWidth onClick={() => logIn(mnemonic)}>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
fullWidth
|
||||
onClick={() => logIn({ type: toggle, value: toggle === 'mnemonic' ? mnemonic : password })}
|
||||
>
|
||||
{`Sign in with ${toggle}`}
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from './welcome-content';
|
||||
export * from './create-account';
|
||||
export * from './create-mnemonic';
|
||||
export * from './verify-mnemonic';
|
||||
export * from './create-password';
|
||||
export * from './existing-account';
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Stack } from '@mui/material';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Button, CircularProgress, Stack } from '@mui/material';
|
||||
import { useSnackbar } from 'notistack';
|
||||
import { HiddenWords, Subtitle, Title, WordTiles } from '../components';
|
||||
import { THiddenMnemonicWord, THiddenMnemonicWords, TMnemonicWord, TMnemonicWords, TPages } from '../types';
|
||||
import { randomNumberBetween } from '../../../utils';
|
||||
import { SignInContext } from '../context';
|
||||
import { createPassword } from '../../../requests';
|
||||
|
||||
const numberOfRandomWords = 4;
|
||||
const numberOfRandomWords = 6;
|
||||
|
||||
export const VerifyMnemonic = ({
|
||||
mnemonicWords,
|
||||
page,
|
||||
onNext,
|
||||
onPrev,
|
||||
}: {
|
||||
mnemonicWords?: TMnemonicWords;
|
||||
page: TPages;
|
||||
onNext: () => void;
|
||||
onPrev: () => void;
|
||||
}) => {
|
||||
export const VerifyMnemonic = ({ page, onNext, onPrev }: { page: TPages; onNext: () => void; onPrev: () => void }) => {
|
||||
const [randomWords, setRandomWords] = useState<TMnemonicWords>();
|
||||
const [hiddenRandomWords, setHiddenRandomWords] = useState<THiddenMnemonicWords>();
|
||||
const [currentSelection, setCurrentSelection] = useState(0);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const { mnemonicWords, mnemonic, password } = useContext(SignInContext);
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const storePassword = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await createPassword({ mnemonic, password });
|
||||
enqueueSnackbar('Password successfully created', { variant: 'success' });
|
||||
} catch (e) {
|
||||
enqueueSnackbar(e as string, { variant: 'error' });
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (mnemonicWords) {
|
||||
@@ -59,8 +68,12 @@ export const VerifyMnemonic = ({
|
||||
variant="contained"
|
||||
fullWidth
|
||||
size="large"
|
||||
disabled={currentSelection !== numberOfRandomWords}
|
||||
onClick={onNext}
|
||||
disabled={currentSelection !== numberOfRandomWords || isLoading}
|
||||
onClick={async () => {
|
||||
await storePassword();
|
||||
onNext();
|
||||
}}
|
||||
endIcon={isLoading && <CircularProgress />}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user