more storybook work for multi accounts

This commit is contained in:
fmtabbara
2022-04-07 16:27:30 +01:00
parent c6578384a8
commit 585724fc79
3 changed files with 158 additions and 41 deletions
+2
View File
@@ -44,6 +44,7 @@
"semver": "^6.3.0",
"string-to-color": "^2.2.2",
"use-clipboard-copy": "^0.2.0",
"uuid": "^8.3.2",
"yup": "^0.32.9"
},
"devDependencies": {
@@ -72,6 +73,7 @@
"@types/react-router": "^5.1.18",
"@types/react-router-dom": "^5.1.8",
"@types/semver": "^7.3.8",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.13.0",
"@typescript-eslint/parser": "^5.13.0",
"babel-loader": "^8.2.2",
@@ -2,6 +2,7 @@ import React from 'react';
import { Box } from '@mui/material';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { Accounts } from 'src/components/Accounts';
import { v4 as uuid4 } from 'uuid';
export default {
title: 'Wallet / Multi Account',
@@ -16,8 +17,13 @@ const Template: ComponentStory<typeof Accounts> = (args) => (
export const Default = Template.bind({});
Default.args = {
accounts: [
{ name: 'Account 1', address: 'abcd1234uvw987xyz' },
{ name: 'Account 2', address: 'cd102034u087xyz' },
storedAccounts: [{ name: 'Account 1', address: uuid4() }],
};
export const MultipleAccounts = Template.bind({});
MultipleAccounts.args = {
storedAccounts: [
{ name: 'Account 1', address: uuid4() },
{ name: 'Account 2', address: uuid4() },
],
};
+147 -38
View File
@@ -1,8 +1,23 @@
import React, { useState } from 'react';
import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Typography } from '@mui/material';
import React, { useEffect, useState } from 'react';
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
ListItem,
ListItemAvatar,
ListItemButton,
ListItemIcon,
ListItemText,
TextField,
Typography,
} from '@mui/material';
import stc from 'string-to-color';
import { Add, Circle, Close, Edit } from '@mui/icons-material';
import { NymCard } from './NymCard';
import { v4 as uuidv4 } from 'uuid';
export type TAccount = {
name: string;
@@ -11,30 +26,35 @@ export type TAccount = {
const AccountColor = ({ address }: { address: string }) => <Circle sx={{ color: stc(address) }} />;
const AccountItem = ({ name, address }: { name: string; address: string }) => (
<NymCard
title={
<Box>
<Typography>{name}</Typography>
<Typography variant="caption">{address}</Typography>
</Box>
}
noPadding
borderless
Icon={
<Box sx={{ mr: 1.5 }}>
const AccountItem = ({ name, address, onSelect }: { name: string; address: string; onSelect: () => void }) => (
<ListItem disablePadding disableGutters>
<ListItemButton disableRipple onClick={onSelect}>
<ListItemAvatar>
<AccountColor address={address} />
</Box>
}
Action={
<IconButton size="small">
<Edit fontSize="small" />
</IconButton>
}
/>
</ListItemAvatar>
<ListItemText primary={name} secondary={address} />
<ListItemIcon>
<IconButton onClick={(e) => e.stopPropagation()}>
<Edit />
</IconButton>
</ListItemIcon>
</ListItemButton>
</ListItem>
);
const AccountModal = ({ show, addresses, onClose }: { show: boolean; addresses: TAccount[]; onClose: () => void }) => (
const AccountModal = ({
show,
accounts,
onClose,
onAccountSelect,
onAddAccount,
}: {
show: boolean;
accounts: TAccount[];
onClose: () => void;
onAccountSelect: (account: TAccount) => void;
onAddAccount: () => void;
}) => (
<Dialog open={show} onClose={onClose} fullWidth>
<DialogTitle>
<Box display="flex" justifyContent="space-between" alignItems="center">
@@ -43,38 +63,127 @@ const AccountModal = ({ show, addresses, onClose }: { show: boolean; addresses:
<Close />
</IconButton>
</Box>
<Typography variant="caption" sx={{ color: 'grey.600' }}>
<Typography variant="body1" sx={{ color: 'grey.600' }}>
Switch between accounts
</Typography>
</DialogTitle>
<DialogContent>
{addresses.map(({ name, address }) => (
<AccountItem name={name} address={address} />
<DialogContent sx={{ padding: 0 }}>
{accounts.map(({ name, address }) => (
<AccountItem
name={name}
address={address}
onSelect={() => {
onAccountSelect({ name, address });
onClose();
}}
key={address}
/>
))}
</DialogContent>
<DialogActions>
<Button fullWidth variant="contained" size="large" startIcon={<Add fontSize="small" />}>
<DialogActions sx={{ p: 3 }}>
<Button
fullWidth
disableElevation
variant="contained"
size="large"
startIcon={<Add fontSize="small" />}
onClick={onAddAccount}
>
Add new account
</Button>
</DialogActions>
</Dialog>
);
export const Accounts = ({ accounts }: { accounts: TAccount[] }) => {
const [addresses, setAddresses] = useState(accounts);
const [selectedAddress, setSelectedAddress] = useState(accounts[0]);
const [showDialog, setShowDialog] = useState(false);
const AddAccountModal = ({
show,
onClose,
onAdd,
}: {
show: boolean;
onClose: () => void;
onAdd: (accountName: string) => void;
}) => {
const [accountName, setAccountName] = useState('');
useEffect(() => {
if (!show) setAccountName('');
}, [show]);
return (
<Dialog open={show} onClose={onClose} fullWidth>
<DialogTitle>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Typography variant="h6">Account</Typography>
<IconButton onClick={onClose}>
<Close />
</IconButton>
</Box>
<Typography variant="body1" sx={{ color: 'grey.600' }}>
New wallet address
</Typography>
</DialogTitle>
<DialogContent sx={{ p: 0 }}>
<Box sx={{ px: 3, mt: 1 }}>
<TextField
label="Account name"
fullWidth
value={accountName}
onChange={(e) => setAccountName(e.target.value)}
/>
</Box>
</DialogContent>
<DialogActions sx={{ p: 3 }}>
<Button
fullWidth
disableElevation
variant="contained"
size="large"
startIcon={<Add fontSize="small" />}
onClick={() => onAdd(accountName)}
disabled={!accountName.length}
>
Add
</Button>
</DialogActions>
</Dialog>
);
};
export const Accounts = ({ storedAccounts }: { storedAccounts: TAccount[] }) => {
const [accounts, setAccounts] = useState(storedAccounts);
const [selectedAccount, setSelectedAccount] = useState(accounts[0]);
const [showAccountsDialog, setShowAccountsDialog] = useState(false);
const [showNewAccountsDialog, setShowNewAccountsDialog] = useState(false);
return (
<>
<Button
startIcon={<AccountColor address={selectedAddress.address} />}
startIcon={<AccountColor address={selectedAccount.address} />}
color="inherit"
onClick={() => setShowDialog(true)}
onClick={() => setShowAccountsDialog(true)}
>
{selectedAddress.name}
{selectedAccount.name}
</Button>
<AccountModal show={showDialog} onClose={() => setShowDialog(false)} addresses={addresses} />
<AccountModal
show={showAccountsDialog}
onClose={() => setShowAccountsDialog(false)}
accounts={accounts}
onAccountSelect={(acc) => setSelectedAccount(acc)}
onAddAccount={() => {
setShowAccountsDialog(false);
setShowNewAccountsDialog(true);
}}
/>
<AddAccountModal
show={showNewAccountsDialog}
onClose={() => setShowNewAccountsDialog(false)}
onAdd={(name) => {
setAccounts((accs) => [...accs, { address: uuidv4(), name }]);
setShowNewAccountsDialog(false);
setShowAccountsDialog(true);
}}
/>
</>
);
};