import accounts wip
This commit is contained in:
@@ -4,7 +4,6 @@ import { AccountsContext } from 'src/context';
|
||||
import { EditAccountModal } from './EditAccountModal';
|
||||
import { AddAccountModal } from './AddAccountModal';
|
||||
import { AccountsModal } from './AccountsModal';
|
||||
import { ImportAccountModal } from './ImportAccountModal';
|
||||
import { AccountAvatar } from './AccountAvatar';
|
||||
|
||||
export const Accounts = () => {
|
||||
@@ -23,7 +22,6 @@ export const Accounts = () => {
|
||||
<AccountsModal />
|
||||
<AddAccountModal />
|
||||
<EditAccountModal />
|
||||
<ImportAccountModal />
|
||||
</>
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -19,6 +19,11 @@ import { createMnemonic } from 'src/requests';
|
||||
import { AccountsContext } from 'src/context';
|
||||
|
||||
const createAccountSteps = ['Save and copy mnemonic for your new account', 'Name your new account', 'Confirm password'];
|
||||
const importAccountSteps = [
|
||||
'Provide mnemonic of account you want to import',
|
||||
'Name your new account',
|
||||
'Confirm password',
|
||||
];
|
||||
|
||||
const passwordCreationSteps = [
|
||||
'Log out',
|
||||
@@ -91,6 +96,36 @@ const MnemonicStep = ({ mnemonic, onNext }: { mnemonic: string; onNext: () => vo
|
||||
);
|
||||
};
|
||||
|
||||
const ImportMnemonic = ({
|
||||
value,
|
||||
onChange,
|
||||
onNext,
|
||||
}: {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
onNext: () => void;
|
||||
}) => (
|
||||
<Box sx={{ mt: 1 }}>
|
||||
<DialogContent>
|
||||
<Stack spacing={2} alignItems="center">
|
||||
<TextField multiline rows={3} value={value} onChange={(e) => onChange(e.target.value)} fullWidth />
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ p: 3, pt: 0 }}>
|
||||
<Button
|
||||
disabled={value.length === 0}
|
||||
fullWidth
|
||||
disableElevation
|
||||
variant="contained"
|
||||
size="large"
|
||||
onClick={onNext}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const NameAccount = ({ onNext }: { onNext: (value: string) => void }) => {
|
||||
const [value, setValue] = useState('');
|
||||
return (
|
||||
@@ -142,9 +177,9 @@ const ConfirmPassword = ({ onConfirm }: { onConfirm: (password: string) => void
|
||||
|
||||
export const AddAccountModal = ({ withoutPassword }: { withoutPassword?: boolean }) => {
|
||||
const [step, setStep] = useState(0);
|
||||
const [data, setData] = useState<{ mnemonic?: string; accountName?: string }>({
|
||||
mnemonic: undefined,
|
||||
accountName: undefined,
|
||||
const [data, setData] = useState({
|
||||
mnemonic: '',
|
||||
accountName: '',
|
||||
});
|
||||
|
||||
const { dialogToDisplay, setDialogToDisplay, handleAddAccount } = useContext(AccountsContext);
|
||||
@@ -156,19 +191,25 @@ export const AddAccountModal = ({ withoutPassword }: { withoutPassword?: boolean
|
||||
|
||||
const handleClose = () => {
|
||||
setDialogToDisplay('Accounts');
|
||||
setData({ mnemonic: undefined, accountName: undefined });
|
||||
setData({ mnemonic: '', accountName: '' });
|
||||
setStep(0);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (dialogToDisplay === 'Accounts') generateMnemonic();
|
||||
if (dialogToDisplay === 'Add') generateMnemonic();
|
||||
else setData({ mnemonic: '', accountName: '' });
|
||||
}, [dialogToDisplay]);
|
||||
|
||||
return (
|
||||
<Dialog open={dialogToDisplay === 'Add'} onClose={handleClose} fullWidth hideBackdrop>
|
||||
<Dialog
|
||||
open={dialogToDisplay === 'Add' || dialogToDisplay === 'Import'}
|
||||
onClose={handleClose}
|
||||
fullWidth
|
||||
hideBackdrop
|
||||
>
|
||||
<DialogTitle>
|
||||
<Box display="flex" justifyContent="space-between" alignItems="center">
|
||||
<Typography variant="h6">Add new account</Typography>
|
||||
<Typography variant="h6">{`${dialogToDisplay} new account`}</Typography>
|
||||
<IconButton onClick={handleClose}>
|
||||
<Close />
|
||||
</IconButton>
|
||||
@@ -178,15 +219,24 @@ export const AddAccountModal = ({ withoutPassword }: { withoutPassword?: boolean
|
||||
{`Step ${step + 1}/${createAccountSteps.length}`}
|
||||
</Typography>
|
||||
)}
|
||||
<Typography sx={{ mt: 2 }}>{createAccountSteps[step]}</Typography>
|
||||
<Typography sx={{ mt: 2 }}>
|
||||
{dialogToDisplay === 'Add' ? createAccountSteps[step] : importAccountSteps[step]}
|
||||
</Typography>
|
||||
</DialogTitle>
|
||||
{withoutPassword && <NoPassword onClose={handleClose} />}
|
||||
{!withoutPassword &&
|
||||
data.mnemonic &&
|
||||
(() => {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return <MnemonicStep mnemonic={data.mnemonic} onNext={() => setStep((s) => s + 1)} />;
|
||||
return dialogToDisplay === 'Add' ? (
|
||||
<MnemonicStep mnemonic={data.mnemonic} onNext={() => setStep((s) => s + 1)} />
|
||||
) : (
|
||||
<ImportMnemonic
|
||||
value={data.mnemonic}
|
||||
onChange={(value) => setData((d) => ({ ...d, mnemonic: value }))}
|
||||
onNext={() => setStep((s) => s + 1)}
|
||||
/>
|
||||
);
|
||||
case 1:
|
||||
return (
|
||||
<NameAccount
|
||||
|
||||
@@ -65,13 +65,9 @@ export const AccountsProvider: React.FC = ({ children }) => {
|
||||
setAccountToEdit(accounts?.find((acc) => acc.id === accountName));
|
||||
|
||||
const handleSelectAccount = async (accountName: string) => {
|
||||
try {
|
||||
await onAccountChange(accountName);
|
||||
const match = accounts?.find((acc) => acc.id === accountName);
|
||||
setSelectedAccount(match);
|
||||
} catch (e) {
|
||||
console.log('boom!');
|
||||
}
|
||||
await onAccountChange(accountName);
|
||||
const match = accounts?.find((acc) => acc.id === accountName);
|
||||
setSelectedAccount(match);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useMemo, createContext, useEffect, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useSnackbar } from 'notistack';
|
||||
import { TLoginType } from 'src/pages/sign-in/types';
|
||||
import { Account, Network, TCurrency, TMixnodeBondDetails, AccountEntry } from '../types';
|
||||
import { TUseuserBalance, useGetBalance } from '../hooks/useGetBalance';
|
||||
import { config } from '../../config';
|
||||
@@ -30,6 +29,8 @@ export const urls = (networkName?: Network) =>
|
||||
networkExplorer: `https://${networkName}-explorer.nymtech.net`,
|
||||
};
|
||||
|
||||
type TLoginType = 'mnemonic' | 'password';
|
||||
|
||||
type TClientContext = {
|
||||
mode: 'light' | 'dark';
|
||||
clientDetails?: Account;
|
||||
@@ -42,13 +43,14 @@ type TClientContext = {
|
||||
currency?: TCurrency;
|
||||
isLoading: boolean;
|
||||
error?: string;
|
||||
loginType?: TLoginType;
|
||||
setIsLoading: (isLoading: boolean) => void;
|
||||
setError: (value?: string) => void;
|
||||
switchNetwork: (network: Network) => void;
|
||||
getBondDetails: () => Promise<void>;
|
||||
handleShowSettings: () => void;
|
||||
handleShowAdmin: () => void;
|
||||
logIn: (opts: { type: 'mnemonic' | 'password'; value: string }) => void;
|
||||
logIn: (opts: { type: TLoginType; value: string }) => void;
|
||||
signInWithPassword: (password: string) => void;
|
||||
logOut: () => void;
|
||||
onAccountChange: (accountId: string) => void;
|
||||
@@ -65,6 +67,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
const [showAdmin, setShowAdmin] = useState(false);
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
const [mode] = useState<'light' | 'dark'>('light');
|
||||
const [loginType, setLoginType] = useState<'mnemonic' | 'password'>();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string>();
|
||||
|
||||
@@ -108,14 +111,15 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
}
|
||||
};
|
||||
|
||||
const refreshAccount = async (_network: Network) => {
|
||||
await loadAccount(_network);
|
||||
if (loginType === 'password') {
|
||||
await loadStoredAccounts();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const refreshAccount = async () => {
|
||||
if (network) {
|
||||
await loadAccount(network);
|
||||
await loadStoredAccounts();
|
||||
}
|
||||
};
|
||||
refreshAccount();
|
||||
if (network) refreshAccount(network);
|
||||
}, [network]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -131,9 +135,10 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
setIsLoading(true);
|
||||
if (type === 'mnemonic') {
|
||||
await signInWithMnemonic(value);
|
||||
setLoginType('mnemonic');
|
||||
} else {
|
||||
await signInWithPassword(value);
|
||||
await loadStoredAccounts();
|
||||
setLoginType('password');
|
||||
}
|
||||
setNetwork('MAINNET');
|
||||
history.push('/balance');
|
||||
@@ -182,6 +187,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
showSettings,
|
||||
network,
|
||||
currency,
|
||||
loginType,
|
||||
setIsLoading,
|
||||
setError,
|
||||
signInWithPassword,
|
||||
@@ -194,6 +200,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
onAccountChange,
|
||||
}),
|
||||
[
|
||||
loginType,
|
||||
mode,
|
||||
isLoading,
|
||||
error,
|
||||
|
||||
@@ -19,5 +19,3 @@ export type TMnemonicWords = TMnemonicWord[];
|
||||
export type THiddenMnemonicWord = { hidden: boolean } & TMnemonicWord;
|
||||
|
||||
export type THiddenMnemonicWords = THiddenMnemonicWord[];
|
||||
|
||||
export type TLoginType = 'mnemonic' | 'password';
|
||||
|
||||
Reference in New Issue
Block a user