163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
import {
|
|
Box,
|
|
Button,
|
|
Divider,
|
|
IconButton,
|
|
Paper,
|
|
SvgIcon,
|
|
Typography,
|
|
useMediaQuery,
|
|
useTheme,
|
|
} from "@mui/material";
|
|
import { styled } from '@mui/material/styles';
|
|
import CloseIcon from '@mui/icons-material/Close';
|
|
import LoopIcon from '@mui/icons-material/Loop';
|
|
import { ReactElement, useState, useEffect } from "react";
|
|
import { useNavigate, createSearchParams } from "react-router-dom";
|
|
|
|
import GhostStyledIcon from "../../Icon/GhostIcon";
|
|
import { Tokens, useWallet } from "./Token";
|
|
import { PrimaryButton, SecondaryButton } from "../../Button";
|
|
|
|
import ArrowUpIcon from "../../../assets/icons/arrow-up.svg?react";
|
|
import { formatCurrency, shorten } from "../../../helpers";
|
|
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
|
import { RESERVE_ADDRESSES, FTSO_ADDRESSES } from "../../../constants/addresses";
|
|
|
|
import { useAccount, useDisconnect, useSwitchChain } from "wagmi";
|
|
|
|
const DisconnectButton = ({ onClose }) => {
|
|
const { disconnect } = useDisconnect();
|
|
return (
|
|
<PrimaryButton
|
|
onClick={() => {
|
|
disconnect();
|
|
onClose();
|
|
}}
|
|
variant="contained"
|
|
fullWidth
|
|
>
|
|
Disconnect
|
|
</PrimaryButton>
|
|
);
|
|
};
|
|
|
|
const CloseButton = styled(IconButton)(theme => ({
|
|
root: {
|
|
...theme.overrides?.MuiButton?.containedSecondary,
|
|
width: "30px",
|
|
height: "30px",
|
|
},
|
|
}));
|
|
|
|
const WalletTotalValue = ({ address, tokens }) => {
|
|
const ghstPrice = tokens.ghst.price;
|
|
const [currency, setCurrency] = useState("USD");
|
|
const [topHovered, setTopHovered] = useState(false);
|
|
|
|
const walletTotalValueUSD = Object.values(tokens).reduce(
|
|
(totalValue, token) => totalValue.add(token.balance.mul(token.price)),
|
|
new DecimalBigNumber(0n, 0),
|
|
);
|
|
|
|
const walletValue = {
|
|
USD: walletTotalValueUSD ? walletTotalValueUSD : new DecimalBigNumber(0n, 0),
|
|
GHST: walletTotalValueUSD && ghstPrice.gt(new DecimalBigNumber(0, 0)) ?
|
|
walletTotalValueUSD.div(ghstPrice)
|
|
:
|
|
new DecimalBigNumber(0n, 0),
|
|
};
|
|
|
|
return (
|
|
<Box
|
|
style={{ cursor: "pointer" }}
|
|
onClick={() => setCurrency(currency === "USD" ? "GHST" : "USD")}
|
|
onMouseEnter={() => setTopHovered(true)}
|
|
onMouseLeave={() => setTopHovered(false)}
|
|
>
|
|
<Box width="120px" display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
|
<Box>
|
|
<Typography style={{ lineHeight: 1.1, fontWeight: 600, fontSize: "0.975rem" }} color="textSecondary">
|
|
MY WALLET
|
|
</Typography>
|
|
<Typography style={{ fontSize: ".85rem", lineHeight: 1.1 }} variant="h3">
|
|
{shorten(address)}
|
|
</Typography>
|
|
</Box>
|
|
<Box pt="1px">
|
|
<GhostStyledIcon
|
|
viewBox="0 0 24 24"
|
|
component={LoopIcon}
|
|
style={{
|
|
transition: "transform .3s ease-in-out",
|
|
transitionTimingFunction: " cubic-bezier(.4,0,.2,1)",
|
|
transform: topHovered ? "rotateZ(-180deg)" : "rotateZ(0deg)",
|
|
}}
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
|
|
|
|
<Typography style={{ fontWeight: 700 }} variant="h3">
|
|
{formatCurrency(walletValue[currency], 2, currency === "USD" ? "USD" : "👻" )}
|
|
</Typography>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|
const theme = useTheme();
|
|
const navigate = useNavigate();
|
|
const tokens = useWallet(chainId, address);
|
|
const { chains } = useSwitchChain();
|
|
|
|
const onBtnClick = (dexName, from, to) => {
|
|
navigate({
|
|
pathname: `${chains.find(chain => chain.id === chainId).name.toLowerCase()}/dex/` + dexName,
|
|
search: createSearchParams({
|
|
pool: true,
|
|
from: from,
|
|
to: to,
|
|
}).toString()
|
|
})
|
|
onClose();
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (isWalletOpen) {
|
|
Object.values(tokens ?? {}).forEach(token => token.refetch());
|
|
}
|
|
}, [isWalletOpen, tokens])
|
|
|
|
return (
|
|
<Paper>
|
|
<Box sx={{ padding: theme.spacing(0, 3), display: "flex", flexDirection: "column", minHeight: "100vh" }}>
|
|
<Box sx={{ display: "flex", justifyContent: "space-between", padding: theme.spacing(3, 0, 1) }}>
|
|
<WalletTotalValue address={address} tokens={tokens} />
|
|
<CloseButton size="small" onClick={onClose} aria-label="close wallet">
|
|
<GhostStyledIcon component={CloseIcon} />
|
|
</CloseButton>
|
|
</Box>
|
|
|
|
<Box sx={{ margin: theme.spacing(2, -3) }}>
|
|
<Divider />
|
|
</Box>
|
|
|
|
<Box sx={{ display: "flex", flexDirection: "column" }} style={{ gap: theme.spacing(1) }}>
|
|
<Tokens address={address} tokens={tokens} onClose={onClose} />
|
|
</Box>
|
|
|
|
<Box sx={{ margin: theme.spacing(2, -3, 3) }}>
|
|
<Divider />
|
|
</Box>
|
|
|
|
<Box sx={{ width: "100%", marginTop: "auto", marginX: "auto", padding: theme.spacing(2, 0) }}>
|
|
<DisconnectButton onClose={onClose} />
|
|
</Box>
|
|
</Box>
|
|
</Paper>
|
|
);
|
|
}
|
|
|
|
export default InitialWalletView;
|