refactor(wallet): ui adjustments (#3182)
This commit is contained in:
@@ -22,12 +22,12 @@ export const MultiAccountWithPwdHowTo = ({ show, handleClose }: { show: boolean;
|
||||
>
|
||||
<Stack spacing={2}>
|
||||
<Warning sx={{ textAlign: 'center' }}>
|
||||
<Typography fontWeight={600} sx={{ mb: 1 }}>
|
||||
<Typography variant="body2" fontWeight={600} sx={{ mb: 1 }}>
|
||||
This machine already has a password set on it
|
||||
</Typography>
|
||||
<Typography>
|
||||
<Typography variant="caption">
|
||||
In order to import or create account(s) you need to log in with your password or create a new one. Creating a
|
||||
new password will overwrite any old one. Make sure your menonics are all wirtten down before creating a new
|
||||
new password will overwrite any old one. Make sure your mnemonics are all written down before creating a new
|
||||
password.
|
||||
</Typography>
|
||||
</Warning>
|
||||
@@ -35,13 +35,14 @@ export const MultiAccountWithPwdHowTo = ({ show, handleClose }: { show: boolean;
|
||||
{passwordCreationSteps.map((step, index) => (
|
||||
<Stack key={step} direction="row" spacing={1}>
|
||||
<Typography fontWeight={600}>{`${index + 1}.`}</Typography>
|
||||
<Typography>{`${step}`}</Typography>
|
||||
<Typography variant="body2">{`${step}`}</Typography>
|
||||
</Stack>
|
||||
))}
|
||||
<Link
|
||||
href="https://nymtech.net/docs/stable/wallet#importing-or-creating-accounts-when-you-have-signed-in-with-mnemonic-but-a-password-already-exists-on-your-machine"
|
||||
target="_blank"
|
||||
text="Open Nym docs for this guide in a browser window"
|
||||
variant="body2"
|
||||
fontWeight={600}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Alert as MuiAlert, IconButton } from '@mui/material';
|
||||
import { Alert as MuiAlert, IconButton, SxProps } from '@mui/material';
|
||||
import { Close } from '@mui/icons-material';
|
||||
|
||||
export const Alert = ({ title, dismissable }: { title: string | React.ReactNode; dismissable?: boolean }) => {
|
||||
export const Alert = ({
|
||||
title,
|
||||
dismissable,
|
||||
sxAlert,
|
||||
bgColor,
|
||||
}: {
|
||||
title: string | React.ReactNode;
|
||||
dismissable?: boolean;
|
||||
sxAlert?: SxProps;
|
||||
bgColor?: string;
|
||||
}) => {
|
||||
const [displayAlert, setDisplayAlert] = useState(true);
|
||||
const handleDismiss = () => setDisplayAlert(false);
|
||||
|
||||
@@ -14,9 +24,10 @@ export const Alert = ({ title, dismissable }: { title: string | React.ReactNode;
|
||||
sx={{
|
||||
width: '100%',
|
||||
borderRadius: 0,
|
||||
bgcolor: 'background.default',
|
||||
bgcolor: bgColor || 'background.default',
|
||||
color: (theme) => theme.palette.nym.nymWallet.text.blue,
|
||||
'& .MuiAlert-icon': { color: 'nym.nymWallet.text.blue', mr: 1 },
|
||||
...sxAlert,
|
||||
}}
|
||||
action={
|
||||
dismissable && (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from '@nymproject/react/link/Link';
|
||||
import { Box, Button, Typography } from '@mui/material';
|
||||
import { NymCard } from '../NymCard';
|
||||
|
||||
@@ -18,7 +19,12 @@ export const Bond = ({
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<Typography variant="body2">Bond a mixnode or a gateway</Typography>
|
||||
<Typography variant="body2">
|
||||
Bond a mix node or a gateway. Learn how to set up and run a node{' '}
|
||||
<Link href="https://nymtech.net/docs/nodes/setup-guides.html" target="_blank">
|
||||
here
|
||||
</Link>
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
|
||||
@@ -42,6 +42,7 @@ const GatewayInitForm = ({
|
||||
initialValue={gatewayData?.identityKey}
|
||||
errorText={errors.identityKey?.message}
|
||||
onChanged={(value) => setValue('identityKey', value)}
|
||||
showTickOnValid={false}
|
||||
/>
|
||||
<TextField
|
||||
{...register('sphinxKey')}
|
||||
|
||||
@@ -36,6 +36,7 @@ const MixnodeInitForm = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; on
|
||||
initialValue={mixnodeData?.identityKey}
|
||||
errorText={errors.identityKey?.message}
|
||||
onChanged={(value) => setValue('identityKey', value)}
|
||||
showTickOnValid={false}
|
||||
/>
|
||||
<TextField
|
||||
{...register('sphinxKey')}
|
||||
|
||||
@@ -40,7 +40,7 @@ export const ClientAddressDisplay: FC<ClientAddressProps & { address?: string }>
|
||||
)}
|
||||
|
||||
<AddressTooltip address={address} visible={!showEntireAddress}>
|
||||
<Typography variant="body2" component="span" sx={{ mr: 1, color: 'text.primary', fontWeight: 400 }}>
|
||||
<Typography variant="body2" component="span" sx={{ color: 'text.primary', fontWeight: 400 }}>
|
||||
{showEntireAddress ? address || '' : splice(6, address)}
|
||||
</Typography>
|
||||
</AddressTooltip>
|
||||
|
||||
@@ -257,6 +257,7 @@ export const DelegateModal: FCWithChildren<{
|
||||
textFieldProps={{
|
||||
autoFocus: !initialIdentityKey,
|
||||
}}
|
||||
showTickOnValid={false}
|
||||
/>
|
||||
</Box>
|
||||
<Typography
|
||||
@@ -277,16 +278,9 @@ export const DelegateModal: FCWithChildren<{
|
||||
autoFocus={Boolean(initialIdentityKey)}
|
||||
onChanged={handleAmountChanged}
|
||||
denom={denom}
|
||||
validationError={errorAmount}
|
||||
/>
|
||||
</Box>
|
||||
<Typography
|
||||
component="div"
|
||||
textAlign="left"
|
||||
variant="caption"
|
||||
sx={{ color: 'error.main', mx: 2, mt: errorAmount && 1 }}
|
||||
>
|
||||
{errorAmount}
|
||||
</Typography>
|
||||
<Box sx={{ mt: 3 }}>
|
||||
<ModalListItem label="Account balance" value={accountBalance?.toUpperCase()} divider fontWeight={600} />
|
||||
</Box>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react';
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
||||
import { Box } from '@mui/material';
|
||||
import { MockMainContextProvider } from '../context/mocks/main';
|
||||
import { NetworkSelector } from './NetworkSelector';
|
||||
|
||||
export default {
|
||||
title: 'Wallet / Network Selector',
|
||||
component: NetworkSelector,
|
||||
} as ComponentMeta<typeof NetworkSelector>;
|
||||
|
||||
const Template: ComponentStory<typeof NetworkSelector> = () => (
|
||||
<Box mt={2} height={800}>
|
||||
<MockMainContextProvider>
|
||||
<NetworkSelector />
|
||||
</MockMainContextProvider>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useContext } from 'react';
|
||||
import { Button, List, ListItem, ListItemIcon, ListItemText, ListSubheader, Popover } from '@mui/material';
|
||||
import { ArrowDropDown, CheckSharp } from '@mui/icons-material';
|
||||
import { Button, List, ListItemButton, ListItemIcon, ListItemText, ListSubheader, Popover, Stack } from '@mui/material';
|
||||
import { ArrowDropDown, Check } from '@mui/icons-material';
|
||||
import { Network } from 'src/types';
|
||||
import { AppContext } from '../context/main';
|
||||
import { config } from '../config';
|
||||
@@ -16,10 +16,29 @@ const NetworkItem: FCWithChildren<{ title: string; isSelected: boolean; onSelect
|
||||
isSelected,
|
||||
onSelect,
|
||||
}) => (
|
||||
<ListItem button onClick={onSelect}>
|
||||
<ListItemIcon>{isSelected && <CheckSharp color="success" />}</ListItemIcon>
|
||||
<ListItemText>{title}</ListItemText>
|
||||
</ListItem>
|
||||
<ListItemButton
|
||||
onClick={onSelect}
|
||||
sx={{
|
||||
minWidth: '180px',
|
||||
'&:hover': {
|
||||
backgroundColor: isSelected ? 'rgba(251, 110, 78, 0.08) !important' : undefined,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center" gap={2} width="100%">
|
||||
<ListItemText
|
||||
primaryTypographyProps={{
|
||||
color: isSelected ? 'primary' : undefined,
|
||||
}}
|
||||
primary={title}
|
||||
/>
|
||||
{isSelected && (
|
||||
<ListItemIcon sx={{ justifyContent: 'flex-end' }}>
|
||||
<Check color="primary" fontSize="small" />
|
||||
</ListItemIcon>
|
||||
)}
|
||||
</Stack>
|
||||
</ListItemButton>
|
||||
);
|
||||
|
||||
export const NetworkSelector = () => {
|
||||
|
||||
@@ -19,7 +19,6 @@ export const ReceiveModal = ({
|
||||
return (
|
||||
<SimpleModal
|
||||
header="Receive"
|
||||
subHeader="Provide your address to receive tokens"
|
||||
open
|
||||
onClose={onClose}
|
||||
okLabel=""
|
||||
|
||||
@@ -128,7 +128,7 @@ export const SendInputModal = ({
|
||||
<Stack gap={0.5} sx={{ mt: 1 }}>
|
||||
<ModalListItem label="Account balance" value={balance?.toUpperCase()} divider fontWeight={600} />
|
||||
<Typography fontSize="smaller" sx={{ color: 'text.primary' }}>
|
||||
Est. fee for this transaction will be show on the next page
|
||||
Est. fee for this transaction will be shown on the next page
|
||||
</Typography>
|
||||
</Stack>
|
||||
<FormControlLabel
|
||||
@@ -139,7 +139,7 @@ export const SendInputModal = ({
|
||||
{showMore && (
|
||||
<Stack direction="column" gap={3} mt={2} mb={3}>
|
||||
<CurrencyFormField
|
||||
label="Fees"
|
||||
label="Fee"
|
||||
onChanged={(v) => onUserFeesChange(v)}
|
||||
initialValue={userFees?.amount}
|
||||
fullWidth
|
||||
|
||||
@@ -77,7 +77,7 @@ export const SendModal = ({ onClose, hasStorybookStyles }: { onClose: () => void
|
||||
} catch (e) {
|
||||
Console.error(e as string);
|
||||
if (/Raw log: out of gas/.test(e as string)) {
|
||||
setGasError('Out of gas, please increase the amount of fees');
|
||||
setGasError('Specified fee was too small. Please increase the amount and try again');
|
||||
} else {
|
||||
setSendError(true);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
||||
import { Box } from '@mui/material';
|
||||
import { TokenPoolSelector } from './TokenPoolSelector';
|
||||
import { MockMainContextProvider } from '../context/mocks/main';
|
||||
|
||||
export default {
|
||||
title: 'Wallet / Token pool',
|
||||
component: TokenPoolSelector,
|
||||
} as ComponentMeta<typeof TokenPoolSelector>;
|
||||
|
||||
const Template: ComponentStory<typeof TokenPoolSelector> = (args) => (
|
||||
<Box mt={2} height={800}>
|
||||
<MockMainContextProvider>
|
||||
<TokenPoolSelector {...args} />
|
||||
</MockMainContextProvider>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
disabled: false,
|
||||
onSelect: () => {},
|
||||
};
|
||||
@@ -1,5 +1,15 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { FormControl, InputLabel, ListItemText, MenuItem, Select, SelectChangeEvent, Typography } from '@mui/material';
|
||||
import {
|
||||
FormControl,
|
||||
InputLabel,
|
||||
ListItemText,
|
||||
MenuItem,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
Stack,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { Check as CheckIcon } from '@mui/icons-material';
|
||||
import { AppContext } from '../context/main';
|
||||
|
||||
export type TPoolOption = 'balance' | 'locked';
|
||||
@@ -40,20 +50,29 @@ export const TokenPoolSelector: FCWithChildren<{ disabled: boolean; onSelect: (p
|
||||
renderValue={(val) => <Typography sx={{ textTransform: 'capitalize' }}>{val}</Typography>}
|
||||
>
|
||||
<MenuItem value="balance">
|
||||
<ListItemText
|
||||
primary="Balance"
|
||||
secondary={`${balance?.printable_balance}`}
|
||||
secondaryTypographyProps={{ sx: { textTransform: 'uppercase' } }}
|
||||
/>
|
||||
<Stack direction="row" alignItems="center" gap={2} width="100%">
|
||||
<ListItemText
|
||||
primary="Balance"
|
||||
secondary={`${balance?.printable_balance}`}
|
||||
secondaryTypographyProps={{ sx: { textTransform: 'uppercase', color: 'nym.text.muted' } }}
|
||||
/>
|
||||
{value === 'balance' && <CheckIcon fontSize="small" />}
|
||||
</Stack>
|
||||
</MenuItem>
|
||||
<MenuItem value="locked">
|
||||
{tokenAllocation && (
|
||||
<ListItemText
|
||||
primary="Locked"
|
||||
secondary={`${
|
||||
+tokenAllocation.locked + +tokenAllocation.spendable
|
||||
} ${clientDetails?.display_mix_denom.toUpperCase()}`}
|
||||
/>
|
||||
<Stack direction="row" alignItems="center" gap={2} width="100%">
|
||||
<ListItemText
|
||||
primary="Locked"
|
||||
secondary={`${
|
||||
+tokenAllocation.locked + +tokenAllocation.spendable
|
||||
} ${clientDetails?.display_mix_denom.toUpperCase()}`}
|
||||
secondaryTypographyProps={{
|
||||
sx: { textTransform: 'uppercase', color: 'nym.text.muted' },
|
||||
}}
|
||||
/>
|
||||
{value === 'locked' && <CheckIcon fontSize="small" />}
|
||||
</Stack>
|
||||
)}
|
||||
</MenuItem>
|
||||
</Select>
|
||||
|
||||
+36
-29
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { Box, Button, Divider, Grid, TextField, Typography } from '@mui/material';
|
||||
import { Button, Divider, Grid, Stack, TextField, Typography } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { isMixnode } from 'src/types';
|
||||
import { simulateUpdateMixnodeConfig, simulateVestingUpdateMixnodeConfig, updateMixnodeConfig } from 'src/requests';
|
||||
@@ -62,7 +62,7 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container xs item>
|
||||
<Grid container xs>
|
||||
{fee && (
|
||||
<ConfirmTx
|
||||
open
|
||||
@@ -76,14 +76,17 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
{isSubmitting && <LoadingModal />}
|
||||
<Alert
|
||||
title={
|
||||
<Box sx={{ fontWeight: 600 }}>
|
||||
Changing these values will ONLY change the data about your node on the blockchain. Remember to change your
|
||||
node’s config file with the same values too
|
||||
</Box>
|
||||
<Stack>
|
||||
<Typography fontWeight={600}>
|
||||
Changing these values will ONLY change the data about your node on the blockchain.
|
||||
</Typography>
|
||||
<Typography>Remember to change your node’s config file with the same values too.</Typography>
|
||||
</Stack>
|
||||
}
|
||||
bgColor={`${theme.palette.nym.nymWallet.text.blue}0D !important`}
|
||||
dismissable
|
||||
/>
|
||||
<Grid container>
|
||||
<Grid container mt={2}>
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
@@ -126,7 +129,7 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider flexItem />
|
||||
<Divider sx={{ width: '100%' }} />
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
@@ -147,7 +150,7 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider flexItem />
|
||||
<Divider sx={{ width: '100%' }} />
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
@@ -168,31 +171,35 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider flexItem />
|
||||
<Grid container justifyContent="end">
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={isSubmitting || !isDirty || !isValid}
|
||||
onClick={handleSubmit((data) =>
|
||||
getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeConfig : simulateUpdateMixnodeConfig, {
|
||||
host: data.host,
|
||||
mix_port: data.mixPort,
|
||||
verloc_port: data.verlocPort,
|
||||
http_api_port: data.httpApiPort,
|
||||
version: data.version,
|
||||
}),
|
||||
)}
|
||||
sx={{ m: 3 }}
|
||||
>
|
||||
Submit changes to the blockchain
|
||||
</Button>
|
||||
<Divider sx={{ width: '100%' }} />
|
||||
<Grid item container direction="row" justifyContent="space-between" padding={3}>
|
||||
<Grid item />
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={isSubmitting || !isDirty || !isValid}
|
||||
onClick={handleSubmit((data) =>
|
||||
getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeConfig : simulateUpdateMixnodeConfig, {
|
||||
host: data.host,
|
||||
mix_port: data.mixPort,
|
||||
verloc_port: data.verlocPort,
|
||||
http_api_port: data.httpApiPort,
|
||||
version: data.version,
|
||||
}),
|
||||
)}
|
||||
sx={{ m: 3, mr: 0 }}
|
||||
fullWidth
|
||||
>
|
||||
Submit changes to the blockchain
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<SimpleModal
|
||||
open={openConfirmationModal}
|
||||
header="Your changes are submitted to the blockchain"
|
||||
subHeader="Remember to change the values
|
||||
subHeader="Remember to change the values
|
||||
on your node’s config file too."
|
||||
okLabel="close"
|
||||
hideCloseIcon
|
||||
|
||||
+71
-30
@@ -1,7 +1,18 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { Box, Button, Divider, FormHelperText, Grid, InputAdornment, TextField, Typography } from '@mui/material';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Divider,
|
||||
FormHelperText,
|
||||
Grid,
|
||||
InputAdornment,
|
||||
Stack,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { CurrencyDenom, MixNodeCostParams } from '@nymproject/types';
|
||||
import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
|
||||
@@ -24,6 +35,12 @@ import { AppContext } from 'src/context';
|
||||
import { useGetFee } from 'src/hooks/useGetFee';
|
||||
import { ConfirmTx } from 'src/components/ConfirmTX';
|
||||
import { LoadingModal } from 'src/components/Modals/LoadingModal';
|
||||
import { InfoOutlined } from '@mui/icons-material';
|
||||
|
||||
const operatorCostHint = `This is your (operator) rewards including the PM and cost. Rewards are automatically compounded every epoch.You can redeem your rewards at any time.
|
||||
`;
|
||||
const profitMarginHint =
|
||||
'PM is the percentage of the node rewards that you as the node operator take before rewards are distributed to the delegators.';
|
||||
|
||||
export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): JSX.Element => {
|
||||
const [openConfirmationModal, setOpenConfirmationModal] = useState<boolean>(false);
|
||||
@@ -114,10 +131,9 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
<Grid
|
||||
container
|
||||
xs
|
||||
item
|
||||
sx={{
|
||||
'& .MuiGrid-item': {
|
||||
pl: 0,
|
||||
pl: 3,
|
||||
},
|
||||
}}
|
||||
>
|
||||
@@ -132,13 +148,29 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
/>
|
||||
)}
|
||||
{isSubmitting && <LoadingModal />}
|
||||
<Alert title={<Box component="span" sx={{ fontWeight: 600 }}>{`Next interval: ${intervalTime}`}</Box>} />
|
||||
<Grid container direction="column">
|
||||
<Alert
|
||||
title={<Typography sx={{ fontWeight: 600 }}>{`Next interval: ${intervalTime}`}</Typography>}
|
||||
bgColor={`${theme.palette.nym.nymWallet.text.blue}0D !important`}
|
||||
sxAlert={{
|
||||
icon: false as unknown as number,
|
||||
'& .MuiAlert-message': {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Grid container direction="column" mt={2}>
|
||||
<Grid item container alignItems="left" justifyContent="space-between" padding={3} spacing={1}>
|
||||
<Grid item xl={6}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Profit Margin
|
||||
</Typography>
|
||||
<Tooltip title={profitMarginHint} placement="top-end">
|
||||
<Stack flexDirection="row" gap={0.5}>
|
||||
<InfoOutlined fontSize="inherit" />
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Profit Margin
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Tooltip>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
@@ -180,12 +212,17 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Divider flexItem sx={{ position: 'relative', left: '-24px', width: 'calc(100% + 24px)' }} />
|
||||
<Divider sx={{ width: '100%' }} />
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3} spacing={1}>
|
||||
<Grid item>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Operating cost
|
||||
</Typography>
|
||||
<Tooltip title={operatorCostHint} placement="top-end">
|
||||
<Stack flexDirection="row" gap={0.5}>
|
||||
<InfoOutlined fontSize="inherit" />
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Operator cost
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Tooltip>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
@@ -201,7 +238,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
<CurrencyFormField
|
||||
required
|
||||
fullWidth
|
||||
label="Operating cost"
|
||||
label="Operator cost"
|
||||
onChanged={(newValue) => {
|
||||
setValue('operatorCost', newValue, { shouldValidate: true, shouldDirty: true });
|
||||
}}
|
||||
@@ -221,23 +258,27 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider flexItem sx={{ position: 'relative', left: '-24px', width: 'calc(100% + 24px)' }} />
|
||||
<Grid container justifyContent="end">
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={isSubmitting || !isDirty || !isValid}
|
||||
onClick={handleSubmit((data) => {
|
||||
getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeCostParams : simulateUpdateMixnodeCostParams, {
|
||||
profit_margin_percent: (+data.profitMargin / 100).toString(),
|
||||
interval_operating_cost: data.operatorCost,
|
||||
});
|
||||
})}
|
||||
type="submit"
|
||||
sx={{ m: 3 }}
|
||||
>
|
||||
Submit changes to the blockchain
|
||||
</Button>
|
||||
<Divider sx={{ width: '100%' }} />
|
||||
<Grid item container direction="row" justifyContent="space-between" padding={3}>
|
||||
<Grid item />
|
||||
<Grid item xs={12} md={6}>
|
||||
<Button
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={isSubmitting || !isDirty || !isValid}
|
||||
onClick={handleSubmit((data) => {
|
||||
getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeCostParams : simulateUpdateMixnodeCostParams, {
|
||||
profit_margin_percent: (+data.profitMargin / 100).toString(),
|
||||
interval_operating_cost: data.operatorCost,
|
||||
});
|
||||
})}
|
||||
type="submit"
|
||||
sx={{ m: 3, mr: 0, ml: 0 }}
|
||||
fullWidth
|
||||
>
|
||||
Save changes
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<SimpleModal
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { TBondedMixnode, TBondedGateway } from '../../../../../context/bonding';
|
||||
import { InfoSettings } from './InfoSettings';
|
||||
import { ParametersSettings } from './ParametersSettings';
|
||||
|
||||
const nodeGeneralNav = ['Info', 'Parameters'];
|
||||
const nodeGeneralNav = ['Node info', 'Parameters'];
|
||||
|
||||
export const NodeGeneralSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBondedGateway }) => {
|
||||
const [settingsCard, setSettingsCard] = useState<string>(nodeGeneralNav[0]);
|
||||
|
||||
@@ -303,6 +303,24 @@ export const getDesignTokens = (mode: PaletteMode): ThemeOptions => {
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiSelect: {
|
||||
defaultProps: {
|
||||
MenuProps: {
|
||||
PaperProps: {
|
||||
sx: {
|
||||
'&& .Mui-selected': {
|
||||
color: nymPalette.highlight,
|
||||
backgroundColor: (t) =>
|
||||
t.palette.mode === 'dark' ? `${t.palette.background.default} !important` : '#FFFFFF !important',
|
||||
},
|
||||
'&& .Mui-selected:hover': {
|
||||
backgroundColor: 'rgba(251, 110, 78, 0.08) !important',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiMenu: {
|
||||
styleOverrides: {
|
||||
list: ({ _, theme }) => ({
|
||||
|
||||
@@ -84,7 +84,7 @@ export const CurrencyFormField: FCWithChildren<{
|
||||
|
||||
// it can't be lower than one micro coin
|
||||
if (newNumber < MIN_VALUE) {
|
||||
setValidationError('Amount cannot be less than 1 uNYM');
|
||||
setValidationError('Amount cannot be less than 0.000001');
|
||||
return fireOnValidate(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user