Skip to content

Commit

Permalink
feat: add account drawer UI for account switch (#516)
Browse files Browse the repository at this point in the history
* chore: fix ui redux state over subscribe

* fix: lint

* feat: add account drawer modal

* feat: add account drawer modal

* chore: refinement

* chore: refine sidebar

* fix: undefined account chain id from ui

* chore: remove account switch pull down

* chore: refine

* chore: lint

* chore: rename file

* chore: update path

* chore: remove space

* chore: disable click for selected account

* chore: fix account click event

* chore: add missing redux state separation

* chore: add no hidden account text

* chore(wallet-ui): update flex style

---------

Co-authored-by: khanti42 <[email protected]>
  • Loading branch information
stanleyyconsensys and khanti42 authored Feb 25, 2025
1 parent b91e762 commit ed2b4d6
Show file tree
Hide file tree
Showing 35 changed files with 545 additions and 534 deletions.
12 changes: 9 additions & 3 deletions packages/wallet-ui/src/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
"accountName": {
"message": "Account name"
},
"accounts": {
"message": "Accounts"
},
"accountDeployedSuccessfully": {
"message": "Account deployed successfully."
},
Expand Down Expand Up @@ -148,6 +145,9 @@
"gotIt": {
"message": "GOT IT!"
},
"hiddenAccounts": {
"message": "Hidden accounts"
},
"inputAmountExceedsBalance": {
"message": "Input amount exceeds user balance"
},
Expand Down Expand Up @@ -214,6 +214,9 @@
"nonZeroBalanceOnCairo0": {
"message": "You have a non-zero balance on a Cairo 0 non-deployed address"
},
"noHiddenAccount": {
"message": "No hidden accounts"
},
"openBetaVersion": {
"message": "This is the Open Beta version of the dapp, updates are made regularly"
},
Expand Down Expand Up @@ -244,6 +247,9 @@
"selectTokenForTransactionFees": {
"message": "Select Token for Transaction Fees"
},
"selectAnAccount": {
"message": "Select an account"
},
"send": {
"message": "Send"
},
Expand Down
12 changes: 9 additions & 3 deletions packages/wallet-ui/src/assets/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
"accountName": {
"message": "Nom du compte"
},
"accounts": {
"message": "Comptes"
},
"accountDeployedSuccessfully": {
"message": "Compte déployé avec succès."
},
Expand Down Expand Up @@ -142,6 +139,9 @@
"gotIt": {
"message": "COMPRIS !"
},
"hiddenAccounts": {
"message": "Comptes cachés"
},
"inputAmountExceedsBalance": {
"message": "Le montant entré dépasse le solde de l'utilisateur"
},
Expand Down Expand Up @@ -208,6 +208,9 @@
"nonZeroBalanceOnCairo0": {
"message": "Vous avez un solde non nul sur une adresse Cairo 0 non déployée"
},
"noHiddenAccount": {
"message": "Pas de comptes cachés"
},
"openBetaVersion": {
"message": "Il s'agit de la version Open Beta de la dApp, des mises à jour sont effectuées régulièrement"
},
Expand Down Expand Up @@ -238,6 +241,9 @@
"selectTokenForTransactionFees": {
"message": "Sélectionner un jeton pour les frais de transaction"
},
"selectAnAccount": {
"message": "Sélectionnez un compte"
},
"send": {
"message": "Envoie"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from 'styled-components';

export const ScrollableWrapper = styled.div`
overflow-y: scroll;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useScrollTo } from 'hooks';
import { RefObject } from 'react';

import { ScrollableWrapper } from './Scrollable.style';

export interface Props<Element> {
height: number;
child: (scrollTo: RefObject<Element>) => React.ReactNode;
}

export const ScrollableView = <Element extends HTMLElement>({
child,
height,
}: Props<Element>) => {
const { scrollTo } = useScrollTo<Element>();
return (
<ScrollableWrapper
style={{
height,
}}
>
{child(scrollTo)}
</ScrollableWrapper>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ScrollableView as Scrollable } from './Scrollable.view';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Button } from 'components/ui/atom/Button';
import styled from 'styled-components';

export const Drawer = styled(Button).attrs((props) => ({
fontSize: props.theme.typography.c1.fontSize,
upperCaseOnly: false,
textStyle: {
fontWeight: props.theme.typography.p1.fontWeight,
fontFamily: props.theme.typography.p1.fontFamily,
},
iconStyle: {
fontSize: props.theme.typography.i1.fontSize,
color: props.theme.palette.grey.grey1,
},
}))`
padding: ${(props) => props.theme.spacing.tiny2};
height: ${(props) => props.theme.spacing.base};
color: ${(props) => props.theme.palette.grey.black};
border-radius: ${(props) => props.theme.corner.medium};
border: 1px solid ${(props) => props.theme.palette.grey.grey3};
:hover {
background-color: ${(props) => props.theme.palette.grey.grey4};
border: none;
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useState } from 'react';

import { PopIn } from 'components/ui/molecule/PopIn';
import { formatAddress } from 'utils/utils';
import { useCurrentAccount } from 'hooks';
import { AccountListModal } from '../AccountListModal';
import { AddAccountModal } from '../AddAccountModal';
import { Drawer } from './AccountDrawer.style';

export interface Props {
starkName?: string;
}

export const AccountDrawerView = ({ starkName }: Props) => {
const [accountListModalOpen, setAccountListModalOpen] = useState(false);
const [accountAddModalOpen, setAccountAddModalOpen] = useState(false);
const { address } = useCurrentAccount();

return (
<>
<PopIn isOpen={accountListModalOpen} setIsOpen={setAccountListModalOpen}>
<AccountListModal
onClose={() => setAccountListModalOpen(false)}
onAddAccountClick={() => {
setAccountListModalOpen(false);
setAccountAddModalOpen(true);
}}
/>
</PopIn>
<PopIn isOpen={accountAddModalOpen} setIsOpen={setAccountAddModalOpen}>
<AddAccountModal onClose={() => setAccountAddModalOpen(false)} />
</PopIn>
<Drawer
backgroundTransparent
iconRight="angle-down"
onClick={() => setAccountListModalOpen(true)}
>
{formatAddress(address, starkName)}
</Drawer>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AccountDrawerView as AccountDrawer } from './AccountDrawer.view';
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import styled from 'styled-components';
import { AccountImage } from 'components/ui/atom/AccountImage';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

export const Wrapper = styled.div<{ selected: boolean; visible: boolean }>`
display: flex;
align-items: center;
justify-content: space-between;
opacity: ${(props) => (props.visible ? 1 : 0.5)};
background-color: ${(props) =>
props.selected ? props.theme.palette.grey.grey4 : 'transparent'};
border-left: ${(props) =>
props.selected
? `${props.theme.spacing.tiny} solid ${props.theme.palette.secondary.main}`
: `${props.theme.spacing.tiny} solid ${props.theme.palette.secondary.contrastText}`};
padding: ${(props) => props.theme.spacing.small};
cursor: pointer;
`;

export const AccountInfoWrapper = styled.div`
display: flex;
align-items: center;
`;

export const AccountImageStyled = styled(AccountImage)`
cursor: pointer;
`;

export const VisibilityIcon = styled(FontAwesomeIcon)`
color: ${(props) => props.theme.palette.grey.grey1};
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { IconButton } from '@mui/material';

import { Account } from 'types';
import { formatAddress } from 'utils/utils';
import {
AccountInfoWrapper,
AccountImageStyled,
VisibilityIcon,
Wrapper,
} from './AccountItem.style';

export interface Props {
account: Account;
selected?: boolean;
visible: boolean;
scrollToRef?: React.RefObject<HTMLDivElement> | null;
onItemClick?: (account: Account) => Promise<void>;
onIconButtonClick: (account: Account) => Promise<void>;
}

export const AccountItem = ({
selected = false,
account,
visible,
scrollToRef,
onItemClick,
onIconButtonClick,
}: Props) => {
const { address, accountName } = account;

const preventDefaultMouseEvent = (event: React.MouseEvent) => {
// Prevent triggering the native behaviour
event.preventDefault();
// Prevent triggering the parent onClick event
event.stopPropagation();
};

const onIconBtnClick = async (event: React.MouseEvent) => {
preventDefaultMouseEvent(event);
await onIconButtonClick(account);
};

const onClick = async (event: React.MouseEvent) => {
preventDefaultMouseEvent(event);
if (typeof onItemClick === 'function') {
await onItemClick(account);
}
};

return (
<Wrapper
ref={scrollToRef}
selected={selected}
visible={visible}
onClick={onClick}
>
<AccountInfoWrapper>
<AccountImageStyled size={30} address={address} />
<div>
<div>{accountName}</div>
<div>{formatAddress(address)}</div>
</div>
</AccountInfoWrapper>
<IconButton size="small" onClick={onIconBtnClick}>
<VisibilityIcon icon={visible ? 'eye-slash' : 'eye'} />
</IconButton>
</Wrapper>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import styled from 'styled-components';

export const Wrapper = styled.div`
width: ${(props) => props.theme.modal.base};
padding: ${(props) => props.theme.spacing.base};
background-color: ${(props) => props.theme.palette.grey.white};
border-radius: ${(props) => props.theme.corner.small};
`;

export const ButtonWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
padding: ${(props) => props.theme.spacing.base};
padding-top: 0;
`;

export const Title = styled.div`
text-align: center;
font-style: normal;
font-weight: ${(props) => props.theme.typography.h3.fontWeight};
font-size: ${(props) => props.theme.typography.h3.fontSize};
font-family: ${(props) => props.theme.typography.h3.fontFamily};
line-height: ${(props) => props.theme.typography.h3.lineHeight};
color: ${(props) => props.theme.palette.primary.main};
margin-bottom: ${(props) => props.theme.spacing.base};
`;

export const HiddenAccountBar = styled.div`
display: flex;
justify-content: space-between;
padding: ${(props) => props.theme.spacing.base};
padding-bottom: 0;
cursor: pointer;
`;

export const HiddenAccountBarLeftIcon = styled(FontAwesomeIcon)`
color: ${(props) => props.theme.palette.grey.grey1};
margin-right: ${(props) => props.theme.spacing.tiny2};
`;

export const HiddenAccountBarRightIcon = styled(FontAwesomeIcon)`
color: ${(props) => props.theme.palette.grey.grey1};
margin-left: ${(props) => props.theme.spacing.tiny2};
`;

export const NoHiddenAccountText = styled.span`
color: ${(props) => props.theme.palette.grey.grey1};
`;

export const VerticalAlignBox = styled.div`
height: 100%;
display: flex;
align-item: center;
justify-content: center;
flex-direction: column;
text-align: center;
`;
Loading

0 comments on commit ed2b4d6

Please sign in to comment.