use context for accounts state

This commit is contained in:
fmtabbara
2022-05-04 16:18:56 +01:00
parent a1e0087760
commit 92fcae9a37
3 changed files with 100 additions and 67 deletions
@@ -1,60 +0,0 @@
import React, { useEffect, useState } from 'react';
import { AccountEntry } from 'src/types';
import { addAccount as addAccountRequest } from 'src/requests';
import { Accounts } from './Accounts';
import { TDialog } from './types';
export const AccountsContainer = ({ storedAccounts }: { storedAccounts: AccountEntry[] }) => {
const [accounts, setAccounts] = useState<AccountEntry[]>(storedAccounts);
const [selectedAccount, setSelectedAccount] = useState<AccountEntry>(storedAccounts[0]);
const [accountToEdit, setAccountToEdit] = useState<AccountEntry>();
const [dialogToDisplay, setDialogToDisplay] = useState<TDialog>();
useEffect(() => {
const selected = accounts?.find((acc) => acc.address === selectedAccount?.address);
if (selected) setSelectedAccount(selected);
}, [accounts, storedAccounts]);
useEffect(() => {
setAccounts(storedAccounts);
}, [storedAccounts]);
const addAccount = async ({
accountName,
mnemonic,
password,
}: {
accountName: string;
mnemonic: string;
password: string;
}) => {
await addAccountRequest({
accountName,
mnemonic,
password,
});
};
const editAccount = (account: AccountEntry) =>
setAccounts((accs) => accs?.map((acc) => (acc.address === account.address ? account : acc)));
const importAccount = (account: AccountEntry) => setAccounts((accs) => [...accs, account]);
const handleAccountToEdit = (accountName: string) => setAccountToEdit(accounts.find((acc) => acc.id === accountName));
const handleSelectedAccount = (accountName: string) => {
const match = accounts.find((acc) => acc.id === accountName);
if (match) setSelectedAccount(match);
};
return (
<Accounts
accounts={accounts}
selectedAccount={selectedAccount}
accountToEdit={accountToEdit}
dialogToDisplay={dialogToDisplay}
addAccount={addAccount}
editAccount={editAccount}
importAccount={importAccount}
setAccountToEdit={handleAccountToEdit}
setSelectedAccount={handleSelectedAccount}
setDialogToDisplay={setDialogToDisplay}
/>
);
};
+8 -7
View File
@@ -1,24 +1,25 @@
import React, { useContext } from 'react';
import { AppBar as MuiAppBar, Grid, IconButton, Toolbar } from '@mui/material';
import { Logout } from '@mui/icons-material';
import { AccountsProvider } from 'src/context/accounts';
import { ClientContext } from '../context/main';
import { NetworkSelector } from './NetworkSelector';
import { Node as NodeIcon } from '../svg-icons/node';
import { AccountsContainer } from './Accounts/AccountContainer';
import { Accounts } from './Accounts/Accounts';
export const AppBar = () => {
const { showSettings, storedAccounts, logOut, handleShowSettings } = useContext(ClientContext);
const { showSettings, logOut, handleShowSettings } = useContext(ClientContext);
return (
<MuiAppBar position="sticky" sx={{ boxShadow: 'none', bgcolor: 'transparent' }}>
<Toolbar disableGutters>
<Grid container justifyContent="space-between" alignItems="center" flexWrap="nowrap">
<Grid item container alignItems="center" spacing={1}>
{storedAccounts && (
<Grid item>
<AccountsContainer storedAccounts={storedAccounts} />
</Grid>
)}
<Grid item>
<AccountsProvider>
<Accounts />
</AccountsProvider>
</Grid>
<Grid item>
<NetworkSelector />
</Grid>
+92
View File
@@ -0,0 +1,92 @@
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { Account, AccountEntry, TAccountsDialog } from 'src/types';
import { addAccount as addAccountRequest } from 'src/requests';
import { ClientContext } from './main';
type TAccounts = {
accounts?: AccountEntry[];
selectedAccount?: AccountEntry;
accountToEdit?: AccountEntry;
dialogToDisplay?: TAccountsDialog;
handleAddAccount: (data: { accountName: string; mnemonic: string; password: string }) => void;
setDialogToDisplay: (dialog?: TAccountsDialog) => void;
handleSelectAccount: (accountId: string) => void;
handleAccountToEdit: (accountId: string) => void;
handleEditAccount: (account: AccountEntry) => void;
handleImportAccount: (account: AccountEntry) => void;
};
export const AccountsContext = createContext({} as TAccounts);
export const AccountsProvider: React.FC = ({ children }) => {
const [accounts, setAccounts] = useState<AccountEntry[]>();
const [selectedAccount, setSelectedAccount] = useState<AccountEntry>();
const [accountToEdit, setAccountToEdit] = useState<AccountEntry>();
const [dialogToDisplay, setDialogToDisplay] = useState<TAccountsDialog>();
const { onAccountChange, storedAccounts } = useContext(ClientContext);
const handleAddAccount = async ({
accountName,
mnemonic,
password,
}: {
accountName: string;
mnemonic: string;
password: string;
}) => {
await addAccountRequest({
accountName,
mnemonic,
password,
});
};
const handleEditAccount = (account: AccountEntry) =>
setAccounts((accs) => accs?.map((acc) => (acc.address === account.address ? account : acc)));
const handleImportAccount = (account: AccountEntry) => setAccounts((accs) => [...(accs ? [...accs] : []), account]);
const handleAccountToEdit = (accountName: string) =>
setAccountToEdit(accounts?.find((acc) => acc.id === accountName));
const handleSelectAccount = async (accountName: string) => {
const match = accounts?.find((acc) => acc.id === accountName);
if (match) {
try {
await onAccountChange(match.id);
setSelectedAccount(match);
} catch (e) {
console.log('Error swtiching account');
}
}
};
useEffect(() => {
if (storedAccounts) {
setAccounts(storedAccounts);
setSelectedAccount(storedAccounts[0]);
}
}, [storedAccounts]);
return (
<AccountsContext.Provider
value={useMemo(
() => ({
accounts,
selectedAccount,
accountToEdit,
dialogToDisplay,
setDialogToDisplay,
handleAddAccount,
handleEditAccount,
handleAccountToEdit,
handleSelectAccount,
handleImportAccount,
}),
[accounts, selectedAccount, accountToEdit, dialogToDisplay],
)}
>
{children}
</AccountsContext.Provider>
);
};