logic refactor
This commit is contained in:
@@ -45,7 +45,7 @@ export const SimpleModal: React.FC<{
|
||||
<Modal open={open} onClose={onClose} BackdropProps={backdropProps}>
|
||||
<Box sx={{ ...modalStyle, ...sx }}>
|
||||
{displayErrorIcon && <ErrorOutline color="error" sx={{ mb: 3 }} />}
|
||||
{displayInfoIcon && <InfoOutlinedIcon sx={{ mb: 2, color: 'info.dark' }} />}
|
||||
{displayInfoIcon && <InfoOutlinedIcon sx={{ mb: 2, color: (theme) => theme.palette.nym.nymWallet.text.blue }} />}
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||
{typeof header === 'string' ? (
|
||||
<Typography fontSize={20} fontWeight={600} sx={{ color: 'text.primary', ...headerStyles }}>
|
||||
|
||||
@@ -195,7 +195,7 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod
|
||||
operatorRewards,
|
||||
status,
|
||||
stakeSaturation,
|
||||
host: mix_node.host,
|
||||
host: mix_node.host.replace(/\s/g, ''),
|
||||
httpApiPort: mix_node.http_api_port,
|
||||
mixPort: mix_node.mix_port,
|
||||
profitMarginPercent: mix_node.profit_margin_percent,
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Box, Button, Divider, Typography, TextField, Grid, Alert } from '@mui/material';
|
||||
import { Button, Divider, Typography, TextField, Grid, Alert } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { TBondedMixnode, TBondedGateway } from '../../../../context/bonding';
|
||||
import { SimpleModal } from '../../../../components/Modals/SimpleModal';
|
||||
|
||||
const getNumberlength = (number: number) => {
|
||||
return number.toString().length;
|
||||
};
|
||||
|
||||
// TODO: adding ip regex that works well
|
||||
const ipRegex = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
|
||||
// TODO: only accept valid nym wallet versions
|
||||
@@ -11,7 +16,6 @@ const appVersionRegex = /^\d+(?:\.\d+){2}$/gm;
|
||||
export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBondedGateway }) => {
|
||||
const { mixPort, verlocPort, httpApiPort, host, version } = bondedNode;
|
||||
|
||||
const [valueChanged, setValueChanged] = useState<boolean>(false);
|
||||
const [buttonActive, setButtonActive] = useState<boolean>(false);
|
||||
const [openConfirmationModal, setOpenConfirmationModal] = useState<boolean>(false);
|
||||
const [mixPortUpdated, setMixPortUpdated] = useState<number>(mixPort);
|
||||
@@ -20,23 +24,53 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
const [hostUpdated, setHostUpdated] = useState<string>(host);
|
||||
const [versionUpdated, setVersionUpdated] = useState<string>(version);
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
if (valueChanged) {
|
||||
if (
|
||||
Boolean(mixPortUpdated.toString().length === 4) &&
|
||||
Boolean(verlocPortUpdated.toString().length === 4) &&
|
||||
Boolean(httpApiPortUpdated.toString().length === 4) &&
|
||||
Boolean(versionUpdated.match(appVersionRegex))
|
||||
) {
|
||||
setButtonActive(true);
|
||||
return;
|
||||
}
|
||||
setButtonActive(true);
|
||||
if (
|
||||
mixPortUpdated === mixPort &&
|
||||
verlocPortUpdated === verlocPort &&
|
||||
httpApiPortUpdated === httpApiPort &&
|
||||
hostUpdated === host &&
|
||||
versionUpdated === version
|
||||
) {
|
||||
setButtonActive(false);
|
||||
}
|
||||
setButtonActive(false);
|
||||
}, [valueChanged, mixPortUpdated, verlocPortUpdated, httpApiPortUpdated, hostUpdated, versionUpdated]);
|
||||
if (
|
||||
getNumberlength(mixPortUpdated) !== 4 ||
|
||||
getNumberlength(verlocPortUpdated) !== 4 ||
|
||||
getNumberlength(httpApiPortUpdated) !== 4 ||
|
||||
!versionUpdated.match(appVersionRegex)
|
||||
) {
|
||||
setButtonActive(false);
|
||||
}
|
||||
}, [mixPortUpdated, verlocPortUpdated, httpApiPortUpdated, hostUpdated, versionUpdated]);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const { value, id } = e.target;
|
||||
const numNewValue = parseInt(value) || 0;
|
||||
|
||||
switch (id) {
|
||||
case 'mixPort':
|
||||
setMixPortUpdated(numNewValue);
|
||||
break;
|
||||
case 'verlocPort':
|
||||
setVerlocPortUpdated(numNewValue);
|
||||
break;
|
||||
case 'httpApiPort':
|
||||
setHttpApiPortUpdated(numNewValue);
|
||||
break;
|
||||
case 'host':
|
||||
setHostUpdated(value);
|
||||
break;
|
||||
case 'version':
|
||||
setVersionUpdated(value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ width: '79.88%' }}>
|
||||
<Grid container xs>
|
||||
{buttonActive && (
|
||||
<Alert
|
||||
severity="info"
|
||||
@@ -44,8 +78,8 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
px: 2,
|
||||
borderRadius: 0,
|
||||
bgcolor: 'background.default',
|
||||
color: 'info.dark',
|
||||
'& .MuiAlert-icon': { color: 'info.dark' },
|
||||
color: (theme) => theme.palette.nym.nymWallet.text.blue,
|
||||
'& .MuiAlert-icon': { color: (theme) => theme.palette.nym.nymWallet.text.blue },
|
||||
}}
|
||||
>
|
||||
<strong>Your changes will be ONLY saved on the display.</strong> Remember to change the values on your node’s
|
||||
@@ -55,50 +89,51 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
<Grid container>
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item>
|
||||
<Typography sx={{ fontSize: 16, fontWeight: 600, mb: 1 }}>Port</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Port
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
mb: 2,
|
||||
color: (t) => (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'),
|
||||
}}
|
||||
>
|
||||
Change profit margin of your node
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid spacing={3} item container alignItems="center" maxWidth="348px">
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Grid item width={1}>
|
||||
<TextField
|
||||
id="mixPort"
|
||||
type="input"
|
||||
label="Mix Port"
|
||||
value={mixPortUpdated}
|
||||
onChange={(e) => {
|
||||
setMixPortUpdated(parseInt(e.target.value));
|
||||
setValueChanged(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
inputProps={{ maxLength: 4 }}
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item width={1}>
|
||||
<TextField
|
||||
id="verlocPort"
|
||||
type="input"
|
||||
label="Verloc Port"
|
||||
value={verlocPortUpdated}
|
||||
onChange={(e) => {
|
||||
setVerlocPortUpdated(parseInt(e.target.value));
|
||||
setValueChanged(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
inputProps={{ maxLength: 4 }}
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item width={1}>
|
||||
<TextField
|
||||
id="httpApiPort"
|
||||
type="input"
|
||||
label="HTTP port"
|
||||
value={httpApiPortUpdated}
|
||||
onChange={(e) => {
|
||||
setHttpApiPortUpdated(parseInt(e.target.value));
|
||||
setValueChanged(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
inputProps={{ maxLength: 4 }}
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
@@ -107,26 +142,28 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
<Divider flexItem />
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item>
|
||||
<Typography sx={{ fontSize: 16, fontWeight: 600, mb: 1 }}>Host</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Host
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
mb: 2,
|
||||
color: (t) => (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'),
|
||||
}}
|
||||
>
|
||||
Lock wallet after certain time
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid spacing={3} item container alignItems="center" maxWidth="348px">
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Grid item width={1}>
|
||||
<TextField
|
||||
id="host"
|
||||
type="input"
|
||||
label="host"
|
||||
value={hostUpdated}
|
||||
onChange={(e) => {
|
||||
setHostUpdated(e.target.value);
|
||||
setValueChanged(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
@@ -135,26 +172,28 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
<Divider flexItem />
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item>
|
||||
<Typography sx={{ fontSize: 16, fontWeight: 600, mb: 1 }}>Version</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Version
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
mb: 2,
|
||||
color: (t) => (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'),
|
||||
}}
|
||||
>
|
||||
Lock wallet after certain time
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid spacing={3} item container alignItems="center" maxWidth="348px">
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Grid item width={1}>
|
||||
<TextField
|
||||
id="version"
|
||||
type="input"
|
||||
label="Version"
|
||||
value={versionUpdated}
|
||||
onChange={(e) => {
|
||||
setVersionUpdated(e.target.value);
|
||||
setValueChanged(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
@@ -196,7 +235,7 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
width: '100%',
|
||||
mb: 1,
|
||||
textAlign: 'center',
|
||||
color: 'info.dark',
|
||||
color: theme.palette.nym.nymWallet.text.blue,
|
||||
fontSize: 16,
|
||||
textTransform: 'capitalize',
|
||||
}}
|
||||
@@ -209,6 +248,6 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon
|
||||
textTransform: 'capitalize',
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
+47
-24
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Box, Button, Divider, Typography, TextField, InputAdornment, Grid, Alert } from '@mui/material';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button, Divider, Typography, TextField, InputAdornment, Grid, Alert } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { TBondedMixnode, TBondedGateway } from '../../../../context/bonding';
|
||||
import { SimpleModal } from '../../../../components/Modals/SimpleModal';
|
||||
|
||||
@@ -8,54 +9,74 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
|
||||
const [buttonActive, setButtonActive] = useState<boolean>(false);
|
||||
const [openConfirmationModal, setOpenConfirmationModal] = useState<boolean>(false);
|
||||
const [profitMargin, setProfitMargin] = useState<number | ''>(profitMarginPercent);
|
||||
const [operatorCost, setOperatorCost] = useState<string>(bond.amount);
|
||||
const [profitMargin, setProfitMargin] = useState<number>(profitMarginPercent);
|
||||
const [operatorCost, setOperatorCost] = useState<number>(parseInt(bond.amount));
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
if (!profitMargin || !operatorCost || 0 >= profitMargin || 100 < profitMargin) {
|
||||
if (profitMargin === profitMarginPercent && operatorCost === parseInt(bond.amount)) {
|
||||
setButtonActive(false);
|
||||
} else {
|
||||
setButtonActive(true);
|
||||
}
|
||||
}, [profitMargin, operatorCost]);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const { value, id } = e.target;
|
||||
const numNewValue = parseInt(value) || 0;
|
||||
switch (id) {
|
||||
case 'profitMargin':
|
||||
setProfitMargin(numNewValue);
|
||||
break;
|
||||
case 'operatorCost':
|
||||
setOperatorCost(numNewValue);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ width: '79.88%', minHeight: '' }}>
|
||||
<Grid container xs>
|
||||
{buttonActive && (
|
||||
<Alert
|
||||
severity="info"
|
||||
sx={{
|
||||
width: 1,
|
||||
px: 2,
|
||||
borderRadius: 0,
|
||||
bgcolor: 'background.default',
|
||||
color: 'info.dark',
|
||||
'& .MuiAlert-icon': { color: 'info.dark' },
|
||||
color: (theme) => theme.palette.nym.nymWallet.text.blue,
|
||||
'& .MuiAlert-icon': { color: (theme) => theme.palette.nym.nymWallet.text.blue },
|
||||
}}
|
||||
>
|
||||
<strong>Profit margin can be changed once a month, your changes will be applied in the next interval</strong>
|
||||
</Alert>
|
||||
)}
|
||||
<Grid container direction="column">
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3} spacing={1}>
|
||||
<Grid item direction="column">
|
||||
<Typography sx={{ fontSize: 16, fontWeight: 600, mb: 1 }}>Profit Margin</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Profit Margin
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
mb: 2,
|
||||
color: (t) => (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'),
|
||||
}}
|
||||
>
|
||||
Profit margin can be changed once a month
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid spacing={3} item container alignItems="center" maxWidth="348px">
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Grid item width={1} spacing={3}>
|
||||
<TextField
|
||||
id="profitMargin"
|
||||
type="input"
|
||||
label="Profit margin"
|
||||
value={profitMargin}
|
||||
onChange={(e) => {
|
||||
setProfitMargin(parseInt(e.target.value) || '');
|
||||
setButtonActive(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
@@ -69,28 +90,30 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider flexItem />
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
|
||||
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3} spacing={1}>
|
||||
<Grid item direction="column">
|
||||
<Typography sx={{ fontSize: 16, fontWeight: 600, mb: 1 }}>Operator cost</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
|
||||
Operator cost
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
mb: 2,
|
||||
color: (t) => (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'),
|
||||
}}
|
||||
>
|
||||
Lock Wallet after a certain time
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid spacing={3} item container alignItems="center" maxWidth="348px">
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Grid item width={1} spacing={3}>
|
||||
<TextField
|
||||
id="operatorCost"
|
||||
type="input"
|
||||
label="Operator cost"
|
||||
value={operatorCost}
|
||||
onChange={(e) => {
|
||||
setOperatorCost(e.target.value);
|
||||
setButtonActive(true);
|
||||
}}
|
||||
onChange={(e) => handleChange(e)}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
@@ -138,7 +161,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
width: '100%',
|
||||
mb: 1,
|
||||
textAlign: 'center',
|
||||
color: 'info.dark',
|
||||
color: theme.palette.nym.nymWallet.text.blue,
|
||||
fontSize: 16,
|
||||
textTransform: 'capitalize',
|
||||
}}
|
||||
@@ -146,6 +169,6 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
m: 0,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ export const NodeGeneralSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
return (
|
||||
<Box sx={{ pl: 3, pt: 3 }}>
|
||||
<Grid container direction="row" spacing={3}>
|
||||
<Grid item container direction="column" width={0.2}>
|
||||
<Grid item container direction="column" xs={3}>
|
||||
{nodeGeneralNav.map((item) => (
|
||||
<Button
|
||||
size="small"
|
||||
|
||||
Vendored
+1
-1
@@ -31,7 +31,6 @@ declare module '@mui/material/styles' {
|
||||
highlight: string;
|
||||
success: string;
|
||||
info: string;
|
||||
infoDark: string;
|
||||
fee: string;
|
||||
background: { light: string; dark: string };
|
||||
text: {
|
||||
@@ -58,6 +57,7 @@ declare module '@mui/material/styles' {
|
||||
warn: string;
|
||||
contrast: string;
|
||||
grey: string;
|
||||
blue: string;
|
||||
};
|
||||
topNav: {
|
||||
background: string;
|
||||
|
||||
@@ -23,7 +23,6 @@ const nymPalette: NymPalette = {
|
||||
highlight: '#FB6E4E',
|
||||
success: '#21D073',
|
||||
info: '#60D7EF',
|
||||
infoDark: '#514EFB',
|
||||
fee: '#967FF0',
|
||||
background: { light: '#F4F6F8', dark: '#1D2125' },
|
||||
text: {
|
||||
@@ -50,6 +49,7 @@ const darkMode: NymPaletteVariant = {
|
||||
warn: '#FFE600',
|
||||
contrast: '#1D2125',
|
||||
grey: '#5B6174',
|
||||
blue: '#60D7EF',
|
||||
},
|
||||
topNav: {
|
||||
background: '#111826',
|
||||
@@ -77,6 +77,7 @@ const lightMode: NymPaletteVariant = {
|
||||
warn: '#FFE600',
|
||||
contrast: '#FFFFFF',
|
||||
grey: '#3A4053',
|
||||
blue: '#514EFB',
|
||||
},
|
||||
topNav: {
|
||||
background: '#111826',
|
||||
@@ -123,7 +124,6 @@ const variantToMUIPalette = (variant: NymPaletteVariant): PaletteOptions => ({
|
||||
},
|
||||
info: {
|
||||
main: nymPalette.info,
|
||||
dark: nymPalette.infoDark,
|
||||
},
|
||||
background: {
|
||||
default: variant.background.main,
|
||||
|
||||
Reference in New Issue
Block a user