mirror of
https://github.com/Qortal/q-trade.git
synced 2025-06-15 10:51:21 +00:00
Merge branch 'qortal-master' of https://github.com/Qortal/q-trade into justin/redesign
This commit is contained in:
commit
2fe23b439b
106
package-lock.json
generated
106
package-lock.json
generated
@ -19,8 +19,10 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-countdown-circle-timer": "^3.2.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-ga4": "^2.1.0",
|
"react-ga4": "^2.1.0",
|
||||||
|
"react-loader-spinner": "^6.1.6",
|
||||||
"react-router-dom": "^6.23.0",
|
"react-router-dom": "^6.23.0",
|
||||||
"react-toastify": "^10.0.5",
|
"react-toastify": "^10.0.5",
|
||||||
"sass": "^1.76.0",
|
"sass": "^1.76.0",
|
||||||
@ -3236,6 +3238,11 @@
|
|||||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/stylis": {
|
||||||
|
"version": "4.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
|
||||||
|
"integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw=="
|
||||||
|
},
|
||||||
"node_modules/@types/trusted-types": {
|
"node_modules/@types/trusted-types": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||||
@ -3826,6 +3833,14 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/camelize": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001660",
|
"version": "1.0.30001660",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz",
|
||||||
@ -4003,6 +4018,24 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/css-color-keywords": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/css-to-react-native": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"camelize": "^1.0.0",
|
||||||
|
"css-color-keywords": "^1.0.0",
|
||||||
|
"postcss-value-parser": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
@ -5984,7 +6017,6 @@
|
|||||||
"version": "3.3.7",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -6218,7 +6250,6 @@
|
|||||||
"version": "8.4.38",
|
"version": "8.4.38",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
|
||||||
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
|
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -6242,6 +6273,11 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/postcss-value-parser": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||||
|
},
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@ -6332,6 +6368,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-countdown-circle-timer": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-countdown-circle-timer/-/react-countdown-circle-timer-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-yBAy/9ILXOiFbLBM+3jS72TW5LeRcH8wkRC9NNqMpUkCXkGjSnaeRbJMsR9lsYF0oVXjSDbJaRbCuVMT+9HnKA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "18.2.0",
|
"version": "18.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||||
@ -6354,6 +6398,22 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-loader-spinner": {
|
||||||
|
"version": "6.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-6.1.6.tgz",
|
||||||
|
"integrity": "sha512-x5h1Jcit7Qn03MuKlrWcMG9o12cp9SNDVHVJTNRi9TgtGPKcjKiXkou4NRfLAtXaFB3+Z8yZsVzONmPzhv2ErA==",
|
||||||
|
"dependencies": {
|
||||||
|
"react-is": "^18.2.0",
|
||||||
|
"styled-components": "^6.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
|
||||||
@ -6788,6 +6848,11 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/shallowequal": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@ -7041,6 +7106,38 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/styled-components": {
|
||||||
|
"version": "6.1.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz",
|
||||||
|
"integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/is-prop-valid": "1.2.2",
|
||||||
|
"@emotion/unitless": "0.8.1",
|
||||||
|
"@types/stylis": "4.2.5",
|
||||||
|
"css-to-react-native": "3.2.0",
|
||||||
|
"csstype": "3.1.3",
|
||||||
|
"postcss": "8.4.38",
|
||||||
|
"shallowequal": "1.1.0",
|
||||||
|
"stylis": "4.3.2",
|
||||||
|
"tslib": "2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/styled-components"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 16.8.0",
|
||||||
|
"react-dom": ">= 16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/styled-components/node_modules/stylis": {
|
||||||
|
"version": "4.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
|
||||||
|
"integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg=="
|
||||||
|
},
|
||||||
"node_modules/stylis": {
|
"node_modules/stylis": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
||||||
@ -7210,6 +7307,11 @@
|
|||||||
"typescript": ">=4.2.0"
|
"typescript": ">=4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||||
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
@ -21,8 +21,10 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-countdown-circle-timer": "^3.2.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-ga4": "^2.1.0",
|
"react-ga4": "^2.1.0",
|
||||||
|
"react-loader-spinner": "^6.1.6",
|
||||||
"react-router-dom": "^6.23.0",
|
"react-router-dom": "^6.23.0",
|
||||||
"react-toastify": "^10.0.5",
|
"react-toastify": "^10.0.5",
|
||||||
"sass": "^1.76.0",
|
"sass": "^1.76.0",
|
||||||
|
File diff suppressed because it is too large
Load Diff
110
src/components/history/History.tsx
Normal file
110
src/components/history/History.tsx
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import { Alert, Box, Button, ButtonBase, DialogActions, DialogContent, DialogTitle, IconButton, InputLabel, Snackbar, SnackbarCloseReason, TextField, Typography, styled } from '@mui/material'
|
||||||
|
import React, { useCallback, useContext, useEffect, useMemo, 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 HistoryList from './HistoryList';
|
||||||
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const History = ({qortAddress, show}) => {
|
||||||
|
const [buyHistory, setBuyHistory] = useState({})
|
||||||
|
const [sellHistory, setSellHistory] = useState({})
|
||||||
|
|
||||||
|
const { getCoinLabel, selectedCoin} = useContext(gameContext)
|
||||||
|
const [mode, setMode] = useState('buyHistory')
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
|
const selectedHistory = useMemo(()=> {
|
||||||
|
if(mode === 'buyHistory') return buyHistory[selectedCoin] || []
|
||||||
|
if(mode === 'sellHistory') return sellHistory[selectedCoin] || []
|
||||||
|
}, [selectedCoin, buyHistory, sellHistory, mode])
|
||||||
|
const getBuyHistory = useCallback((address, foreignBlockchain, mode, limit = 20)=> {
|
||||||
|
setOpen(true)
|
||||||
|
let historyUrl
|
||||||
|
if(mode === 'buyHistory'){
|
||||||
|
historyUrl = `/crosschain/trades?foreignBlockchain=${foreignBlockchain}&buyerAddress=${address}&limit=${limit}&reverse=true`;
|
||||||
|
|
||||||
|
}
|
||||||
|
if(mode === 'sellHistory'){
|
||||||
|
historyUrl = `/crosschain/trades?foreignBlockchain=${foreignBlockchain}&sellerAddress=${address}&limit=${limit}&reverse=true`;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fetch(historyUrl)
|
||||||
|
.then((response) => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if(mode === 'buyHistory'){
|
||||||
|
setBuyHistory((prev)=> {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
[foreignBlockchain]: data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(mode === 'sellHistory'){
|
||||||
|
setSellHistory((prev)=> {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
[foreignBlockchain]: data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch(()=> {}).finally(()=> {
|
||||||
|
setOpen(false)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(()=> {
|
||||||
|
if(!qortAddress || !selectedCoin) return
|
||||||
|
if(mode === 'buyHistory' && buyHistory[selectedCoin])return
|
||||||
|
if(mode === 'sellHistory' && sellHistory[selectedCoin])return
|
||||||
|
|
||||||
|
getBuyHistory(qortAddress, selectedCoin, mode)
|
||||||
|
}, [qortAddress, selectedCoin, buyHistory, mode])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
width: '100%',
|
||||||
|
display: show ? 'block' : 'none'
|
||||||
|
}}>
|
||||||
|
<Button variant='outlined' onClick={()=> {
|
||||||
|
setMode('buyHistory')
|
||||||
|
}}>Buy History</Button>
|
||||||
|
<Button onClick={()=> {
|
||||||
|
setMode('sellHistory')
|
||||||
|
}} variant='outlined'>Sell History</Button>
|
||||||
|
<ButtonBase onClick={()=> {
|
||||||
|
getBuyHistory(qortAddress, selectedCoin, mode)
|
||||||
|
}}>
|
||||||
|
<RefreshIcon />
|
||||||
|
</ButtonBase>
|
||||||
|
<Typography>Showing most recent 20 results</Typography>
|
||||||
|
<HistoryList qortAddress={qortAddress} historyList={selectedHistory} />
|
||||||
|
<Snackbar
|
||||||
|
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
|
||||||
|
open={open}
|
||||||
|
onClose={()=> {
|
||||||
|
setOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Alert
|
||||||
|
onClose={()=> setOpen(false)}
|
||||||
|
severity="info"
|
||||||
|
variant="filled"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
{'Fetching History'}
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
190
src/components/history/HistoryList.tsx
Normal file
190
src/components/history/HistoryList.tsx
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
import { ColDef } from "ag-grid-community";
|
||||||
|
import { AgGridReact } from "ag-grid-react";
|
||||||
|
import React, {
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import { autoSizeStrategy, baseLocalHost } from "../Grids/TradeOffers";
|
||||||
|
import { Alert, Box, Snackbar, SnackbarCloseReason, Typography } from "@mui/material";
|
||||||
|
import gameContext from "../../contexts/gameContext";
|
||||||
|
import { formatTimestampForum } from "../../utils/formatTime";
|
||||||
|
|
||||||
|
const defaultColDef = {
|
||||||
|
resizable: true, // Make columns resizable by default
|
||||||
|
sortable: true, // Make columns sortable by default
|
||||||
|
suppressMovable: true, // Prevent columns from being movable
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function HistoryList({ qortAddress, historyList }) {
|
||||||
|
const gridRef = useRef<any>(null);
|
||||||
|
console.log('historyList', historyList)
|
||||||
|
const { getCoinLabel, selectedCoin} = useContext(gameContext)
|
||||||
|
const [qortalNames, setQortalNames] = useState({});
|
||||||
|
|
||||||
|
|
||||||
|
const onGridReady = useCallback((params: any) => {
|
||||||
|
params.api.sizeColumnsToFit(); // Adjust columns to fit the grid width
|
||||||
|
const allColumnIds = params.columnApi
|
||||||
|
.getAllColumns()
|
||||||
|
.map((col: any) => col.getColId());
|
||||||
|
params.columnApi.autoSizeColumns(allColumnIds); // Automatically adjust the width to fit content
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getName = async (address) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/names/address/" + address);
|
||||||
|
const nameData = await response.json();
|
||||||
|
if (nameData?.length > 0) {
|
||||||
|
setQortalNames((prev) => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
[address]: nameData[0].name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setQortalNames((prev) => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
[address]: null,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const columnDefs: ColDef[] = useMemo(()=> {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
headerName: "QORT AMOUNT",
|
||||||
|
field: "qortAmount",
|
||||||
|
flex: 1, // Flex makes this column responsive
|
||||||
|
minWidth: 150, // Ensure it doesn't shrink too much
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: `${getCoinLabel()}/QORT`,
|
||||||
|
valueGetter: (params) =>
|
||||||
|
+params.data.foreignAmount / +params.data.qortAmount,
|
||||||
|
sortable: true,
|
||||||
|
flex: 1, // Flex makes this column responsive
|
||||||
|
minWidth: 150, // Ensure it doesn't shrink too much
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: `Total ${getCoinLabel()} Value`,
|
||||||
|
field: "foreignAmount",
|
||||||
|
flex: 1, // Flex makes this column responsive
|
||||||
|
minWidth: 150, // Ensure it doesn't shrink too much
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "Time",
|
||||||
|
field: "tradeTimestamp",
|
||||||
|
valueGetter: (params) =>
|
||||||
|
formatTimestampForum(params.data.tradeTimestamp),
|
||||||
|
flex: 1, // Flex makes this column responsive
|
||||||
|
minWidth: 200, // Ensure it doesn't shrink too much
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "Buyer",
|
||||||
|
field: "buyerReceivingAddress",
|
||||||
|
flex: 1, // Flex makes this column responsive
|
||||||
|
minWidth: 200, // Ensure it doesn't shrink too much
|
||||||
|
resizable: true,
|
||||||
|
valueGetter: (params) => {
|
||||||
|
if (params?.data?.buyerReceivingAddress) {
|
||||||
|
if (qortalNames[params?.data?.buyerReceivingAddress]) {
|
||||||
|
return qortalNames[params?.data?.buyerReceivingAddress];
|
||||||
|
} else if (qortalNames[params?.data?.buyerReceivingAddress] === undefined) {
|
||||||
|
getName(params?.data?.buyerReceivingAddress);
|
||||||
|
|
||||||
|
return params?.data?.buyerReceivingAddress;
|
||||||
|
} else {
|
||||||
|
return params?.data?.buyerReceivingAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "Seller",
|
||||||
|
field: "sellerAddress",
|
||||||
|
flex: 1, // Flex makes this column responsive
|
||||||
|
minWidth: 200, // Ensure it doesn't shrink too much
|
||||||
|
resizable: true,
|
||||||
|
valueGetter: (params) => {
|
||||||
|
if (params?.data?.sellerAddress) {
|
||||||
|
if (qortalNames[params?.data?.sellerAddress]) {
|
||||||
|
return qortalNames[params?.data?.sellerAddress];
|
||||||
|
} else if (qortalNames[params?.data?.sellerAddress] === undefined) {
|
||||||
|
getName(params?.data?.sellerAddress);
|
||||||
|
|
||||||
|
return params?.data?.sellerAddress;
|
||||||
|
} else {
|
||||||
|
return params?.data?.sellerAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
}, [selectedCoin, qortalNames])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// const onSelectionChanged = (event: any) => {
|
||||||
|
// const selectedRows = event.api.getSelectedRows();
|
||||||
|
// if(selectedRows[0]){
|
||||||
|
// setSelectedTrade(selectedRows[0])
|
||||||
|
// } else {
|
||||||
|
// setSelectedTrade(null)
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ag-theme-alpine-dark"
|
||||||
|
style={{ height: 400, width: "100%" }}
|
||||||
|
>
|
||||||
|
<AgGridReact
|
||||||
|
ref={gridRef}
|
||||||
|
columnDefs={columnDefs}
|
||||||
|
defaultColDef={defaultColDef}
|
||||||
|
rowData={historyList}
|
||||||
|
// onRowClicked={onRowClicked}
|
||||||
|
// onSelectionChanged={onSelectionChanged}
|
||||||
|
// getRowStyle={getRowStyle}
|
||||||
|
autoSizeStrategy={autoSizeStrategy}
|
||||||
|
rowSelection="single" // Enable multi-select
|
||||||
|
suppressHorizontalScroll={false} // Allow horizontal scroll on mobile if needed
|
||||||
|
suppressCellFocus={true} // Prevents cells from stealing focus in mobile
|
||||||
|
// pagination={true}
|
||||||
|
// paginationPageSize={10}
|
||||||
|
onGridReady={onGridReady}
|
||||||
|
// domLayout='autoHeight'
|
||||||
|
// getRowId={(params) => params.data.qortalAtAddress} // Ensure rows have unique IDs
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -232,7 +232,7 @@ export const CreateSell = ({qortAddress, show}) => {
|
|||||||
/>
|
/>
|
||||||
<Spacer height="6px" />
|
<Spacer height="6px" />
|
||||||
<CustomLabel htmlFor="standard-adornment-amount">
|
<CustomLabel htmlFor="standard-adornment-amount">
|
||||||
{`Price Each (${getCoinLabel()})`}
|
{`Price of Each QORT (in ${getCoinLabel()})`}
|
||||||
</CustomLabel>
|
</CustomLabel>
|
||||||
<Spacer height="5px" />
|
<Spacer height="5px" />
|
||||||
<CustomInput
|
<CustomInput
|
||||||
@ -245,7 +245,7 @@ export const CreateSell = ({qortAddress, show}) => {
|
|||||||
<Spacer height="6px" />
|
<Spacer height="6px" />
|
||||||
<Typography>{`${qortAmount * foreignAmount} ${getCoinLabel()}`} for {qortAmount} QORT</Typography>
|
<Typography>{`${qortAmount * foreignAmount} ${getCoinLabel()}`} for {qortAmount} QORT</Typography>
|
||||||
<Typography sx={{
|
<Typography sx={{
|
||||||
fontSize: '12px'
|
fontSize: '14px'
|
||||||
}}>Total sell amount needs to be greater than: {minimumAmountSellTrades[selectedCoin]?.value} {' '} {minimumAmountSellTrades[selectedCoin]?.ticker}</Typography>
|
}}>Total sell amount needs to be greater than: {minimumAmountSellTrades[selectedCoin]?.value} {' '} {minimumAmountSellTrades[selectedCoin]?.ticker}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
@ -18,47 +18,7 @@ const defaultColDef = {
|
|||||||
suppressMovable: true, // Prevent columns from being movable
|
suppressMovable: true, // Prevent columns from being movable
|
||||||
};
|
};
|
||||||
|
|
||||||
// const columnDefs: ColDef[] = [
|
|
||||||
// {
|
|
||||||
// headerCheckboxSelection: false, // Adds a checkbox in the header for selecting all rows
|
|
||||||
// checkboxSelection: true, // Adds checkboxes in each row for selection
|
|
||||||
// headerName: "Select", // You can customize the header name
|
|
||||||
// width: 50, // Adjust the width as needed
|
|
||||||
// pinned: "left", // Optional, to pin this column on the left
|
|
||||||
// resizable: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// headerName: "QORT AMOUNT",
|
|
||||||
// field: "qortAmount",
|
|
||||||
// flex: 1, // Flex makes this column responsive
|
|
||||||
// minWidth: 150, // Ensure it doesn't shrink too much
|
|
||||||
// resizable: true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// headerName: "LTC/QORT",
|
|
||||||
// valueGetter: (params) =>
|
|
||||||
// +params.data.foreignAmount / +params.data.qortAmount,
|
|
||||||
// sortable: true,
|
|
||||||
// sort: "asc",
|
|
||||||
// flex: 1, // Flex makes this column responsive
|
|
||||||
// minWidth: 150, // Ensure it doesn't shrink too much
|
|
||||||
// resizable: true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// headerName: "Total LTC Value",
|
|
||||||
// field: "foreignAmount",
|
|
||||||
// flex: 1, // Flex makes this column responsive
|
|
||||||
// minWidth: 150, // Ensure it doesn't shrink too much
|
|
||||||
// resizable: true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// headerName: "Status",
|
|
||||||
// field: "status",
|
|
||||||
// flex: 1, // Flex makes this column responsive
|
|
||||||
// minWidth: 300, // Ensure it doesn't shrink too much
|
|
||||||
// resizable: true,
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
export default function TradeBotList({ qortAddress, failedTradeBots }) {
|
||||||
const [tradeBotList, setTradeBotList] = useState([]);
|
const [tradeBotList, setTradeBotList] = useState([]);
|
||||||
|
@ -11,6 +11,7 @@ import { Spacer } from "../../components/common/Spacer";
|
|||||||
import { ReusableModal } from "../../components/common/reusable-modal/ReusableModal";
|
import { ReusableModal } from "../../components/common/reusable-modal/ReusableModal";
|
||||||
import { Tab, TabDivider, TabsContainer, TabsRow } from "./Home-Styles";
|
import { Tab, TabDivider, TabsContainer, TabsRow } from "./Home-Styles";
|
||||||
import { CreateSell } from "../../components/sell/CreateSell";
|
import { CreateSell } from "../../components/sell/CreateSell";
|
||||||
|
import { History } from "../../components/history/History";
|
||||||
|
|
||||||
export const HomePage = () => {
|
export const HomePage = () => {
|
||||||
const {
|
const {
|
||||||
@ -22,7 +23,8 @@ export const HomePage = () => {
|
|||||||
onGoingTrades,
|
onGoingTrades,
|
||||||
selectedCoin,
|
selectedCoin,
|
||||||
} = useContext(gameContext);
|
} = useContext(gameContext);
|
||||||
const [mode, setMode] = useState("buy");
|
const { setNotification } = useContext(NotificationContext);
|
||||||
|
const [mode, setMode] = useState("history");
|
||||||
const filteredOngoingTrades = useMemo(() => {
|
const filteredOngoingTrades = useMemo(() => {
|
||||||
return onGoingTrades?.filter(
|
return onGoingTrades?.filter(
|
||||||
(item) => item?.tradeInfo?.foreignBlockchain === selectedCoin
|
(item) => item?.tradeInfo?.foreignBlockchain === selectedCoin
|
||||||
@ -111,6 +113,7 @@ export const HomePage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CreateSell show={mode === "sell"} qortAddress={userInfo?.address} />
|
<CreateSell show={mode === "sell"} qortAddress={userInfo?.address} />
|
||||||
|
<History show={mode === "history"} qortAddress={userInfo?.address} />
|
||||||
</AppContainer>
|
</AppContainer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,25 @@
|
|||||||
|
import moment from "moment";
|
||||||
|
|
||||||
export function formatTime(seconds: number): string {
|
export function formatTime(seconds: number): string {
|
||||||
const minutes = Math.floor(seconds / 60);
|
const minutes = Math.floor(seconds / 60);
|
||||||
const remainingSeconds = seconds % 60;
|
const remainingSeconds = seconds % 60;
|
||||||
// Pad the seconds with a leading zero if less than 10
|
// Pad the seconds with a leading zero if less than 10
|
||||||
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function formatTimestampForum(timestamp: number): string {
|
||||||
|
const now = moment();
|
||||||
|
const timestampMoment = moment(timestamp);
|
||||||
|
const elapsedTime = now.diff(timestampMoment, 'minutes');
|
||||||
|
|
||||||
|
if (elapsedTime < 1) {
|
||||||
|
return `Just now - ${timestampMoment.format('h:mm A')}`;
|
||||||
|
} else if (elapsedTime < 60) {
|
||||||
|
return `${elapsedTime}m ago - ${timestampMoment.format('h:mm A')}`;
|
||||||
|
} else if (elapsedTime < 1440) {
|
||||||
|
return `${Math.floor(elapsedTime / 60)}h ago - ${timestampMoment.format('h:mm A')}`;
|
||||||
|
} else {
|
||||||
|
return timestampMoment.format('MMM D, YYYY - h:mm A');
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user