rebuild BondedNodeCard using existing shared components

This commit is contained in:
fmtabbara
2022-07-20 22:01:14 +01:00
parent 641b8179ba
commit e945c94afc
12 changed files with 64 additions and 171 deletions
+13
View File
@@ -0,0 +1,13 @@
import React from 'react';
import { Stack, Typography } from '@mui/material';
import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard';
import { splice } from 'src/utils';
export const IdentityKey = ({ identityKey }: { identityKey: string }) => (
<Stack direction="row">
<Typography variant="body2" component="span" fontWeight={400} sx={{ mr: 1, color: 'text.primary' }}>
{splice(6, identityKey)}
</Typography>
<CopyToClipboard value={identityKey} sx={{ fontSize: 18 }} />
</Stack>
);
+7 -30
View File
@@ -162,18 +162,14 @@ export const BondingContextProvider = ({
const [error, setError] = useState<string>();
const [bondedMixnode, setBondedMixnode] = useState<BondedMixnode | null>(null);
const [bondedGateway, setBondedGateway] = useState<BondedGateway | null>(null);
const { fee, resetFeeState, feeError, isFeeLoading } = useGetFee();
const { ownership, checkOwnership } = useCheckOwnership();
const { userBalance } = useContext(AppContext);
const { ownership, checkOwnership } = useCheckOwnership();
const { fee, resetFeeState, feeError, isFeeLoading } = useGetFee();
const isVesting = Boolean(ownership.vestingPledge);
useEffect(() => {
const init = async () => {
await checkOwnership();
};
init();
}, [checkOwnership]);
console.log(ownership);
useEffect(() => {
if (feeError) {
@@ -188,26 +184,13 @@ export const BondingContextProvider = ({
setBondedMixnode(null);
};
const fetchMixnodeStatus = useCallback(async () => {
setLoading(true);
if (bondedMixnode) {
try {
const { status } = await getMixnodeStatus(bondedMixnode.identityKey);
setBondedMixnode({ ...bondedMixnode, status });
} catch (e: any) {
setError(`While fetching mixnode status, an error occurred: ${e}`);
} finally {
setLoading(false);
}
}
}, [bondedMixnode]);
const refresh = useCallback(async () => {
let data, status;
setLoading(true);
if (ownership.hasOwnership && ownership.nodeType === 'mixnode') {
let data;
try {
data = await getMixnodeBondDetails();
status = data ? await getMixnodeStatus(data?.mix_node.identity_key) : undefined;
} catch (e: any) {
setError(`While fetching current bond state, an error occurred: ${e}`);
}
@@ -215,9 +198,9 @@ export const BondingContextProvider = ({
setBondedMixnode(bounded);
}
if (ownership.hasOwnership && ownership.nodeType === 'gateway') {
let data;
try {
data = await getGatewayBondDetails();
status = data ? await getMixnodeStatus(data?.gateway.identity_key) : undefined;
} catch (e: any) {
setError(`While fetching current bond state, an error occurred: ${e}`);
}
@@ -232,12 +215,6 @@ export const BondingContextProvider = ({
refresh();
}, [network, ownership]);
useEffect(() => {
if (bondedMixnode) {
fetchMixnodeStatus();
}
}, [bondedMixnode]);
const bondMixnode = async (data: Omit<TBondMixNodeArgs, 'fee'>, tokenPool: TokenPool) => {
let tx: TransactionExecuteResult | undefined;
const payload = {
@@ -92,7 +92,7 @@ const AmountModal = ({ open, onClose, onSubmit, nodeType }: Props) => {
</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Typography fontWeight={400}>Est. fee for this transaction will be cauculated in the next page</Typography>
<Typography fontWeight={400}>Est. fee for this transaction will be calculated in the next page</Typography>
</Box>
</SimpleModal>
);
@@ -1,86 +0,0 @@
import * as React from 'react';
import { Card, CardContent, CardHeader, Stack, Typography } from '@mui/material';
import { MixnodeStatus } from '@nymproject/types';
import { CheckCircleOutline, CircleOutlined, PauseCircleOutlined } from '@mui/icons-material';
import { CopyToClipboard } from '../../../components';
import { splice } from '../../../utils';
interface Props {
children?: React.ReactNode;
title: string;
identityKey: string;
status?: MixnodeStatus;
action?: React.ReactNode;
}
const IdentityKey = ({ identityKey }: { identityKey: string }) => (
<Typography variant="body2" component="span" fontWeight={400} sx={{ mr: 1, color: 'text.primary' }}>
{splice(6, identityKey)}
<CopyToClipboard text={identityKey} iconButton />
</Typography>
);
export const getNodeStatus = ({ status }: { status: MixnodeStatus }) => {
switch (status) {
case 'active':
return (
<Typography display="flex" alignItems="center" sx={{ color: 'success.main' }}>
<CheckCircleOutline color="success" sx={{ mr: 0.5, fontSize: 13 }} /> Active
</Typography>
);
case 'standby':
return (
<Typography display="flex" alignItems="center" sx={{ color: 'info.main' }}>
<PauseCircleOutlined color="info" sx={{ mr: 0.5, fontSize: 13 }} /> Standby
</Typography>
);
case 'inactive':
return (
<Typography display="flex" alignItems="center" sx={{ color: 'nym.text.dark' }}>
<CircleOutlined sx={{ mr: 0.5, color: 'nym.text.dark', fontSize: 13 }} /> Inactive
</Typography>
);
case 'not_found':
return (
<Typography display="flex" alignItems="center" sx={{ color: 'nym.text.dark' }}>
<CircleOutlined sx={{ mr: 0.5, color: 'nym.text.dark', fontSize: 13 }} /> Not found
</Typography>
);
default:
return null;
}
};
const BondedNodeCard = (props: Props) => {
const { title: rawTitle, identityKey, status: rawStatus, action, children } = props;
let Title: string | React.ReactNode = (
<Typography fontSize={20} fontWeight={600}>
{rawTitle}
</Typography>
);
if (rawStatus) {
Title = (
<Stack direction="column" spacing={1.2}>
{getNodeStatus({ status: rawStatus })}
<Typography fontSize={20} fontWeight={600}>
{rawTitle}
</Typography>
</Stack>
);
}
return (
<Card variant="outlined" sx={{ overflow: 'auto', border: 'none', dropShadow: 'none' }}>
<CardHeader
title={Title}
subheader={<IdentityKey identityKey={identityKey} />}
action={action}
disableTypography
sx={{ pb: 0 }}
/>
<CardContent sx={{ p: 3 }}>{children}</CardContent>
</Card>
);
};
export default BondedNodeCard;
@@ -1,4 +1,3 @@
export { default as BondedNodeCard } from './BondedNodeCard';
export { default as NodeTable } from './NodeTable';
export { default as CheckboxInput } from './CheckboxInput';
export { default as RadioInput } from './RadioInput';
@@ -2,9 +2,12 @@ import React, { useMemo, useState } from 'react';
import { useTheme } from '@mui/material/styles';
import EditIcon from '@mui/icons-material/Edit';
import { BondedGateway } from '../../../context';
import { NodeTable, BondedNodeCard, Cell, Header, NodeMenu } from '../components';
import { NodeTable, Cell, Header, NodeMenu } from '../components';
import { GatewayFlow } from './types';
import Unbond from '../unbond';
import { NymCard } from 'src/components';
import { Stack, Typography } from '@mui/material';
import { IdentityKey } from 'src/components/IdentityKey';
const headers: Header[] = [
{
@@ -57,10 +60,17 @@ const GatewayCard = ({ gateway }: { gateway: BondedGateway }) => {
[gateway, theme, nodeMenuOpen],
);
return (
<BondedNodeCard title="Valhalla gateway" identityKey={gateway.identityKey}>
<NymCard
title={
<Stack gap={2}>
<Typography variant="h5">Valhalla gateway</Typography>
<IdentityKey identityKey={gateway.identityKey} />
</Stack>
}
>
<NodeTable headers={headers} cells={cells} />
<Unbond node={gateway} show={flow === 'unbond'} onClose={() => setFlow(null)} />
</BondedNodeCard>
</NymCard>
);
};
+3 -5
View File
@@ -13,11 +13,9 @@ const Bonding = () => {
// TODO display a special UI on loading state
return (
<PageLayout>
<Box display="flex" flexDirection="column" gap={2}>
{!bondedMixnode && !bondedGateway && <BondingCard />}
{bondedMixnode && <MixnodeCard mixnode={bondedMixnode} />}
{bondedGateway && <GatewayCard gateway={bondedGateway} />}
</Box>
{!bondedMixnode && !bondedGateway && <BondingCard />}
{bondedMixnode && <MixnodeCard mixnode={bondedMixnode} />}
{bondedGateway && <GatewayCard gateway={bondedGateway} />}
</PageLayout>
);
};
@@ -1,17 +1,20 @@
import React, { useMemo, useState } from 'react';
import { Button, Typography } from '@mui/material';
import { useMemo, useState } from 'react';
import { Button, Stack, Typography } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { Link } from '@nymproject/react/link/Link';
import { NymCard } from 'src/components';
import { IdentityKey } from 'src/components/IdentityKey';
import { NodeStatus } from 'src/components/NodeStatus';
import { BondedMixnode } from '../../../context';
import { Node as NodeIcon } from '../../../svg-icons/node';
import { NodeTable, BondedNodeCard, Cell, Header, NodeMenu } from '../components';
import NodeSettings from './node-settings';
import BondMore from './bond-more';
import { MixnodeFlow } from './types';
import RedeemRewards from './redeem';
import Unbond from '../unbond';
import CompoundRewards from './compound';
import { Bond as BondIcon, Unbond as UnbondIcon } from '../../../svg-icons';
import { Node as NodeIcon } from '../../../svg-icons/node';
import { Cell, Header, NodeMenu, NodeTable } from '../components';
import Unbond from '../unbond';
import BondMore from './bond-more';
import CompoundRewards from './compound';
import NodeSettings from './node-settings';
import RedeemRewards from './redeem';
import { MixnodeFlow } from './types';
const headers: Header[] = [
{
@@ -126,23 +129,16 @@ const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
[mixnode, theme, nodeMenuOpen],
);
return (
<BondedNodeCard
title="Monster node"
identityKey={mixnode.identityKey}
status={mixnode.status}
action={
<Button
variant="text"
color="secondary"
onClick={() => setFlow('nodeSettings')}
sx={{
fontWeight: 500,
'& .MuiSvgIcon-root': {
fontSize: 14,
},
}}
startIcon={<NodeIcon />}
>
<NymCard
title={
<Stack gap={2}>
<NodeStatus status={mixnode.status} />
<Typography variant="h5">Monster node</Typography>
<IdentityKey identityKey={mixnode.identityKey} />
</Stack>
}
Action={
<Button variant="text" color="secondary" onClick={() => setFlow('nodeSettings')} startIcon={<NodeIcon />}>
Node settings
</Button>
}
@@ -159,7 +155,7 @@ const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
<RedeemRewards mixnode={mixnode} show={flow === 'redeem'} onClose={() => setFlow(null)} />
<Unbond node={mixnode} show={flow === 'unbond'} onClose={() => setFlow(null)} />
<CompoundRewards mixnode={mixnode} show={flow === 'compound'} onClose={() => setFlow(null)} />
</BondedNodeCard>
</NymCard>
);
};
@@ -90,7 +90,7 @@ const BondModal = ({ open, onClose, onConfirm, currentBond }: Props) => {
<Typography>{`${currentBond.amount} ${currentBond.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Typography fontWeight={400}>Est. fee for this transaction will be cauculated in the next page</Typography>
<Typography fontWeight={400}>Est. fee for this transaction will be calculated in the next page</Typography>
</Box>
</SimpleModal>
);
@@ -27,20 +27,6 @@ const NodeSettings = ({ mixnode, show, onClose }: Props) => {
const { network } = useContext(AppContext);
const { updateMixnode, error, fee, getFee } = useBondingContext();
useEffect(() => {
if (error) {
setStatus('error');
}
}, [error]);
const fetchFee = async () => {
await getFee('updateMixnode', {});
};
useEffect(() => {
fetchFee();
}, []);
const submit = async () => {
const txResult = await updateMixnode(profitMargin as number);
if (txResult) {
@@ -75,7 +75,7 @@ const NodeSettingsModal = ({ open, onClose, onConfirm, estimatedOpReward, curren
<Typography fontWeight={400}>{`~${estimatedOpReward.amount} ${estimatedOpReward.denom}`}</Typography>
</Stack>
<Divider sx={{ my: 1 }} />
<Typography fontWeight={400}>Est. fee for this transaction will be cauculated in the next page</Typography>
<Typography fontWeight={400}>Est. fee for this transaction will be calculated in the next page</Typography>
</Box>
</SimpleModal>
);
@@ -34,7 +34,7 @@ const Unbond = ({ node, show, onClose }: Props) => {
}, [error, feeError]);
useEffect(() => {
if ('profitMarfin' in node) {
if ('profitMargin' in node) {
setNodeType('mixnode');
} else {
setNodeType('gateway');