mirror of
https://github.com/Qortal/q-trade.git
synced 2025-06-20 13:11:21 +00:00
Fixed bottom UI buy container
This commit is contained in:
parent
7ef7a8b73f
commit
a52308d838
@ -1,5 +1,12 @@
|
||||
import { Box, styled } from "@mui/system";
|
||||
import { Typography } from "@mui/material";
|
||||
import { Button, Typography } from "@mui/material";
|
||||
|
||||
export const MainContainer = styled(Box)({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
});
|
||||
|
||||
export const TextTableTitle = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Inter",
|
||||
@ -11,14 +18,39 @@ export const TextTableTitle = styled(Typography)(({ theme }) => ({
|
||||
}));
|
||||
|
||||
export const BuyContainer = styled(Box)({
|
||||
width: "calc(100% - 60px)",
|
||||
position: "fixed",
|
||||
width: "calc(100% - 14px)",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
position: "fixed",
|
||||
bottom: "0px",
|
||||
height: "100px",
|
||||
padding: "7px 14px",
|
||||
padding: "18px 14px 12px 14px",
|
||||
background: "#323336",
|
||||
zIndex: 3
|
||||
zIndex: 3,
|
||||
});
|
||||
|
||||
export const BuyContainerDivider = styled(Box)({
|
||||
position: "absolute",
|
||||
width: "60%",
|
||||
height: "1px",
|
||||
background: "lightgray",
|
||||
top: "10px",
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
});
|
||||
|
||||
export const BuyOrderBtn = styled("button")(({ theme }) => ({
|
||||
borderRadius: "8px",
|
||||
width: "74px",
|
||||
height: "30px",
|
||||
background: "#4D7345",
|
||||
color: "white",
|
||||
cursor: "pointer",
|
||||
border: "1px solid #375232",
|
||||
boxShadow: "0px 2.77px 2.21px 0px #00000005",
|
||||
marginRight: "10px",
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
marginRight: "5px",
|
||||
}
|
||||
}));
|
||||
|
@ -15,8 +15,6 @@ import {
|
||||
} from "ag-grid-community";
|
||||
import "ag-grid-community/styles/ag-grid.css";
|
||||
import "ag-grid-community/styles/ag-theme-alpine.css";
|
||||
import axios from "axios";
|
||||
import { sendRequestToExtension } from "../../App";
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
@ -39,9 +37,15 @@ import { Hourglass } from "react-loader-spinner";
|
||||
import ErrorIcon from "@mui/icons-material/Error";
|
||||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||||
import { CountdownCircleTimer } from "react-countdown-circle-timer";
|
||||
import { BuyContainer } from "./Table-styles";
|
||||
import {
|
||||
BuyContainer,
|
||||
BuyContainerDivider,
|
||||
BuyOrderBtn,
|
||||
ContentArea,
|
||||
MainContainer,
|
||||
} from "./Table-styles";
|
||||
|
||||
export const baseLocalHost = window.location.host
|
||||
export const baseLocalHost = window.location.host;
|
||||
// export const baseLocalHost = "127.0.0.1:12391";
|
||||
|
||||
interface RowData {
|
||||
@ -110,23 +114,7 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [info, setInfo] = useState<any>(null);
|
||||
const BuyButton = () => {
|
||||
return (
|
||||
<button
|
||||
onClick={buyOrder}
|
||||
style={{
|
||||
borderRadius: "8px",
|
||||
width: "74px",
|
||||
height: "30px",
|
||||
background: "#4D7345",
|
||||
color: "white",
|
||||
cursor: "pointer",
|
||||
border: "1px solid #375232",
|
||||
boxShadow: "0px 2.77px 2.21px 0px #00000005",
|
||||
}}
|
||||
>
|
||||
BUY
|
||||
</button>
|
||||
);
|
||||
return <BuyOrderBtn onClick={buyOrder}>BUY</BuyOrderBtn>;
|
||||
};
|
||||
|
||||
const defaultColDef = {
|
||||
@ -500,12 +488,12 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
const buyOrder = async () => {
|
||||
try {
|
||||
if (+foreignCoinBalance < +selectedTotalLTC.toFixed(4)) {
|
||||
setOpen(true)
|
||||
setOpen(true);
|
||||
setInfo({
|
||||
type: 'error',
|
||||
message: `You don't have enough ${getCoinLabel()} or your balance was not retrieved`
|
||||
})
|
||||
return
|
||||
type: "error",
|
||||
message: `You don't have enough ${getCoinLabel()} or your balance was not retrieved`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedOffers?.length < 1) return;
|
||||
@ -653,11 +641,7 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<MainContainer>
|
||||
<div
|
||||
className="ag-theme-alpine-dark"
|
||||
style={{ height: 400, width: "100%" }}
|
||||
@ -686,47 +670,75 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
|
||||
)} */}
|
||||
</div>
|
||||
<div style={{
|
||||
height: '120px'
|
||||
}} />
|
||||
<div
|
||||
style={{
|
||||
height: "120px",
|
||||
}}
|
||||
/>
|
||||
<BuyContainer>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '5px',
|
||||
flexDirection: 'column',
|
||||
width: '100%'
|
||||
}}>
|
||||
<Typography sx={{
|
||||
fontSize: '16px',
|
||||
color: 'white',
|
||||
width: 'calc(100% - 75px)'
|
||||
}}>{selectedTotalQORT?.toFixed(3)} QORT</Typography>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
alignItems: 'center',
|
||||
width: 'calc(100% - 75px)'
|
||||
}}>
|
||||
<Typography sx={{
|
||||
fontSize: '16px',
|
||||
color: selectedTotalLTC > foreignCoinBalance ? 'red' : 'white',
|
||||
}}><span>{selectedTotalLTC?.toFixed(4)}</span> <span style={{
|
||||
marginLeft: 'auto'
|
||||
}}>{`${getCoinLabel()} `}</span></Typography>
|
||||
|
||||
|
||||
<BuyContainerDivider />
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "5px",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
color: "white",
|
||||
width: "calc(100% - 75px)",
|
||||
}}
|
||||
>
|
||||
{selectedTotalQORT?.toFixed(3)} QORT
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
width: "calc(100% - 75px)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
color: selectedTotalLTC > foreignCoinBalance ? "red" : "white",
|
||||
}}
|
||||
>
|
||||
<span>{selectedTotalLTC?.toFixed(4)}</span>{" "}
|
||||
<span
|
||||
style={{
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
>{`${getCoinLabel()} `}</span>
|
||||
</Typography>
|
||||
</Box>
|
||||
<Typography sx={{
|
||||
fontSize: '16px',
|
||||
color: 'white',
|
||||
|
||||
}}><span>{foreignCoinBalance?.toFixed(4)}</span> <span style={{
|
||||
marginLeft: 'auto'
|
||||
}}>{`${getCoinLabel()} `} balance</span></Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<span>{foreignCoinBalance?.toFixed(4)}</span>{" "}
|
||||
<span
|
||||
style={{
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
>
|
||||
{`${getCoinLabel()} `} balance
|
||||
</span>
|
||||
</Typography>
|
||||
</Box>
|
||||
{BuyButton()}
|
||||
</BuyContainer>
|
||||
<Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} open={open} onClose={handleClose}>
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Alert
|
||||
onClose={handleClose}
|
||||
severity={info?.type}
|
||||
@ -826,8 +838,7 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
</Typography>
|
||||
<Spacer height="20px" />
|
||||
<Typography>
|
||||
You can see the progress of your
|
||||
order in the "Pending" table.
|
||||
You can see the progress of your order in the "Pending" table.
|
||||
</Typography>
|
||||
<Spacer height="20px" />
|
||||
<Typography>
|
||||
@ -860,14 +871,17 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
{isUsingGateway && (
|
||||
<>
|
||||
<Typography>
|
||||
Using gateway: might take up to 3 minutes to submit the buy order.
|
||||
Using gateway: might take up to 3 minutes to submit the
|
||||
buy order.
|
||||
</Typography>
|
||||
<Spacer height="20px" />
|
||||
<Box sx={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<CountdownCircleTimer
|
||||
isPlaying
|
||||
duration={180}
|
||||
@ -879,7 +893,9 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
size={60}
|
||||
strokeWidth={4}
|
||||
>
|
||||
{({ remainingTime }) => <Typography>{remainingTime}</Typography>}
|
||||
{({ remainingTime }) => (
|
||||
<Typography>{remainingTime}</Typography>
|
||||
)}
|
||||
</CountdownCircleTimer>
|
||||
</Box>
|
||||
</>
|
||||
@ -905,6 +921,6 @@ export const TradeOffers: React.FC<any> = ({ foreignCoinBalance }: any) => {
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
)}
|
||||
</Box>
|
||||
</MainContainer>
|
||||
);
|
||||
};
|
||||
|
@ -1,10 +1,24 @@
|
||||
import { Alert, Box, Button, DialogActions, DialogContent, DialogTitle, IconButton, InputLabel, Snackbar, SnackbarCloseReason, TextField, Typography, styled } from '@mui/material'
|
||||
import React, { useContext } 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 {
|
||||
Alert,
|
||||
Box,
|
||||
Button,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
InputLabel,
|
||||
Snackbar,
|
||||
SnackbarCloseReason,
|
||||
TextField,
|
||||
Typography,
|
||||
styled,
|
||||
} from "@mui/material";
|
||||
import React, { useContext } 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";
|
||||
|
||||
export const CustomLabel = styled(InputLabel)`
|
||||
font-weight: 400;
|
||||
@ -12,13 +26,12 @@ export const CustomLabel = styled(InputLabel)`
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
|
||||
`
|
||||
`;
|
||||
|
||||
export const minimumAmountSellTrades = {
|
||||
'LITECOIN': {
|
||||
LITECOIN: {
|
||||
value: 0.01,
|
||||
ticker: 'LTC'
|
||||
ticker: "LTC",
|
||||
},
|
||||
DOGECOIN: {
|
||||
value: 1,
|
||||
@ -40,7 +53,7 @@ export const minimumAmountSellTrades = {
|
||||
value: 0.0002,
|
||||
ticker: "ARRR",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const CustomInput = styled(TextField)({
|
||||
width: "183px", // Adjust the width as needed
|
||||
@ -61,13 +74,13 @@ export const CustomInput = styled(TextField)({
|
||||
},
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
border: "0.5px solid rgba(255, 255, 255, 0.5)",
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
border: "0.5px solid rgba(255, 255, 255, 0.5)",
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
border: "0.5px solid rgba(255, 255, 255, 0.5)",
|
||||
},
|
||||
},
|
||||
"& .MuiInput-underline:before": {
|
||||
@ -81,126 +94,144 @@ export const CustomInput = styled(TextField)({
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
export const CreateSell = ({ qortAddress, show }) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [qortAmount, setQortAmount] = React.useState(0)
|
||||
const [foreignAmount, setForeignAmount] = React.useState(0)
|
||||
const {updateTemporaryFailedTradeBots, sellOrders, fetchTemporarySellOrders, isUsingGateway, getCoinLabel, selectedCoin} = useContext(gameContext)
|
||||
const [openAlert, setOpenAlert] = React.useState(false)
|
||||
const [info, setInfo] = React.useState<any>(null)
|
||||
const [qortAmount, setQortAmount] = React.useState(0);
|
||||
const [foreignAmount, setForeignAmount] = React.useState(0);
|
||||
const {
|
||||
updateTemporaryFailedTradeBots,
|
||||
sellOrders,
|
||||
fetchTemporarySellOrders,
|
||||
isUsingGateway,
|
||||
getCoinLabel,
|
||||
selectedCoin,
|
||||
} = useContext(gameContext);
|
||||
const [openAlert, setOpenAlert] = React.useState(false);
|
||||
const [info, setInfo] = React.useState<any>(null);
|
||||
const handleClickOpen = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
setForeignAmount(0)
|
||||
setQortAmount(0)
|
||||
setForeignAmount(0);
|
||||
setQortAmount(0);
|
||||
};
|
||||
|
||||
const createSellOrder = async () => {
|
||||
try {
|
||||
setInfo({
|
||||
type: 'info',
|
||||
message: "Attempting to create sell order. Please wait..."
|
||||
})
|
||||
const res = await qortalRequestWithTimeout({
|
||||
type: "info",
|
||||
message: "Attempting to create sell order. Please wait...",
|
||||
});
|
||||
const res = await qortalRequestWithTimeout(
|
||||
{
|
||||
action: "CREATE_TRADE_SELL_ORDER",
|
||||
qortAmount,
|
||||
foreignBlockchain: selectedCoin,
|
||||
foreignAmount: qortAmount * foreignAmount
|
||||
}, 900000);
|
||||
foreignAmount: qortAmount * foreignAmount,
|
||||
},
|
||||
900000
|
||||
);
|
||||
|
||||
if (res?.error && res?.failedTradeBot) {
|
||||
await updateTemporaryFailedTradeBots({
|
||||
atAddress: res?.failedTradeBot?.atAddress,
|
||||
status: 'FAILED',
|
||||
status: "FAILED",
|
||||
qortAddress: res?.failedTradeBot?.creatorAddress,
|
||||
|
||||
})
|
||||
fetchTemporarySellOrders()
|
||||
setOpenAlert(true)
|
||||
});
|
||||
fetchTemporarySellOrders();
|
||||
setOpenAlert(true);
|
||||
setInfo({
|
||||
type: 'error',
|
||||
message: "Unable to create sell order. Please try again."
|
||||
})
|
||||
type: "error",
|
||||
message: "Unable to create sell order. Please try again.",
|
||||
});
|
||||
}
|
||||
if (!res?.error) {
|
||||
setOpenAlert(true)
|
||||
setForeignAmount(0)
|
||||
setQortAmount(0)
|
||||
setOpen(false)
|
||||
setOpenAlert(true);
|
||||
setForeignAmount(0);
|
||||
setQortAmount(0);
|
||||
setOpen(false);
|
||||
|
||||
setInfo({
|
||||
type: 'success',
|
||||
message: "Sell order created. Please wait a couple of minutes for the network to propogate the changes."
|
||||
})
|
||||
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',
|
||||
status: "FAILED",
|
||||
qortAddress: error?.failedTradeBot?.creatorAddress,
|
||||
|
||||
})
|
||||
fetchTemporarySellOrders()
|
||||
setOpenAlert(true)
|
||||
});
|
||||
fetchTemporarySellOrders();
|
||||
setOpenAlert(true);
|
||||
setInfo({
|
||||
type: 'error',
|
||||
message: "Unable to create sell order. Please try again."
|
||||
})
|
||||
}
|
||||
type: "error",
|
||||
message: "Unable to create sell order. Please try again.",
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseAlert = (
|
||||
event?: React.SyntheticEvent | Event,
|
||||
reason?: SnackbarCloseReason,
|
||||
reason?: SnackbarCloseReason
|
||||
) => {
|
||||
if (reason === 'clickaway') {
|
||||
if (reason === "clickaway") {
|
||||
return;
|
||||
}
|
||||
|
||||
setOpenAlert(false);
|
||||
setInfo(null)
|
||||
setInfo(null);
|
||||
};
|
||||
|
||||
if (isUsingGateway) {
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
width: '100%',
|
||||
display: show ? 'flex' : 'none',
|
||||
height: '500px',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
<Typography sx={{
|
||||
color: 'white',
|
||||
maxWidth: '340px',
|
||||
padding: '10px'
|
||||
}}>
|
||||
Managing your sell orders is not possible using a gateway node. Please switch to a local or custom node at the authentication page
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
display: show ? "flex" : "none",
|
||||
height: "500px",
|
||||
alignItems: "flex-start",
|
||||
marginTop: "20px",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "white",
|
||||
maxWidth: "340px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
Managing your sell orders is not possible using a gateway node. Please
|
||||
switch to a local or custom node at the authentication page
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div style={{
|
||||
width: '100%',
|
||||
display: show ? 'block' : 'none'
|
||||
}}>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
display: show ? "block" : "none",
|
||||
}}
|
||||
>
|
||||
<Button onClick={handleClickOpen}>New Sell Order</Button>
|
||||
<TradeBotList qortAddress={qortAddress} failedTradeBots={sellOrders.filter((item)=> item.status === 'FAILED')} />
|
||||
<TradeBotList
|
||||
qortAddress={qortAddress}
|
||||
failedTradeBots={sellOrders.filter((item) => item.status === "FAILED")}
|
||||
/>
|
||||
|
||||
<BootstrapDialog
|
||||
onClose={handleClose}
|
||||
aria-labelledby="customized-dialog-title"
|
||||
open={open}
|
||||
sx={{
|
||||
'& .MuiDialogContent-root': {
|
||||
width: '300px'
|
||||
"& .MuiDialogContent-root": {
|
||||
width: "300px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
@ -211,7 +242,7 @@ export const CreateSell = ({qortAddress, show}) => {
|
||||
aria-label="close"
|
||||
onClick={handleClose}
|
||||
sx={(theme) => ({
|
||||
position: 'absolute',
|
||||
position: "absolute",
|
||||
right: 8,
|
||||
top: 8,
|
||||
color: theme.palette.grey[500],
|
||||
@ -221,7 +252,9 @@ export const CreateSell = ({qortAddress, show}) => {
|
||||
</IconButton>
|
||||
<DialogContent dividers>
|
||||
<Box>
|
||||
<CustomLabel htmlFor="standard-adornment-name">QORT amount</CustomLabel>
|
||||
<CustomLabel htmlFor="standard-adornment-name">
|
||||
QORT amount
|
||||
</CustomLabel>
|
||||
<Spacer height="5px" />
|
||||
<CustomInput
|
||||
id="standard-adornment-name"
|
||||
@ -243,34 +276,54 @@ export const CreateSell = ({qortAddress, show}) => {
|
||||
autoComplete="off"
|
||||
/>
|
||||
<Spacer height="6px" />
|
||||
<Typography>{`${qortAmount * foreignAmount} ${getCoinLabel()}`} for {qortAmount} QORT</Typography>
|
||||
<Typography sx={{
|
||||
fontSize: '14px'
|
||||
}}>Total sell amount needs to be greater than: {minimumAmountSellTrades[selectedCoin]?.value} {' '} {minimumAmountSellTrades[selectedCoin]?.ticker}</Typography>
|
||||
<Typography>
|
||||
{`${qortAmount * foreignAmount} ${getCoinLabel()}`} for{" "}
|
||||
{qortAmount} QORT
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Total sell amount needs to be greater than:{" "}
|
||||
{minimumAmountSellTrades[selectedCoin]?.value}{" "}
|
||||
{minimumAmountSellTrades[selectedCoin]?.ticker}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button autoFocus onClick={handleClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Button disabled={!qortAmount || !(qortAmount * foreignAmount > minimumAmountSellTrades[selectedCoin]?.value)} autoFocus onClick={createSellOrder}>
|
||||
<Button
|
||||
disabled={
|
||||
!qortAmount ||
|
||||
!(
|
||||
qortAmount * foreignAmount >
|
||||
minimumAmountSellTrades[selectedCoin]?.value
|
||||
)
|
||||
}
|
||||
autoFocus
|
||||
onClick={createSellOrder}
|
||||
>
|
||||
Create sell order
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</BootstrapDialog>
|
||||
<Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} open={openAlert} onClose={handleCloseAlert}>
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
|
||||
open={openAlert}
|
||||
onClose={handleCloseAlert}
|
||||
>
|
||||
<Alert
|
||||
|
||||
|
||||
onClose={handleCloseAlert}
|
||||
severity={info?.type}
|
||||
variant="filled"
|
||||
sx={{ width: '100%' }}
|
||||
sx={{ width: "100%" }}
|
||||
>
|
||||
{info?.message}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -9,8 +9,15 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { autoSizeStrategy, baseLocalHost } from "../Grids/TradeOffers";
|
||||
import { Alert, Box, Snackbar, SnackbarCloseReason, Typography } from "@mui/material";
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
Snackbar,
|
||||
SnackbarCloseReason,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import gameContext from "../../contexts/gameContext";
|
||||
import { BuyContainerDivider } from "../Grids/Table-styles";
|
||||
|
||||
const defaultColDef = {
|
||||
resizable: true, // Make columns resizable by default
|
||||
@ -18,18 +25,22 @@ const defaultColDef = {
|
||||
suppressMovable: true, // Prevent columns from being movable
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
const [tradeBotList, setTradeBotList] = useState([]);
|
||||
const [selectedTrade, setSelectedTrade] = useState(null);
|
||||
const tradeBotListRef = useRef([])
|
||||
const tradeBotListRef = useRef([]);
|
||||
const offeringTrades = useRef<any[]>([]);
|
||||
const qortAddressRef = useRef(null);
|
||||
const gridRef = useRef<any>(null);
|
||||
const {updateTemporaryFailedTradeBots, fetchTemporarySellOrders, deleteTemporarySellOrder, getCoinLabel, selectedCoin} = useContext(gameContext)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [info, setInfo] = useState<any>(null)
|
||||
const {
|
||||
updateTemporaryFailedTradeBots,
|
||||
fetchTemporarySellOrders,
|
||||
deleteTemporarySellOrder,
|
||||
getCoinLabel,
|
||||
selectedCoin,
|
||||
} = useContext(gameContext);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [info, setInfo] = useState<any>(null);
|
||||
const filteredOutTradeBotListWithoutFailed = useMemo(() => {
|
||||
const list = tradeBotList.filter(
|
||||
(item) =>
|
||||
@ -37,7 +48,7 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
(failedItem) => failedItem.atAddress === item.atAddress
|
||||
)
|
||||
);
|
||||
return list
|
||||
return list;
|
||||
}, [failedTradeBots, tradeBotList]);
|
||||
|
||||
const onGridReady = useCallback((params: any) => {
|
||||
@ -48,7 +59,6 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
params.columnApi.autoSizeColumns(allColumnIds); // Automatically adjust the width to fit content
|
||||
}, []);
|
||||
|
||||
|
||||
const columnDefs: ColDef[] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
@ -91,8 +101,7 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
resizable: true,
|
||||
},
|
||||
];
|
||||
|
||||
}, [selectedCoin])
|
||||
}, [selectedCoin]);
|
||||
useEffect(() => {
|
||||
if (qortAddress) {
|
||||
qortAddressRef.current = qortAddress;
|
||||
@ -161,21 +170,23 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
|
||||
const restartTradeOffers = () => {
|
||||
if (socketRef.current) {
|
||||
socketRef.current.close(1000, 'forced'); // Close with a custom reason
|
||||
socketRef.current = null
|
||||
socketRef.current.close(1000, "forced"); // Close with a custom reason
|
||||
socketRef.current = null;
|
||||
}
|
||||
offeringTrades.current = []
|
||||
offeringTrades.current = [];
|
||||
setTradeBotList([]);
|
||||
tradeBotListRef.current = [];
|
||||
}
|
||||
};
|
||||
|
||||
const socketRef = useRef(null)
|
||||
const socketRef = useRef(null);
|
||||
|
||||
const initTradeOffersWebSocket = (restarted = false) => {
|
||||
let tradeOffersSocketCounter = 0;
|
||||
let socketTimeout: any;
|
||||
// let socketLink = `ws://127.0.0.1:12391/websockets/crosschain/tradebot?foreignBlockchain=LITECOIN`;
|
||||
let socketLink = `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${baseLocalHost}/websockets/crosschain/tradebot?foreignBlockchain=${selectedCoin}`;
|
||||
let socketLink = `${
|
||||
window.location.protocol === "https:" ? "wss:" : "ws:"
|
||||
}//${baseLocalHost}/websockets/crosschain/tradebot?foreignBlockchain=${selectedCoin}`;
|
||||
socketRef.current = new WebSocket(socketLink);
|
||||
socketRef.current.onopen = () => {
|
||||
setTimeout(pingSocket, 50);
|
||||
@ -188,8 +199,8 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
};
|
||||
socketRef.current.onclose = (event) => {
|
||||
clearTimeout(socketTimeout);
|
||||
if (event.reason === 'forced') {
|
||||
return
|
||||
if (event.reason === "forced") {
|
||||
return;
|
||||
}
|
||||
restartTradeOffersWebSocket();
|
||||
};
|
||||
@ -203,94 +214,113 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!qortAddress) return
|
||||
if(selectedCoin === null) return
|
||||
restartTradeOffers()
|
||||
if (!qortAddress) return;
|
||||
if (selectedCoin === null) return;
|
||||
restartTradeOffers();
|
||||
|
||||
setTimeout(() => {
|
||||
initTradeOffersWebSocket()
|
||||
|
||||
initTradeOffersWebSocket();
|
||||
}, 500);
|
||||
return () => {
|
||||
if (socketRef.current) {
|
||||
socketRef.current.close(1000, 'forced');
|
||||
}
|
||||
socketRef.current.close(1000, "forced");
|
||||
}
|
||||
};
|
||||
}, [qortAddress, selectedCoin]);
|
||||
|
||||
const onSelectionChanged = (event: any) => {
|
||||
const selectedRows = event.api.getSelectedRows();
|
||||
if (selectedRows[0]) {
|
||||
setSelectedTrade(selectedRows[0])
|
||||
setSelectedTrade(selectedRows[0]);
|
||||
} else {
|
||||
setSelectedTrade(null)
|
||||
setSelectedTrade(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = (
|
||||
event?: React.SyntheticEvent | Event,
|
||||
reason?: SnackbarCloseReason,
|
||||
reason?: SnackbarCloseReason
|
||||
) => {
|
||||
if (reason === 'clickaway') {
|
||||
if (reason === "clickaway") {
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
setInfo(null)
|
||||
setInfo(null);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const cancelSell = async () => {
|
||||
try {
|
||||
if(!selectedTrade) return
|
||||
setOpen(true)
|
||||
if (!selectedTrade) return;
|
||||
setOpen(true);
|
||||
|
||||
setInfo({
|
||||
type: 'info',
|
||||
message: "Attempting to cancel sell order"
|
||||
})
|
||||
const res = await qortalRequestWithTimeout({
|
||||
type: "info",
|
||||
message: "Attempting to cancel sell order",
|
||||
});
|
||||
const res = await qortalRequestWithTimeout(
|
||||
{
|
||||
action: "CANCEL_TRADE_SELL_ORDER",
|
||||
qortAmount: selectedTrade.qortAmount,
|
||||
foreignBlockchain: selectedTrade.foreignBlockchain,
|
||||
foreignAmount: selectedTrade.foreignAmount,
|
||||
atAddress: selectedTrade.atAddress
|
||||
}, 900000);
|
||||
atAddress: selectedTrade.atAddress,
|
||||
},
|
||||
900000
|
||||
);
|
||||
if (res?.signature) {
|
||||
await deleteTemporarySellOrder(selectedTrade.atAddress)
|
||||
await deleteTemporarySellOrder(selectedTrade.atAddress);
|
||||
|
||||
|
||||
setSelectedTrade(null)
|
||||
setOpen(true)
|
||||
setSelectedTrade(null);
|
||||
setOpen(true);
|
||||
setInfo({
|
||||
type: 'success',
|
||||
message: "Sell order canceled. Please wait a couple of minutes for the network to propogate the changes"
|
||||
})
|
||||
type: "success",
|
||||
message:
|
||||
"Sell order canceled. Please wait a couple of minutes for the network to propogate the changes",
|
||||
});
|
||||
}
|
||||
if (res?.error && res?.failedTradeBot) {
|
||||
setOpen(true)
|
||||
setOpen(true);
|
||||
setInfo({
|
||||
type: 'error',
|
||||
message: "Unable to cancel sell order. Please try again."
|
||||
})
|
||||
type: "error",
|
||||
message: "Unable to cancel sell order. Please try again.",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (error?.error && error?.failedTradeBot) {
|
||||
setOpen(true)
|
||||
setOpen(true);
|
||||
setInfo({
|
||||
type: 'error',
|
||||
message: "Unable to cancel sell order. Please try again."
|
||||
})
|
||||
}
|
||||
type: "error",
|
||||
message: "Unable to cancel sell order. Please try again.",
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const CancelButton = () => {
|
||||
return (
|
||||
<button disabled={!selectedTrade || selectedTrade?.status === 'PENDING'} onClick={cancelSell} style={{borderRadius: '8px', width: '150px', height:"30px", background: (!selectedTrade || selectedTrade?.status === 'PENDING') ? 'gray' : "#4D7345",
|
||||
color: 'white', cursor: (!selectedTrade || selectedTrade?.status === 'PENDING') ? 'default' : 'pointer', border: '1px solid #375232', boxShadow: '0px 2.77px 2.21px 0px #00000005'
|
||||
}}>
|
||||
<button
|
||||
disabled={!selectedTrade || selectedTrade?.status === "PENDING"}
|
||||
onClick={cancelSell}
|
||||
style={{
|
||||
borderRadius: "8px",
|
||||
width: "150px",
|
||||
height: "auto",
|
||||
minHeight: "30px",
|
||||
background:
|
||||
!selectedTrade || selectedTrade?.status === "PENDING"
|
||||
? "gray"
|
||||
: "#4D7345",
|
||||
color: "white",
|
||||
cursor:
|
||||
!selectedTrade || selectedTrade?.status === "PENDING"
|
||||
? "default"
|
||||
: "pointer",
|
||||
border: "1px solid #375232",
|
||||
boxShadow: "0px 2.77px 2.21px 0px #00000005",
|
||||
marginRight: "15px",
|
||||
}}
|
||||
>
|
||||
Cancel sell order
|
||||
</button>
|
||||
);
|
||||
@ -329,43 +359,52 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
|
||||
)} */}
|
||||
</div>
|
||||
<Box sx={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
position: 'fixed',
|
||||
bottom: '0px',
|
||||
height: '100px',
|
||||
padding: '7px',
|
||||
background: '#181d1f',
|
||||
|
||||
}}>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '5px',
|
||||
flexDirection: 'column',
|
||||
width: '100%'
|
||||
}}>
|
||||
<div
|
||||
style={{
|
||||
height: "120px",
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
width: "calc(100% - 14px)",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
position: "fixed",
|
||||
bottom: "0px",
|
||||
height: "100px",
|
||||
padding: "7px",
|
||||
background: "#323336",
|
||||
}}
|
||||
>
|
||||
<BuyContainerDivider />
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "5px",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{/* <Typography sx={{
|
||||
fontSize: '16px',
|
||||
color: 'white',
|
||||
width: 'calc(100% - 75px)'
|
||||
}}>{selectedTotalQORT?.toFixed(3)} QORT</Typography> */}
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
alignItems: 'center',
|
||||
width: 'calc(100% - 75px)'
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
width: "calc(100% - 75px)",
|
||||
}}
|
||||
>
|
||||
{/* <Typography sx={{
|
||||
fontSize: '16px',
|
||||
color: selectedTotalLTC > foreignCoinBalance ? 'red' : 'white',
|
||||
}}><span>{selectedTotalLTC?.toFixed(4)}</span> <span style={{
|
||||
marginLeft: 'auto'
|
||||
}}>LTC</span></Typography> */}
|
||||
|
||||
|
||||
</Box>
|
||||
{/* <Typography sx={{
|
||||
fontSize: '16px',
|
||||
@ -377,14 +416,16 @@ export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||
</Box>
|
||||
{CancelButton()}
|
||||
</Box>
|
||||
<Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} open={open} onClose={handleClose}>
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Alert
|
||||
|
||||
|
||||
onClose={handleClose}
|
||||
severity={info?.type}
|
||||
variant="filled"
|
||||
sx={{ width: '100%' }}
|
||||
sx={{ width: "100%" }}
|
||||
>
|
||||
{info?.message}
|
||||
</Alert>
|
||||
|
@ -69,7 +69,6 @@ export const HomeWrapper = styled(Box)({
|
||||
export const TabsContainer = styled(Box)({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "15px",
|
||||
alignItems: "flex-start",
|
||||
width: "100%",
|
||||
justifyContent: "center",
|
||||
@ -78,6 +77,7 @@ export const TabsContainer = styled(Box)({
|
||||
export const TabsRow = styled(Box)({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: "5px",
|
||||
justifyContent: "space-evenly",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#323336",
|
||||
|
@ -58,17 +58,17 @@ export const HomePage = () => {
|
||||
<Tab activeTab={mode === "buy"} onClick={() => setMode("buy")}>
|
||||
Buy QORT
|
||||
</Tab>
|
||||
<TabDivider activeTab={mode === "buy" || mode === "sell"} />
|
||||
{/* <TabDivider activeTab={mode === "buy" || mode === "sell"} /> */}
|
||||
<Tab activeTab={mode === "sell"} onClick={() => setMode("sell")}>
|
||||
Sell QORT
|
||||
</Tab>
|
||||
<TabDivider activeTab={mode === "sell" || mode === "history"} />
|
||||
<Tab
|
||||
{/* <TabDivider activeTab={mode === "sell" || mode === "history"} /> */}
|
||||
{/* <Tab
|
||||
activeTab={mode === "history"}
|
||||
onClick={() => setMode("history")}
|
||||
>
|
||||
Trade History
|
||||
</Tab>
|
||||
</Tab> */}
|
||||
</TabsRow>
|
||||
</TabsContainer>
|
||||
<div
|
||||
|
Loading…
x
Reference in New Issue
Block a user