partial: Analytics css migration

This commit is contained in:
Rafael Taranto 2025-04-28 10:06:33 +01:00
parent b9b7dcdcd7
commit 92ccd8cb92
12 changed files with 116 additions and 268 deletions

View file

@ -1,6 +1,4 @@
import { useQuery, gql } from "@apollo/client";
import Box from '@mui/material/Box'
import { makeStyles } from '@mui/styles'
import { useQuery, gql } from '@apollo/client'
import classnames from 'classnames'
import { endOfToday } from 'date-fns'
import { subDays, format, add, startOfWeek } from 'date-fns/fp'
@ -17,15 +15,12 @@ import { fromNamespace } from 'src/utils/config'
import { numberToFiatAmount } from 'src/utils/number'
import { DAY, WEEK, MONTH } from 'src/utils/time'
import styles from './Analytics.styles'
import LegendEntry from './components/LegendEntry'
import HourOfDayWrapper from './components/wrappers/HourOfDayWrapper'
import OverTimeWrapper from './components/wrappers/OverTimeWrapper'
import TopMachinesWrapper from './components/wrappers/TopMachinesWrapper'
import VolumeOverTimeWrapper from './components/wrappers/VolumeOverTimeWrapper'
const useStyles = makeStyles(styles)
const MACHINE_OPTIONS = [{ code: 'all', display: 'All machines' }]
const REPRESENTING_OPTIONS = [
{ code: 'overTime', display: 'Over time' },
@ -106,26 +101,28 @@ const GET_DATA = gql`
}
`
const OverviewEntry = ({ label, value, oldValue, currency }) => {
const classes = useStyles()
const VerticalLine = () => (
<div className="h-16 border-solid border border-comet2" />
)
const OverviewEntry = ({ label, value, oldValue, currency }) => {
const _oldValue = !oldValue || R.equals(oldValue, 0) ? 1 : oldValue
const growthRate = ((value - oldValue) * 100) / _oldValue
const growthClasses = {
[classes.growthPercentage]: true,
[classes.growth]: R.gt(value, oldValue),
[classes.decline]: R.gt(oldValue, value)
'font-bold': true,
'text-malachite': R.gt(value, oldValue),
'text-tomato': R.gt(oldValue, value)
}
return (
<div className={classes.overviewEntry}>
<div>
<P noMargin>{label}</P>
<Info2 noMargin className={classes.overviewFieldWrapper}>
<span>{numberToFiatAmount(value)}</span>
<Info2 noMargin className="mt-[6px] mb-[6px]">
<span className="text-[24px]">{numberToFiatAmount(value)}</span>
{!!currency && ` ${currency}`}
</Info2>
<span className={classes.overviewGrowth}>
<span className="flex items-center gap-1">
{R.gt(growthRate, 0) && <UpIcon height={10} />}
{R.lt(growthRate, 0) && <DownIcon height={10} />}
{R.equals(growthRate, 0) && <EqualIcon height={10} />}
@ -138,8 +135,6 @@ const OverviewEntry = ({ label, value, oldValue, currency }) => {
}
const Analytics = () => {
const classes = useStyles()
const { data: txResponse, loading: txLoading } = useQuery(GET_TRANSACTIONS, {
variables: {
from: subDays(65, endOfToday()),
@ -320,7 +315,7 @@ const Analytics = () => {
!loading && (
<>
<TitleSection title="Analytics">
<Box className={classes.overviewLegend}>
<div className="flex gap-6 justify-end">
<LegendEntry
IconComponent={UpIcon}
label={'Up since last period'}
@ -333,10 +328,10 @@ const Analytics = () => {
IconComponent={EqualIcon}
label={'Same since last period'}
/>
</Box>
</div>
</TitleSection>
<div className={classes.dropdownsOverviewWrapper}>
<div className={classes.dropdowns}>
<div className="flex justify-between items-center mb-4">
<div className="flex flex-row gap-6">
<Select
label="Representing"
onSelectedItemChange={handleRepresentationChange}
@ -354,27 +349,27 @@ const Analytics = () => {
defaultAsFilter
/>
</div>
<div className={classes.overview}>
<div className="flex flex-row items-center gap-10">
<OverviewEntry
label="Transactions"
value={txs.current}
oldValue={txs.previous}
/>
<div className={classes.verticalLine} />
<VerticalLine />
<OverviewEntry
label="Median amount"
value={medianAmount.current}
oldValue={medianAmount.previous}
currency={fiatLocale}
/>
<div className={classes.verticalLine} />
<VerticalLine />
<OverviewEntry
label="Volume"
value={txVolume.current}
oldValue={txVolume.previous}
currency={fiatLocale}
/>
<div className={classes.verticalLine} />
<VerticalLine />
<OverviewEntry
label="Commissions"
value={commissions.current}

View file

@ -1,163 +0,0 @@
import {
offColor,
offDarkColor,
tomato,
neon,
java
} from 'src/styling/variables'
import typographyStyles from '../../components/typography/styles'
const { label1 } = typographyStyles
const styles = {
overviewLegend: {
display: 'flex',
justifyContent: 'flex-end',
'& span': {
marginRight: 24
},
'& > :last-child': {
marginRight: 0
}
},
legendEntry: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
'& > :first-child': {
marginRight: 8
}
},
dropdownsOverviewWrapper: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 16
},
verticalLine: {
height: 64,
width: 1,
border: 'solid',
borderWidth: 0.5,
borderColor: offDarkColor
},
dropdowns: {
display: 'flex',
flexDirection: 'row',
'& div': {
marginRight: 24
},
'& > :last-child': {
marginRight: 0
}
},
overview: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
'& div': {
marginRight: 40
},
'& > :last-child': {
marginRight: 0
}
},
overviewFieldWrapper: {
marginTop: 6,
marginBottom: 6,
'& span': {
fontSize: 24
}
},
overviewGrowth: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
'& p': {
marginLeft: 4
}
},
growthPercentage: {
fontWeight: 'bold'
},
growth: {
color: '#00CD5A'
},
decline: {
color: tomato
},
// Graph
graphHeaderWrapper: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 40
},
graphHeaderLeft: {
display: 'flex',
flexDirection: 'column'
},
graphHeaderRight: {
marginTop: 15,
display: 'flex',
flexDirection: 'row',
'& > *': {
marginRight: 30,
'&:last-child': {
marginRight: 0
}
}
},
graphLegend: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
'& span': {
marginRight: 24
},
'& > :last-child': {
marginRight: 0
}
},
machineSelector: {
width: 248
},
cashInIcon: {
width: 12,
height: 12,
borderRadius: 12,
backgroundColor: java
},
cashOutIcon: {
width: 12,
height: 12,
borderRadius: 12,
backgroundColor: neon
},
txIcon: {
width: 12,
height: 12,
borderRadius: 12,
backgroundColor: '#000'
},
topMachinesRadio: {
display: 'flex',
flexDirection: 'row'
},
graphHeaderSwitchBox: {
display: 'flex',
flexDirection: 'column',
'& > *': {
margin: 0
},
'& > :first-child': {
marginBottom: 2,
extend: label1,
color: offColor
}
}
}
export default styles

View file

@ -1,16 +1,9 @@
import { makeStyles } from '@mui/styles'
import React from 'react'
import { P } from 'src/components/typography'
import styles from '../Analytics.styles'
const useStyles = makeStyles(styles)
const LegendEntry = ({ IconElement, IconComponent, label }) => {
const classes = useStyles()
return (
<span className={classes.legendEntry}>
<span className="flex items-center gap-2">
{!!IconComponent && <IconComponent height={12} />}
{!!IconElement && IconElement}
<P>{label}</P>

View file

@ -10,10 +10,6 @@ import { numberToFiatAmount } from 'src/utils/number'
import { singularOrPlural } from 'src/utils/string'
import { formatDate, formatDateNonUtc } from 'src/utils/timezones'
import styles from './GraphTooltip.styles'
const useStyles = makeStyles(styles)
const GraphTooltip = ({
coords,
data,
@ -22,8 +18,6 @@ const GraphTooltip = ({
currency,
representing
}) => {
const classes = useStyles(coords)
const formattedDateInterval = !R.includes('hourOfDay', representing.code)
? [
formatDate(dateInterval[1], null, 'MMM d'),
@ -48,28 +42,30 @@ const GraphTooltip = ({
)
return (
<Paper className={classes.dotOtWrapper}>
<Paper
className="absolute top-[351px] w-[150px] p-3 rounded-lg"
style={{ left: coords?.x ?? 0 }}>
{!R.includes('hourOfDay', representing.code) && (
<Info2 noMargin>{`${formattedDateInterval[0]}`}</Info2>
)}
<Info2 noMargin>
{`${formattedDateInterval[1]} - ${formattedDateInterval[2]}`}
</Info2>
<P noMargin className={classes.dotOtTransactionAmount}>
<P noMargin className="my-2">
{R.length(data)}{' '}
{singularOrPlural(R.length(data), 'transaction', 'transactions')}
</P>
<P noMargin className={classes.dotOtTransactionVolume}>
<P noMargin className="text-comet">
{numberToFiatAmount(transactions.volume)} {currency} in volume
</P>
<div className={classes.dotOtTransactionClasses}>
<div className="mt-4">
<Label3 noMargin>
<TxInIcon />
<span>{transactions.cashIn} cash-in</span>
<span className="ml-1">{transactions.cashIn} cash-in</span>
</Label3>
<Label3 noMargin>
<Label3 noMargin className="mt-1">
<TxOutIcon />
<span>{transactions.cashOut} cash-out</span>
<span className="ml-1">{transactions.cashOut} cash-out</span>
</Label3>
</div>
</Paper>

View file

@ -1,29 +0,0 @@
import { comet } from 'src/styling/variables'
const styles = {
dotOtWrapper: {
position: 'absolute',
top: coords => coords?.y ?? 0,
left: coords => coords?.x ?? 0,
width: 150,
padding: 12,
borderRadius: 8
},
dotOtTransactionAmount: {
margin: [[8, 0, 8, 0]]
},
dotOtTransactionVolume: {
color: comet
},
dotOtTransactionClasses: {
marginTop: 15,
'& p > span': {
marginLeft: 5
},
'& p:last-child': {
marginTop: 5
}
}
}
export default styles

View file

@ -1,5 +1,4 @@
import Box from '@mui/material/Box'
import { makeStyles } from '@mui/styles'
import { getTimezoneOffset } from 'date-fns-tz'
import * as R from 'ramda'
import React, { useState } from 'react'
@ -8,11 +7,9 @@ import { H2 } from 'src/components/typography'
import { Select } from 'src/components/inputs'
import { MINUTE } from 'src/utils/time'
import styles from '../../Analytics.styles'
import Graph from '../../graphs/Graph'
import LegendEntry from '../LegendEntry'
const useStyles = makeStyles(styles)
import classes from './wrappers.module.css'
const options = [
{ code: 'hourOfDayTransactions', display: 'Transactions' },
@ -32,8 +29,6 @@ const HourOfDayBarGraphHeader = ({
timezone,
currency
}) => {
const classes = useStyles()
const [graphType /*, setGraphType */] = useState(options[0].code)
const legend = {

View file

@ -1,17 +1,14 @@
import Switch from '@mui/material/Switch'
import Box from '@mui/material/Box'
import { makeStyles } from '@mui/styles'
import React, { useState } from 'react'
import { H2 } from 'src/components/typography'
import { H2, Label1 } from 'src/components/typography'
import { Select } from 'src/components/inputs'
import { primaryColor } from 'src/styling/variables'
import styles from '../../Analytics.styles'
import Graph from '../../graphs/Graph'
import LegendEntry from '../LegendEntry'
const useStyles = makeStyles(styles)
import classes from './wrappers.module.css'
const OverTimeDotGraphHeader = ({
title,
@ -24,8 +21,6 @@ const OverTimeDotGraphHeader = ({
timezone,
currency
}) => {
const classes = useStyles()
const [logarithmic, setLogarithmic] = useState()
const legend = {
@ -61,8 +56,13 @@ const OverTimeDotGraphHeader = ({
</div>
<div className={classes.graphHeaderRight}>
<div className={classes.graphHeaderSwitchBox}>
<span>Log. scale</span>
<Switch onChange={event => setLogarithmic(event.target.checked)} />
<Label1 noMargin className="mb-1 text-comet">
Log. scale
</Label1>
<Switch
className="m-0"
onChange={event => setLogarithmic(event.target.checked)}
/>
</div>
<Select
label="Machines"

View file

@ -1,14 +1,11 @@
import Box from '@mui/material/Box'
import { makeStyles } from '@mui/styles'
import * as R from 'ramda'
import React, { useState } from 'react'
import { H2 } from 'src/components/typography'
import styles from '../../Analytics.styles'
import Graph from '../../graphs/Graph'
import LegendEntry from '../LegendEntry'
const useStyles = makeStyles(styles)
import classes from './wrappers.module.css'
const options = [
{ code: 'topMachinesTransactions', display: 'Transactions' },
@ -24,8 +21,6 @@ const TopMachinesBarGraphHeader = ({
timezone,
currency
}) => {
const classes = useStyles()
const [graphType /*, setGraphType */] = useState(options[0].code)
const legend = {

View file

@ -1,17 +1,14 @@
import Box from '@mui/material/Box'
import Switch from '@mui/material/Switch'
import { makeStyles } from '@mui/styles'
import React, { useState } from 'react'
import { H2 } from 'src/components/typography'
import { H2, Label1 } from 'src/components/typography'
import { Select } from 'src/components/inputs'
import { neon, java } from 'src/styling/variables'
import styles from '../../Analytics.styles'
import Graph from '../../graphs/Graph'
import LegendEntry from '../LegendEntry'
const useStyles = makeStyles(styles)
import classes from './wrappers.module.css'
const VolumeOverTimeGraphHeader = ({
title,
@ -24,8 +21,6 @@ const VolumeOverTimeGraphHeader = ({
timezone,
currency
}) => {
const classes = useStyles()
const [logarithmic, setLogarithmic] = useState()
const legend = {
@ -63,8 +58,13 @@ const VolumeOverTimeGraphHeader = ({
</div>
<div className={classes.graphHeaderRight}>
<div className={classes.graphHeaderSwitchBox}>
<span>Log. scale</span>
<Switch onChange={event => setLogarithmic(event.target.checked)} />
<Label1 noMargin className="mb-1 text-comet">
Log. scale
</Label1>
<Switch
className="m-0"
onChange={event => setLogarithmic(event.target.checked)}
/>
</div>
<Select
label="Machines"

View file

@ -0,0 +1,56 @@
.graphHeaderWrapper {
display: flex;
justify-content: space-between;
margin-bottom: 40px;
}
.graphHeaderLeft {
display: flex;
flex-direction: column;
}
.graphHeaderRight {
margin-top: 15px;
display: flex;
gap: 30px
}
.cashInIcon {
width: 12px;
height: 12px;
border-radius: 12px;
background-color: var(--java);
}
.cashOutIcon {
width: 12px;
height: 12px;
border-radius: 12px;
background-color: var(--neon);
}
.graphLegend {
display: flex;
align-items: center;
gap: 24px;
}
.txIcon {
width: 12px;
height: 12px;
border-radius: 12px;
background-color: #000;
}
.graphHeaderSwitchBox {
display: flex;
flex-direction: column;
/*'& > *': {*/
/* margin: 0*/
/*},*/
/*'& > :first-child': {*/
/* marginBottom: 2,*/
/* extend: label1,*/
/* color: offColor*/
/*}*/
}

View file

@ -13,10 +13,17 @@
--spring3: #ecfbef;
--comet: #5f668a;
--comet2: #72799d;
--comet3: #525772;
--tomato: #ff584a;
--ghost: #fafbff;
--zircon: #ebefff;
--java: #16d6d3;
--neon: #5a67ff;
--malachite: #00CD5A;
}
@theme {
@ -25,9 +32,12 @@
--color-spring2: var(--spring2);
--color-spring3: var(--spring3);
--color-comet: var(--comet);
--color-comet2: var(--comet2);
--color-comet3: var(--comet3);
--color-tomato: var(--tomato);
--color-ghost: var(--ghost);
--color-zircon: var(--zircon);
--color-malachite: var(--malachite);
}
body {