Feat: make dashboard and machine profile page
This commit is contained in:
parent
d17ca43abb
commit
19cd086436
54 changed files with 11680 additions and 2611 deletions
|
|
@ -0,0 +1,292 @@
|
|||
import { useQuery } from '@apollo/react-hooks'
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import gql from 'graphql-tag'
|
||||
import moment from 'moment'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
|
||||
import { Label1, Label2 } from 'src/components/typography/index'
|
||||
import { ReactComponent as TriangleDown } from 'src/styling/icons/arrow/triangle_down.svg'
|
||||
import { ReactComponent as TriangleUp } from 'src/styling/icons/arrow/triangle_up.svg'
|
||||
import { fromNamespace } from 'src/utils/config'
|
||||
|
||||
import LineChart from './Graphs/RefLineChart'
|
||||
import Scatterplot from './Graphs/RefScatterplot'
|
||||
import InfoWithLabel from './InfoWithLabel'
|
||||
import Nav from './Nav'
|
||||
import styles from './SystemPerformance.styles'
|
||||
|
||||
const isNotProp = R.curry(R.compose(R.isNil, R.prop))
|
||||
const getFiats = R.map(R.prop('fiat'))
|
||||
const getProps = propName => R.map(R.prop(propName))
|
||||
const useStyles = makeStyles(styles)
|
||||
const getDateDaysAgo = (days = 0) => {
|
||||
return moment().subtract(days, 'day')
|
||||
}
|
||||
|
||||
// const now = moment()
|
||||
|
||||
const GET_DATA = gql`
|
||||
query getData {
|
||||
transactions {
|
||||
fiatCode
|
||||
fiat
|
||||
cashInFee
|
||||
commissionPercentage
|
||||
created
|
||||
txClass
|
||||
error
|
||||
}
|
||||
btcRates {
|
||||
code
|
||||
name
|
||||
rate
|
||||
}
|
||||
config
|
||||
}
|
||||
`
|
||||
|
||||
const currentTime = new Date()
|
||||
|
||||
const SystemPerformance = () => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [selectedRange, setSelectedRange] = useState('Day')
|
||||
const [transactionsToShow, setTransactionsToShow] = useState([])
|
||||
const [transactionsLastTimePeriod, setTransactionsLastTimePeriod] = useState(
|
||||
[]
|
||||
)
|
||||
|
||||
const { data, loading } = useQuery(GET_DATA)
|
||||
|
||||
const fiatLocale = fromNamespace('locale')(data?.config).fiatCurrency
|
||||
|
||||
useEffect(() => {
|
||||
const isInRange = (getLastTimePeriod = false) => t => {
|
||||
const now = moment(currentTime)
|
||||
switch (selectedRange) {
|
||||
case 'Day':
|
||||
if (getLastTimePeriod) {
|
||||
return (
|
||||
t.error === null &&
|
||||
moment(t.created).isBetween(
|
||||
getDateDaysAgo(2),
|
||||
now.subtract(25, 'hours')
|
||||
)
|
||||
)
|
||||
}
|
||||
return (
|
||||
t.error === null &&
|
||||
moment(t.created).isBetween(getDateDaysAgo(1), now)
|
||||
)
|
||||
case 'Week':
|
||||
if (getLastTimePeriod) {
|
||||
return (
|
||||
t.error === null &&
|
||||
moment(t.created).isBetween(
|
||||
getDateDaysAgo(14),
|
||||
now.subtract(24 * 7 + 1, 'hours')
|
||||
)
|
||||
)
|
||||
}
|
||||
return (
|
||||
t.error === null &&
|
||||
moment(t.created).isBetween(getDateDaysAgo(7), now)
|
||||
)
|
||||
case 'Month':
|
||||
if (getLastTimePeriod) {
|
||||
return (
|
||||
t.error === null &&
|
||||
moment(t.created).isBetween(
|
||||
getDateDaysAgo(60),
|
||||
now.subtract(24 * 30 + 1, 'hours')
|
||||
)
|
||||
)
|
||||
}
|
||||
return (
|
||||
t.error === null &&
|
||||
moment(t.created).isBetween(getDateDaysAgo(30), now)
|
||||
)
|
||||
default:
|
||||
return t.error === null && true
|
||||
}
|
||||
}
|
||||
|
||||
const convertFiatToLocale = item => {
|
||||
if (item.fiatCode === fiatLocale) return item
|
||||
const itemRate = R.find(R.propEq('code', item.fiatCode))(data.btcRates)
|
||||
const localeRate = R.find(R.propEq('code', fiatLocale))(data.btcRates)
|
||||
const multiplier = localeRate.rate / itemRate.rate
|
||||
return { ...item, fiat: parseFloat(item.fiat) * multiplier }
|
||||
}
|
||||
|
||||
setTransactionsToShow(
|
||||
R.map(convertFiatToLocale)(
|
||||
R.filter(isInRange(false), data?.transactions ?? [])
|
||||
)
|
||||
)
|
||||
setTransactionsLastTimePeriod(
|
||||
R.map(convertFiatToLocale)(
|
||||
R.filter(isInRange(true), data?.transactions ?? [])
|
||||
)
|
||||
)
|
||||
}, [data, fiatLocale, selectedRange])
|
||||
|
||||
const handleSetRange = range => {
|
||||
setSelectedRange(range)
|
||||
}
|
||||
|
||||
const getNumTransactions = () => {
|
||||
return R.length(R.filter(isNotProp('error'), transactionsToShow))
|
||||
}
|
||||
|
||||
const getFiatVolume = () => {
|
||||
// for explanation check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
|
||||
return +(
|
||||
Math.round(
|
||||
R.sum(getFiats(R.filter(isNotProp('error'), transactionsToShow))) +
|
||||
'e+2'
|
||||
) + 'e-2'
|
||||
)
|
||||
}
|
||||
|
||||
const getProfit = (transactions = transactionsToShow) => {
|
||||
const cashInFees = R.sum(
|
||||
getProps('cashInFee')(R.filter(isNotProp('error'), transactions))
|
||||
)
|
||||
let commissionFees = 0
|
||||
transactions.forEach(t => {
|
||||
if (t.error === null) {
|
||||
commissionFees +=
|
||||
Number.parseFloat(t.commissionPercentage) * Number.parseFloat(t.fiat)
|
||||
}
|
||||
})
|
||||
return +(Math.round(commissionFees + cashInFees + 'e+2') + 'e-2')
|
||||
}
|
||||
|
||||
const getPercentChange = () => {
|
||||
const thisTimePeriodProfit = getProfit(transactionsToShow)
|
||||
const previousTimePeriodProfit = getProfit(transactionsLastTimePeriod)
|
||||
if (previousTimePeriodProfit === 0) {
|
||||
return 100
|
||||
}
|
||||
return Math.round(
|
||||
(100 * (thisTimePeriodProfit - previousTimePeriodProfit)) /
|
||||
Math.abs(previousTimePeriodProfit)
|
||||
)
|
||||
}
|
||||
|
||||
const getDirectionPercent = () => {
|
||||
const directions = {
|
||||
cashIn: 0,
|
||||
cashOut: 0,
|
||||
length: 0
|
||||
}
|
||||
transactionsToShow.forEach(t => {
|
||||
if (t.error === null) {
|
||||
switch (t.txClass) {
|
||||
case 'cashIn':
|
||||
directions.cashIn += 1
|
||||
directions.length += 1
|
||||
break
|
||||
case 'cashOut':
|
||||
directions.cashOut += 1
|
||||
directions.length += 1
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
return {
|
||||
cashIn:
|
||||
directions.length > 0
|
||||
? Math.round((directions.cashIn / directions.length) * 100)
|
||||
: 0,
|
||||
cashOut:
|
||||
directions.length > 0
|
||||
? Math.round((directions.cashOut / directions.length) * 100)
|
||||
: 0
|
||||
}
|
||||
}
|
||||
|
||||
const percentChange = getPercentChange()
|
||||
|
||||
return (
|
||||
<>
|
||||
<Nav handleSetRange={handleSetRange} />
|
||||
{!loading && (
|
||||
<>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={3}>
|
||||
<InfoWithLabel
|
||||
info={getNumTransactions()}
|
||||
label={'transactions'}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<InfoWithLabel
|
||||
info={getFiatVolume()}
|
||||
label={`${data?.config.locale_fiatCurrency} volume`}
|
||||
/>
|
||||
</Grid>
|
||||
{/* todo new customers */}
|
||||
</Grid>
|
||||
<Grid container style={{ marginTop: 30 }}>
|
||||
<Grid item xs={12}>
|
||||
<Label2>Transactions</Label2>
|
||||
<Scatterplot
|
||||
timeFrame={selectedRange}
|
||||
data={transactionsToShow}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container style={{ marginTop: 30 }}>
|
||||
<Grid item xs={8}>
|
||||
<Label2>Profit from commissions</Label2>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
margin: '0 26px -30px 16px',
|
||||
position: 'relative'
|
||||
}}>
|
||||
<div className={classes.profitLabel}>
|
||||
{`${getProfit()} ${data?.config.locale_fiatCurrency}`}
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
percentChange <= 0 ? classes.percentDown : classes.percentUp
|
||||
}>
|
||||
{percentChange <= 0 ? (
|
||||
<TriangleDown style={{ height: 13 }} />
|
||||
) : (
|
||||
<TriangleUp style={{ height: 10 }} />
|
||||
)}{' '}
|
||||
{`${percentChange}%`}
|
||||
</div>
|
||||
</div>
|
||||
<LineChart timeFrame={selectedRange} data={transactionsToShow} />
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<Label2>Direction</Label2>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
<Label1>CashIn: </Label1>
|
||||
{` ${getDirectionPercent().cashIn}%`}
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Label1>CashOut: </Label1>
|
||||
{` ${getDirectionPercent().cashOut}%`}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SystemPerformance
|
||||
Loading…
Add table
Add a link
Reference in a new issue