import { useState, useEffect, useRef, useContext, ChangeEvent, useMemo } from "react"; import { BubbleCardColored1, CoinActionContainer, CoinActionRow, CoinActionsRow, CoinCancelBtn, CoinConfirmSendBtn, CoinReceiveBtn, CoinSelectRow, CoinSendBtn, CustomInputField, HeaderNav, HeaderRow, HeaderText, LogoColumn, NameRow, RightColumn, SendFont, TotalCol, Username, } from "./Header-styles"; import gameContext from "../../contexts/gameContext"; import { UserContext } from "../../contexts/userContext"; import { cropAddress } from "../../utils/cropAddress"; import qtradeLogo from "../../components/common/icons/qtradeLogo.png"; import qortIcon from "../../assets/img/qort.png"; import ErrorIcon from "@mui/icons-material/Error"; import { CopyToClipboard } from "react-copy-to-clipboard"; import Copy from "../../assets/SVG/Copy.svg"; import {AddressQRCode} from './AddressQRCode' import {FallingLines} from 'react-loader-spinner' import { Alert, AppBar, Avatar, Box, Card, CardContent, FormControl, FormControlLabel, MenuItem, Select, Snackbar, SnackbarCloseReason, Switch, Typography, styled, } from "@mui/material"; import { sendRequestToExtension } from "../../App"; import { Terms } from "../Terms"; import ltcIcon from "../../assets/img/ltc.png"; import btcIcon from "../../assets/img/btc.png"; import dogeIcon from "../../assets/img/doge.png"; import rvnIcon from "../../assets/img/rvn.png"; import dgbIcon from "../../assets/img/dgb.png"; import arrrIcon from "../../assets/img/arrr.png"; import { Spacer } from "../common/Spacer"; import { ReusableModal } from "../common/reusable-modal/ReusableModal"; import { NotificationContext } from "../../contexts/notificationContext"; const checkIfLocal = async () => { try { const response = await sendRequestToExtension("CHECK_IF_LOCAL"); if (!response.error) { return response; } } catch (error) { return false; } }; export const Label = styled("label")( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 14px; display: block; margin-bottom: 4px; font-weight: 400; ` ); interface CoinModalProps { coin: string; type: string; } const getCoinIcon = (coin) => { let img; switch (coin) { case "LTC": img = ltcIcon; break; case "BTC": img = btcIcon; break; case "DOGE": img = dogeIcon; break; case "RVN": img = rvnIcon; break; case "ARRR": img = arrrIcon; break; case "DGB": img = dgbIcon; break; default: null; } return img; }; const SelectRow = ({ coin }) => { let img = getCoinIcon(coin); return (

{coin}

); }; export const Header = ({ qortBalance, foreignCoinBalance }: any) => { const [openDropdown, setOpenDropdown] = useState(false); const dropdownRef = useRef(null); const buttonRef = useRef(null); const [checked, setChecked] = useState(false); const [open, setOpen] = useState(false); const [info, setInfo] = useState(null); const [openCoinActionModal, setOpenCoinActionModal] = useState(null); const [receiverAddress, setReceiverAddress] = useState(""); const [senderAddress, setSenderAddress] = useState(""); const [amount, setAmount] = useState(""); const [coinAddresses, setCoinAddresses] = useState({}); const { isUsingGateway } = useContext(gameContext); const handleChange = (event: ChangeEvent) => { setChecked(false); setOpen(true); setInfo({ type: "error", message: "Change the node you are using at the authentication page", }); }; const { userInfo, selectedCoin, setSelectedCoin, getCoinLabel } = useContext(gameContext); const { setNotification } = useContext(NotificationContext); const LocalNodeSwitch = styled(Switch)(({ theme }) => ({ padding: 8, "& .MuiSwitch-track": { borderRadius: 22 / 2, "&::before, &::after": { content: '""', position: "absolute", top: "50%", transform: "translateY(-50%)", width: 16, height: 16, }, "&::before": { backgroundImage: `url('data:image/svg+xml;utf8,')`, left: 12, }, "&::after": { backgroundImage: `url('data:image/svg+xml;utf8,')`, right: 12, }, }, "& .MuiSwitch-thumb": { boxShadow: "none", width: 16, height: 16, margin: 2, }, })); const handleClose = ( event?: React.SyntheticEvent | Event, reason?: SnackbarCloseReason ) => { if (reason === "clickaway") { return; } setOpen(false); setInfo(null); }; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) && buttonRef.current && !buttonRef.current.contains(event.target as Node) ) { setOpenDropdown(false); } }; document.addEventListener("click", handleClickOutside); return () => { document.removeEventListener("click", handleClickOutside); }; }, []); // // Fetch avatar on userInfo change // useEffect(() => { // if (userInfo?.name) { // getAvatar(); // } // }, [userInfo]); const sendCoin = async ()=> { try { const coin = openCoinActionModal.coin === "QORT" ? 'QORT' : getCoinLabel() if(!coin) return setOpen(true); setInfo({ type: "info", message: "Sending Coin...", autoHideDurationOff: true }); const response = await qortalRequest({ action: "SEND_COIN", coin, destinationAddress: senderAddress, amount: +amount }); if(response?.error){ throw new Error(response?.error || "Failed to send coin.") } setOpen(true); setInfo({ type: "success", message: "Coin sent", }); setAmount('') } catch (error) { setOpen(true); setInfo({ type: "error", message: error?.error || error?.message, }); } } return ( <> } label="Is using Gateway" /> {userInfo?.name ? ( {userInfo?.name?.charAt(0)?.toUpperCase()} ) : userInfo?.address ? ( ) : null} {userInfo?.name ? ( {userInfo?.name} ) : userInfo?.address ? ( {cropAddress(userInfo?.address)} ) : null} Total Balance {qortBalance} QORT { setOpenCoinActionModal({ coin: "QORT", type: "send", }); }} > Send { setOpenCoinActionModal({ coin: "QORT", type: "receive", }); }} > Receive {foreignCoinBalance === null ? ( ) : foreignCoinBalance}{" "} {getCoinLabel()} { setOpenCoinActionModal({ coin: selectedCoin, type: "send", }); }} > Send { setOpenCoinActionModal({ coin: selectedCoin, type: "receive", }); }} > Receive {info?.type && ( {info?.message} )} {openCoinActionModal && ( { setOpenCoinActionModal(null); setAmount('') setSenderAddress('') }} backdrop > {openCoinActionModal.type === "send" ? <> {openCoinActionModal.type === "send" && openCoinActionModal.coin === "QORT" ? ( <> Send {openCoinActionModal.coin} ) : openCoinActionModal.type === "send" && openCoinActionModal.coin !== "QORT" ? ( <> Send {openCoinActionModal.coin} ) : null} { if (openCoinActionModal.type === "send") { setSenderAddress(e.target.value); } else { setReceiverAddress(e.target.value); } }} /> {openCoinActionModal.type === "send" && ( { setAmount(e.target.value) }} /> )} : ( <> )} {openCoinActionModal.type === 'send' && ( {/* setOpenCoinActionModal(null)}> Cancel */} { if(openCoinActionModal.type === 'send'){ sendCoin() } setNotification({ alertType: "alertInfo", msg: "Sending...", }); }} > {openCoinActionModal.type === "send" ? "Send" : "Receive"} )} )} ); }; export const AddressBox = styled(Box)` display: flex; border: 1px solid var(--50-white, rgba(255, 255, 255, 0.5)); justify-content: space-between; align-items: center; width: auto; word-break: break-word; padding: 5px 15px 5px 15px; gap: 5px; border-radius: 100px; font-family: Inter; font-size: 12px; font-weight: 600; line-height: 14.52px; text-align: left; color: var(--50-white, rgba(255, 255, 255, 0.5)); cursor: pointer; transition: all 0.2s; &:hover { background-color: rgba(41, 41, 43, 1); color: white; svg path { fill: white; // Fill color changes to white on hover } } ` const ReceiveCoin = ({coinAddresses, setCoinAddresses, selectedCoin, setOpen, setInfo})=> { const [errorMsg, setErrorMsg] = useState('') const foreignAddress = useMemo(()=> { return coinAddresses[selectedCoin] || null }, [coinAddresses, selectedCoin]) const getForeignAddress = async (coin)=> { try { setOpen(true); setInfo({ type: "info", message: "Retrieving address...", }); const response = await qortalRequest({ action: "GET_USER_WALLET", coin }); if(response?.address){ setCoinAddresses((prev)=> { return { ...prev, [coin]: response.address } }) } if(response?.error){ throw new Error(response?.error || "Failed to send coin.") } } catch (error) { setErrorMsg(error?.message) } finally { setOpen(false); setInfo(null); } } useEffect(()=> { if(!selectedCoin) return if(!coinAddresses[selectedCoin]){ getForeignAddress(selectedCoin) } }, [selectedCoin, coinAddresses]) return ( {`Send ${selectedCoin} to your address below`} {foreignAddress && ( { setOpen(true); setInfo({ type: "info", message: "Address copied!", }); }}> {foreignAddress} )} {foreignAddress && ( <> )} {errorMsg && ( <> {errorMsg} )} ) }