adjust memo field again

- add additional warning about profit margin changing
This commit is contained in:
Tommy Verrall
2025-03-21 10:23:59 +01:00
parent d06a8e0b21
commit 4f67998127
3 changed files with 66 additions and 23 deletions
@@ -1,6 +1,6 @@
import * as React from 'react';
import { useEffect, useState } from 'react';
import { Typography } from '@mui/material';
import { Typography, Box, Alert } from '@mui/material';
import { TBondedNode } from 'src/context';
import { useGetFee } from 'src/hooks/useGetFee';
import { ModalFee } from '../../Modals/ModalFee';
@@ -32,7 +32,9 @@ export const UpdateCostParametersModal = ({
}: Props) => {
const { fee, isFeeLoading, getFee, feeError } = useGetFee();
const [hasFetchedFee, setHasFetchedFee] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
// Handle fee errors
useEffect(() => {
if (feeError) {
onError(feeError);
@@ -50,7 +52,7 @@ export const UpdateCostParametersModal = ({
try {
const decimalProfitMargin = (parseFloat(profitMarginPercent) / 100).toString();
const uNymAmount = String(Math.floor(Number(intervalOperatingCost) * 1000000));
const uNymAmount = String(Math.floor(Number(intervalOperatingCost || '0') * 1000000));
const costParams: NodeCostParams = {
profit_margin_percent: decimalProfitMargin,
@@ -61,7 +63,6 @@ export const UpdateCostParametersModal = ({
};
getFee(simulateUpdateMixnodeCostParams, costParams);
setHasFetchedFee(true);
} catch (error) {
onError(error as string);
@@ -69,18 +70,33 @@ export const UpdateCostParametersModal = ({
}
}, [hasFetchedFee, intervalOperatingCost, profitMarginPercent, getFee, onError, node]);
// Handle confirmation with loading state
const handleConfirm = async () => {
if (isSubmitting) return;
try {
setIsSubmitting(true);
await onConfirm();
} catch (error) {
onError(error as string);
} finally {
setIsSubmitting(false);
}
};
return (
<SimpleModal
open
header="Update Cost Parameters"
subHeader="Modify your node's economic parameters"
okLabel="Update"
onOk={onConfirm}
okLabel={isSubmitting ? "Updating..." : "Update"}
onOk={handleConfirm}
onClose={onClose}
okDisabled={isSubmitting || isFeeLoading}
>
<ModalListItem
label="Interval Operating Cost"
value={`${intervalOperatingCost} nym`}
value={`${intervalOperatingCost || '0'} nym`}
divider
/>
<ModalListItem
@@ -89,10 +105,21 @@ export const UpdateCostParametersModal = ({
divider
/>
<ModalFee isLoading={isFeeLoading} fee={fee} divider />
<Typography fontSize="small">
These changes will affect your node's economics and delegator rewards.
Your new profit margin and operating cost will be applied in the next interval.
</Typography>
{/* Warning message */}
<Box mt={2}>
<Alert severity="warning">
<Typography variant="body2" fontWeight="medium">
This action will overwrite your existing profit margin and operating cost settings.
Only one cost parameter update is allowed per epoch.
</Typography>
</Alert>
</Box>
</SimpleModal>
);
};
@@ -121,6 +121,19 @@ export const SendInputModal = ({
initialValue={amount?.amount}
denom={denom}
/>
<TextField
name="memo"
label="Memo"
onChange={(e) => onMemoChange(e.target.value)}
value={memo}
error={!memoIsValid}
placeholder="Optional"
helperText={
!memoIsValid ? 'The text is invalid, only alphanumeric characters and white spaces are allowed' : undefined
}
InputLabelProps={{ shrink: true }}
fullWidth
/>
<Typography fontSize="smaller" sx={{ color: 'error.main' }}>
{error}
</Typography>
@@ -144,22 +157,8 @@ export const SendInputModal = ({
initialValue={userFees?.amount}
fullWidth
/>
<TextField
name="memo"
label="Memo"
onChange={(e) => onMemoChange(e.target.value)}
value={memo}
error={!memoIsValid}
helperText={
!memoIsValid
? ' The text is invalid, only alphanumeric characters and white spaces are allowed'
: undefined
}
InputLabelProps={{ shrink: true }}
fullWidth
/>
</Stack>
)}
</SimpleModal>
);
};
};
@@ -11,9 +11,15 @@ interface Props {
bondedNode: TBondedNode;
onConfirm: () => Promise<void>;
onError: (e: string) => void;
onUpdateData?: (profitMarginPercent: string, intervalOperatingCost: string, fee?: FeeDetails) => void;
}
export const NodeCostParametersPage = ({ bondedNode, onConfirm, onError }: Props) => {
export const NodeCostParametersPage = ({
bondedNode,
onConfirm,
onError,
onUpdateData
}: Props) => {
const { updateCostParameters } = useBondingContext();
const [intervalOperatingCost, setIntervalOperatingCost] = useState('');
const [profitMarginPercent, setProfitMarginPercent] = useState('');
@@ -33,6 +39,12 @@ export const NodeCostParametersPage = ({ bondedNode, onConfirm, onError }: Props
}
}, [bondedNode]);
useEffect(() => {
if (onUpdateData && isFormValid) {
onUpdateData(profitMarginPercent, intervalOperatingCost, fee);
}
}, [profitMarginPercent, intervalOperatingCost, fee, isFormValid, onUpdateData]);
const handleIntervalOperatingCostChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
if (value === '' || /^[0-9]*\.?[0-9]*$/.test(value)) {
@@ -63,6 +75,10 @@ export const NodeCostParametersPage = ({ bondedNode, onConfirm, onError }: Props
try {
const uNymAmount = String(Math.floor(Number(intervalOperatingCost) * 1000000));
if (onUpdateData) {
onUpdateData(profitMarginPercent, intervalOperatingCost, fee);
}
await updateCostParameters(profitMarginPercent, uNymAmount, fee);
setIsConfirmed(false);
onConfirm();
@@ -120,7 +136,8 @@ export const NodeCostParametersPage = ({ bondedNode, onConfirm, onError }: Props
InputProps={{
endAdornment: <InputAdornment position="end">%</InputAdornment>,
}}
helperText="Input your profit margin (e.g., 20 for 20%)"
helperText="Input your profit margin (must be between 20% and 50%)"
error={profitMarginPercent !== '' && (Number(profitMarginPercent) < 20 || Number(profitMarginPercent) > 50)}
/>
<Button