ghost-dao-interface/src/containers/Stake/components/StakeConfirmationModal.jsx
Uncle Fatso e244299465
apply small changes for the app
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2026-07-12 13:57:02 +03:00

224 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { CheckBoxOutlineBlank, CheckBoxOutlined } from "@mui/icons-material";
import { Box, Checkbox, FormControlLabel, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import GhostStyledIcon from "../../../components/Icon/GhostIcon";
import Modal from "../../../components/Modal/Modal";
import Metric from "../../../components/Metric/Metric";
import Token from "../../../components/Token/Token";
import { PrimaryButton, SecondaryButton } from "../../../components/Button";
import { TokenAllowanceGuard } from "../../../components/TokenAllowanceGuard/TokenAllowanceGuard";
import { useWarmupLength, stake, unstake, wrap, unwrap } from "../../../hooks/staking";
import { formatNumber } from "../../../helpers";
import { STAKING_ADDRESSES } from "../../../constants/addresses";
const StakeConfirmationModal = (props) => {
const { warmupLength, warmupExists: needsWarmup } = useWarmupLength(props.chainId);
const [acknowledgedWarmup, setAcknowledgedWarmup] = useState(false);
const [isPending, setIsPending] = useState(false);
useEffect(() => setAcknowledgedWarmup(acknowledgedWarmup || !needsWarmup), [acknowledgedWarmup, needsWarmup])
const AcknowledgeWarmupCheckbox = () => {
if (!needsWarmup) return <></>;
return (
<>
<Box sx={{ marginBottom: "1rem" }}>
<hr style={{ borderWidth: "0.5px" }} />
<FormControlLabel
control={
<Checkbox
data-testid="acknowledge-stake-warm-up"
checked={acknowledgedWarmup}
onChange={event => setAcknowledgedWarmup(event.target.checked)}
icon={<CheckBoxOutlineBlank viewBox="0 0 24 24" />}
checkedIcon={<CheckBoxOutlined viewBox="0 0 24 24" />}
/>
}
label={
<Typography variant="body2">
{`I understand the ${props.ftsoSymbol} Im staking will only be available to claim ${warmupLength.toString()} epochs after my transaction is confirmed`}
</Typography>
}
/>
</Box>
</>
);
};
const NeedsWarmupDetails = () => {
if (needsWarmup && props.action === "STAKE") {
return (
<>
<AcknowledgeWarmupCheckbox />
<SecondaryButton
fullWidth
href="https://ghostchain.io/ghostdao_litepaper"
>
Why is there a warm-up?
</SecondaryButton>
</>
);
} else {
return <></>;
}
};
const doAction = async () => {
setIsPending(true);
const actionAmount = new DecimalBigNumber(props.amount, props.spendDecimals);
let isRebase = false;
switch (props.action.toUpperCase()) {
case "STAKE":
isRebase = props.bottomToken === props.stnkSymbol;
await stake(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
isRebase,
props.isClaim,
props.ftsoSymbol,
props.stnkSymbol,
props.ghstSymbol
);
break;
case "UNSTAKE":
isRebase = props.upperToken === props.stnkSymbol;
await unstake(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
props.isTrigger,
isRebase,
props.ftsoSymbol,
props.stnkSymbol,
props.ghstSymbol
);
break;
case "WRAP":
await wrap(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
props.ghstSymbol
);
break;
case "UNWRAP":
await unwrap(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
props.stnkSymbol
);
break;
default:
console.log("Wrong action to be executed!");
}
setIsPending(false);
props.onClose();
}
return (
<Modal
data-testid="stake-confirmation-modal"
maxWidth="476px"
headerContent={
<Typography variant="h4">{`Confirm ${props.action}`}</Typography>
}
open={props.open}
onClose={() => isPending ? {} : props.onClose()}
minHeight={"100px"}
>
<Box display="flex" flexDirection="column">
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
<Box height="170px" display="flex" flexDirection="column">
<Metric
label={`Assets to Spend`}
metric={formatNumber(new DecimalBigNumber(props.amount, props.spendDecimals), 5)}
/>
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
<Token
parentSx={{
height: "80px",
"& svg:nth-of-type(2)": {
transform: "translate(50%, -30%)",
zIndex: 100,
}
}}
sx={{ transform: "scale(1.65)", }}
chainTokenName={props.chainSymbol}
name={props.upperToken}
/>
<Typography>{props.upperToken}</Typography>
</Box>
</Box>
<GhostStyledIcon component={ArrowRightIcon} />
<Box display="flex" flexDirection="column">
<Metric
label="Assets to Receive"
metric={formatNumber(new DecimalBigNumber(props.receiveAmount, props.receiveDecimals), 5)}
/>
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
<Token
parentSx={{
height: "80px",
"& svg:nth-of-type(2)": {
transform: "translate(50%, -30%)",
zIndex: 100,
}
}}
sx={{ transform: "scale(1.65)", }}
chainTokenName={props.chainSymbol}
name={props.upperToken === props.ftsoSymbol ? props.ghstSymbol : props.ftsoSymbol}
/>
<Typography>{props.bottomToken}</Typography>
</Box>
</Box>
</Box>
<Box sx={{ marginTop: "1.5rem" }}>
{acknowledgedWarmup || props.action !== "STAKE" ?
<TokenAllowanceGuard
spendAmount={new DecimalBigNumber(props.amount, props.spendDecimals)}
tokenName={props.upperToken}
owner={props.address}
spender={STAKING_ADDRESSES[props.chainId]}
decimals={props.spendDecimals}
approvalText={`Approve ${props.upperToken}`}
approvalPendingText={"Approving..."}
connect={props.connect}
isVertical
>
<PrimaryButton
data-testid="submit-modal-button"
loading={isPending}
fullWidth
disabled={
isPending ||
parseFloat(props.amount) === 0 ||
props.amountExceedsBalance ||
(props.action === "STAKE" && !acknowledgedWarmup)
}
onClick={() => doAction()}
>
Confirm
</PrimaryButton>
</TokenAllowanceGuard>
:
<NeedsWarmupDetails />
}
</Box>
</Box>
</Modal>
);
};
export default StakeConfirmationModal;