ghost-dao-interface/src/containers/Bond/components/BondConfirmModal.jsx
Uncle Fatso 13a05bf0dd
fix issues with bond representation and bond purchase
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2025-08-14 16:13:40 +03:00

118 lines
4.4 KiB
JavaScript

import { useState } from "react";
import { Box, Typography } from "@mui/material";
import { styled, useTheme } from "@mui/material/styles";
import SettingsIcon from '@mui/icons-material/Settings';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import toast from "react-hot-toast";
import GhostStyledIcon from "../../../components/Icon/GhostIcon";
import Metric from "../../../components/Metric/Metric";
import Modal from "../../../components/Modal/Modal";
import TokenStack from "../../../components/TokenStack/TokenStack";
import DataRow from "../../../components/DataRow/DataRow";
import { PrimaryButton } from "../../../components/Button";
import BondDiscount from "./BondDiscount";
import BondVesting from "./BondVesting";
import BondSlippage from "./BondSlippage";
import { purchaseBond } from "../../../hooks/bonds";
const StyledBox = styled(Box, {
shouldForwardProp: prop => prop !== "template",
})(({ theme }) => {
return {
root: {},
};
});
const BondConfirmModal = ({
chainId,
bond,
slippage,
recipientAddress,
spendAmountValue,
spendAmount,
receiveAmount,
sender,
handleSettingsOpen,
isOpen,
handleConfirmClose
}) => {
const theme = useTheme();
const [isPending, setIsPending] = useState(false);
const onSubmit = async () => {
setIsPending(true);
const shares = 100000;
const one = BigInt(shares * 100);
const floatSlippage = slippage === "" ? 0 : parseFloat(slippage);
const bigIntSlippage = one + BigInt(Math.round(floatSlippage * shares));
const maxPrice = bond.price.inBaseToken._value * bigIntSlippage / one;
const referral = import.meta.env.VITE_APP_REFERRAL_ADDRESS;
await purchaseBond(
chainId,
bond.id,
spendAmountValue._value.toBigInt(),
maxPrice,
recipientAddress,
sender,
referral
);
setIsPending(false);
handleConfirmClose();
}
return (
<Modal
maxWidth="476px"
minHeight="200px"
open={isOpen}
headerContent={
<Box display="flex" flexDirection="row">
<TokenStack tokens={bond.quoteToken.icons} sx={{ fontSize: "27px" }} />
<Typography variant="h4" sx={{ marginLeft: "6px" }}>
{bond.quoteToken.name}
</Typography>
</Box>
}
onClose={!isPending && handleConfirmClose}
topLeft={<GhostStyledIcon viewBox="0 0 23 23" component={SettingsIcon} style={{ cursor: "pointer" }} onClick={handleSettingsOpen} />}
>
<>
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
<Box display="flex" flexDirection="column">
<Metric
label="Assets to Bond"
metric={spendAmount}
/>
<Box display="flex" flexDirection="row" justifyContent="center">
<Typography>{bond.quoteToken.name}</Typography>
</Box>
</Box>
<GhostStyledIcon sx={{ transform: "rotate(-90deg)" }} component={ArrowDropDownIcon} />
<Box display="flex" flexDirection="column">
<Metric label="Assets to Receive" metric={receiveAmount} />
<Box display="flex" flexDirection="row" justifyContent="center">
<Typography>{bond.baseToken.name}</Typography>
</Box>
</Box>
</Box>
<Box mt="21px" mb="21px" borderTop={`1px solid ${theme.colors.gray[500]}`}></Box>
<DataRow title="ROI" balance={<BondDiscount discount={bond.discount} textOnly />} />
<DataRow title="Bond Slippage" balance={<BondSlippage slippage={slippage} textOnly />} />
<DataRow title="Vesting Term" balance={<BondVesting vesting={bond.vesting} />} />
<PrimaryButton fullWidth onClick={onSubmit} disabled={isPending} loading={isPending}>
{isPending ? "Bonding..." : "Confirm Bond Purchase"}
</PrimaryButton>
</>
</Modal>
);
};
export default BondConfirmModal;