mirror of
https://github.com/joinmarket-webui/jam.git
synced 2026-08-17 13:07:34 +02:00
feat: display basic yield generator report (#73)
* feat: display basic yield generator report * feat: add toggle for yield generator report * review: use button instead of toggle to show/hide report * review: better message on yield generator report error
This commit is contained in:
parent
174726b74f
commit
b37de7083e
2 changed files with 177 additions and 69 deletions
|
|
@ -1,20 +1,67 @@
|
|||
import React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import * as rb from 'react-bootstrap'
|
||||
import { useSettings } from '../context/SettingsContext'
|
||||
import Sprite from './Sprite'
|
||||
import * as Api from '../libs/JmWalletApi'
|
||||
|
||||
const OFFERTYPE_REL = 'sw0reloffer'
|
||||
const OFFERTYPE_ABS = 'sw0absoffer'
|
||||
|
||||
const YieldgenReport = ({ lines }) => {
|
||||
const settings = useSettings()
|
||||
|
||||
const empty = !lines || lines.length < 2
|
||||
const headers = empty ? [] : lines[0].split(',')
|
||||
const linesWithoutHeader = empty
|
||||
? []
|
||||
: lines
|
||||
.slice(1, lines.length)
|
||||
.map((line) => line.split(','))
|
||||
.reverse()
|
||||
|
||||
return (
|
||||
<div className="mt-2 mb-3">
|
||||
{empty && <rb.Alert variant="info">The report is empty.</rb.Alert>}
|
||||
{!empty && (
|
||||
<>
|
||||
<rb.Table striped bordered hover variant={settings.theme} responsive>
|
||||
<thead>
|
||||
<tr>
|
||||
{headers.map((name, index) => (
|
||||
<th key={`header_${index}`}>{name}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{linesWithoutHeader.map((line, lineIndex) => (
|
||||
<tr key={lineIndex}>
|
||||
{line.map((val, valIndex) => (
|
||||
<td key={valIndex}>{val}</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</rb.Table>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Earn({ currentWallet, makerRunning }) {
|
||||
const settings = useSettings()
|
||||
const [validated, setValidated] = useState(false)
|
||||
const [alert, setAlert] = useState(null)
|
||||
const [isSending, setIsSending] = useState(false)
|
||||
const [isWaiting, setIsWaiting] = useState(false)
|
||||
const [isReportLoading, setIsReportLoading] = useState(false)
|
||||
const [isShowReport, setIsShowReport] = useState(false)
|
||||
const [offertype, setOffertype] = useState(window.localStorage.getItem('jm-offertype') || OFFERTYPE_REL)
|
||||
const [feeRel, setFeeRel] = useState(parseFloat(window.localStorage.getItem('jm-feeRel')) || 0.0003)
|
||||
const [feeAbs, setFeeAbs] = useState(parseInt(window.localStorage.getItem('jm-feeAbs'), 10) || 250)
|
||||
const [minsize, setMinsize] = useState(parseInt(window.localStorage.getItem('jm-minsize'), 10) || 100000)
|
||||
const [yieldgenReportLines, setYieldgenReportLines] = useState([])
|
||||
|
||||
const setAndPersistOffertype = (value) => {
|
||||
setOffertype(value)
|
||||
|
|
@ -74,6 +121,30 @@ export default function Earn({ currentWallet, makerRunning }) {
|
|||
setAlert(null)
|
||||
}, [makerRunning])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isShowReport) return
|
||||
|
||||
const abortCtrl = new AbortController()
|
||||
setIsReportLoading(true)
|
||||
|
||||
Api.getYieldgenReport({ signal: abortCtrl.signal })
|
||||
.then((res) => {
|
||||
if (res.ok) return res.json()
|
||||
// 404 is returned till the maker is started at least once
|
||||
if (res.status === 404) return {}
|
||||
return Promise.reject(new Error(res.message || 'Failed to load yield generator report.'))
|
||||
})
|
||||
.then((data) => setYieldgenReportLines(data.yigen_data))
|
||||
.catch((err) => {
|
||||
console.log(`Error while loading yield generator`, err)
|
||||
})
|
||||
// show the loader a little longer to avoid flickering
|
||||
.then((_) => new Promise((r) => setTimeout(r, 200)))
|
||||
.finally(() => setIsReportLoading(false))
|
||||
|
||||
return () => abortCtrl.abort()
|
||||
}, [makerRunning, isShowReport])
|
||||
|
||||
const stopMakerService = async () => {
|
||||
const { name: walletName, token } = currentWallet
|
||||
|
||||
|
|
@ -118,79 +189,109 @@ export default function Earn({ currentWallet, makerRunning }) {
|
|||
const isRelOffer = offertype === OFFERTYPE_REL
|
||||
|
||||
return (
|
||||
<rb.Form onSubmit={onSubmit} validated={validated} noValidate>
|
||||
<>
|
||||
{alert && <rb.Alert variant={alert.variant}>{alert.message}</rb.Alert>}
|
||||
<p>Service {makerRunning ? 'running' : 'not running'}.</p>
|
||||
{!makerRunning && !isWaiting && (
|
||||
<>
|
||||
<rb.Form.Group className="mb-3" controlId="offertype">
|
||||
<rb.Form.Check
|
||||
type="switch"
|
||||
label="Relative offer"
|
||||
checked={isRelOffer}
|
||||
onChange={(e) => setAndPersistOffertype(e.target.checked ? OFFERTYPE_REL : OFFERTYPE_ABS)}
|
||||
/>
|
||||
</rb.Form.Group>
|
||||
{isRelOffer ? (
|
||||
<rb.Form.Group className="mb-3" controlId="feeRel">
|
||||
<rb.Form.Label>Relative Fee (percent)</rb.Form.Label>
|
||||
<rb.Form.Control
|
||||
type="number"
|
||||
name="feeRel"
|
||||
required
|
||||
step={0.0001}
|
||||
value={feeRel}
|
||||
min={0}
|
||||
max={0.1}
|
||||
style={{ width: '16ch' }}
|
||||
onChange={(e) => setAndPersistFeeRel(e.target.value)}
|
||||
/>
|
||||
<rb.Form.Control.Feedback type="invalid">Please provide a relative fee.</rb.Form.Control.Feedback>
|
||||
</rb.Form.Group>
|
||||
) : (
|
||||
<rb.Form.Group className="mb-3" controlId="feeAbs">
|
||||
<rb.Form.Label>Absolute Fee in SATS</rb.Form.Label>
|
||||
<rb.Form.Control
|
||||
type="number"
|
||||
name="feeAbs"
|
||||
required
|
||||
step={1}
|
||||
value={feeAbs}
|
||||
min={0}
|
||||
style={{ width: '16ch' }}
|
||||
onChange={(e) => setAndPersistFeeAbs(e.target.value)}
|
||||
/>
|
||||
<rb.Form.Control.Feedback type="invalid">Please provide an absolute fee.</rb.Form.Control.Feedback>
|
||||
</rb.Form.Group>
|
||||
)}
|
||||
<rb.Form.Group className="mb-3" controlId="minsize">
|
||||
<rb.Form.Label>Minimum amount in SATS</rb.Form.Label>
|
||||
<rb.Form.Control
|
||||
type="number"
|
||||
name="minsize"
|
||||
required
|
||||
step={1000}
|
||||
value={minsize}
|
||||
min={0}
|
||||
style={{ width: '16ch' }}
|
||||
onChange={(e) => setAndPersistMinsize(e.target.value)}
|
||||
/>
|
||||
<rb.Form.Control.Feedback type="invalid">Please provide a minimum amount.</rb.Form.Control.Feedback>
|
||||
</rb.Form.Group>
|
||||
</>
|
||||
)}
|
||||
<rb.Button variant="dark" type="submit" disabled={isSending}>
|
||||
{isSending ? (
|
||||
<rb.Form onSubmit={onSubmit} validated={validated} noValidate>
|
||||
{!makerRunning && !isWaiting && (
|
||||
<>
|
||||
<rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
|
||||
{makerRunning === true ? 'Stopping' : 'Starting'}
|
||||
<rb.Form.Group className="mb-3" controlId="offertype">
|
||||
<rb.Form.Check
|
||||
type="switch"
|
||||
label="Relative offer"
|
||||
checked={isRelOffer}
|
||||
onChange={(e) => setAndPersistOffertype(e.target.checked ? OFFERTYPE_REL : OFFERTYPE_ABS)}
|
||||
/>
|
||||
</rb.Form.Group>
|
||||
{isRelOffer ? (
|
||||
<rb.Form.Group className="mb-3" controlId="feeRel">
|
||||
<rb.Form.Label>Relative Fee (percent)</rb.Form.Label>
|
||||
<rb.Form.Control
|
||||
type="number"
|
||||
name="feeRel"
|
||||
required
|
||||
step={0.0001}
|
||||
value={feeRel}
|
||||
min={0}
|
||||
max={0.1}
|
||||
style={{ width: '16ch' }}
|
||||
onChange={(e) => setAndPersistFeeRel(e.target.value)}
|
||||
/>
|
||||
<rb.Form.Control.Feedback type="invalid">Please provide a relative fee.</rb.Form.Control.Feedback>
|
||||
</rb.Form.Group>
|
||||
) : (
|
||||
<rb.Form.Group className="mb-3" controlId="feeAbs">
|
||||
<rb.Form.Label>Absolute Fee in SATS</rb.Form.Label>
|
||||
<rb.Form.Control
|
||||
type="number"
|
||||
name="feeAbs"
|
||||
required
|
||||
step={1}
|
||||
value={feeAbs}
|
||||
min={0}
|
||||
style={{ width: '16ch' }}
|
||||
onChange={(e) => setAndPersistFeeAbs(e.target.value)}
|
||||
/>
|
||||
<rb.Form.Control.Feedback type="invalid">Please provide an absolute fee.</rb.Form.Control.Feedback>
|
||||
</rb.Form.Group>
|
||||
)}
|
||||
<rb.Form.Group className="mb-3" controlId="minsize">
|
||||
<rb.Form.Label>Minimum amount in SATS</rb.Form.Label>
|
||||
<rb.Form.Control
|
||||
type="number"
|
||||
name="minsize"
|
||||
required
|
||||
step={1000}
|
||||
value={minsize}
|
||||
min={0}
|
||||
style={{ width: '16ch' }}
|
||||
onChange={(e) => setAndPersistMinsize(e.target.value)}
|
||||
/>
|
||||
<rb.Form.Control.Feedback type="invalid">Please provide a minimum amount.</rb.Form.Control.Feedback>
|
||||
</rb.Form.Group>
|
||||
</>
|
||||
) : makerRunning === true ? (
|
||||
'Stop'
|
||||
) : (
|
||||
'Start'
|
||||
)}
|
||||
</rb.Button>
|
||||
</rb.Form>
|
||||
<rb.Button variant="dark" type="submit" disabled={isSending || isWaiting}>
|
||||
{isSending ? (
|
||||
<>
|
||||
<rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
|
||||
{makerRunning === true ? 'Stopping' : 'Starting'}
|
||||
</>
|
||||
) : makerRunning === true ? (
|
||||
'Stop'
|
||||
) : (
|
||||
'Start'
|
||||
)}
|
||||
</rb.Button>
|
||||
</rb.Form>
|
||||
|
||||
{settings.useAdvancedWalletMode && (
|
||||
<div className="mt-5 mb-3 pe-3">
|
||||
<h6>Report</h6>
|
||||
<rb.Button
|
||||
variant="outline-dark"
|
||||
className="border-0 mb-2 d-inline-flex align-items-center"
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setIsShowReport(!isShowReport)
|
||||
}}
|
||||
>
|
||||
<Sprite symbol={isShowReport ? 'hide' : 'show'} width="24" height="24" className="me-2" />
|
||||
{isShowReport ? 'Hide' : 'Show'} report
|
||||
{isReportLoading && (
|
||||
<rb.Spinner
|
||||
as="span"
|
||||
animation="border"
|
||||
size="sm"
|
||||
role="status"
|
||||
aria-hidden="true"
|
||||
className="ms-2 me-1"
|
||||
/>
|
||||
)}
|
||||
</rb.Button>
|
||||
{isShowReport && <YieldgenReport lines={yieldgenReportLines} />}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,12 @@ const postCoinjoin = async ({ walletName, token }, { account, destination, amoun
|
|||
})
|
||||
}
|
||||
|
||||
const getYieldgenReport = async ({ signal }) => {
|
||||
return await fetch(`/api/v1/wallet/yieldgen/report`, {
|
||||
signal,
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
postMakerStart,
|
||||
getMakerStop,
|
||||
|
|
@ -137,4 +143,5 @@ export {
|
|||
getWalletLock,
|
||||
postWalletUnlock,
|
||||
getWalletUtxos,
|
||||
getYieldgenReport,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue