rebuild BondedNodeCard using existing shared components
This commit is contained in:
@@ -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>
|
||||
);
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user