feat(wallet): use confirmation modal component

This commit is contained in:
pierre
2022-07-04 17:13:32 +02:00
committed by fmtabbara
parent 468d0f38e9
commit 508f8324f9
25 changed files with 372 additions and 26 deletions
@@ -16,7 +16,13 @@ const Template: ComponentStory<typeof SimpleDialog> = (args) => {
<Button variant="outlined" onClick={() => setOpen(true)}>
Open simple dialog
</Button>
<SimpleDialog {...args} open={open} confirmButton="Confirm">
<SimpleDialog
{...args}
open={open}
confirmButton="Confirm"
onClose={() => setOpen(false)}
onConfirm={() => setOpen(false)}
>
Dialog content.
</SimpleDialog>
</>
@@ -14,7 +14,7 @@ import {
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import CloseIcon from '@mui/icons-material/Close';
interface Props {
export interface Props {
open: boolean;
onConfirm: () => void;
onClose?: () => void;
+1
View File
@@ -20,3 +20,4 @@ export * from './TokenPoolSelector';
export * from './TransactionDetails';
export * from './Warning';
export * from './Modals/ConfirmationModal';
export * from './SimpleDialog';
-1
View File
@@ -2,4 +2,3 @@ export * from './main';
export * from './auth';
export * from './accounts';
export * from './bonding';
@@ -5,8 +5,8 @@ import { Box, Divider, Stack, Typography } from '@mui/material';
import { AmountData, NodeType } from '../types';
import { AppContext } from '../../../context';
import amountSchema from './amountSchema';
import { TokenPoolSelector } from '../../../components';
import { TextFieldInput, CurrencyInput, SimpleDialog } from '../components';
import { SimpleDialog, TokenPoolSelector } from '../../../components';
import { TextFieldInput, CurrencyInput } from '../components';
import { checkHasEnoughFunds, checkHasEnoughLockedTokens } from '../../../utils';
export interface Props {
@@ -2,7 +2,7 @@ import React, { useContext, useEffect, useReducer } from 'react';
import { Box, Button, Typography } from '@mui/material';
import { Link } from '@nymproject/react/link/Link';
import { Gateway, MajorCurrencyAmount, MixNode } from '@nymproject/types';
import { NymCard } from '../../../components';
import { ConfirmationModal, NymCard } from '../../../components';
import NodeIdentityModal from './NodeIdentityModal';
import { ACTIONTYPE, AmountData, BondState, FormStep, NodeData, NodeType } from '../types';
import AmountModal from './AmountModal';
@@ -11,7 +11,6 @@ import SummaryModal from './SummaryModal';
import { bond, vestingBond } from '../../../requests';
import { TBondArgs } from '../../../types';
import { Console } from '../../../utils/console';
import { SimpleDialog } from '../components';
const initialState: BondState = {
showModal: false,
@@ -170,7 +169,7 @@ const BondingCard = () => {
/>
)}
{formStep === 4 && showModal && (
<SimpleDialog
<ConfirmationModal
open={formStep === 4 && showModal}
onConfirm={onConfirm}
onClose={onConfirm}
@@ -178,12 +177,11 @@ const BondingCard = () => {
confirmButton="Done"
maxWidth="xs"
fullWidth
sx={{ textAlign: 'center' }}
>
<Link href={`${urls(network).blockExplorer}/transaction/${state.tx?.transaction_hash}`} noIcon>
View on blockchain
</Link>
</SimpleDialog>
</ConfirmationModal>
)}
</NymCard>
);
@@ -3,8 +3,9 @@ import { useForm, useWatch } from 'react-hook-form';
import { Stack } from '@mui/material';
import { yupResolver } from '@hookform/resolvers/yup';
import { NodeData, NodeType } from '../types';
import { RadioInput, TextFieldInput, CheckboxInput, SimpleDialog } from '../components';
import { RadioInput, TextFieldInput, CheckboxInput } from '../components';
import nodeSchema from './nodeSchema';
import { SimpleDialog } from '../../../components';
export interface Props {
open: boolean;
@@ -4,7 +4,7 @@ import { MajorCurrencyAmount } from '@nymproject/types';
import { getGasFee } from '../../../requests';
import { NodeType } from '../types';
import { AppContext } from '../../../context';
import { SimpleDialog } from '../components';
import { SimpleDialog } from '../../../components';
export interface Props {
open: boolean;
@@ -1,6 +1,5 @@
export { default as BondedNodeCard } from './BondedNodeCard';
export { default as NodeTable } from './NodeTable';
export { default as SimpleDialog } from './SimpleDialog';
export { default as CheckboxInput } from './CheckboxInput';
export { default as RadioInput } from './RadioInput';
export { default as TextFieldInput } from './TextFieldInput';
@@ -9,6 +9,9 @@ import NodeSettings from './node-settings';
import BondMore from './bond-more';
import NodeMenu from './NodeMenu';
import { MixnodeFlow } from './types';
import RedeemRewards from './redeem';
import Unbond from './unbond';
import CompoundRewards from './compound';
const headers: Header[] = [
{
@@ -131,6 +134,9 @@ const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
</Typography>
<NodeSettings mixnode={mixnode} show={flow === 'nodeSettings'} onClose={() => setFlow(null)} />
<BondMore mixnode={mixnode} show={flow === 'bondMore'} onClose={() => setFlow(null)} />
<RedeemRewards mixnode={mixnode} show={flow === 'redeem'} onClose={() => setFlow(null)} />
<Unbond mixnode={mixnode} show={flow === 'unbound'} onClose={() => setFlow(null)} />
<CompoundRewards mixnode={mixnode} show={flow === 'compound'} onClose={() => setFlow(null)} />
</BondedNodeCard>
);
};
@@ -4,10 +4,10 @@ import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { Box, Divider, Stack, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { CurrencyInput, SimpleDialog, TextFieldInput } from '../../components';
import { CurrencyInput, TextFieldInput } from '../../components';
import schema from './schema';
import { AppContext } from '../../../../context';
import { TokenPoolSelector } from '../../../../components';
import { TokenPoolSelector, SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
@@ -5,7 +5,7 @@ import { Link } from '@nymproject/react/link/Link';
import { Typography } from '@mui/material';
import { AppContext, BondedMixnode, urls } from '../../../../context';
import SummaryModal from './SummaryModal';
import { SimpleDialog } from '../../components';
import { ConfirmationModal } from '../../../../components';
import BondModal from './BondModal';
interface Props {
@@ -61,20 +61,19 @@ const BondMore = ({ mixnode, show, onClose }: Props) => {
addBond={addBond}
fee={fee as MajorCurrencyAmount}
/>
<SimpleDialog
<ConfirmationModal
open={show && step === 3}
onClose={reset}
onConfirm={reset}
title="Bonding successful"
confirmButton="Done"
maxWidth="xs"
sx={{ textAlign: 'center' }}
>
<Typography sx={{ mb: 2 }}>This operation can take up to one hour to process</Typography>
<Link href={`${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`} noIcon>
View on blockchain
</Link>
</SimpleDialog>
</ConfirmationModal>
</>
);
};
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Divider, Stack, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { SimpleDialog } from '../../components';
import { SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
@@ -0,0 +1,65 @@
import * as React from 'react';
import { useContext, useEffect, useState } from 'react';
import { MajorCurrencyAmount, TransactionExecuteResult } from '@nymproject/types';
import { Link } from '@nymproject/react/link/Link';
import { Typography } from '@mui/material';
import { AppContext, BondedMixnode, urls } from '../../../../context';
import SummaryModal from './SummaryModal';
import { ConfirmationModal } from '../../../../components';
interface Props {
mixnode: BondedMixnode;
show: boolean;
onClose: () => void;
}
const CompoundRewards = ({ mixnode, show, onClose }: Props) => {
const [fee, setFee] = useState<MajorCurrencyAmount>({ amount: '0', denom: 'NYM' });
const [step, setStep] = useState<1 | 2>(1);
const [tx, setTx] = useState<TransactionExecuteResult>();
const { network } = useContext(AppContext);
useEffect(() => {
setFee({ amount: '42', denom: 'NYM' }); // TODO fetch real fee amount
}, []);
const submit = () => {
// TODO send request to compound rewards
setStep(2); // on success
// setTx(requestResult)
};
const reset = () => {
setStep(1);
onClose();
};
return (
<>
<SummaryModal
open={show && step === 1}
onClose={reset}
onConfirm={submit}
onCancel={reset}
rewards={mixnode.operatorRewards}
fee={fee as MajorCurrencyAmount}
/>
<ConfirmationModal
open={show && step === 2}
onClose={reset}
onConfirm={reset}
title="Rewards compounded successfuly"
confirmButton="Done"
maxWidth="xs"
>
<Typography sx={{ mb: 2 }}>This operation can take up to one hour to process</Typography>
<Link href={`${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`} noIcon>
View on blockchain
</Link>
</ConfirmationModal>
</>
);
};
export default CompoundRewards;
@@ -0,0 +1,42 @@
import * as React from 'react';
import { Divider, Stack, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
onClose: () => void;
onConfirm: () => void;
onCancel: () => void;
rewards: MajorCurrencyAmount;
fee: MajorCurrencyAmount;
}
const SummaryModal = ({ open, onClose, onConfirm, onCancel, rewards, fee }: Props) => (
<SimpleDialog
open={open}
onClose={onClose}
onConfirm={onConfirm}
onCancel={onCancel}
title="Compound rewards"
subTitle="Get more rewards by compounding"
confirmButton="Compound"
closeButton
maxWidth="xs"
fullWidth
>
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Operator rewards</Typography>
<Typography fontWeight={400}>{`${rewards.amount} ${rewards.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Fee for this operation</Typography>
<Typography fontWeight={400}>{`${fee.amount} ${fee.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Typography fontWeight={400}>Rewards will be added to your bonding pool</Typography>
</SimpleDialog>
);
export default SummaryModal;
@@ -0,0 +1,3 @@
import CompoundRewards from './CompoundRewards';
export default CompoundRewards;
@@ -6,7 +6,7 @@ import { Typography } from '@mui/material';
import ProfitMarginModal from './ProfitMarginModal';
import { AppContext, BondedMixnode, urls } from '../../../../context';
import SummaryModal from './SummaryModal';
import { SimpleDialog } from '../../components';
import { ConfirmationModal } from '../../../../components';
interface Props {
mixnode: BondedMixnode;
@@ -62,20 +62,19 @@ const NodeSettings = ({ mixnode, show, onClose }: Props) => {
newPm={profitMargin as number}
fee={fee as MajorCurrencyAmount}
/>
<SimpleDialog
<ConfirmationModal
open={show && step === 3}
onClose={reset}
onConfirm={reset}
title="Operation successful"
confirmButton="Done"
maxWidth="xs"
sx={{ textAlign: 'center' }}
>
<Typography sx={{ mb: 2 }}>This operation can take up to one hour to process</Typography>
<Link href={`${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`} noIcon>
View on blockchain
</Link>
</SimpleDialog>
</ConfirmationModal>
</>
);
};
@@ -3,9 +3,10 @@ import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { Box, Divider, Stack, Tooltip, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { SimpleDialog, TextFieldInput } from '../../components';
import { TextFieldInput } from '../../components';
import { Node as NodeIcon } from '../../../../svg-icons/node';
import getSchema from './schema';
import { SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Divider, Stack, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { SimpleDialog } from '../../components';
import { SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
@@ -0,0 +1,65 @@
import * as React from 'react';
import { useContext, useEffect, useState } from 'react';
import { MajorCurrencyAmount, TransactionExecuteResult } from '@nymproject/types';
import { Link } from '@nymproject/react/link/Link';
import { Typography } from '@mui/material';
import { AppContext, BondedMixnode, urls } from '../../../../context';
import SummaryModal from './SummaryModal';
import { ConfirmationModal } from '../../../../components';
interface Props {
mixnode: BondedMixnode;
show: boolean;
onClose: () => void;
}
const RedeemRewards = ({ mixnode, show, onClose }: Props) => {
const [fee, setFee] = useState<MajorCurrencyAmount>({ amount: '0', denom: 'NYM' });
const [step, setStep] = useState<1 | 2>(1);
const [tx, setTx] = useState<TransactionExecuteResult>();
const { network } = useContext(AppContext);
useEffect(() => {
setFee({ amount: '42', denom: 'NYM' }); // TODO fetch real fee amount
}, []);
const submit = () => {
// TODO send request to redeem rewards
setStep(2); // on success
// setTx(requestResult)
};
const reset = () => {
setStep(1);
onClose();
};
return (
<>
<SummaryModal
open={show && step === 1}
onClose={reset}
onConfirm={submit}
onCancel={reset}
rewards={mixnode.operatorRewards}
fee={fee as MajorCurrencyAmount}
/>
<ConfirmationModal
open={show && step === 2}
onClose={reset}
onConfirm={reset}
title="Rewards redemption succesfull"
confirmButton="Done"
maxWidth="xs"
>
<Typography sx={{ mb: 2 }}>This operation can take up to one hour to process</Typography>
<Link href={`${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`} noIcon>
View on blockchain
</Link>
</ConfirmationModal>
</>
);
};
export default RedeemRewards;
@@ -0,0 +1,42 @@
import * as React from 'react';
import { Divider, Stack, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
onClose: () => void;
onConfirm: () => void;
onCancel: () => void;
rewards: MajorCurrencyAmount;
fee: MajorCurrencyAmount;
}
const SummaryModal = ({ open, onClose, onConfirm, onCancel, rewards, fee }: Props) => (
<SimpleDialog
open={open}
onClose={onClose}
onConfirm={onConfirm}
onCancel={onCancel}
title="Redeem rewards"
subTitle="Claim your rewards"
confirmButton="Redeem rewards"
closeButton
maxWidth="xs"
fullWidth
>
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Rewards to redeem</Typography>
<Typography fontWeight={400}>{`${rewards.amount} ${rewards.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Fee for this operation</Typography>
<Typography fontWeight={400}>{`${fee.amount} ${fee.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Typography fontWeight={400}>Rewards will be transferred to the account you are logged in with</Typography>
</SimpleDialog>
);
export default SummaryModal;
@@ -0,0 +1,3 @@
import RedeemRewards from './RedeemRewards';
export default RedeemRewards;
@@ -0,0 +1,48 @@
import * as React from 'react';
import { Divider, Stack, Typography } from '@mui/material';
import { MajorCurrencyAmount } from '@nymproject/types';
import { SimpleDialog } from '../../../../components';
export interface Props {
open: boolean;
onClose: () => void;
onConfirm: () => void;
onCancel: () => void;
bond: MajorCurrencyAmount;
rewards: MajorCurrencyAmount;
fee: MajorCurrencyAmount;
}
const SummaryModal = ({ open, onClose, onConfirm, onCancel, bond, rewards, fee }: Props) => (
<SimpleDialog
open={open}
onClose={onClose}
onConfirm={onConfirm}
onCancel={onCancel}
title="Unbond"
subTitle="Unbond and remove your node from the mixnet"
confirmButton="Unbond"
closeButton
maxWidth="xs"
fullWidth
>
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Amount to unbond</Typography>
<Typography fontWeight={400}>{`${bond.amount} ${bond.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Operator rewards</Typography>
<Typography fontWeight={400}>{`${rewards.amount} ${rewards.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight={400}>Fee for this operation</Typography>
<Typography fontWeight={400}>{`${fee.amount} ${fee.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Typography fontWeight={400}>Tokens will be transferred to account you are logged in with now</Typography>
</SimpleDialog>
);
export default SummaryModal;
@@ -0,0 +1,66 @@
import * as React from 'react';
import { useContext, useEffect, useState } from 'react';
import { MajorCurrencyAmount, TransactionExecuteResult } from '@nymproject/types';
import { Link } from '@nymproject/react/link/Link';
import { Typography } from '@mui/material';
import { AppContext, BondedMixnode, urls } from '../../../../context';
import SummaryModal from './SummaryModal';
import { ConfirmationModal } from '../../../../components';
interface Props {
mixnode: BondedMixnode;
show: boolean;
onClose: () => void;
}
const Unbond = ({ mixnode, show, onClose }: Props) => {
const [fee, setFee] = useState<MajorCurrencyAmount>({ amount: '0', denom: 'NYM' });
const [step, setStep] = useState<1 | 2>(1);
const [tx, setTx] = useState<TransactionExecuteResult>();
const { network } = useContext(AppContext);
useEffect(() => {
setFee({ amount: '42', denom: 'NYM' }); // TODO fetch real fee amount
}, []);
const submit = () => {
// TODO send request to unbond
setStep(2); // on success
// setTx(requestResult)
};
const reset = () => {
setStep(1);
onClose();
};
return (
<>
<SummaryModal
open={show && step === 1}
onClose={reset}
onConfirm={submit}
onCancel={reset}
bond={mixnode.bond}
rewards={mixnode.operatorRewards}
fee={fee as MajorCurrencyAmount}
/>
<ConfirmationModal
open={show && step === 2}
onClose={reset}
onConfirm={reset}
title="Unbonding succesfull"
confirmButton="Done"
maxWidth="xs"
>
<Typography sx={{ mb: 2 }}>This operation can take up to one hour to process</Typography>
<Link href={`${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`} noIcon>
View on blockchain
</Link>
</ConfirmationModal>
</>
);
};
export default Unbond;
@@ -0,0 +1,3 @@
import Unbond from './Unbond';
export default Unbond;