reorder pages
This commit is contained in:
@@ -1,129 +1,67 @@
|
||||
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 React, { useContext, useEffect } from 'react';
|
||||
import { Alert, Button, Grid, Stack, Typography } from '@mui/material';
|
||||
import { Check, ContentCopySharp } from '@mui/icons-material';
|
||||
import { useClipboard } from 'use-clipboard-copy';
|
||||
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 } =
|
||||
const { mnemonic, mnemonicWords, 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]);
|
||||
generateMnemonic();
|
||||
}, []);
|
||||
|
||||
const { copy, copied } = useClipboard({ copiedTimeout: 5000 });
|
||||
|
||||
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>
|
||||
<Stack alignItems="center" spacing={3}>
|
||||
<Typography sx={{ color: 'common.white', fontWeight: 600 }} textAlign="center">
|
||||
Write down your mnemonic
|
||||
</Typography>
|
||||
|
||||
<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>
|
||||
<Alert variant="outlined" severity="warning" sx={{ textAlign: 'center' }}>
|
||||
<Typography>Below is your 24 word mnemonic, please store the mnemonic in a safe place.</Typography>
|
||||
<Typography>This is the only way to access your wallet!</Typography>
|
||||
</Alert>
|
||||
|
||||
<WordTiles mnemonicWords={mnemonicWords} showIndex />
|
||||
|
||||
<Button
|
||||
color="inherit"
|
||||
disableElevation
|
||||
size="large"
|
||||
onClick={() => {
|
||||
copy(mnemonic);
|
||||
}}
|
||||
sx={{
|
||||
width: 250,
|
||||
}}
|
||||
endIcon={!copied ? <ContentCopySharp /> : <Check color="success" />}
|
||||
>
|
||||
Copy mnemonic
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disableElevation
|
||||
size="large"
|
||||
onClick={onNext}
|
||||
sx={{ width: 250 }}
|
||||
disabled={!copied}
|
||||
>
|
||||
I saved my mnemonic
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,61 +1,69 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { Button, FormControl, Grid, Stack } from '@mui/material';
|
||||
import { Button, FormControl, Stack } from '@mui/material';
|
||||
import { useSnackbar } from 'notistack';
|
||||
import { TPages } from '../types';
|
||||
import { Subtitle, Title, PasswordStrength } from '../components';
|
||||
import { PasswordInput } from '../components/textfields';
|
||||
import { SignInContext } from '../context';
|
||||
import { createPassword } from '../../../requests';
|
||||
|
||||
export const CreatePassword = ({ page, onPrev, onNext }: { page: TPages; onNext: () => void; onPrev: () => void }) => {
|
||||
export const CreatePassword = ({ onSkip, onNext }: { page: TPages; onNext: () => void; onSkip: () => void }) => {
|
||||
const { password, setPassword } = useContext(SignInContext);
|
||||
const [confirmedPassword, setConfirmedPassword] = useState<string>('');
|
||||
const [isStrongPassword, setIsStrongPassword] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const handleOnPrev = () => {
|
||||
const { mnemonic } = useContext(SignInContext);
|
||||
|
||||
const handleSkip = () => {
|
||||
setPassword('');
|
||||
onPrev();
|
||||
onSkip();
|
||||
};
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const storePassword = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await createPassword({ mnemonic, password });
|
||||
enqueueSnackbar('Password successfully created', { variant: 'success' });
|
||||
setPassword('');
|
||||
onNext();
|
||||
} catch (e) {
|
||||
enqueueSnackbar(e as string, { variant: 'error' });
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={page} />
|
||||
<Stack spacing={3} alignItems="center" minWidth="50%">
|
||||
<Title title="Create password" />
|
||||
<Subtitle subtitle="Create a strong password. Min 8 characters, at least one capital letter, number and special symbol" />
|
||||
<Grid container justifyContent="center">
|
||||
<Grid item xs={6}>
|
||||
<FormControl fullWidth>
|
||||
<Stack spacing={2}>
|
||||
<>
|
||||
<PasswordInput password={password} onUpdatePassword={(pswd) => setPassword(pswd)} label="Password" />
|
||||
<PasswordStrength password={password} onChange={(isStrong) => setIsStrongPassword(isStrong)} />
|
||||
</>
|
||||
<PasswordInput
|
||||
password={confirmedPassword}
|
||||
onUpdatePassword={(pswd) => setConfirmedPassword(pswd)}
|
||||
label="Confirm password"
|
||||
/>
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={password !== confirmedPassword || password.length === 0 || !isStrongPassword}
|
||||
onClick={onNext}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
size="large"
|
||||
onClick={handleOnPrev}
|
||||
sx={{
|
||||
color: 'common.white',
|
||||
border: '1px solid white',
|
||||
'&:hover': { border: '1px solid white', '&:hover': { background: 'none' } },
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
</Stack>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</>
|
||||
<FormControl fullWidth>
|
||||
<Stack spacing={2}>
|
||||
<>
|
||||
<PasswordInput password={password} onUpdatePassword={(pswd) => setPassword(pswd)} label="Password" />
|
||||
<PasswordStrength password={password} onChange={(isStrong) => setIsStrongPassword(isStrong)} />
|
||||
</>
|
||||
<PasswordInput
|
||||
password={confirmedPassword}
|
||||
onUpdatePassword={(pswd) => setConfirmedPassword(pswd)}
|
||||
label="Confirm password"
|
||||
/>
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={password !== confirmedPassword || password.length === 0 || !isStrongPassword || isLoading}
|
||||
onClick={storePassword}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button size="large" color="info" onClick={handleSkip}>
|
||||
Skip and sign in with mnemonic
|
||||
</Button>
|
||||
</Stack>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,22 +13,11 @@ export const WelcomeContent: React.FC<{
|
||||
<Title title="Welcome to NYM" />
|
||||
<SubtitleSlick subtitle="Next generation of privacy" />
|
||||
<Stack spacing={3} sx={{ width: 300 }}>
|
||||
<Button fullWidth variant="contained" color="primary" disableElevation size="large" onClick={onCreateAccount}>
|
||||
Create Account
|
||||
<Button fullWidth color="primary" variant="contained" size="large" onClick={onUseExisting}>
|
||||
Sign in
|
||||
</Button>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
size="large"
|
||||
sx={{
|
||||
color: 'common.white',
|
||||
border: '1px solid white',
|
||||
'&:hover': { border: '1px solid white', '&:hover': { background: 'none' } },
|
||||
}}
|
||||
onClick={onUseExisting}
|
||||
disableRipple
|
||||
>
|
||||
Use existing account
|
||||
<Button fullWidth color="inherit" disableElevation size="large" onClick={onCreateAccount}>
|
||||
Create account
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { useState } from 'react';
|
||||
import { useClipboard } from 'use-clipboard-copy';
|
||||
|
||||
export const useClipboardHook = () => {
|
||||
const [isCopied, setIsCopied] = useState(false);
|
||||
|
||||
const clipboard = useClipboard();
|
||||
|
||||
const copy = (value: string) => {
|
||||
clipboard.copy(value);
|
||||
setIsCopied(true);
|
||||
};
|
||||
|
||||
return { isCopied, copy };
|
||||
};
|
||||
Reference in New Issue
Block a user