Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
maxaleks committed Nov 1, 2022
2 parents 0099bb1 + 6cb6891 commit 0008a30
Show file tree
Hide file tree
Showing 38 changed files with 876 additions and 270 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"rc-tooltip": "^5.1.1",
"react": "^17.0.2",
"react-copy-to-clipboard": "^5.0.4",
"react-device-detect": "^1.17.0",
"react-device-detect": "^2.2.2",
"react-dom": "^17.0.2",
"react-modal": "^3.14.3",
"react-outside-click-handler": "^1.3.0",
Expand All @@ -36,7 +36,7 @@
"unique-names-generator": "^4.7.1",
"web-vitals": "^1.0.1",
"webpack": "^5.70.0",
"zkbob-client-js": "0.7.5"
"zkbob-client-js": "0.8.0"
},
"scripts": {
"start": "react-app-rewired start",
Expand Down
18 changes: 18 additions & 0 deletions src/assets/incognito-avatar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
102 changes: 67 additions & 35 deletions src/components/AccountModal/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import React, { useState, useCallback } from 'react';
import styled from 'styled-components';
import { CopyToClipboard } from 'react-copy-to-clipboard';

Expand All @@ -9,18 +9,31 @@ import PrivateAddress from 'components/PrivateAddress';
import Tooltip from 'components/Tooltip';
import { ZkAvatar } from 'components/ZkAccountIdentifier';

import { ReactComponent as CopyIconDefault } from 'assets/copy.svg';
import { ReactComponent as CheckIcon } from 'assets/check.svg';

import { shortAddress, formatNumber } from 'utils';
import { tokenSymbol, tokenIcon } from 'utils/token';

export default ({
isOpen, onClose, account = '', zkAccount, zkAccountId,
changeAccount, changeZkAccount, connector, logout,
changeAccount, changeZkAccount, connector, logout, changePassword,
balance, poolBalance, privateAddress, generatePrivateAddress,
}) => {
const [isCopied, setIsCopied] = useState(false);

const onCopy = useCallback((text, result) => {
if (result) {
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000);
}
}, []);

const change = useCallback(cb => {
onClose();
cb();
}, [onClose]);

return (
<Modal
isOpen={isOpen}
Expand All @@ -31,16 +44,7 @@ export default ({
{account ? (
<>
<RowSpaceBetween>
<AccountTitle>Connected with {connector?.name}</AccountTitle>
<Button type="link" onClick={() => change(changeAccount)}>
Change
</Button>
</RowSpaceBetween>
<RowSpaceBetween>
<Row>
{connector?.icon && <Icon src={connector.icon} />}
<Address>{shortAddress(account)}</Address>
</Row>
<AccountTitle>Wallet</AccountTitle>
<TokenContainer>
<TokenIcon src={tokenIcon()} />
<Tooltip content={formatNumber(balance, 18)} placement="top">
Expand All @@ -49,14 +53,23 @@ export default ({
<span style={{ marginLeft: 5 }}>{tokenSymbol()}</span>
</TokenContainer>
</RowSpaceBetween>
<Row>
<CopyToClipboard text={account} style={{ marginRight: 16 }}>
<Button type="link">Copy address</Button>
</CopyToClipboard>
<CopyToClipboard text={account} onCopy={onCopy}>
<AddressContainer>
{connector?.icon && <Icon src={connector.icon} />}
<Address>{shortAddress(account, 22)}</Address>
<Tooltip content="Copied" placement="right" visible={isCopied}>
{isCopied ? <CheckIcon /> : <CopyIcon />}
</Tooltip>
</AddressContainer>
</CopyToClipboard>
<RowSpaceBetween>
<Link href={process.env.REACT_APP_EXPLORER_ADDRESS_TEMPLATE.replace('%s', account)}>
View in Explorer
</Link>
</Row>
<Button type="link" onClick={() => change(changeAccount)}>
Switch
</Button>
</RowSpaceBetween>
</>
) : (
<RowSpaceBetween>
Expand All @@ -70,20 +83,6 @@ export default ({
<>
<RowSpaceBetween>
<AccountTitle>zkAccount</AccountTitle>
<Row>
<Button type="link" onClick={() => change(changeZkAccount)} style={{ marginRight: 20 }}>
Change
</Button>
<Button type="link" onClick={logout}>
Log out
</Button>
</Row>
</RowSpaceBetween>
<RowSpaceBetween>
<Row>
<ZkAvatar seed={zkAccountId} size={20} />
<Address>zkAccount</Address>
</Row>
<TokenContainer>
<TokenIcon src={tokenIcon(true)} />
<Tooltip content={formatNumber(poolBalance, 18)} placement="top">
Expand All @@ -92,6 +91,12 @@ export default ({
<span style={{ marginLeft: 5 }}>{tokenSymbol(true)}</span>
</TokenContainer>
</RowSpaceBetween>
<RowSpaceBetween>
<Row>
<ZkAvatar seed={zkAccountId} size={20} />
<Address>zkAccount</Address>
</Row>
</RowSpaceBetween>
{privateAddress ? (
<PrivateAddress>{privateAddress}</PrivateAddress>
) : (
Expand All @@ -102,6 +107,19 @@ export default ({
You create a new address each time you connect.{' '}
Receive tokens to this address or a previously generated address.
</PrivateAddressDescription>
<RowSpaceBetween>
<Button type="link" onClick={() => change(changePassword)}>
Change password
</Button>
<Row>
<Button type="link" onClick={() => change(changeZkAccount)} style={{ marginRight: 20 }}>
Switch
</Button>
<Button type="link" onClick={logout}>
Log out
</Button>
</Row>
</RowSpaceBetween>
</>
) : (
<RowSpaceBetween>
Expand Down Expand Up @@ -137,7 +155,7 @@ const RowSpaceBetween = styled(Row)`
width: 100%;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
Expand All @@ -152,7 +170,7 @@ const Address = styled.span`
font-size: 20px;
color: ${({ theme }) => theme.text.color.primary};
font-weight: ${({ theme }) => theme.text.weight.default};
margin-left: 8px;
margin: 0 8px;
`;

const Icon = styled.img`
Expand All @@ -169,13 +187,27 @@ const TokenIcon = styled.img`
const TokenContainer = styled.div`
display: flex;
align-items: center;
font-size: 20px;
font-size: 16px;
`;

const PrivateAddressDescription = styled.span`
text-align: center;
font-size: 14px;
color: ${({ theme }) => theme.text.color.secondary};
margin-top: 10px;
margin: 10px 0 20px;
line-height: 22px;
`;

const CopyIcon = styled(CopyIconDefault)``;

const AddressContainer = styled(Row)`
cursor: pointer;
margin-bottom: 20px;
align-self: flex-start;
flex-wrap: wrap;
&:hover ${CopyIcon} {
path {
fill: ${props => props.theme.color.purple};
}
}
`;
2 changes: 1 addition & 1 deletion src/components/AccountSetUpModal/Password/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const RulesContainer = styled.div`
`;

const Rule = styled.span`
font-size: 12px;
font-size: 14px;
color: ${props => props.theme.text.color[props.$error ? 'error' : 'secondary']};
position: relative;
margin-bottom: 8px;
Expand Down
4 changes: 2 additions & 2 deletions src/components/Card/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import styled from 'styled-components';

export default ({ title, note, children, style }) => (
export default ({ title, note, children, style, titleStyle }) => (
<Card style={style}>
{title && <Title>{title}</Title>}
{title && <Title style={titleStyle}>{title}</Title>}
{children}
{note && <Note>{note}</Note>}
</Card>
Expand Down
141 changes: 141 additions & 0 deletions src/components/ChangePasswordModal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import React, { useCallback, useState, useContext} from 'react';
import styled from 'styled-components';

import Button from 'components/Button';
import Input from 'components/Input';
import Modal from 'components/Modal';
import { ModalContext, ZkAccountContext } from 'contexts';

export default () => {
const { isChangePasswordModalOpen, closeChangePasswordModal } = useContext(ModalContext);
const { changePassword, verifyPassword } = useContext(ZkAccountContext);
const [oldPassword, setOldPassword] = useState('');
const [newPassword, setNewPassword] = useState('');
const [newPasswordConfirmation, setNewPasswordConfirmation] = useState('');
const [lengthError, setLengthError] = useState(false);
const [matchError, setMatchError] = useState(false);
const [wrongPasswordError, setWrongPasswordError] = useState(false);

const handleOldPasswordChange = useCallback(e => {
setWrongPasswordError(false);
setOldPassword(e.target.value);
}, []);

const handleNewPasswordChange = useCallback(e => {
setLengthError(false);
setMatchError(false);
setNewPassword(e.target.value);
}, []);

const handleNewPasswordConfirmationChange = useCallback(e => {
setLengthError(false);
setMatchError(false);
setNewPasswordConfirmation(e.target.value);
}, []);

const closeModal = useCallback(() => {
setWrongPasswordError(false);
setLengthError(false);
setMatchError(false);
setOldPassword('');
setNewPassword('');
setNewPasswordConfirmation('');
closeChangePasswordModal();
}, [closeChangePasswordModal]);

const confirm = useCallback(async () => {
const wrongPasswordError = !verifyPassword(oldPassword);
const lengthError = !newPassword || newPassword.length < 6;
const matchError = newPassword !== newPasswordConfirmation;
setWrongPasswordError(wrongPasswordError);
setLengthError(lengthError);
setMatchError(matchError);
if (!lengthError && !matchError && !wrongPasswordError) {
changePassword(oldPassword, newPassword);
closeModal();
}
}, [
oldPassword, newPassword, newPasswordConfirmation,
changePassword, verifyPassword, closeModal,
]);

const handleKeyPress = useCallback(event => {
if(event.key === 'Enter'){
confirm();
}
}, [confirm]);

return (
<Modal
isOpen={isChangePasswordModalOpen}
onClose={closeModal}
title="Change password"
>
<Container onKeyPress={handleKeyPress}>
<Input
type="password"
placeholder="Old password"
value={oldPassword}
onChange={handleOldPasswordChange}
error={wrongPasswordError}
/>
<Input
type="password"
placeholder="New password 6+ characters"
value={newPassword}
onChange={handleNewPasswordChange}
error={lengthError || matchError}
/>
<Input
type="password"
placeholder="Verify new password"
value={newPasswordConfirmation}
onChange={handleNewPasswordConfirmationChange}
error={lengthError || matchError}
/>
<RulesContainer>
<Rule $error={wrongPasswordError}>Enter the correct old password</Rule>
<Rule $error={lengthError}>Please enter 6 or more characters</Rule>
<Rule $error={matchError}>New password should match</Rule>
</RulesContainer>
<Button onClick={confirm}>Confirm</Button>
</Container>
</Modal>
);
};

const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
box-sizing: border-box;
& > * {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
`;

const RulesContainer = styled.div`
display: flex;
flex-direction: column;
padding: 0 25px;
`;

const Rule = styled.span`
font-size: 14px;
color: ${props => props.theme.text.color[props.$error ? 'error' : 'secondary']};
position: relative;
margin-bottom: 8px;
&::before {
content: ".";
position: absolute;
left: -12px;
top: -10px;
font-size: 20px;
}
&:last-child {
margin-bottom: 0;
}
`;
Loading

0 comments on commit 0008a30

Please sign in to comment.