import { Alert, Box, Button, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, InputLabel, Snackbar, SnackbarCloseReason, TextField, Typography, styled, } from "@mui/material"; import React, { useContext, useEffect, useState } from "react"; import { BootstrapDialog } from "../Terms"; import CloseIcon from "@mui/icons-material/Close"; import { Spacer } from "../common/Spacer"; import gameContext from "../../contexts/gameContext"; import TradeBotList from "./TradeBotList"; import { stuckTradesAtom } from "../../global/state"; import { useAtom } from "jotai/react"; import { StuckOrdersTable } from "./StuckOrdersTable"; import { useGlobal } from "qapp-core"; export const CustomLabel = styled(InputLabel)` font-weight: 400; font-family: Inter; font-size: 14px; line-height: 1.2; color: rgba(255, 255, 255, 0.5); white-space: normal; `; export const minimumAmountSellTrades = { LITECOIN: { value: 0.01, ticker: "LTC", }, DOGECOIN: { value: 1, ticker: "DOGE", }, BITCOIN: { value: 0.001, ticker: "BTC", }, DIGIBYTE: { value: 0.01, ticker: "DGB", }, RAVENCOIN: { value: 0.01, ticker: "RVN", }, PIRATECHAIN: { value: 0.0002, ticker: "ARRR", }, }; export const CustomInput = styled(TextField)({ width: "183px", // Adjust the width as needed borderRadius: "5px", // backgroundColor: "rgba(30, 30, 32, 1)", outline: "none", input: { fontSize: '14px', fontFamily: "Inter", fontWeight: 400, color: "white", "&::placeholder": { fontSize: '14px', color: "rgba(255, 255, 255, 0.2)", }, outline: "none", padding: "10px", }, "& .MuiOutlinedInput-root": { "& fieldset": { border: "0.5px solid rgba(255, 255, 255, 0.5)", }, "&:hover fieldset": { border: "0.5px solid rgba(255, 255, 255, 0.5)", }, "&.Mui-focused fieldset": { border: "0.5px solid rgba(255, 255, 255, 0.5)", }, }, "& .MuiInput-underline:before": { borderBottom: "none", }, "& .MuiInput-underline:hover:not(.Mui-disabled):before": { borderBottom: "none", }, "& .MuiInput-underline:after": { borderBottom: "none", }, }); export const CreateSell = ({ qortAddress, show }) => { const [open, setOpen] = React.useState(false); const [openStuckOrders, setOpenStuckOrders] = React.useState(false); const [qortAmount, setQortAmount] = React.useState(''); const [foreignAmount, setForeignAmount] = React.useState(''); const { updateTemporaryFailedTradeBots, sellOrders, fetchTemporarySellOrders, isUsingGateway, getCoinLabel, selectedCoin, } = useContext(gameContext); const [openAlert, setOpenAlert] = React.useState(false); const [info, setInfo] = React.useState(null); const handleClickOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false); setForeignAmount(''); setQortAmount(''); }; const createSellOrder = async () => { try { setInfo({ type: "info", message: "Attempting to create sell order. Please wait...", }); const res = await qortalRequestWithTimeout( { action: "CREATE_TRADE_SELL_ORDER", qortAmount: +qortAmount, foreignBlockchain: selectedCoin, foreignAmount: +qortAmount * +foreignAmount, }, 900000 ); if (res?.error && res?.failedTradeBot) { await updateTemporaryFailedTradeBots({ atAddress: res?.failedTradeBot?.atAddress, status: "FAILED", qortAddress: res?.failedTradeBot?.creatorAddress, }); fetchTemporarySellOrders(); setOpenAlert(true); setInfo({ type: "error", message: "Unable to create sell order. Please try again.", }); } if (!res?.error) { setOpenAlert(true); setForeignAmount(''); setQortAmount(''); setOpen(false); setInfo({ type: "success", message: "Sell order created. Please wait a couple of minutes for the network to propogate the changes.", }); } } catch (error) { if (error?.error && error?.failedTradeBot) { await updateTemporaryFailedTradeBots({ atAddress: error?.failedTradeBot?.atAddress, status: "FAILED", qortAddress: error?.failedTradeBot?.creatorAddress, }); fetchTemporarySellOrders(); setOpenAlert(true); setInfo({ type: "error", message: "Unable to create sell order. Please try again.", }); } } }; const handleCloseAlert = ( event?: React.SyntheticEvent | Event, reason?: SnackbarCloseReason ) => { if (reason === "clickaway") { return; } setOpenAlert(false); setInfo(null); }; if (isUsingGateway) { return (
Managing your sell orders is not possible using a gateway node. Please switch to a local or custom node at the authentication page
); } return (
{!isUsingGateway && ( )} item.status === "FAILED")} /> {`New Sell Order - QORT for ${getCoinLabel()}`} ({ position: "absolute", right: 8, top: 8, color: theme.palette.grey[500], })} > QORT amount { const value = e.target.value; const regex = /^\d*\.?\d{0,8}$/; // allows up to 8 decimal places if (value === '' || regex.test(value)) { setQortAmount(value); } }} autoComplete="off" /> {`Price of Each QORT (in ${getCoinLabel()})`} { const value = e.target.value; const regex = /^\d*\.?\d{0,8}$/; // allows up to 8 decimal places if (value === '' || regex.test(value)) { setForeignAmount(value); } }} autoComplete="off" /> {`${Number(+qortAmount * +foreignAmount)?.toFixed(8)} ${getCoinLabel()}`} for{" "} {qortAmount || 0} QORT Total sell amount needs to be greater than:{" "} {minimumAmountSellTrades[selectedCoin]?.value}{" "} {minimumAmountSellTrades[selectedCoin]?.ticker} {info?.message} {openStuckOrders && ( )}
); }; const StuckOrders = ({setOpenStuckOrders})=> { const [stuckTrades] = useAtom(stuckTradesAtom) const address = useGlobal().auth.address const filteredByAddress = stuckTrades ?.filter((item) => item?.qortalCreator === address) .sort((a, b) => { const timestampA = a?.timestamp ?? a?.creationTimestamp ?? 0; const timestampB = b?.timestamp ?? b?.creationTimestamp ?? 0; return timestampB - timestampA; // Newest first }); return ( Stuck sell orders setOpenStuckOrders(false)} sx={(theme) => ({ position: "absolute", right: 8, top: 8, color: theme.palette.grey[500], })} > {filteredByAddress?.length === 0 && ( No stuck trades )} ) }