chore: reformat code

This commit is contained in:
Rafael Taranto 2025-05-12 14:49:39 +01:00
parent 3d930aa73b
commit aedabcbdee
509 changed files with 6030 additions and 4266 deletions

View file

@ -58,7 +58,7 @@ const QrCodeComponent = ({ qrCode, name, count, onPaired }) => {
if (hasNewMachine) {
timeout.current = setTimeout(
() => onPaired(addedMachine),
CLOSE_SCREEN_TIMEOUT
CLOSE_SCREEN_TIMEOUT,
)
}
@ -111,7 +111,7 @@ const QrCodeComponent = ({ qrCode, name, count, onPaired }) => {
}
const initialValues = {
name: ''
name: '',
}
const validationSchema = Yup.object().shape({
@ -124,9 +124,9 @@ const validationSchema = Yup.object().shape({
(value, context) =>
!R.includes(
R.toLower(value),
R.map(R.toLower, context.options.context.machineNames)
)
)
R.map(R.toLower, context.options.context.machineNames),
),
),
})
const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
@ -138,7 +138,7 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
setQrCode(createPairingTotem)
nextStep()
},
onError: e => console.log(e)
onError: e => console.log(e),
})
const { data } = useQuery(GET_MACHINES)
@ -147,7 +147,7 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
const uniqueNameValidator = value => {
try {
validationSchema.validateSync(value, {
context: { machineNames: machineNames }
context: { machineNames: machineNames },
})
} catch (error) {
return error
@ -189,12 +189,12 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
const steps = [
{
label: 'Machine name',
component: MachineNameComponent
component: MachineNameComponent,
},
{
label: 'Scan QR code',
component: QrCodeComponent
}
component: QrCodeComponent,
},
]
const renderStepper = (step, it, idx) => {
@ -208,7 +208,7 @@ const renderStepper = (step, it, idx) => {
className={classnames({
'mr-6 text-comet': true,
'text-zodiac font-bold': active,
'text-zodiac': past
'text-zodiac': past,
})}>
{it.label}
</span>
@ -219,7 +219,7 @@ const renderStepper = (step, it, idx) => {
<div
className={classnames({
'absolute h-7 w-px border border-comet border-solid right-2 top-[18px]': true,
'border-zodiac': past
'border-zodiac': past,
})}></div>
)}
</div>

View file

@ -26,29 +26,29 @@ const REPRESENTING_OPTIONS = [
{ code: 'overTime', display: 'Over time' },
{ code: 'volumeOverTime', display: 'Volume' },
{ code: 'topMachines', display: 'Top machines' },
{ code: 'hourOfTheDay', display: 'Hour of the day' }
{ code: 'hourOfTheDay', display: 'Hour of the day' },
]
const PERIOD_OPTIONS = [
{ code: 'day', display: 'Last 24 hours' },
{ code: 'threeDays', display: 'Last 3 days' },
{ code: 'week', display: 'Last 7 days' },
{ code: 'month', display: 'Last 30 days' }
{ code: 'month', display: 'Last 30 days' },
]
const TIME_OPTIONS = {
day: DAY,
threeDays: 3 * DAY,
week: WEEK,
month: MONTH
month: MONTH,
}
const DAY_OPTIONS = R.map(
it => ({
code: R.toLower(it),
display: it
display: it,
}),
Array.from(Array(7)).map((_, i) =>
format('EEEE', add({ days: i }, startOfWeek(new Date())))
)
format('EEEE', add({ days: i }, startOfWeek(new Date()))),
),
)
const GET_TRANSACTIONS = gql`
@ -112,7 +112,7 @@ const OverviewEntry = ({ label, value, oldValue, currency }) => {
const growthClasses = {
'font-bold': true,
'text-malachite': R.gt(value, oldValue),
'text-tomato': R.gt(oldValue, value)
'text-tomato': R.gt(oldValue, value),
}
return (
@ -139,8 +139,8 @@ const Analytics = () => {
variables: {
from: subDays(65, endOfToday()),
until: endOfToday(),
excludeTestingCustomers: true
}
excludeTestingCustomers: true,
},
})
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
@ -148,7 +148,7 @@ const Analytics = () => {
const [period, setPeriod] = useState(PERIOD_OPTIONS[0])
const [machine, setMachine] = useState(MACHINE_OPTIONS[0])
const [selectedDay, setSelectedDay] = useState(
R.equals(representing.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null
R.equals(representing.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null,
)
const loading = txLoading || configLoading
@ -175,20 +175,20 @@ const Analytics = () => {
tx =>
(!tx.dispensed || !tx.expired) &&
(tx.sendConfirmed || tx.dispense) &&
!tx.hasError
)
!tx.hasError,
),
) ?? []
const machineOptions = R.clone(MACHINE_OPTIONS)
R.forEach(
m => machineOptions.push({ code: m.deviceId, display: m.name }),
machines
machines,
)
const machineTxs = R.filter(
tx => (machine.code === 'all' ? true : tx.deviceId === machine.code),
data
data,
)
const filteredData = timeInterval => ({
@ -213,35 +213,35 @@ const Analytics = () => {
txDay < Date.now() - TIME_OPTIONS[timeInterval] &&
txDay >= Date.now() - 2 * TIME_OPTIONS[timeInterval]
)
}) ?? []
}) ?? [],
})
const txs = {
current: filteredData(period.code).current.length,
previous: filteredData(period.code).previous.length
previous: filteredData(period.code).previous.length,
}
const median = values => (values.length === 0 ? 0 : R.median(values))
const medianAmount = {
current: median(R.map(d => d.fiat, filteredData(period.code).current)),
previous: median(R.map(d => d.fiat, filteredData(period.code).previous))
previous: median(R.map(d => d.fiat, filteredData(period.code).previous)),
}
const txVolume = {
current: R.sum(R.map(d => d.fiat, filteredData(period.code).current)),
previous: R.sum(R.map(d => d.fiat, filteredData(period.code).previous))
previous: R.sum(R.map(d => d.fiat, filteredData(period.code).previous)),
}
const commissions = {
current: R.sum(R.map(d => d.profit, filteredData(period.code).current)),
previous: R.sum(R.map(d => d.profit, filteredData(period.code).previous))
previous: R.sum(R.map(d => d.profit, filteredData(period.code).previous)),
}
const handleRepresentationChange = newRepresentation => {
setRepresenting(newRepresentation)
setSelectedDay(
R.equals(newRepresentation.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null
R.equals(newRepresentation.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null,
)
}

View file

@ -13,20 +13,19 @@ const GraphTooltip = ({
coords,
data,
dateInterval,
period,
currency,
representing
representing,
}) => {
const formattedDateInterval = !R.includes('hourOfDay', representing.code)
? [
formatDate(dateInterval[1], null, 'MMM d'),
formatDate(dateInterval[1], null, 'HH:mm'),
formatDate(dateInterval[0], null, 'HH:mm')
formatDate(dateInterval[0], null, 'HH:mm'),
]
: [
formatDate(dateInterval[1], null, 'MMM d'),
formatDateNonUtc(dateInterval[1], 'HH:mm'),
formatDateNonUtc(dateInterval[0], 'HH:mm')
formatDateNonUtc(dateInterval[0], 'HH:mm'),
]
const transactions = R.reduce(
@ -37,7 +36,7 @@ const GraphTooltip = ({
return acc
},
{ volume: 0, cashIn: 0, cashOut: 0 },
data
data,
)
return (

View file

@ -12,7 +12,7 @@ import classes from './wrappers.module.css'
const options = [
{ code: 'hourOfDayTransactions', display: 'Transactions' },
{ code: 'hourOfDayVolume', display: 'Volume' }
{ code: 'hourOfDayVolume', display: 'Volume' },
]
const HourOfDayBarGraphHeader = ({
@ -26,13 +26,13 @@ const HourOfDayBarGraphHeader = ({
dayOptions,
handleDayChange,
timezone,
currency
currency,
}) => {
const [graphType /*, setGraphType */] = useState(options[0].code)
const legend = {
cashIn: <div className={classes.cashInIcon}></div>,
cashOut: <div className={classes.cashOutIcon}></div>
cashOut: <div className={classes.cashOutIcon}></div>,
}
const offset = getTimezoneOffset(timezone)
@ -41,7 +41,7 @@ const HourOfDayBarGraphHeader = ({
(acc, value) => {
const created = new Date(value.created)
created.setTime(
created.getTime() + created.getTimezoneOffset() * MINUTE + offset
created.getTime() + created.getTimezoneOffset() * MINUTE + offset,
)
switch (created.getDay()) {
case 0:
@ -71,7 +71,7 @@ const HourOfDayBarGraphHeader = ({
return acc
},
R.fromPairs(R.map(it => [it.code, []], dayOptions)),
data
data,
)
return (

View file

@ -18,7 +18,7 @@ const OverTimeDotGraphHeader = ({
selectedMachine,
handleMachineChange,
timezone,
currency
currency,
}) => {
const [logarithmic, setLogarithmic] = useState()
@ -35,7 +35,7 @@ const OverTimeDotGraphHeader = ({
d="M 5 6 l 20 0"
/>
</svg>
)
),
}
return (

View file

@ -8,7 +8,7 @@ import classes from './wrappers.module.css'
const options = [
{ code: 'topMachinesTransactions', display: 'Transactions' },
{ code: 'topMachinesVolume', display: 'Volume' }
{ code: 'topMachinesVolume', display: 'Volume' },
]
const TopMachinesBarGraphHeader = ({
@ -18,13 +18,13 @@ const TopMachinesBarGraphHeader = ({
machines,
selectedMachine,
timezone,
currency
currency,
}) => {
const [graphType /*, setGraphType */] = useState(options[0].code)
const legend = {
cashIn: <div className={classes.cashInIcon}></div>,
cashOut: <div className={classes.cashOutIcon}></div>
cashOut: <div className={classes.cashOutIcon}></div>,
}
return (

View file

@ -18,7 +18,7 @@ const VolumeOverTimeGraphHeader = ({
selectedMachine,
handleMachineChange,
timezone,
currency
currency,
}) => {
const [logarithmic, setLogarithmic] = useState()
@ -42,7 +42,7 @@ const VolumeOverTimeGraphHeader = ({
strokeLinecap="round"
/>
</svg>
)
),
}
return (

View file

@ -12,7 +12,7 @@
.graphHeaderRight {
margin-top: 15px;
display: flex;
gap: 30px
gap: 30px;
}
.cashInIcon {
@ -45,12 +45,12 @@
.graphHeaderSwitchBox {
display: flex;
flex-direction: column;
/*'& > *': {*/
/* margin: 0*/
/*},*/
/*'& > :first-child': {*/
/* marginBottom: 2,*/
/* extend: label1,*/
/* color: offColor*/
/*}*/
/*'& > *': {*/
/* margin: 0*/
/*},*/
/*'& > :first-child': {*/
/* marginBottom: 2,*/
/* extend: label1,*/
/* color: offColor*/
/*}*/
}

View file

@ -17,7 +17,7 @@ const GraphWrapper = ({
selectedMachine,
machines,
selectedDay,
log
log,
}) => {
const [selectionCoords, setSelectionCoords] = useState(null)
const [selectionDateInterval, setSelectionDateInterval] = useState(null)

View file

@ -11,7 +11,7 @@ import {
subheaderDarkColor,
fontColor,
fontSecondary,
subheaderColor
subheaderColor,
} from 'src/styling/variables'
import { MINUTE } from 'src/utils/time'
import { toUtc } from 'src/utils/timezones'
@ -22,7 +22,6 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
selectedMachine
}) => {
const ref = useRef(null)
@ -36,9 +35,9 @@ const Graph = ({
top: 25,
right: 0.5,
bottom: 27,
left: 36.5
left: 36.5,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -64,7 +63,7 @@ const Graph = ({
const tzCreated = new Date(it.created).setTime(
new Date(it.created).getTime() +
new Date(it.created).getTimezoneOffset() * MINUTE +
offset
offset,
)
const created = new Date(tzCreated)
@ -77,7 +76,7 @@ const Graph = ({
created.getUTCHours() < new Date(upperBound).getUTCHours())
)
}, data),
[data, offset]
[data, offset],
)
const txClassByHourInterval = useCallback(
@ -91,16 +90,16 @@ const Graph = ({
return acc
},
{ cashIn: 0, cashOut: 0 },
filterByHourInterval(lowerBound, upperBound)
filterByHourInterval(lowerBound, upperBound),
),
[filterByHourInterval]
[filterByHourInterval],
)
const x = d3
.scaleUtc()
.domain([
toUtc(startOfDay(new Date())),
toUtc(add({ days: 1 }, startOfDay(new Date())))
toUtc(add({ days: 1 }, startOfDay(new Date()))),
])
.rangeRound([GRAPH_MARGIN.left, GRAPH_WIDTH - GRAPH_MARGIN.right])
@ -111,7 +110,7 @@ const Graph = ({
const upperBound = R.clone(it)
return [lowerBound, filterByHourInterval(lowerBound, upperBound)]
},
R.init(getTickIntervals(x.domain(), 2))
R.init(getTickIntervals(x.domain(), 2)),
)
const groupedByTxClass = R.map(
@ -121,7 +120,7 @@ const Graph = ({
const upperBound = R.clone(it)
return [lowerBound, txClassByHourInterval(lowerBound, upperBound)]
},
R.init(getTickIntervals(x.domain(), 2))
R.init(getTickIntervals(x.domain(), 2)),
)
const y = d3
@ -130,13 +129,13 @@ const Graph = ({
0,
d3.max(
groupedByTxClass.map(it => it[1]),
d => d.cashIn + d.cashOut
d => d.cashIn + d.cashOut,
) !== 0
? d3.max(
groupedByTxClass.map(it => it[1]),
d => d.cashIn + d.cashOut
d => d.cashIn + d.cashOut,
)
: 50
: 50,
])
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -145,15 +144,15 @@ const Graph = ({
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
.axisBottom(x)
.ticks(d3.timeHour.every(2))
.tickFormat(d3.timeFormat('%H:%M'))
.tickFormat(d3.timeFormat('%H:%M')),
),
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const buildYAxis = useCallback(
@ -165,10 +164,10 @@ const Graph = ({
.axisLeft(y)
.ticks(GRAPH_HEIGHT / 100)
.tickSize(0)
.tickFormat(``)
.tickFormat(``),
)
.call(g => g.select('.domain').remove()),
[GRAPH_MARGIN, y]
[GRAPH_MARGIN, y],
)
const buildVerticalLines = useCallback(
@ -195,7 +194,7 @@ const Graph = ({
})
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const buildHoverableEventRects = useCallback(
@ -227,15 +226,15 @@ const Graph = ({
const endDate = R.clone(date)
const filteredData = groupedByDateInterval.find(it =>
R.equals(startDate, it[0])
R.equals(startDate, it[0]),
)[1]
const rectXCoords = {
left: R.clone(d.target.getBoundingClientRect().x),
right: R.clone(
d.target.getBoundingClientRect().x +
d.target.getBoundingClientRect().width
)
d.target.getBoundingClientRect().width,
),
}
const xCoord =
@ -248,18 +247,18 @@ const Graph = ({
setSelectionData(filteredData)
setSelectionCoords({
x: Math.round(xCoord),
y: Math.round(yCoord)
y: Math.round(yCoord),
})
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
'fill',
subheaderColor
subheaderColor,
)
})
.on('mouseleave', d => {
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
'fill',
'transparent'
'transparent',
)
setSelectionDateInterval(null)
setSelectionData(null)
@ -271,8 +270,8 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
x
]
x,
],
)
const buildEventRects = useCallback(
@ -298,7 +297,7 @@ const Graph = ({
.attr('height', GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top)
.attr('stroke', 'transparent')
.attr('fill', 'transparent'),
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const formatTicksText = useCallback(
@ -309,7 +308,7 @@ const Graph = ({
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const drawCashIn = useCallback(
@ -334,7 +333,7 @@ const Graph = ({
GRAPH_HEIGHT -
y(interval[1].cashIn) -
GRAPH_MARGIN.bottom -
BAR_MARGIN / 2
BAR_MARGIN / 2,
)
})
.attr('width', d => {
@ -348,7 +347,7 @@ const Graph = ({
})
.attr('rx', 2.5)
},
[x, y, GRAPH_MARGIN, groupedByTxClass]
[x, y, GRAPH_MARGIN, groupedByTxClass],
)
const drawCashOut = useCallback(
@ -377,7 +376,7 @@ const Graph = ({
GRAPH_HEIGHT -
y(interval[1].cashOut) -
GRAPH_MARGIN.bottom -
BAR_MARGIN / 2
BAR_MARGIN / 2,
)
})
.attr('width', d => {
@ -391,7 +390,7 @@ const Graph = ({
})
.attr('rx', 2.5)
},
[x, y, GRAPH_MARGIN, groupedByTxClass]
[x, y, GRAPH_MARGIN, groupedByTxClass],
)
const drawChart = useCallback(() => {
@ -417,7 +416,7 @@ const Graph = ({
buildVerticalLines,
drawCashIn,
formatTicksText,
drawCashOut
drawCashOut,
])
useEffect(() => {
@ -433,5 +432,5 @@ export default memo(
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedDay, next.selectedDay) &&
R.equals(prev.selectedMachine, next.selectedMachine)
R.equals(prev.selectedMachine, next.selectedMachine),
)

View file

@ -13,7 +13,7 @@ import {
fontColor,
primaryColor,
fontSecondary,
subheaderColor
subheaderColor,
} from 'src/styling/variables'
import { numberToFiatAmount } from 'src/utils/number'
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
@ -25,7 +25,7 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
log = false
log = false,
}) => {
const ref = useRef(null)
@ -38,9 +38,9 @@ const Graph = ({
top: 25,
right: 3.5,
bottom: 27,
left: 38
left: 38,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -50,7 +50,7 @@ const Graph = ({
day: [NOW - DAY, NOW],
threeDays: [NOW - 3 * DAY, NOW],
week: [NOW - WEEK, NOW],
month: [NOW - MONTH, NOW]
month: [NOW - MONTH, NOW],
}
const dataPoints = useMemo(
@ -59,28 +59,28 @@ const Graph = ({
freq: 24,
step: 60 * 60 * 1000,
tick: d3.utcHour.every(1),
labelFormat: '%H:%M'
labelFormat: '%H:%M',
},
threeDays: {
freq: 12,
step: 6 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
week: {
freq: 7,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
month: {
freq: 30,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%d'
}
labelFormat: '%d',
},
}),
[]
[],
)
const getPastAndCurrentDayLabels = useCallback(d => {
@ -97,11 +97,11 @@ const Graph = ({
const previousDateMonth = previousDate.getUTCMonth()
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
format('EEE', add({ days: i }, startOfWeek(new Date())))
format('EEE', add({ days: i }, startOfWeek(new Date()))),
)
const months = Array.from(Array(12)).map((_, i) =>
format('LLL', add({ months: i }, startOfYear(new Date())))
format('LLL', add({ months: i }, startOfYear(new Date()))),
)
return {
@ -112,7 +112,7 @@ const Graph = ({
current:
currentDateMonth !== previousDateMonth
? months[currentDateMonth]
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
}
}, [])
@ -134,7 +134,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const buildAreas = useCallback(
@ -159,7 +159,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const x = d3
@ -177,7 +177,7 @@ const Graph = ({
.scaleLinear()
.domain([
0,
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.03
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.03,
])
.nice()
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -186,7 +186,7 @@ const Graph = ({
.scaleLog()
.domain([
(d3.min(data, d => new BigNumber(d.fiat).toNumber()) ?? 1) * 0.9,
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.1
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.1,
])
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -196,7 +196,7 @@ const Graph = ({
const fullBreakpoints = [
graphLimits[1],
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
dataLimits[0]
dataLimits[0],
]
const intervals = []
@ -227,7 +227,7 @@ const Graph = ({
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -235,18 +235,18 @@ const Graph = ({
.ticks(dataPoints[period.code].tick)
.tickFormat(d => {
return d3.timeFormat(dataPoints[period.code].labelFormat)(
d.getTime() + d.getTimezoneOffset() * MINUTE
d.getTime() + d.getTimezoneOffset() * MINUTE,
)
})
.tickSizeOuter(0)
.tickSizeOuter(0),
)
.call(g =>
g
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1)
.attr('stroke-width', 1),
),
[GRAPH_MARGIN, dataPoints, period.code, x]
[GRAPH_MARGIN, dataPoints, period.code, x],
)
const buildYAxis = useCallback(
@ -264,12 +264,12 @@ const Graph = ({
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
return numberToFiatAmount(d)
})
}),
)
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1),
[GRAPH_MARGIN, y, log]
[GRAPH_MARGIN, y, log],
)
const buildGrid = useCallback(
@ -286,7 +286,7 @@ const Graph = ({
.attr('x1', d => 0.5 + x(d))
.attr('x2', d => 0.5 + x(d))
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
)
// Horizontal lines
.call(g =>
@ -297,13 +297,13 @@ const Graph = ({
d3
.axisLeft(y)
.scale()
.ticks(GRAPH_HEIGHT / 100)
.ticks(GRAPH_HEIGHT / 100),
)
.join('line')
.attr('y1', d => 0.5 + y(d))
.attr('y2', d => 0.5 + y(d))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
// Vertical transparent rectangles for events
.call(g =>
@ -319,14 +319,14 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const interval = getAreaIntervalByX(intervals, xValue)
return Math.round((interval[0] - interval[1]) * 100) / 100
})
.attr(
'height',
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top,
)
.attr('stroke', 'transparent')
.attr('fill', 'transparent')
@ -336,7 +336,7 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
@ -354,8 +354,8 @@ const Graph = ({
left: R.clone(d.target.getBoundingClientRect().x),
right: R.clone(
d.target.getBoundingClientRect().x +
d.target.getBoundingClientRect().width
)
d.target.getBoundingClientRect().width,
),
}
const xCoord =
@ -370,7 +370,7 @@ const Graph = ({
setSelectionData(filteredData)
setSelectionCoords({
x: Math.round(xCoord),
y: Math.round(yCoord)
y: Math.round(yCoord),
})
d3.select(d.target).attr('fill', subheaderColor)
@ -380,7 +380,7 @@ const Graph = ({
setSelectionDateInterval(null)
setSelectionData(null)
setSelectionCoords(null)
})
}),
)
// Thick vertical lines
.call(g =>
@ -391,7 +391,7 @@ const Graph = ({
buildTicks(x.domain()).filter(x => {
if (period.code === 'day') return x.getUTCHours() === 0
return x.getUTCDate() === 1
})
}),
)
.join('line')
.attr('class', 'dateSeparator')
@ -400,7 +400,7 @@ const Graph = ({
.attr('y1', GRAPH_MARGIN.top - 50)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('stroke-width', 5)
.join('text')
.join('text'),
)
// Left side breakpoint label
.call(g => {
@ -458,8 +458,8 @@ const Graph = ({
offset,
setSelectionCoords,
setSelectionData,
setSelectionDateInterval
]
setSelectionDateInterval,
],
)
const formatTicksText = useCallback(
@ -470,7 +470,7 @@ const Graph = ({
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatText = useCallback(
@ -481,7 +481,7 @@ const Graph = ({
.style('fill', offColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatTicks = useCallback(() => {
@ -505,10 +505,10 @@ const Graph = ({
.attr('y1', 0.5 + y(median))
.attr('y2', 0.5 + y(median))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
},
[GRAPH_MARGIN, y, data, log]
[GRAPH_MARGIN, y, data, log],
)
const drawData = useCallback(
@ -524,7 +524,7 @@ const Graph = ({
.attr('fill', d => (d.txClass === 'cashIn' ? java : neon))
.attr('r', 3.5)
},
[data, offset, x, y]
[data, offset, x, y],
)
const drawChart = useCallback(() => {
@ -550,7 +550,7 @@ const Graph = ({
drawData,
formatText,
formatTicks,
formatTicksText
formatTicksText,
])
useEffect(() => {
@ -566,5 +566,5 @@ export default memo(
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedMachine, next.selectedMachine) &&
R.equals(prev.log, next.log)
R.equals(prev.log, next.log),
)

View file

@ -8,7 +8,7 @@ import {
differenceInMilliseconds,
format,
startOfWeek,
startOfYear
startOfYear,
} from 'date-fns/fp'
import * as R from 'ramda'
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
@ -21,7 +21,7 @@ import {
fontColor,
primaryColor,
fontSecondary,
subheaderColor
subheaderColor,
} from 'src/styling/variables'
import { numberToFiatAmount } from 'src/utils/number'
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
@ -33,7 +33,7 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
log = false
log = false,
}) => {
const ref = useRef(null)
@ -46,9 +46,9 @@ const Graph = ({
top: 25,
right: 3.5,
bottom: 27,
left: 38
left: 38,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -58,7 +58,7 @@ const Graph = ({
day: [NOW - DAY, NOW],
threeDays: [NOW - 3 * DAY, NOW],
week: [NOW - WEEK, NOW],
month: [NOW - MONTH, NOW]
month: [NOW - MONTH, NOW],
}
const dataPoints = useMemo(
@ -67,28 +67,28 @@ const Graph = ({
freq: 24,
step: 60 * 60 * 1000,
tick: d3.utcHour.every(1),
labelFormat: '%H:%M'
labelFormat: '%H:%M',
},
threeDays: {
freq: 12,
step: 6 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
week: {
freq: 7,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
month: {
freq: 30,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%d'
}
labelFormat: '%d',
},
}),
[]
[],
)
const getPastAndCurrentDayLabels = useCallback(d => {
@ -105,11 +105,11 @@ const Graph = ({
const previousDateMonth = previousDate.getUTCMonth()
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
format('EEE', add({ days: i }, startOfWeek(new Date())))
format('EEE', add({ days: i }, startOfWeek(new Date()))),
)
const months = Array.from(Array(12)).map((_, i) =>
format('LLL', add({ months: i }, startOfYear(new Date())))
format('LLL', add({ months: i }, startOfYear(new Date()))),
)
return {
@ -120,7 +120,7 @@ const Graph = ({
current:
currentDateMonth !== previousDateMonth
? months[currentDateMonth]
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
}
}, [])
@ -142,7 +142,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const buildAreas = useCallback(
@ -167,7 +167,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const x = d3
@ -192,14 +192,14 @@ const Graph = ({
else if (i === dates.length - 1)
return addMilliseconds(
-dataPoints[period.code].step,
dates[dates.length - 2]
dates[dates.length - 2],
)
else return date
})
.map(date => {
const middleOfBin = addMilliseconds(
dataPoints[period.code].step / 2,
date
date,
)
const txs = data.filter(tx => {
@ -236,7 +236,7 @@ const Graph = ({
.scaleLog()
.domain([
min === 0 ? 0.9 : min * 0.9,
(max === min ? min + Math.pow(10, 2 * min + 1) : max) * 2
(max === min ? min + Math.pow(10, 2 * min + 1) : max) * 2,
])
.clamp(true)
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -247,7 +247,7 @@ const Graph = ({
const fullBreakpoints = [
graphLimits[1],
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
dataLimits[0]
dataLimits[0],
]
const intervals = []
@ -278,7 +278,7 @@ const Graph = ({
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -286,18 +286,18 @@ const Graph = ({
.ticks(dataPoints[period.code].tick)
.tickFormat(d => {
return d3.timeFormat(dataPoints[period.code].labelFormat)(
d.getTime() + d.getTimezoneOffset() * MINUTE
d.getTime() + d.getTimezoneOffset() * MINUTE,
)
})
.tickSizeOuter(0)
.tickSizeOuter(0),
)
.call(g =>
g
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1)
.attr('stroke-width', 1),
),
[GRAPH_MARGIN, dataPoints, period.code, x]
[GRAPH_MARGIN, dataPoints, period.code, x],
)
const buildYAxis = useCallback(
@ -315,12 +315,12 @@ const Graph = ({
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
return numberToFiatAmount(d)
})
}),
)
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1),
[GRAPH_MARGIN, y, log]
[GRAPH_MARGIN, y, log],
)
const buildGrid = useCallback(
@ -337,7 +337,7 @@ const Graph = ({
.attr('x1', d => 0.5 + x(d))
.attr('x2', d => 0.5 + x(d))
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
)
// Horizontal lines
.call(g =>
@ -348,13 +348,13 @@ const Graph = ({
d3
.axisLeft(y)
.scale()
.ticks(GRAPH_HEIGHT / 100)
.ticks(GRAPH_HEIGHT / 100),
)
.join('line')
.attr('y1', d => 0.5 + y(d))
.attr('y2', d => 0.5 + y(d))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
// Vertical transparent rectangles for events
.call(g =>
@ -370,14 +370,14 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const interval = getAreaIntervalByX(intervals, xValue)
return Math.round((interval[0] - interval[1]) * 100) / 100
})
.attr(
'height',
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top,
)
.attr('stroke', 'transparent')
.attr('fill', 'transparent')
@ -387,7 +387,7 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
@ -405,8 +405,8 @@ const Graph = ({
left: R.clone(d.target.getBoundingClientRect().x),
right: R.clone(
d.target.getBoundingClientRect().x +
d.target.getBoundingClientRect().width
)
d.target.getBoundingClientRect().width,
),
}
const xCoord =
@ -421,7 +421,7 @@ const Graph = ({
setSelectionData(filteredData)
setSelectionCoords({
x: Math.round(xCoord),
y: Math.round(yCoord)
y: Math.round(yCoord),
})
d3.select(d.target).attr('fill', subheaderColor)
@ -431,7 +431,7 @@ const Graph = ({
setSelectionDateInterval(null)
setSelectionData(null)
setSelectionCoords(null)
})
}),
)
// Thick vertical lines
.call(g =>
@ -442,7 +442,7 @@ const Graph = ({
buildTicks(x.domain()).filter(x => {
if (period.code === 'day') return x.getUTCHours() === 0
return x.getUTCDate() === 1
})
}),
)
.join('line')
.attr('class', 'dateSeparator')
@ -451,7 +451,7 @@ const Graph = ({
.attr('y1', GRAPH_MARGIN.top - 50)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('stroke-width', 5)
.join('text')
.join('text'),
)
// Left side breakpoint label
.call(g => {
@ -509,8 +509,8 @@ const Graph = ({
offset,
setSelectionCoords,
setSelectionData,
setSelectionDateInterval
]
setSelectionDateInterval,
],
)
const formatTicksText = useCallback(
@ -521,7 +521,7 @@ const Graph = ({
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatText = useCallback(
@ -532,7 +532,7 @@ const Graph = ({
.style('fill', offColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatTicks = useCallback(() => {
@ -574,7 +574,7 @@ const Graph = ({
.line()
.curve(d3.curveMonotoneX)
.x(d => x(d.date))
.y(d => y(d.cashIn))
.y(d => y(d.cashIn)),
)
g.append('g')
@ -599,10 +599,10 @@ const Graph = ({
.line()
.curve(d3.curveMonotoneX)
.x(d => x(d.date))
.y(d => y(d.cashOut))
.y(d => y(d.cashOut)),
)
},
[x, y, bins, GRAPH_MARGIN]
[x, y, bins, GRAPH_MARGIN],
)
const drawChart = useCallback(() => {
@ -626,7 +626,7 @@ const Graph = ({
drawData,
formatText,
formatTicks,
formatTicksText
formatTicksText,
])
useEffect(() => {
@ -642,5 +642,5 @@ export default memo(
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedMachine, next.selectedMachine) &&
R.equals(prev.log, next.log)
R.equals(prev.log, next.log),
)

View file

@ -8,10 +8,10 @@ import {
neon,
subheaderDarkColor,
fontColor,
fontSecondary
fontSecondary,
} from 'src/styling/variables'
const Graph = ({ data, machines, currency, selectedMachine }) => {
const Graph = ({ data, machines, currency }) => {
const ref = useRef(null)
const AMOUNT_OF_MACHINES = 5
@ -24,9 +24,9 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
top: 25,
right: 0.5,
bottom: 27,
left: 36.5
left: 36.5,
}),
[]
[],
)
const machinesClone = R.clone(machines)
@ -41,7 +41,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
if (!R.isNil(machinesClone[it])) return machinesClone[it]
return { code: `ghostMachine${it}`, display: `` }
},
R.times(R.identity, AMOUNT_OF_MACHINES)
R.times(R.identity, AMOUNT_OF_MACHINES),
)
const txByDevice = R.reduce(
@ -50,14 +50,14 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
return acc
},
{},
filledMachines
filledMachines,
)
const getDeviceVolume = deviceId =>
R.reduce(
(acc, value) => acc + BigNumber(value.fiat).toNumber(),
0,
txByDevice[deviceId]
txByDevice[deviceId],
)
const getDeviceVolumeByTxClass = deviceId =>
@ -70,18 +70,18 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
return acc
},
{ cashIn: 0, cashOut: 0 },
txByDevice[deviceId]
txByDevice[deviceId],
)
const devicesByVolume = R.sort(
(a, b) => b[1] - a[1],
R.map(m => [m.code, getDeviceVolume(m.code)], filledMachines)
R.map(m => [m.code, getDeviceVolume(m.code)], filledMachines),
)
const topMachines = R.take(AMOUNT_OF_MACHINES, devicesByVolume)
const txClassVolumeByDevice = R.fromPairs(
R.map(v => [v[0], getDeviceVolumeByTxClass(v[0])], topMachines)
R.map(v => [v[0], getDeviceVolumeByTxClass(v[0])], topMachines),
)
const x = d3
@ -94,7 +94,9 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.scaleLinear()
.domain([
0,
d3.max(topMachines, d => d[1]) !== 0 ? d3.max(topMachines, d => d[1]) : 50
d3.max(topMachines, d => d[1]) !== 0
? d3.max(topMachines, d => d[1])
: 50,
])
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -104,7 +106,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.attr('class', 'x-axis-1')
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -113,12 +115,12 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
d =>
`${
R.find(it => it.code === d[0], filledMachines).display ?? ''
}`
}`,
)
.tickSize(0)
.tickPadding(10)
.tickPadding(10),
),
[GRAPH_MARGIN, x, filledMachines]
[GRAPH_MARGIN, x, filledMachines],
)
const buildXAxis2 = useCallback(
@ -126,7 +128,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
g.attr('class', 'x-axis-2')
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -134,24 +136,24 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.tickFormat(d =>
R.includes(`ghostMachine`, d[0])
? ``
: `${d[1].toFixed(2)} ${currency}`
: `${d[1].toFixed(2)} ${currency}`,
)
.tickSize(0)
.tickPadding(10)
.tickPadding(10),
)
},
[GRAPH_MARGIN, x, currency]
[GRAPH_MARGIN, x, currency],
)
const positionXAxisLabels = useCallback(() => {
d3.selectAll('.x-axis-1 .tick text').attr('transform', function (d) {
d3.selectAll('.x-axis-1 .tick text').attr('transform', function () {
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
return `translate(${-widthPerEntry / 2.25 + this.getBBox().width / 2}, 0)`
})
}, [x])
const positionXAxis2Labels = useCallback(() => {
d3.selectAll('.x-axis-2 .tick text').attr('transform', function (d) {
d3.selectAll('.x-axis-2 .tick text').attr('transform', function () {
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
return `translate(${widthPerEntry / 2.25 - this.getBBox().width / 2}, 0)`
})
@ -166,10 +168,10 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.axisLeft(y)
.ticks(GRAPH_HEIGHT / 100)
.tickSize(0)
.tickFormat(``)
.tickFormat(``),
)
.call(g => g.select('.domain').remove()),
[GRAPH_MARGIN, y]
[GRAPH_MARGIN, y],
)
const formatTicksText = useCallback(
@ -180,7 +182,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const buildGrid = useCallback(
@ -213,10 +215,10 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
return 0.5 + x(d) - paddedXValue
})
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
)
},
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const drawCashIn = useCallback(
@ -231,13 +233,13 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
R.clamp(
0,
GRAPH_HEIGHT,
GRAPH_HEIGHT - y(d[1].cashIn) - GRAPH_MARGIN.bottom - BAR_MARGIN
)
GRAPH_HEIGHT - y(d[1].cashIn) - GRAPH_MARGIN.bottom - BAR_MARGIN,
),
)
.attr('width', x.bandwidth())
.attr('rx', 2.5)
},
[txClassVolumeByDevice, x, y, GRAPH_MARGIN]
[txClassVolumeByDevice, x, y, GRAPH_MARGIN],
)
const drawCashOut = useCallback(
@ -252,7 +254,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
d =>
y(d[1].cashIn + d[1].cashOut) -
GRAPH_MARGIN.top +
GRAPH_MARGIN.bottom
GRAPH_MARGIN.bottom,
)
.attr('height', d => {
return R.clamp(
@ -261,13 +263,13 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
GRAPH_HEIGHT -
y(d[1].cashOut) -
GRAPH_MARGIN.bottom -
BAR_MARGIN / 2
BAR_MARGIN / 2,
)
})
.attr('width', x.bandwidth())
.attr('rx', 2.5)
},
[txClassVolumeByDevice, x, y, GRAPH_MARGIN]
[txClassVolumeByDevice, x, y, GRAPH_MARGIN],
)
const drawChart = useCallback(() => {
@ -295,7 +297,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
formatTicksText,
buildGrid,
drawCashIn,
drawCashOut
drawCashOut,
])
useEffect(() => {
@ -310,5 +312,5 @@ export default memo(
Graph,
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedMachine, next.selectedMachine)
R.equals(prev.selectedMachine, next.selectedMachine),
)

View file

@ -1,5 +1,6 @@
.welcomeBackground {
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center center;
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center
center;
background-size: cover;
height: 100vh;
width: 100vw;
@ -22,7 +23,7 @@
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 30px
margin-bottom: 30px;
}
.icon {
@ -70,4 +71,3 @@
.confirm2FAInput {
margin-top: 25px;
}

View file

@ -46,7 +46,7 @@ const Input2FAState = ({ state, dispatch }) => {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
},
})
const [input2FA, { error: mutationError }] = useMutation(INPUT_2FA, {
@ -55,15 +55,15 @@ const Input2FAState = ({ state, dispatch }) => {
return getUserData()
}
return setInvalidToken(true)
}
},
})
const handle2FAChange = value => {
dispatch({
type: STATES.INPUT_2FA,
payload: {
twoFAField: value
}
twoFAField: value,
},
})
setInvalidToken(false)
}
@ -79,8 +79,8 @@ const Input2FAState = ({ state, dispatch }) => {
username: state.clientField,
password: state.passwordField,
code: state.twoFAField,
rememberMe: state.rememberMeField
}
rememberMe: state.rememberMeField,
},
}
input2FA(options)

View file

@ -24,12 +24,12 @@ const validationSchema = Yup.object().shape({
localClient: Yup.string()
.required('Client field is required!')
.email('Username field should be in an email format!'),
localRememberMe: Yup.boolean()
localRememberMe: Yup.boolean(),
})
const initialValues = {
localClient: '',
localRememberMe: false
localRememberMe: false,
}
const InputFIDOState = ({ state, strategy }) => {
@ -74,8 +74,8 @@ const InputFIDOState = ({ state, strategy }) => {
{
onCompleted: ({ validateAssertion: success }) => {
success ? getUserData() : setInvalidToken(true)
}
}
},
},
)
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
@ -86,11 +86,11 @@ const InputFIDOState = ({ state, strategy }) => {
? {
username: state.clientField,
password: state.passwordField,
domain: window.location.hostname
domain: window.location.hostname,
}
: {
username: localClientField,
domain: window.location.hostname
domain: window.location.hostname,
},
onCompleted: ({ generateAssertionOptions: options }) => {
startAssertion(options)
@ -102,31 +102,31 @@ const InputFIDOState = ({ state, strategy }) => {
password: state.passwordField,
rememberMe: state.rememberMeField,
assertionResponse: res,
domain: window.location.hostname
domain: window.location.hostname,
}
: {
username: localClientField,
rememberMe: localRememberMeField,
assertionResponse: res,
domain: window.location.hostname
domain: window.location.hostname,
}
validateAssertion({
variables
variables,
})
})
.catch(err => {
console.error(err)
setInvalidToken(true)
})
}
}
},
},
)
const [getUserData, { error: queryError }] = useLazyQuery(GET_USER_DATA, {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
},
})
const getErrorMsg = (formikErrors, formikTouched) => {

View file

@ -1,6 +1,5 @@
import Paper from '@mui/material/Paper'
import React, { useReducer } from 'react'
import { H5 } from 'src/components/typography'
import Logo from 'src/styling/icons/menu/logo.svg?react'
import Input2FAState from './Input2FAState'
@ -18,7 +17,7 @@ const initialState = {
clientField: '',
passwordField: '',
rememberMeField: false,
loginState: STATES.LOGIN
loginState: STATES.LOGIN,
}
const reducer = (state, action) => {

View file

@ -44,13 +44,13 @@ const GET_USER_DATA = gql`
const validationSchema = Yup.object().shape({
email: Yup.string().label('Email').required().email(),
password: Yup.string().required('Password field is required'),
rememberMe: Yup.boolean()
rememberMe: Yup.boolean(),
})
const initialValues = {
email: '',
password: '',
rememberMe: false
rememberMe: false,
}
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
@ -62,7 +62,7 @@ const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
return null
}
const LoginState = ({ state, dispatch, strategy }) => {
const LoginState = ({ dispatch, strategy }) => {
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -72,8 +72,8 @@ const LoginState = ({ state, dispatch, strategy }) => {
const options = {
variables: {
username,
password
}
password,
},
}
const { data: loginResponse } = await login(options)
@ -84,16 +84,16 @@ const LoginState = ({ state, dispatch, strategy }) => {
payload: {
clientField: username,
passwordField: password,
rememberMeField: rememberMe
}
rememberMeField: rememberMe,
},
})
}
const [validateAssertion, { error: FIDOMutationError }] = useMutation(
VALIDATE_ASSERTION,
{
onCompleted: ({ validateAssertion: success }) => success && getUserData()
}
onCompleted: ({ validateAssertion: success }) => success && getUserData(),
},
)
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
@ -105,15 +105,15 @@ const LoginState = ({ state, dispatch, strategy }) => {
validateAssertion({
variables: {
assertionResponse: res,
domain: window.location.hostname
}
domain: window.location.hostname,
},
})
})
.catch(err => {
console.error(err)
})
}
}
},
},
)
const [getUserData, { error: userDataQueryError }] = useLazyQuery(
@ -122,8 +122,8 @@ const LoginState = ({ state, dispatch, strategy }) => {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
}
},
},
)
return (
@ -149,7 +149,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
)}
/>
<Field
@ -164,7 +164,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
)}
/>
<div className="mt-9 flex">
@ -183,7 +183,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
) && (
<P className="text-tomato">
{getErrorMsg(
@ -192,7 +192,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
)}
</P>
)}
@ -202,11 +202,11 @@ const LoginState = ({ state, dispatch, strategy }) => {
onClick={() => {
return strategy === 'FIDOUsernameless'
? assertionOptions({
variables: { domain: window.location.hostname }
variables: { domain: window.location.hostname },
})
: dispatch({
type: 'FIDO',
payload: {}
payload: {},
})
}}
buttonClassName="w-full"

View file

@ -45,22 +45,22 @@ const validationSchema = Yup.object({
.required('A password is required')
.min(
PASSWORD_MIN_LENGTH,
`Your password must contain at least ${PASSWORD_MIN_LENGTH} characters`
`Your password must contain at least ${PASSWORD_MIN_LENGTH} characters`,
),
confirmPassword: Yup.string()
.required('Please confirm the password')
.oneOf([Yup.ref('password')], 'Passwords must match')
.oneOf([Yup.ref('password')], 'Passwords must match'),
})
const initialValues = {
password: '',
confirmPassword: ''
confirmPassword: '',
}
const initialState = {
username: null,
role: null,
result: ''
result: '',
}
const reducer = (state, action) => {
@ -72,7 +72,7 @@ const getErrorMsg = (
formikErrors,
formikTouched,
queryError,
mutationError
mutationError,
) => {
if (!formikErrors || !formikTouched) return null
if (queryError || mutationError) return 'Internal server error'
@ -94,32 +94,32 @@ const Register = () => {
onCompleted: ({ validateRegisterLink: info }) => {
if (!info) {
return dispatch({
type: 'failure'
type: 'failure',
})
}
dispatch({
type: 'success',
payload: {
username: info.username,
role: info.role
}
role: info.role,
},
})
},
onError: () =>
dispatch({
type: 'failure'
})
type: 'failure',
}),
}
const { error: queryError, loading } = useQuery(
VALIDATE_REGISTER_LINK,
queryOptions
queryOptions,
)
const [register, { error: mutationError }] = useMutation(REGISTER, {
onCompleted: ({ register: success }) => {
if (success) history.push('/wizard', { fromAuthRegister: true })
}
},
})
return (
@ -148,8 +148,8 @@ const Register = () => {
token: token,
username: state.username,
password: values.password,
role: state.role
}
role: state.role,
},
})
}}>
{({ errors, touched }) => (
@ -175,14 +175,14 @@ const Register = () => {
errors,
touched,
queryError,
mutationError
mutationError,
) && (
<P className="text-tomato">
{getErrorMsg(
errors,
touched,
queryError,
mutationError
mutationError,
)}
</P>
)}

View file

@ -34,7 +34,7 @@ const initialState = {
userID: null,
secret: null,
otpauth: null,
result: null
result: null,
}
const reducer = (state, action) => {
@ -63,7 +63,7 @@ const Reset2FA = () => {
onCompleted: ({ validateReset2FALink: info }) => {
if (!info) {
dispatch({
type: 'failure'
type: 'failure',
})
} else {
dispatch({
@ -71,22 +71,22 @@ const Reset2FA = () => {
payload: {
userID: info.user_id,
secret: info.secret,
otpauth: info.otpauth
}
otpauth: info.otpauth,
},
})
}
},
onError: () => {
dispatch({
type: 'failure'
type: 'failure',
})
}
},
})
const [reset2FA, { error: mutationError }] = useMutation(RESET_2FA, {
onCompleted: ({ reset2FA: success }) => {
success ? history.push('/') : setInvalidToken(true)
}
},
})
const getErrorMsg = () => {
@ -107,8 +107,8 @@ const Reset2FA = () => {
variables: {
token: token,
userID: state.userID,
code: twoFAConfirmation
}
code: twoFAConfirmation,
},
})
}

View file

@ -33,17 +33,17 @@ const validationSchema = Yup.object().shape({
.test(
'len',
'New password must contain more than 8 characters',
val => val.length >= 8
val => val.length >= 8,
),
confirmPassword: Yup.string().oneOf(
[Yup.ref('password'), null],
'Passwords must match'
)
'Passwords must match',
),
})
const initialValues = {
password: '',
confirmPassword: ''
confirmPassword: '',
}
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
@ -78,13 +78,13 @@ const ResetPassword = () => {
onError: () => {
setLoading(false)
setSuccess(false)
}
},
})
const [resetPassword, { error }] = useMutation(RESET_PASSWORD, {
onCompleted: ({ resetPassword: success }) => {
if (success) history.push('/')
}
},
})
return (
@ -112,8 +112,8 @@ const ResetPassword = () => {
variables: {
token: token,
userID: userID,
newPassword: values.confirmPassword
}
newPassword: values.confirmPassword,
},
})
}}>
{({ errors, touched }) => (

View file

@ -47,7 +47,7 @@ const GET_USER_DATA = gql`
}
`
const Setup2FAState = ({ state, dispatch }) => {
const Setup2FAState = ({ state }) => {
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -68,7 +68,7 @@ const Setup2FAState = ({ state, dispatch }) => {
onCompleted: ({ get2FASecret }) => {
setSecret(get2FASecret.secret)
setOtpauth(get2FASecret.otpauth)
}
},
}
const mutationOptions = {
@ -76,8 +76,8 @@ const Setup2FAState = ({ state, dispatch }) => {
username: state.clientField,
password: state.passwordField,
rememberMe: state.rememberMeField,
codeConfirmation: twoFAConfirmation
}
codeConfirmation: twoFAConfirmation,
},
}
const { error: queryError } = useQuery(GET_2FA_SECRET, queryOptions)
@ -86,13 +86,13 @@ const Setup2FAState = ({ state, dispatch }) => {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
},
})
const [setup2FA, { error: mutationError }] = useMutation(SETUP_2FA, {
onCompleted: ({ setup2FA: success }) => {
success ? getUserData() : setInvalidToken(true)
}
},
})
const getErrorMsg = () => {

View file

@ -2,7 +2,7 @@ const STATES = {
LOGIN: 'LOGIN',
SETUP_2FA: 'SETUP2FA',
INPUT_2FA: 'INPUT2FA',
FIDO: 'FIDO'
FIDO: 'FIDO',
}
export { STATES }

View file

@ -90,8 +90,8 @@ const PaperWalletDialog = ({ onConfirmed, onDissmised, open, props }) => {
borderRadius: 8,
minWidth: 656,
bottom: 125,
right: 7
}
right: 7,
},
}}
{...props}>
<div className="p-2">
@ -136,20 +136,20 @@ const Blacklist = () => {
setErrorMsg(errorMessage)
},
onCompleted: () => setDeleteDialog(false),
refetchQueries: () => ['getBlacklistData']
refetchQueries: () => ['getBlacklistData'],
})
const [addEntry] = useMutation(ADD_ROW, {
refetchQueries: () => ['getBlacklistData']
refetchQueries: () => ['getBlacklistData'],
})
const [saveConfig] = useMutation(SAVE_CONFIG, {
refetchQueries: () => ['getData']
refetchQueries: () => ['getData'],
})
const [editMessage] = useMutation(EDIT_BLACKLIST_MESSAGE, {
onError: e => setEditMessageError(e),
refetchQueries: () => ['getBlacklistData']
refetchQueries: () => ['getBlacklistData'],
})
const blacklistData = R.path(['blacklist'])(blacklistResponse) ?? []
@ -172,7 +172,7 @@ const Blacklist = () => {
const handleConfirmDialog = confirm => {
addressReuseSave({
enablePaperWalletOnly: confirm
enablePaperWalletOnly: confirm,
})
setConfirmDialog(false)
}
@ -193,6 +193,7 @@ const Blacklist = () => {
setErrorMsg(`Server error${': ' + res?.errors[0]?.message}`)
}
} catch (e) {
console.error(e)
setErrorMsg('Server error')
}
}
@ -201,8 +202,8 @@ const Blacklist = () => {
editMessage({
variables: {
id: r.id,
content: r.content
}
content: r.content,
},
})
}
@ -222,8 +223,8 @@ const Blacklist = () => {
text: 'Advanced settings',
icon: SettingsIcon,
inverseIcon: ReverseSettingsIcon,
toggle: setAdvancedSettings
}
toggle: setAdvancedSettings,
},
]}>
{!advancedSettings && (
<div className="flex items-center justify-end">
@ -234,7 +235,7 @@ const Blacklist = () => {
onChange={e =>
enablePaperWalletOnly
? addressReuseSave({
enablePaperWalletOnly: e.target.checked
enablePaperWalletOnly: e.target.checked,
})
: setConfirmDialog(true)
}

View file

@ -30,7 +30,7 @@ const BlacklistAdvanced = ({
data,
editBlacklistMessage,
onClose,
mutationError
mutationError,
}) => {
const [selectedMessage, setSelectedMessage] = useState(null)
@ -41,7 +41,7 @@ const BlacklistAdvanced = ({
width: 250,
textAlign: 'left',
size: 'sm',
view: it => R.path(['label'], it)
view: it => R.path(['label'], it),
},
{
name: 'content',
@ -49,7 +49,7 @@ const BlacklistAdvanced = ({
width: 690,
textAlign: 'left',
size: 'sm',
view: it => R.path(['content'], it)
view: it => R.path(['content'], it),
},
{
name: 'edit',
@ -63,7 +63,7 @@ const BlacklistAdvanced = ({
<EditIcon />
</SvgIcon>
</IconButton>
)
),
},
{
name: 'deleteButton',
@ -86,8 +86,8 @@ const BlacklistAdvanced = ({
)}
</SvgIcon>
</IconButton>
)
}
),
},
]
const handleModalClose = () => {
@ -102,12 +102,12 @@ const BlacklistAdvanced = ({
const initialValues = {
label: !R.isNil(selectedMessage) ? selectedMessage.label : '',
content: !R.isNil(selectedMessage) ? selectedMessage.content : ''
content: !R.isNil(selectedMessage) ? selectedMessage.content : '',
}
const validationSchema = Yup.object().shape({
label: Yup.string().required('A label is required!'),
content: Yup.string().required('The message content is required!').trim()
content: Yup.string().required('The message content is required!').trim(),
})
return (

View file

@ -27,10 +27,10 @@ const BlackListModal = ({ onClose, addToBlacklist, errorMsg }) => {
validateOnBlur={false}
validateOnChange={false}
initialValues={{
address: ''
address: '',
}}
validationSchema={Yup.object({
address: Yup.string().trim().required('An address is required')
address: Yup.string().trim().required('An address is required'),
})}
onSubmit={({ address }) => {
handleAddToBlacklist(address.trim())

View file

@ -13,7 +13,7 @@ const BlacklistTable = ({
errorMessage,
setErrorMessage,
deleteDialog,
setDeleteDialog
setDeleteDialog,
}) => {
const [toBeDeleted, setToBeDeleted] = useState()
@ -28,7 +28,7 @@ const BlacklistTable = ({
<div className="ml-2">
<CopyToClipboard>{R.path(['address'], it)}</CopyToClipboard>
</div>
)
),
},
{
name: 'deleteButton',
@ -47,8 +47,8 @@ const BlacklistTable = ({
<DeleteIcon />
</SvgIcon>
</IconButton>
)
}
),
},
]
return (

View file

@ -51,7 +51,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
refetchQueries: () => ['getData']
refetchQueries: () => ['getData'],
})
const save = (rawConfig, accounts) => {

View file

@ -21,7 +21,7 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
const LAST_STEP = machine.numberOfCassettes + machine.numberOfRecyclers + 1
const [{ step, config }, setState] = useState({
step: 0,
config: { active: true }
config: { active: true },
})
const options = getBillOptions(locale, denominations)
@ -34,8 +34,8 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
return save(
toNamespace(
machine.deviceId,
DenominationsSchema.cast(config, { assert: false })
)
DenominationsSchema.cast(config, { assert: false }),
),
)
}
@ -43,7 +43,7 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
setState({
step: step + 1,
config: newConfig
config: newConfig,
})
}
@ -57,10 +57,10 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
inputProps: {
options: options,
labelProp: 'display',
valueProp: 'code'
}
valueProp: 'code',
},
}),
R.range(1, machine.numberOfCassettes + 1)
R.range(1, machine.numberOfCassettes + 1),
),
R.map(
it => ({
@ -71,11 +71,11 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
inputProps: {
options: options,
labelProp: 'display',
valueProp: 'code'
}
valueProp: 'code',
},
}),
R.range(1, machine.numberOfRecyclers + 1)
)
R.range(1, machine.numberOfRecyclers + 1),
),
)
const schema = () =>
@ -119,7 +119,7 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
recycler6:
machine.numberOfRecyclers >= 6 && step >= machine.numberOfCassettes + 6
? Yup.number().required()
: Yup.number().transform(transformNumber).nullable()
: Yup.number().transform(transformNumber).nullable(),
})
return (

View file

@ -19,23 +19,23 @@ import tejo4CassetteFour from 'src/styling/icons/cassettes/tejo/4-cassettes/4-ca
const getCassetesArtworks = () => ({
1: {
1: cassetteOne
1: cassetteOne,
},
2: {
1: cassetteOne,
2: cassetteTwo
2: cassetteTwo,
},
3: {
1: tejo3CassetteOne,
2: tejo3CassetteTwo,
3: tejo3CassetteThree
3: tejo3CassetteThree,
},
4: {
1: tejo4CassetteOne,
2: tejo4CassetteTwo,
3: tejo4CassetteThree,
4: tejo4CassetteFour
}
4: tejo4CassetteFour,
},
})
const WizardStep = ({
@ -48,7 +48,7 @@ const WizardStep = ({
steps,
fiatCurrency,
options,
numberOfCassettes
numberOfCassettes,
}) => {
const label = isLastStep ? 'Finish' : 'Next'
const cassetteIcon = getCassetesArtworks()[numberOfCassettes]
@ -68,7 +68,7 @@ const WizardStep = ({
cassette1: '',
cassette2: '',
cassette3: '',
cassette4: ''
cassette4: '',
}}
enableReinitialize
validationSchema={schema}>
@ -101,7 +101,7 @@ const WizardStep = ({
</Info1>
</div>
</div>
)
),
)}
<img
className="relative -top-5 right-4"

View file

@ -14,7 +14,7 @@ const widthsByNumberOfUnits = {
4: { machine: 205, cassette: 200 },
5: { machine: 180, cassette: 165 },
6: { machine: 165, cassette: 140 },
7: { machine: 130, cassette: 125 }
7: { machine: 130, cassette: 125 },
}
const denominationKeys = [
@ -27,7 +27,7 @@ const denominationKeys = [
'recycler3',
'recycler4',
'recycler5',
'recycler6'
'recycler6',
]
const DenominationsSchema = Yup.object()
@ -90,7 +90,7 @@ const DenominationsSchema = Yup.object()
.min(1)
.max(CURRENCY_MAX)
.nullable()
.transform(transformNumber)
.transform(transformNumber),
})
.test((values, context) =>
R.any(key => !R.isNil(values[key]), denominationKeys)
@ -98,19 +98,19 @@ const DenominationsSchema = Yup.object()
: context.createError({
path: '',
message:
'The recyclers or at least one of the cassettes must have a value'
})
'The recyclers or at least one of the cassettes must have a value',
}),
)
const getElements = (machines, locale = {}) => {
const fiatCurrency = R.prop('fiatCurrency')(locale)
const maxNumberOfCassettes = Math.max(
...R.map(it => it.numberOfCassettes, machines),
0
0,
)
const maxNumberOfRecyclers = Math.max(
...R.map(it => it.numberOfRecyclers, machines),
0
0,
)
const numberOfCashUnits =
maxNumberOfCassettes + Math.ceil(maxNumberOfRecyclers / 2)
@ -122,7 +122,7 @@ const getElements = (machines, locale = {}) => {
options: options,
labelProp: 'display',
valueProp: 'code',
className: 'w-full'
className: 'w-full',
}
: { decimalPlaces: 0 }
@ -133,8 +133,8 @@ const getElements = (machines, locale = {}) => {
width: widthsByNumberOfUnits[numberOfCashUnits]?.machine,
view: it => machines.find(({ deviceId }) => deviceId === it).name,
size: 'sm',
editable: false
}
editable: false,
},
]
R.until(
@ -156,11 +156,11 @@ const getElements = (machines, locale = {}) => {
isHidden: machine =>
it >
machines.find(({ deviceId }) => deviceId === machine.id)
.numberOfCassettes
.numberOfCassettes,
})
return R.add(1, it)
},
1
1,
)
R.until(
@ -182,12 +182,12 @@ const getElements = (machines, locale = {}) => {
it >
Math.ceil(
machines.find(({ deviceId }) => deviceId === machine.id)
.numberOfRecyclers / 2
)
.numberOfRecyclers / 2,
),
})
return R.add(1, it)
},
1
1,
)
return elements

View file

@ -36,7 +36,7 @@ const SAVE_CONFIG = gql`
`
const removeCoinFromOverride = crypto => override =>
R.mergeRight(override, {
cryptoCurrencies: R.without([crypto], override.cryptoCurrencies)
cryptoCurrencies: R.without([crypto], override.cryptoCurrencies),
})
const Commissions = ({ name: SCREEN_KEY }) => {
@ -45,7 +45,7 @@ const Commissions = ({ name: SCREEN_KEY }) => {
const { data, loading } = useQuery(GET_DATA)
const [saveConfig] = useMutation(SAVE_CONFIG, {
refetchQueries: () => ['getData'],
onError: error => setError(error)
onError: error => setError(error),
})
const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)
@ -78,11 +78,11 @@ const Commissions = ({ name: SCREEN_KEY }) => {
const machineOverrides = R.map(removeCoin)(filterMachine(it))
const overrides = machineOverrides.concat(
R.filter(it => !sameMachine(it), it)
R.filter(it => !sameMachine(it), it),
)
const config = {
commissions_overrides: R.prepend(override, overrides)
commissions_overrides: R.prepend(override, overrides),
}
return saveConfig({ variables: { config } })
@ -92,8 +92,8 @@ const Commissions = ({ name: SCREEN_KEY }) => {
? [
{
label: 'Override value',
icon: <OverrideLabelIcon />
}
icon: <OverrideLabelIcon />,
},
]
: []
@ -107,8 +107,8 @@ const Commissions = ({ name: SCREEN_KEY }) => {
text: 'List view',
icon: ListingViewIcon,
inverseIcon: ReverseListingViewIcon,
toggle: setShowMachines
}
toggle: setShowMachines,
},
]}
iconClassName="ml-1"
appendix={

View file

@ -8,7 +8,7 @@ import {
getOverridesSchema,
defaults,
overridesDefaults,
getOrder
getOrder,
} from 'src/pages/Commissions/helper'
import { Table as EditableTable } from 'src/components/editableTable'
@ -23,7 +23,7 @@ const CommissionsDetails = memo(
const orderedCommissionsOverrides = R.sortWith([
R.ascend(getOrder),
R.ascend(R.prop('machine'))
R.ascend(R.prop('machine')),
])(commissionOverrides)
const onEditingDefault = (it, editing) => setEditingDefault(editing)
@ -63,7 +63,7 @@ const CommissionsDetails = memo(
validationSchema={getOverridesSchema(
orderedCommissionsOverrides,
data,
locale
locale,
)}
data={orderedCommissionsOverrides}
elements={overrides(data, currency, orderedCommissionsOverrides)}
@ -73,7 +73,7 @@ const CommissionsDetails = memo(
</Section>
</>
)
}
},
)
export default CommissionsDetails

View file

@ -4,7 +4,7 @@ import {
overridesDefaults,
getCommissions,
getListCommissionsSchema,
commissionsList
commissionsList,
} from 'src/pages/Commissions/helper'
import { Table as EditableTable } from 'src/components/editableTable'
@ -12,39 +12,39 @@ import { Select } from 'src/components/inputs'
const SHOW_ALL = {
code: 'SHOW_ALL',
display: 'Show all'
display: 'Show all',
}
const ORDER_OPTIONS = [
{
code: 'machine',
display: 'Machine name'
display: 'Machine name',
},
{
code: 'cryptoCurrencies',
display: 'Cryptocurrency'
display: 'Cryptocurrency',
},
{
code: 'cashIn',
display: 'Cash-in'
display: 'Cash-in',
},
{
code: 'cashOut',
display: 'Cash-out'
display: 'Cash-out',
},
{
code: 'fixedFee',
display: 'Fixed fee'
display: 'Fixed fee',
},
{
code: 'minimumTx',
display: 'Minimum Tx'
}
display: 'Minimum Tx',
},
]
const getElement = (code, display) => ({
code: code,
display: display || code
display: display || code,
})
const sortCommissionsBy = prop => {
@ -61,12 +61,13 @@ const sortCommissionsBy = prop => {
const filterCommissions = (coinFilter, machineFilter) =>
R.compose(
R.filter(
it => (machineFilter === SHOW_ALL) | (machineFilter.code === it.machine)
it => (machineFilter === SHOW_ALL) | (machineFilter.code === it.machine),
),
R.filter(
it =>
(coinFilter === SHOW_ALL) | (coinFilter.code === it.cryptoCurrencies[0])
)
(coinFilter === SHOW_ALL) |
(coinFilter.code === it.cryptoCurrencies[0]),
),
)
const CommissionsList = memo(
@ -79,7 +80,7 @@ const CommissionsList = memo(
const getMachineCoins = deviceId => {
const override = R.prop('overrides', localeConfig)?.find(
R.propEq('machine', deviceId)
R.propEq('machine', deviceId),
)
const machineCoins = override
@ -96,20 +97,20 @@ const CommissionsList = memo(
const machineData = R.sortBy(
R.prop('display'),
R.map(getMachineElement)(R.prop('machines', data))
R.map(getMachineElement)(R.prop('machines', data)),
)
const machinesCoinsTuples = R.unnest(
R.map(getMachineCoins)(machineData.map(R.prop('code')))
R.map(getMachineCoins)(machineData.map(R.prop('code'))),
)
const commissions = R.map(([deviceId, cryptoCode]) =>
getCommissions(cryptoCode, deviceId, config)
getCommissions(cryptoCode, deviceId, config),
)(machinesCoinsTuples)
const tableData = R.compose(
sortCommissionsBy(orderProp),
filterCommissions(coinFilter, machineFilter)
filterCommissions(coinFilter, machineFilter),
)(commissions)
return (
@ -155,7 +156,7 @@ const CommissionsList = memo(
</div>
</div>
)
}
},
)
export default CommissionsList

View file

@ -14,12 +14,12 @@ import { CURRENCY_MAX } from 'src/utils/constants'
const ALL_MACHINES = {
name: 'All Machines',
deviceId: 'ALL_MACHINES'
deviceId: 'ALL_MACHINES',
}
const ALL_COINS = {
display: 'All Coins',
code: 'ALL_COINS'
code: 'ALL_COINS',
}
const cashInAndOutHeaderStyle = { marginLeft: 6, whiteSpace: 'nowrap' }
@ -68,11 +68,11 @@ const onCryptoChange = (prev, curr, setValue) => {
setValue(curr)
}
const getOverridesFields = (getData, currency, auxElements) => {
const getOverridesFields = (getData, currency) => {
const machineData = [ALL_MACHINES].concat(getData(['machines']))
const rawCryptos = getData(['cryptoCurrencies'])
const cryptoData = [ALL_COINS].concat(
R.map(it => ({ display: it.code, code: it.code }))(rawCryptos ?? [])
R.map(it => ({ display: it.code, code: it.code }))(rawCryptos ?? []),
)
return [
@ -85,8 +85,8 @@ const getOverridesFields = (getData, currency, auxElements) => {
inputProps: {
options: machineData,
valueProp: 'deviceId',
labelProp: 'name'
}
labelProp: 'name',
},
},
{
name: 'cryptoCurrencies',
@ -100,8 +100,8 @@ const getOverridesFields = (getData, currency, auxElements) => {
labelProp: 'display',
multiple: true,
onChange: onCryptoChange,
shouldStayOpen: true
}
shouldStayOpen: true,
},
},
{
header: cashInHeader,
@ -113,8 +113,8 @@ const getOverridesFields = (getData, currency, auxElements) => {
suffix: '%',
bold: bold,
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
header: cashOutHeader,
@ -126,8 +126,8 @@ const getOverridesFields = (getData, currency, auxElements) => {
suffix: '%',
bold: bold,
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
name: 'fixedFee',
@ -139,8 +139,8 @@ const getOverridesFields = (getData, currency, auxElements) => {
suffix: currency,
bold: bold,
inputProps: {
decimalPlaces: 2
}
decimalPlaces: 2,
},
},
{
name: 'minimumTx',
@ -153,8 +153,8 @@ const getOverridesFields = (getData, currency, auxElements) => {
suffix: currency,
bold: bold,
inputProps: {
decimalPlaces: 2
}
decimalPlaces: 2,
},
},
{
name: 'cashOutFixedFee',
@ -167,9 +167,9 @@ const getOverridesFields = (getData, currency, auxElements) => {
suffix: currency,
bold: bold,
inputProps: {
decimalPlaces: 2
}
}
decimalPlaces: 2,
},
},
]
}
@ -185,8 +185,8 @@ const mainFields = currency => [
suffix: '%',
bold: bold,
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
header: cashOutHeader,
@ -199,8 +199,8 @@ const mainFields = currency => [
suffix: '%',
bold: bold,
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
name: 'fixedFee',
@ -214,8 +214,8 @@ const mainFields = currency => [
suffix: currency,
bold: bold,
inputProps: {
decimalPlaces: 2
}
decimalPlaces: 2,
},
},
{
name: 'minimumTx',
@ -229,8 +229,8 @@ const mainFields = currency => [
suffix: currency,
bold: bold,
inputProps: {
decimalPlaces: 2
}
decimalPlaces: 2,
},
},
{
name: 'cashOutFixedFee',
@ -244,9 +244,9 @@ const mainFields = currency => [
suffix: currency,
bold: bold,
inputProps: {
decimalPlaces: 2
}
}
decimalPlaces: 2,
},
},
]
const overrides = (auxData, currency, auxElements) => {
@ -286,7 +286,7 @@ const getSchema = locale => {
.label('Cash-out fixed fee')
.min(0)
.max(highestBill)
.required()
.required(),
})
}
@ -303,7 +303,7 @@ const getAlreadyUsed = (id, machine, values) => {
const alreadyUsed = R.compose(
R.uniq,
R.flatten,
R.map(getCrypto)
R.map(getCrypto),
)(filteredOverrides)
if (machine !== originalMachineId) return alreadyUsed ?? []
@ -316,11 +316,11 @@ const getOverridesSchema = (values, rawData, locale) => {
const machineData = [ALL_MACHINES].concat(getData(['machines']))
const rawCryptos = getData(['cryptoCurrencies'])
const cryptoData = [ALL_COINS].concat(
R.map(it => ({ display: it.code, code: it.code }))(rawCryptos ?? [])
R.map(it => ({ display: it.code, code: it.code }))(rawCryptos ?? []),
)
const bills = getBillOptions(locale, denominations).map(it =>
parseInt(it.code)
parseInt(it.code),
)
const highestBill = R.isEmpty(bills) ? CURRENCY_MAX : Math.max(...bills)
@ -336,7 +336,7 @@ const getOverridesSchema = (values, rawData, locale) => {
const isAllCoins = R.includes(ALL_COINS.code, cryptoCurrencies)
if (isAllMachines && isAllCoins) {
return this.createError({
message: `All machines and all coins should be configured in the default setup table`
message: `All machines and all coins should be configured in the default setup table`,
})
}
@ -346,7 +346,7 @@ const getOverridesSchema = (values, rawData, locale) => {
const machineView = getView(
machineData,
'name',
'deviceId'
'deviceId',
)(machine)
const message = `${codes} already overridden for machine: ${machineView}`
@ -354,7 +354,7 @@ const getOverridesSchema = (values, rawData, locale) => {
return this.createError({ message })
}
return true
}
},
})
.label('Crypto currencies')
.required()
@ -383,7 +383,7 @@ const getOverridesSchema = (values, rawData, locale) => {
.label('Cash-out fixed fee')
.min(0)
.max(highestBill)
.required()
.required(),
})
}
@ -392,7 +392,7 @@ const defaults = {
cashOut: '',
fixedFee: '',
minimumTx: '',
cashOutFixedFee: ''
cashOutFixedFee: '',
}
const overridesDefaults = {
@ -402,7 +402,7 @@ const overridesDefaults = {
cashOut: '',
fixedFee: '',
minimumTx: '',
cashOutFixedFee: ''
cashOutFixedFee: '',
}
const getOrder = ({ machine, cryptoCurrencies }) => {
@ -426,7 +426,7 @@ const createCommissions = (cryptoCode, deviceId, isDefault, config) => {
machine: deviceId,
cryptoCurrencies: [cryptoCode],
default: isDefault,
id: uuidv4()
id: uuidv4(),
}
}
@ -438,7 +438,8 @@ const getCommissions = (cryptoCode, deviceId, config) => {
}
const specificOverride = R.find(
it => it.machine === deviceId && R.includes(cryptoCode)(it.cryptoCurrencies)
it =>
it.machine === deviceId && R.includes(cryptoCode)(it.cryptoCurrencies),
)(overrides)
if (specificOverride !== undefined)
@ -446,7 +447,7 @@ const getCommissions = (cryptoCode, deviceId, config) => {
const machineOverride = R.find(
it =>
it.machine === deviceId && R.includes('ALL_COINS')(it.cryptoCurrencies)
it.machine === deviceId && R.includes('ALL_COINS')(it.cryptoCurrencies),
)(overrides)
if (machineOverride !== undefined)
@ -455,7 +456,7 @@ const getCommissions = (cryptoCode, deviceId, config) => {
const coinOverride = R.find(
it =>
it.machine === 'ALL_MACHINES' &&
R.includes(cryptoCode)(it.cryptoCurrencies)
R.includes(cryptoCode)(it.cryptoCurrencies),
)(overrides)
if (coinOverride !== undefined)
@ -466,7 +467,7 @@ const getCommissions = (cryptoCode, deviceId, config) => {
const getListCommissionsSchema = locale => {
const bills = getBillOptions(locale, denominations).map(it =>
parseInt(it.code)
parseInt(it.code),
)
const highestBill = R.isEmpty(bills) ? CURRENCY_MAX : Math.max(...bills)
@ -497,21 +498,21 @@ const getListCommissionsSchema = locale => {
.label('Cash-out fixed fee')
.min(0)
.max(highestBill)
.required()
.required(),
})
}
const getTextStyle = (obj, isEditing) => {
const getTextStyle = obj => {
return { color: obj.default ? primaryColor : secondaryColorDark }
}
const commissionsList = (auxData, currency, auxElements) => {
const commissionsList = (auxData, currency) => {
const getData = R.path(R.__, auxData)
return getListCommissionsFields(getData, currency, defaults)
}
const getListCommissionsFields = (getData, currency, defaults) => {
const getListCommissionsFields = (getData, currency) => {
const machineData = [ALL_MACHINES].concat(getData(['machines']))
return [
@ -520,7 +521,7 @@ const getListCommissionsFields = (getData, currency, defaults) => {
width: 196,
size: 'sm',
view: getView(machineData, 'name', 'deviceId'),
editable: false
editable: false,
},
{
name: 'cryptoCurrencies',
@ -528,7 +529,7 @@ const getListCommissionsFields = (getData, currency, defaults) => {
width: 150,
view: R.prop(0),
size: 'sm',
editable: false
editable: false,
},
{
header: cashInHeader,
@ -540,8 +541,8 @@ const getListCommissionsFields = (getData, currency, defaults) => {
suffix: '%',
textStyle: obj => getTextStyle(obj),
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
header: cashOutHeader,
@ -554,8 +555,8 @@ const getListCommissionsFields = (getData, currency, defaults) => {
suffix: '%',
textStyle: obj => getTextStyle(obj),
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
name: 'fixedFee',
@ -567,8 +568,8 @@ const getListCommissionsFields = (getData, currency, defaults) => {
suffix: currency,
textStyle: obj => getTextStyle(obj),
inputProps: {
decimalPlaces: 2
}
decimalPlaces: 2,
},
},
{
name: 'minimumTx',
@ -580,8 +581,8 @@ const getListCommissionsFields = (getData, currency, defaults) => {
suffix: currency,
textStyle: obj => getTextStyle(obj),
inputProps: {
decimalPlaces: 2
}
decimalPlaces: 2,
},
},
{
name: 'cashOutFixedFee',
@ -594,9 +595,9 @@ const getListCommissionsFields = (getData, currency, defaults) => {
suffix: currency,
textStyle: obj => getTextStyle(obj),
inputProps: {
decimalPlaces: 2
}
}
decimalPlaces: 2,
},
},
]
}
@ -610,5 +611,5 @@ export {
getOrder,
getCommissions,
getListCommissionsSchema,
commissionsList
commissionsList,
}

View file

@ -10,7 +10,7 @@ import * as Yup from 'yup'
import { TextInput } from 'src/components/inputs/formik'
import {
OVERRIDE_AUTHORIZED,
OVERRIDE_REJECTED
OVERRIDE_REJECTED,
} from 'src/pages/Customers/components/consts'
import { onlyFirstToUpper } from 'src/utils/string'
@ -20,7 +20,7 @@ import {
customerDataSchemas,
formatDates,
tryFormatDate,
getFormattedPhone
getFormattedPhone,
} from './helper'
const IMAGE_WIDTH = 165
@ -50,7 +50,7 @@ const CustomerData = ({
updateCustomRequest,
authorizeCustomRequest,
updateCustomEntry,
checkAgainstSanctions
checkAgainstSanctions,
}) => {
const [previewPhoto, setPreviewPhoto] = useState(null)
const [previewCard, setPreviewCard] = useState(null)
@ -68,21 +68,22 @@ const CustomerData = ({
: 'Failed'
const sortByName = R.sortBy(
R.compose(R.toLower, R.path(['customInfoRequest', 'customRequest', 'name']))
R.compose(
R.toLower,
R.path(['customInfoRequest', 'customRequest', 'name']),
),
)
const customFields = []
const customRequirements = []
const customInfoRequests = sortByName(
R.path(['customInfoRequests'])(customer) ?? []
R.path(['customInfoRequests'])(customer) ?? [],
)
const phone = R.path(['phone'])(customer)
const email = R.path(['email'])(customer)
const smsData = R.path(['subscriberInfo'])(customer)
const isEven = elem => elem % 2 === 0
const getVisibleCards = R.filter(elem => elem.isAvailable)
const initialValues = {
@ -93,23 +94,23 @@ const CustomerData = ({
dateOfBirth: tryFormatDate(rawDob),
gender: R.path(['gender'])(idData) ?? '',
country: R.path(['country'])(idData) ?? '',
expirationDate: tryFormatDate(rawExpirationDate)
expirationDate: tryFormatDate(rawExpirationDate),
},
usSsn: {
usSsn: customer.usSsn ?? ''
usSsn: customer.usSsn ?? '',
},
frontCamera: {
frontCamera: null
frontCamera: null,
},
idCardPhoto: {
idCardPhoto: null
idCardPhoto: null,
},
email: {
email
email,
},
smsData: {
phoneNumber: getFormattedPhone(phone, locale.country)
}
phoneNumber: getFormattedPhone(phone, locale.country),
},
}
const smsDataElements = [
@ -117,8 +118,8 @@ const CustomerData = ({
name: 'phoneNumber',
label: 'Phone number',
component: TextInput,
editable: false
}
editable: false,
},
]
const smsDataSchema = {
@ -128,10 +129,10 @@ const CustomerData = ({
if (R.length(fields) === 2) {
return Yup.object().shape({
[R.head(fields)]: Yup.string().required(),
[R.last(fields)]: Yup.string().required()
[R.last(fields)]: Yup.string().required(),
})
}
})
}),
}
const cards = [
@ -146,18 +147,18 @@ const CustomerData = ({
deleteEditedData: () => deleteEditedData({ idCardData: null }),
save: values =>
editCustomer({
idCardData: R.merge(idData, formatDates(values))
idCardData: R.merge(idData, formatDates(values)),
}),
validationSchema: customerDataSchemas.idCardData,
checkAgainstSanctions: () =>
checkAgainstSanctions({
variables: {
customerId: R.path(['id'])(customer)
}
customerId: R.path(['id'])(customer),
},
}),
initialValues: initialValues.idCardData,
isAvailable: !R.isNil(idData),
editable: true
editable: true,
},
{
fields: smsDataElements,
@ -169,15 +170,15 @@ const CustomerData = ({
save: values => {
editCustomer({
subscriberInfo: {
result: R.merge(smsData, R.omit(['phoneNumber'])(values))
}
result: R.merge(smsData, R.omit(['phoneNumber'])(values)),
},
})
},
validationSchema: smsDataSchema.smsData,
initialValues: initialValues.smsData,
isAvailable: !R.isNil(phone),
hasAdditionalData: !R.isNil(smsData) && !R.isEmpty(smsData),
editable: false
editable: false,
},
{
title: 'Email',
@ -190,13 +191,13 @@ const CustomerData = ({
deleteEditedData: () => deleteEditedData({ email: null }),
initialValues: initialValues.email,
isAvailable: !R.isNil(customer.email),
editable: false
editable: false,
},
{
title: 'Name',
titleIcon: <EditIcon />,
isAvailable: false,
editable: true
editable: true,
},
{
title: 'Sanctions check',
@ -207,7 +208,7 @@ const CustomerData = ({
reject: () => updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED }),
children: () => <Info3>{sanctionsDisplay}</Info3>,
isAvailable: !R.isNil(sanctions),
editable: true
editable: true,
},
{
fields: customerDataElements.frontCamera,
@ -221,7 +222,7 @@ const CustomerData = ({
setPreviewPhoto(null)
return replacePhoto({
newPhoto: values.frontCamera,
photoType: 'frontCamera'
photoType: 'frontCamera',
})
},
cancel: () => setPreviewPhoto(null),
@ -245,7 +246,7 @@ const CustomerData = ({
validationSchema: customerDataSchemas.frontCamera,
initialValues: initialValues.frontCamera,
isAvailable: !R.isNil(customer.frontCameraPath),
editable: true
editable: true,
},
{
fields: customerDataElements.idCardPhoto,
@ -259,7 +260,7 @@ const CustomerData = ({
setPreviewCard(null)
return replacePhoto({
newPhoto: values.idCardPhoto,
photoType: 'idCardPhoto'
photoType: 'idCardPhoto',
})
},
cancel: () => setPreviewCard(null),
@ -283,7 +284,7 @@ const CustomerData = ({
validationSchema: customerDataSchemas.idCardPhoto,
initialValues: initialValues.idCardPhoto,
isAvailable: !R.isNil(customer.idCardPhotoPath),
editable: true
editable: true,
},
{
fields: customerDataElements.usSsn,
@ -298,8 +299,8 @@ const CustomerData = ({
validationSchema: customerDataSchemas.usSsn,
initialValues: initialValues.usSsn,
isAvailable: !R.isNil(customer.usSsn),
editable: true
}
editable: true,
},
]
R.forEach(it => {
@ -310,8 +311,8 @@ const CustomerData = ({
label: it.customInfoRequest.customRequest.name,
value: it.customerData.data ?? '',
component: TextInput,
editable: true
}
editable: true,
},
],
title: it.customInfoRequest.customRequest.name,
titleIcon: <CardIcon />,
@ -321,16 +322,16 @@ const CustomerData = ({
variables: {
customerId: it.customerId,
infoRequestId: it.customInfoRequest.id,
override: OVERRIDE_AUTHORIZED
}
override: OVERRIDE_AUTHORIZED,
},
}),
reject: () =>
authorizeCustomRequest({
variables: {
customerId: it.customerId,
infoRequestId: it.customInfoRequest.id,
override: OVERRIDE_REJECTED
}
override: OVERRIDE_REJECTED,
},
}),
save: values => {
updateCustomRequest({
@ -339,18 +340,18 @@ const CustomerData = ({
infoRequestId: it.customInfoRequest.id,
data: {
info_request_id: it.customInfoRequest.id,
data: values[it.customInfoRequest.id]
}
}
data: values[it.customInfoRequest.id],
},
},
})
},
deleteEditedData: () => {},
validationSchema: Yup.object().shape({
[it.customInfoRequest.id]: Yup.string()
[it.customInfoRequest.id]: Yup.string(),
}),
initialValues: {
[it.customInfoRequest.id]: it.customerData.data ?? ''
}
[it.customInfoRequest.id]: it.customerData.data ?? '',
},
})
}, customInfoRequests)
@ -363,27 +364,27 @@ const CustomerData = ({
label: it.label,
value: it.value ?? '',
component: TextInput,
editable: true
}
editable: true,
},
],
title: it.label,
titleIcon: <EditIcon />,
save: values => {
updateCustomEntry({
fieldId: it.id,
value: values[it.label]
value: values[it.label],
})
},
deleteEditedData: () => {},
validationSchema: Yup.object().shape({
[it.label]: Yup.string()
[it.label]: Yup.string(),
}),
initialValues: {
[it.label]: it.value ?? ''
}
[it.label]: it.value ?? '',
},
})
},
R.path(['customFields'])(customer) ?? []
R.path(['customFields'])(customer) ?? [],
)
R.forEach(
@ -393,10 +394,10 @@ const CustomerData = ({
name: it,
label: onlyFirstToUpper(it),
component: TextInput,
editable: false
editable: false,
})
},
R.keys(smsData) ?? []
R.keys(smsData) ?? [],
)
const externalCompliance = R.map(it => ({
@ -404,26 +405,26 @@ const CustomerData = ({
{
name: 'externalId',
label: 'Third Party ID',
editable: false
editable: false,
},
{
name: 'lastKnownStatus',
label: 'Last Known Status',
editable: false
editable: false,
},
{
name: 'lastUpdated',
label: 'Last Updated',
editable: false
}
editable: false,
},
],
titleIcon: <CardIcon />,
title: `External Info [${it.service}]`,
initialValues: it ?? {
externalId: '',
lastKnownStatus: '',
lastUpdated: ''
}
lastUpdated: '',
},
}))(customer.externalCompliance ?? [])
const editableCard = (
@ -443,9 +444,9 @@ const CustomerData = ({
hasImage,
hasAdditionalData,
editable,
checkAgainstSanctions
checkAgainstSanctions,
},
idx
idx,
) => {
return (
<div className="mb-4">
@ -474,7 +475,7 @@ const CustomerData = ({
const nonEditableCard = (
{ title, state, titleIcon, fields, hasImage, initialValues, children },
idx
idx,
) => {
return (
<div className="mb-4">

View file

@ -12,14 +12,14 @@ const CustomerNotes = ({
createNote,
deleteNote,
editNote,
timezone
timezone,
}) => {
const [openModal, setOpenModal] = useState(false)
const [editing, setEditing] = useState(null)
const customerNotes = R.sort(
(a, b) => new Date(b?.created).getTime() - new Date(a?.created).getTime(),
customer.notes ?? []
customer.notes ?? [],
)
const handleModalClose = () => {
@ -39,7 +39,7 @@ const CustomerNotes = ({
if (!R.equals(it.newContent, it.oldContent)) {
editNote({
noteId: it.noteId,
newContent: it.newContent
newContent: it.newContent,
})
}
setEditing(null)

View file

@ -49,7 +49,7 @@ export const PhotoCard = ({
date,
src,
setPhotosDialog,
setPhotoClickIndex
setPhotoClickIndex,
}) => {
return (
<Paper

View file

@ -16,7 +16,7 @@ import DataIcon from 'src/styling/icons/button/data/zodiac.svg?react'
import { ActionButton } from 'src/components/buttons'
import {
OVERRIDE_AUTHORIZED,
OVERRIDE_REJECTED
OVERRIDE_REJECTED,
} from 'src/pages/Customers/components/consts'
// TODO: Enable for next release
// import DiscountReversedIcon from 'src/styling/icons/button/discount/white.svg?react'
@ -30,7 +30,7 @@ import {
CustomerDetails,
TransactionsList,
CustomerSidebar,
Wizard
Wizard,
} from './components'
import { getFormattedPhone, getName, formatPhotosData } from './helper'
@ -298,67 +298,67 @@ const CustomerProfile = memo(() => {
const {
data: customerResponse,
refetch: getCustomer,
loading: customerLoading
loading: customerLoading,
} = useQuery(GET_CUSTOMER, {
variables: { customerId }
variables: { customerId },
})
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
const { data: activeCustomRequests } = useQuery(GET_ACTIVE_CUSTOM_REQUESTS, {
variables: {
onlyEnabled: true
}
onlyEnabled: true,
},
})
const [setCustomEntry] = useMutation(SET_CUSTOM_ENTRY, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [editCustomEntry] = useMutation(EDIT_CUSTOM_ENTRY, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [replaceCustomerPhoto] = useMutation(REPLACE_CUSTOMER_PHOTO, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [editCustomerData] = useMutation(EDIT_CUSTOMER, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [deleteCustomerEditedData] = useMutation(DELETE_EDITED_CUSTOMER, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [setCustomer] = useMutation(SET_CUSTOMER, {
onCompleted: () => {
getCustomer()
},
onError: error => setError(error)
onError: error => setError(error),
})
const [authorizeCustomRequest] = useMutation(SET_AUTHORIZED_REQUEST, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [setCustomerCustomInfoRequest] = useMutation(
SET_CUSTOMER_CUSTOM_INFO_REQUEST,
{
onCompleted: () => getCustomer()
}
onCompleted: () => getCustomer(),
},
)
const [createNote] = useMutation(CREATE_NOTE, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [deleteNote] = useMutation(DELETE_NOTE, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [editNote] = useMutation(EDIT_NOTE, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const saveCustomEntry = it => {
@ -366,8 +366,8 @@ const CustomerProfile = memo(() => {
variables: {
customerId,
label: it.title,
value: it.data
}
value: it.data,
},
})
setWizard(null)
}
@ -377,31 +377,31 @@ const CustomerProfile = memo(() => {
variables: {
customerId,
fieldId: it.fieldId,
value: it.value
}
value: it.value,
},
})
}
const [enableTestCustomer] = useMutation(ENABLE_TEST_CUSTOMER, {
variables: { customerId },
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [disableTestCustomer] = useMutation(DISABLE_TEST_CUSTOMER, {
variables: { customerId },
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const [checkAgainstSanctions] = useLazyQuery(CHECK_AGAINST_SANCTIONS, {
onCompleted: () => getCustomer()
onCompleted: () => getCustomer(),
})
const updateCustomer = it =>
setCustomer({
variables: {
customerId,
customerInput: it
}
customerInput: it,
},
})
const replacePhoto = it => {
@ -409,8 +409,8 @@ const CustomerProfile = memo(() => {
variables: {
customerId,
newPhoto: it.newPhoto,
photoType: it.photoType
}
photoType: it.photoType,
},
})
setWizard(null)
}
@ -419,8 +419,8 @@ const CustomerProfile = memo(() => {
editCustomerData({
variables: {
customerId,
customerEdit: it
}
customerEdit: it,
},
})
setWizard(null)
}
@ -429,8 +429,8 @@ const CustomerProfile = memo(() => {
deleteCustomerEditedData({
variables: {
customerId,
customerEdit: it
}
customerEdit: it,
},
})
const createCustomerNote = it =>
@ -438,23 +438,23 @@ const CustomerProfile = memo(() => {
variables: {
customerId,
title: it.title,
content: it.content
}
content: it.content,
},
})
const deleteCustomerNote = it =>
deleteNote({
variables: {
noteId: it.noteId
}
noteId: it.noteId,
},
})
const editCustomerNote = it =>
editNote({
variables: {
noteId: it.noteId,
newContent: it.newContent
}
newContent: it.newContent,
},
})
const onClickSidebarItem = code => setClickedItem(code)
@ -464,7 +464,7 @@ const CustomerProfile = memo(() => {
const customerData = R.path(['customer'])(customerResponse) ?? []
const rawTransactions = R.path(['transactions'])(customerData) ?? []
const sortedTransactions = R.sort(R.descend(R.prop('cryptoAtoms')))(
rawTransactions
rawTransactions,
)
const name = getName(customerData)
const blocked =
@ -477,12 +477,12 @@ const CustomerProfile = memo(() => {
const isPhotos = clickedItem === 'photos'
const frontCameraData = R.pick(['frontCameraPath', 'frontCameraAt'])(
customerData
customerData,
)
const txPhotosData =
sortedTransactions &&
R.map(R.pick(['id', 'txCustomerPhotoPath', 'txCustomerPhotoAt']))(
sortedTransactions
sortedTransactions,
)
const photosData = formatPhotosData(R.append(frontCameraData, txPhotosData))
@ -491,8 +491,8 @@ const CustomerProfile = memo(() => {
{
photoDir: 'id-card-photo',
path: customerData.idCardPhotoPath,
date: customerData.idCardPhotoAt
}
date: customerData.idCardPhotoAt,
},
]
: []
@ -503,7 +503,7 @@ const CustomerProfile = memo(() => {
const customInfoRequirementOptions =
activeCustomRequests?.customInfoRequests?.map(it => ({
value: it.id,
display: it.customRequest.name
display: it.customRequest.name,
})) ?? []
const email = R.path(['email'])(customerData)
@ -565,7 +565,7 @@ const CustomerProfile = memo(() => {
InverseIcon={AuthorizeReversedIcon}
onClick={() =>
updateCustomer({
suspendedUntil: null
suspendedUntil: null,
})
}>
{`Unsuspend customer`}
@ -582,7 +582,7 @@ const CustomerProfile = memo(() => {
updateCustomer({
authorizedOverride: blocked
? OVERRIDE_AUTHORIZED
: OVERRIDE_REJECTED
: OVERRIDE_REJECTED,
})
}>
{`${blocked ? 'Authorize' : 'Block'} customer`}

View file

@ -108,10 +108,10 @@ const Customers = () => {
const {
data: customersResponse,
loading: customerLoading,
refetch
refetch,
} = useQuery(GET_CUSTOMERS, {
variables,
onCompleted: data => setFilteredCustomers(R.path(['customers'])(data))
onCompleted: data => setFilteredCustomers(R.path(['customers'])(data)),
})
const { data: filtersResponse, loading: loadingFilters } =
@ -122,9 +122,9 @@ const Customers = () => {
refetchQueries: () => [
{
query: GET_CUSTOMERS,
variables
}
]
variables,
},
],
})
const configData = R.path(['config'])(customersResponse) ?? []
@ -137,14 +137,14 @@ const Customers = () => {
R.assoc(
'authorizedStatus',
getAuthorizedStatus(c, triggers, customRequirementsData),
c
c,
)
const byAuthorized = c => (c.authorizedStatus.label === 'Pending' ? 0 : 1)
const byLastActive = c => new Date(R.prop('lastActive', c) ?? '0')
const customersData = R.pipe(
R.map(setAuthorizedStatus),
R.sortWith([R.ascend(byAuthorized), R.descend(byLastActive)])
R.sortWith([R.ascend(byAuthorized), R.descend(byLastActive)]),
)(filteredCustomers ?? [])
const onFilterChange = filters => {
@ -157,7 +157,7 @@ const Customers = () => {
name: filtersObject.name,
email: filtersObject.email,
address: filtersObject.address,
id: filtersObject.id
id: filtersObject.id,
})
refetch && refetch()
@ -165,7 +165,7 @@ const Customers = () => {
const onFilterDelete = filter => {
const newFilters = R.filter(
f => !R.whereEq(R.pick(['type', 'value'], f), filter)
f => !R.whereEq(R.pick(['type', 'value'], f), filter),
)(filters)
setFilters(newFilters)
@ -177,7 +177,7 @@ const Customers = () => {
name: filtersObject.name,
email: filtersObject.email,
address: filtersObject.address,
id: filtersObject.id
id: filtersObject.id,
})
refetch && refetch()
@ -192,7 +192,7 @@ const Customers = () => {
name: filtersObject.name,
email: filtersObject.email,
address: filtersObject.address,
id: filtersObject.id
id: filtersObject.id,
})
refetch && refetch()
@ -224,7 +224,7 @@ const Customers = () => {
}
labels={[
{ label: 'Cash-in', icon: <TxInIcon /> },
{ label: 'Cash-out', icon: <TxOutIcon /> }
{ label: 'Cash-out', icon: <TxOutIcon /> },
]}
/>
{filters.length > 0 && (

View file

@ -8,44 +8,37 @@ import TxOutIcon from 'src/styling/icons/direction/cash-out.svg?react'
import { getFormattedPhone, getName } from './helper'
const CustomersList = ({
data,
locale,
onClick,
loading,
triggers,
customRequests
}) => {
const CustomersList = ({ data, locale, onClick, loading }) => {
const elements = [
{
header: 'Phone/email',
width: 199,
view: it => `${getFormattedPhone(it.phone, locale.country) || ''}
${it.email || ''}`
${it.email || ''}`,
},
{
header: 'Name',
width: 241,
view: getName
view: getName,
},
{
header: 'Total Txs',
width: 126,
textAlign: 'right',
view: it => `${Number.parseInt(it.totalTxs)}`
view: it => `${Number.parseInt(it.totalTxs)}`,
},
{
header: 'Total spent',
width: 152,
textAlign: 'right',
view: it =>
`${Number.parseFloat(it.totalSpent)} ${it.lastTxFiatCode ?? ''}`
`${Number.parseFloat(it.totalSpent)} ${it.lastTxFiatCode ?? ''}`,
},
{
header: 'Last active',
width: 133,
view: it =>
(it.lastActive && format('yyyy-MM-dd', new Date(it.lastActive))) ?? ''
(it.lastActive && format('yyyy-MM-dd', new Date(it.lastActive))) ?? '',
},
{
header: 'Last transaction',
@ -62,13 +55,13 @@ const CustomersList = ({
{hasLastTx && lastIcon}
</>
)
}
},
},
{
header: 'Status',
width: 191,
view: it => <MainStatus statuses={[it.authorizedStatus]} />
}
view: it => <MainStatus statuses={[it.authorizedStatus]} />,
},
]
return (

View file

@ -13,7 +13,7 @@ import {
requirementElements,
formatDates,
REQUIREMENT,
ID_CARD_DATA
ID_CARD_DATA,
} from './helper'
const LAST_STEP = 2
@ -41,12 +41,12 @@ const Wizard = ({
error,
customInfoRequirementOptions,
addCustomerData,
addPhoto
addPhoto,
}) => {
const [selectedValues, setSelectedValues] = useState(null)
const [{ step, config }, setState] = useState({
step: 1
step: 1,
})
const isIdCardData = values => values?.requirement === ID_CARD_DATA
@ -67,7 +67,7 @@ const Wizard = ({
case 'customerDataUpload':
return addPhoto({
newPhoto: R.head(R.values(it)),
photoType: R.head(R.keys(it))
photoType: R.head(R.keys(it)),
})
case 'customEntry':
return save(newConfig)
@ -82,7 +82,7 @@ const Wizard = ({
setState({
step: step + 1,
config: newConfig
config: newConfig,
})
}

View file

@ -17,13 +17,14 @@ const getValidationSchema = countryCodes =>
.test('is-valid-number', 'That is not a valid phone number', value => {
try {
return countryCodes.some(countryCode =>
parsePhoneNumberWithError(value, countryCode).isValid()
parsePhoneNumberWithError(value, countryCode).isValid(),
)
} catch (e) {
console.error(e)
return false
}
})
.trim()
.trim(),
})
const formatPhoneNumber = (countryCodes, numberStr) => {
@ -36,7 +37,7 @@ const formatPhoneNumber = (countryCodes, numberStr) => {
}
const initialValues = {
phoneNumber: ''
phoneNumber: '',
}
const getErrorMsg = (formikErrors, formikTouched) => {
@ -49,7 +50,7 @@ const getErrorMsg = (formikErrors, formikTouched) => {
const CreateCustomerModal = ({ showModal, handleClose, onSubmit, locale }) => {
const possibleCountries = R.append(
locale?.country,
R.map(it => it.country, locale?.overrides ?? [])
R.map(it => it.country, locale?.overrides ?? []),
)
return (
@ -68,9 +69,9 @@ const CreateCustomerModal = ({ showModal, handleClose, onSubmit, locale }) => {
variables: {
phoneNumber: formatPhoneNumber(
possibleCountries,
values.phoneNumber
)
}
values.phoneNumber,
),
},
})
}}>
{({ errors, touched }) => (

View file

@ -18,29 +18,29 @@ const CustomerDetails = memo(({ customer, photosData, locale, timezone }) => {
{
header: 'Phone number',
size: 172,
value: getFormattedPhone(customer.phone, locale.country)
}
value: getFormattedPhone(customer.phone, locale.country),
},
]
if (idNumber)
elements.push({
header: 'ID number',
size: 172,
value: idNumber
value: idNumber,
})
if (usSsn)
elements.push({
header: 'US SSN',
size: 127,
value: usSsn
value: usSsn,
})
if (email)
elements.push({
header: 'Email',
size: 190,
value: email
value: email,
})
return (

View file

@ -17,26 +17,26 @@ const CustomerSidebar = ({ isSelected, onClick }) => {
code: 'overview',
display: 'Overview',
Icon: OverviewIcon,
InverseIcon: OverviewReversedIcon
InverseIcon: OverviewReversedIcon,
},
{
code: 'customerData',
display: 'Customer data',
Icon: CustomerDataIcon,
InverseIcon: CustomerDataReversedIcon
InverseIcon: CustomerDataReversedIcon,
},
{
code: 'notes',
display: 'Notes',
Icon: NoteIcon,
InverseIcon: NoteReversedIcon
InverseIcon: NoteReversedIcon,
},
{
code: 'photos',
display: 'Photos & files',
Icon: Photos,
InverseIcon: PhotosReversedIcon
}
InverseIcon: PhotosReversedIcon,
},
]
return (
@ -46,7 +46,7 @@ const CustomerSidebar = ({ isSelected, onClick }) => {
key={idx}
className={classnames({
'gap-4 p-4 cursor-pointer flex items-center': true,
'bg-comet2': isSelected(code)
'bg-comet2': isSelected(code),
})}
onClick={() => onClick(code)}>
{isSelected(code) ? <Icon /> : <InverseIcon />}
@ -54,7 +54,7 @@ const CustomerSidebar = ({ isSelected, onClick }) => {
noMargin
className={classnames({
'text-comet2': true,
'text-white font-bold': isSelected(code)
'text-white font-bold': isSelected(code),
})}>
{display}
</P>

View file

@ -20,7 +20,7 @@ import SaveReversedIcon from 'src/styling/icons/circle buttons/save/white.svg?re
import { ActionButton } from 'src/components/buttons'
import {
OVERRIDE_REJECTED,
OVERRIDE_PENDING
OVERRIDE_PENDING,
} from 'src/pages/Customers/components/consts'
const ReadOnlyField = ({ field, value }) => {
@ -73,9 +73,8 @@ const EditableCard = ({
children = () => {},
validationSchema,
initialValues,
deleteEditedData,
editable,
checkAgainstSanctions
checkAgainstSanctions,
}) => {
const formRef = useRef()

View file

@ -13,7 +13,7 @@ const PhotosCard = memo(({ photosData, timezone }) => {
const sortedPhotosData = R.sortWith(
[(a, b) => R.has('id', a) - R.has('id', b), R.descend(R.prop('date'))],
photosData
photosData,
)
const singlePhoto = R.head(sortedPhotosData)

View file

@ -43,7 +43,7 @@ const PhotosCarousel = memo(({ photosData, timezone }) => {
formatDate(
photosData[currentIndex]?.date,
timezone,
'yyyy-MM-dd HH:mm'
'yyyy-MM-dd HH:mm',
)}
</div>
</>

View file

@ -25,16 +25,16 @@ const TransactionsList = ({ customer, data, loading }) => {
size: 127,
value: ifNotNull(
customer.totalTxs,
`${Number.parseInt(customer.totalTxs)}`
)
`${Number.parseInt(customer.totalTxs)}`,
),
},
{
header: 'Transaction volume',
size: 167,
value: ifNotNull(
customer.totalSpent,
`${Number.parseFloat(customer.totalSpent)} ${customer.lastTxFiatCode}`
)
`${Number.parseFloat(customer.totalSpent)} ${customer.lastTxFiatCode}`,
),
},
{
header: 'Last active',
@ -43,7 +43,7 @@ const TransactionsList = ({ customer, data, loading }) => {
!R.isNil(timezone) &&
((customer.lastActive &&
formatDate(customer.lastActive, timezone, 'yyyy-MM-dd')) ??
'')
''),
},
{
header: 'Last transaction',
@ -54,14 +54,14 @@ const TransactionsList = ({ customer, data, loading }) => {
<LastTxIcon className="mr-3" />
{`${Number.parseFloat(customer.lastTxFiat)}
${customer.lastTxFiatCode}`}
</>
)
</>,
),
},
{
header: 'Last used machine',
size: 198,
value: ifNotNull(lastUsedMachineName, <>{lastUsedMachineName}</>)
}
value: ifNotNull(lastUsedMachineName, <>{lastUsedMachineName}</>),
},
]
const tableElements = [
@ -75,12 +75,12 @@ const TransactionsList = ({ customer, data, loading }) => {
<TxInIcon className="mr-3" />
)}
</>
)
),
},
{
header: 'Machine',
width: 160,
view: R.path(['machineName'])
view: R.path(['machineName']),
},
{
header: 'Transaction ID',
@ -89,7 +89,7 @@ const TransactionsList = ({ customer, data, loading }) => {
<CopyToClipboard className="font-museo whitespace-nowrap overflow-hidden text-ellipsis">
{it.id}
</CopyToClipboard>
)
),
},
{
header: 'Cash',
@ -100,7 +100,7 @@ const TransactionsList = ({ customer, data, loading }) => {
{`${Number.parseFloat(it.fiat)} `}
<Label2 inline>{it.fiatCode}</Label2>
</>
)
),
},
{
header: 'Crypto',
@ -109,22 +109,22 @@ const TransactionsList = ({ customer, data, loading }) => {
view: it => (
<>
{`${toUnit(new BigNumber(it.cryptoAtoms), it.cryptoCode).toFormat(
5
5,
)} `}
<Label2 inline>{it.cryptoCode}</Label2>
</>
)
),
},
{
header: 'Date',
width: 100,
view: it => formatDate(it.created, timezone, 'yyyyMMdd')
view: it => formatDate(it.created, timezone, 'yyyyMMdd'),
},
{
header: 'Time (h:m:s)',
width: 130,
view: it => formatDate(it.created, timezone, 'HH:mm:ss')
}
view: it => formatDate(it.created, timezone, 'HH:mm:ss'),
},
]
return (

View file

@ -27,10 +27,10 @@ const Upload = ({ type }) => {
setData({
preview: isImage
? URL.createObjectURL(R.head(acceptedData))
: R.head(acceptedData).name
: R.head(acceptedData).name,
})
},
[isImage, type, setFieldValue]
[isImage, type, setFieldValue],
)
const { getRootProps, getInputProps } = useDropzone({ onDrop })

View file

@ -12,5 +12,5 @@ export {
CustomerSidebar,
EditableCard,
Wizard,
Upload
Upload,
}

View file

@ -9,12 +9,12 @@ import { TextInput } from 'src/components/inputs/formik'
const initialValues = {
title: '',
content: ''
content: '',
}
const validationSchema = Yup.object().shape({
title: Yup.string().required().trim().max(25),
content: Yup.string().required()
content: Yup.string().required(),
})
const NewNoteModal = ({ showModal, onClose, onSubmit, errorMsg }) => {

View file

@ -17,11 +17,11 @@ const NoteEdit = ({ note, cancel, edit, timezone }) => {
const formRef = useRef()
const validationSchema = Yup.object().shape({
content: Yup.string()
content: Yup.string(),
})
const initialValues = {
content: note.content
content: note.content,
}
return (
@ -33,8 +33,8 @@ const NoteEdit = ({ note, cancel, edit, timezone }) => {
{ delimited: ', ' },
intervalToDuration({
start: toTimezone(new Date(note.lastEditedAt), timezone),
end: toTimezone(new Date(), timezone)
})
end: toTimezone(new Date(), timezone),
}),
)}
{` ago`}
</P>
@ -74,7 +74,7 @@ const NoteEdit = ({ note, cancel, edit, timezone }) => {
edit({
noteId: note.id,
newContent: content,
oldContent: note.content
oldContent: note.content,
})
}
innerRef={formRef}>

View file

@ -10,7 +10,7 @@ import * as Yup from 'yup'
import {
RadioGroup,
TextInput,
Autocomplete
Autocomplete,
} from 'src/components/inputs/formik'
import { MANUAL } from 'src/utils/constants'
@ -24,7 +24,7 @@ const ID_CARD_DATA = 'idCardData'
const getAuthorizedStatus = (it, triggers, customRequests) => {
const fields = R.concat(
['frontCamera', 'idCardData', 'idCardPhoto', 'email', 'usSsn', 'sanctions'],
R.map(ite => ite.id, customRequests)
R.map(ite => ite.id, customRequests),
)
const fieldsWithPathSuffix = ['frontCamera', 'idCardPhoto']
@ -34,13 +34,13 @@ const getAuthorizedStatus = (it, triggers, customRequests) => {
: fieldName
const manualOverrides = R.filter(
ite => R.equals(R.toLower(ite.automation), MANUAL),
triggers?.overrides ?? []
triggers?.overrides ?? [],
)
return (
!!R.find(
ite => R.equals(ite.requirement, triggerName),
manualOverrides
manualOverrides,
) || R.equals(R.toLower(triggers.automation ?? ''), MANUAL)
)
}
@ -50,7 +50,7 @@ const getAuthorizedStatus = (it, triggers, customRequests) => {
if (uuidValidate(ite)) {
const request = R.find(
iter => iter.infoRequestId === ite,
it.customInfoRequests
it.customInfoRequests,
)
return !R.isNil(request) && R.equals(request.override, 'automatic')
}
@ -69,7 +69,7 @@ const getAuthorizedStatus = (it, triggers, customRequests) => {
if (uuidValidate(ite)) {
const request = R.find(
iter => iter.infoRequestId === ite,
it.customInfoRequests
it.customInfoRequests,
)
return !R.isNil(request) && R.equals(request.override, 'blocked')
}
@ -115,11 +115,11 @@ const getName = it => {
const entryOptions = [
{ display: 'Custom entry', code: 'custom' },
{ display: 'Populate existing requirement', code: 'requirement' }
{ display: 'Populate existing requirement', code: 'requirement' },
]
const dataOptions = [
{ display: 'Text', code: 'text' }
{ display: 'Text', code: 'text' },
// TODO: Requires backend modifications to support File and Image
// { display: 'File', code: 'file' },
// { display: 'Image', code: 'image' }
@ -130,12 +130,12 @@ const requirementOptions = [
{ display: 'ID data', code: 'idCardData' },
{ display: 'US SSN', code: 'usSsn' },
{ display: 'Email', code: 'email' },
{ display: 'Customer camera', code: 'frontCamera' }
{ display: 'Customer camera', code: 'frontCamera' },
]
const customTextOptions = [
{ label: 'Data entry title', name: 'title' },
{ label: 'Data entry', name: 'data' }
{ label: 'Data entry', name: 'data' },
]
const customUploadOptions = [{ label: 'Data entry title', name: 'title' }]
@ -144,40 +144,40 @@ const entryTypeSchema = Yup.lazy(values => {
if (values.entryType === 'custom') {
return Yup.object().shape({
entryType: Yup.string().required(),
dataType: Yup.string().required()
dataType: Yup.string().required(),
})
} else if (values.entryType === 'requirement') {
return Yup.object().shape({
entryType: Yup.string().required(),
requirement: Yup.string().required()
requirement: Yup.string().required(),
})
}
})
const customFileSchema = Yup.object().shape({
title: Yup.string().required(),
file: Yup.mixed().required()
file: Yup.mixed().required(),
})
const customImageSchema = Yup.object().shape({
title: Yup.string().required(),
image: Yup.mixed().required()
image: Yup.mixed().required(),
})
const customTextSchema = Yup.object().shape({
title: Yup.string().required(),
data: Yup.string().required()
data: Yup.string().required(),
})
const updateRequirementOptions = it => [
{
display: 'Custom information requirement',
code: 'custom'
code: 'custom',
},
...it
...it,
]
const EntryType = ({ customInfoRequirementOptions }) => {
const EntryType = () => {
const { values } = useFormikContext()
const displayCustomOptions = values.entryType === CUSTOM
@ -265,7 +265,7 @@ const ManualDataEntry = ({ selectedValues, customInfoRequirementOptions }) => {
isOptionEqualToValue={R.eqProps('code')}
labelProp={'display'}
options={customInfoRequirementOptions}
onChange={(evt, it) => {}}
onChange={() => {}}
/>
)}
<div className="mb-6">
@ -297,29 +297,29 @@ const customElements = {
options: customTextOptions,
Component: ManualDataEntry,
initialValues: { data: '', title: '' },
saveType: 'customEntry'
saveType: 'customEntry',
},
file: {
schema: customFileSchema,
options: customUploadOptions,
Component: ManualDataEntry,
initialValues: { file: null, title: '' },
saveType: 'customEntryUpload'
saveType: 'customEntryUpload',
},
image: {
schema: customImageSchema,
options: customUploadOptions,
Component: ManualDataEntry,
initialValues: { image: null, title: '' },
saveType: 'customEntryUpload'
}
saveType: 'customEntryUpload',
},
}
const entryType = {
schema: entryTypeSchema,
options: entryOptions,
Component: EntryType,
initialValues: { entryType: '' }
initialValues: { entryType: '' },
}
// Customer data
@ -330,44 +330,44 @@ const customerDataElements = {
name: 'firstName',
label: 'First name',
component: TextInput,
editable: true
editable: true,
},
{
name: 'documentNumber',
label: 'ID number',
component: TextInput,
editable: true
editable: true,
},
{
name: 'dateOfBirth',
label: 'Birthdate',
component: TextInput,
editable: true
editable: true,
},
{
name: 'gender',
label: 'Gender',
component: TextInput,
editable: true
editable: true,
},
{
name: 'lastName',
label: 'Last name',
component: TextInput,
editable: true
editable: true,
},
{
name: 'expirationDate',
label: 'Expiration date',
component: TextInput,
editable: true
editable: true,
},
{
name: 'country',
label: 'Country',
component: TextInput,
editable: true
}
editable: true,
},
],
usSsn: [
{
@ -375,8 +375,8 @@ const customerDataElements = {
label: 'US SSN',
component: TextInput,
size: 190,
editable: true
}
editable: true,
},
],
email: [
{
@ -384,11 +384,11 @@ const customerDataElements = {
label: 'Email',
component: TextInput,
size: 190,
editable: false
}
editable: false,
},
],
idCardPhoto: [{ name: 'idCardPhoto' }],
frontCamera: [{ name: 'frontCamera' }]
frontCamera: [{ name: 'frontCamera' }],
}
const customerDataSchemas = {
@ -399,7 +399,7 @@ const customerDataSchemas = {
dateOfBirth: Yup.string()
.test({
test: val => isValid(parse(new Date(), 'yyyy-MM-dd', val)),
message: 'Date must be in format YYYY-MM-DD'
message: 'Date must be in format YYYY-MM-DD',
})
.required(),
gender: Yup.string().required(),
@ -407,22 +407,22 @@ const customerDataSchemas = {
expirationDate: Yup.string()
.test({
test: val => isValid(parse(new Date(), 'yyyy-MM-dd', val)),
message: 'Date must be in format YYYY-MM-DD'
message: 'Date must be in format YYYY-MM-DD',
})
.required()
.required(),
}),
usSsn: Yup.object().shape({
usSsn: Yup.string().required()
usSsn: Yup.string().required(),
}),
idCardPhoto: Yup.object().shape({
idCardPhoto: Yup.mixed().required()
idCardPhoto: Yup.mixed().required(),
}),
frontCamera: Yup.object().shape({
frontCamera: Yup.mixed().required()
frontCamera: Yup.mixed().required(),
}),
email: Yup.object().shape({
email: Yup.string().required()
})
email: Yup.string().required(),
}),
}
const requirementElements = {
@ -437,44 +437,44 @@ const requirementElements = {
dateOfBirth: '',
gender: '',
country: '',
expirationDate: ''
expirationDate: '',
},
saveType: 'customerData'
saveType: 'customerData',
},
usSsn: {
schema: customerDataSchemas.usSsn,
options: customerDataElements.usSsn,
Component: ManualDataEntry,
initialValues: { usSsn: '' },
saveType: 'customerData'
saveType: 'customerData',
},
email: {
schema: customerDataSchemas.email,
options: customerDataElements.email,
Component: ManualDataEntry,
initialValues: { email: '' },
saveType: 'customerData'
saveType: 'customerData',
},
idCardPhoto: {
schema: customerDataSchemas.idCardPhoto,
options: customerDataElements.idCardPhoto,
Component: ManualDataEntry,
initialValues: { idCardPhoto: null },
saveType: 'customerDataUpload'
saveType: 'customerDataUpload',
},
frontCamera: {
schema: customerDataSchemas.frontCamera,
options: customerDataElements.frontCamera,
Component: ManualDataEntry,
initialValues: { frontCamera: null },
saveType: 'customerDataUpload'
saveType: 'customerDataUpload',
},
custom: {
// schema: customerDataSchemas.customInfoRequirement,
Component: ManualDataEntry,
initialValues: { customInfoRequirement: null },
saveType: 'customInfoRequirement'
}
saveType: 'customInfoRequirement',
},
}
const tryFormatDate = rawDate => {
@ -485,6 +485,7 @@ const tryFormatDate = rawDate => {
''
)
} catch (err) {
console.error(err)
return ''
}
}
@ -493,8 +494,8 @@ const formatDates = values => {
R.map(
elem =>
(values[elem] = format('yyyyMMdd')(
parse(new Date(), 'yyyy-MM-dd', values[elem])
))
parse(new Date(), 'yyyy-MM-dd', values[elem]),
)),
)(['dateOfBirth', 'expirationDate'])
return values
}
@ -520,13 +521,13 @@ const addPhotoDir = R.map(it => {
const standardizeKeys = R.map(R.compose(R.fromPairs, R.map(mapKeys), R.toPairs))
const filterByPhotoAvailable = R.filter(
tx => !R.isNil(tx.date) && !R.isNil(tx.path)
tx => !R.isNil(tx.date) && !R.isNil(tx.path),
)
const formatPhotosData = R.compose(
filterByPhotoAvailable,
addPhotoDir,
standardizeKeys
standardizeKeys,
)
export {
@ -543,5 +544,5 @@ export {
tryFormatDate,
REQUIREMENT,
CUSTOM,
ID_CARD_DATA
ID_CARD_DATA,
}

View file

@ -35,7 +35,7 @@ const Alerts = ({ onReset, onExpand, size }) => {
const alerts = R.path(['alerts'])(data) ?? []
const machines = R.compose(
R.map(R.prop('name')),
R.indexBy(R.prop('deviceId'))
R.indexBy(R.prop('deviceId')),
)(data?.machines ?? [])
const alertsLength = alerts.length

View file

@ -13,13 +13,13 @@ const icons = {
error: <WarningIcon style={{ height: 20, width: 20, marginRight: 12 }} />,
fiatBalance: (
<CashBoxEmpty style={{ height: 18, width: 18, marginRight: 14 }} />
)
),
}
const links = {
error: '/maintenance/machine-status',
fiatBalance: '/maintenance/cash-cassettes',
cryptoBalance: '/maintenance/funding'
cryptoBalance: '/maintenance/funding',
}
const AlertsTable = ({ numToRender, alerts, machines }) => {

View file

@ -1,2 +1,3 @@
import Alerts from './Alerts'
export default Alerts

View file

@ -47,24 +47,24 @@ const Footer = () => {
const tickerName = tickerIdx > -1 ? accountsConfig[tickerIdx].display : ''
const cashInNoCommission = parseFloat(
R.path(['cryptoRates', 'withoutCommissions', key, 'cashIn'])(data)
R.path(['cryptoRates', 'withoutCommissions', key, 'cashIn'])(data),
)
const cashOutNoCommission = parseFloat(
R.path(['cryptoRates', 'withoutCommissions', key, 'cashOut'])(data)
R.path(['cryptoRates', 'withoutCommissions', key, 'cashOut'])(data),
)
const avgOfAskBid = new BigNumber(
(cashInNoCommission + cashOutNoCommission) / 2
(cashInNoCommission + cashOutNoCommission) / 2,
).toFormat(2)
const cashIn = new BigNumber(
parseFloat(
R.path(['cryptoRates', 'withCommissions', key, 'cashIn'])(data)
)
R.path(['cryptoRates', 'withCommissions', key, 'cashIn'])(data),
),
).toFormat(2)
const cashOut = new BigNumber(
parseFloat(
R.path(['cryptoRates', 'withCommissions', key, 'cashOut'])(data)
)
R.path(['cryptoRates', 'withCommissions', key, 'cashOut'])(data),
),
).toFormat(2)
return (

View file

@ -12,9 +12,9 @@
}
.footer1:hover {
transition: min-height 0.5s ease-in;
min-height: 200px;
}
transition: min-height 0.5s ease-in;
min-height: 200px;
}
.content1 {
width: 1200px;

View file

@ -1,2 +1,3 @@
import Footer from './Footer'
export default Footer

View file

@ -39,7 +39,7 @@ const RightSide = () => {
<CollapsibleCard
className={classnames({
'flex-[0.1]': alertsSize === cardState.SHRUNK,
'flex-[0.9]': alertsSize === cardState.EXPANDED
'flex-[0.9]': alertsSize === cardState.EXPANDED,
})}
state={alertsSize}
shrunkComponent={
@ -62,7 +62,7 @@ const RightSide = () => {
className={classnames({
'flex-[0.1]': systemStatusSize === cardState.SHRUNK,
'flex-1': systemStatusSize === cardState.DEFAULT,
'flex-[0.9]': systemStatusSize === cardState.EXPANDED
'flex-[0.9]': systemStatusSize === cardState.EXPANDED,
})}
state={systemStatusSize}
shrunkComponent={

View file

@ -12,7 +12,7 @@ const PercentageChart = ({ cashIn, cashOut }) => {
const percentageClasses = {
'h-35 rounded-sm flex items-center justify-center': true,
'min-w-2 rounded-xs': value < 5 && value > 0
'min-w-2 rounded-xs': value < 5 && value > 0,
}
return (

View file

@ -23,14 +23,14 @@ const reducer = (acc, tx) => {
const timeFrameMS = {
Day: 24 * 3600 * 1000,
Week: 7 * 24 * 3600 * 1000,
Month: 30 * 24 * 3600 * 1000
Month: 30 * 24 * 3600 * 1000,
}
const RefLineChart = ({
data: realData,
previousTimeData,
previousProfit,
timeFrame
timeFrame,
}) => {
const svgRef = useRef()
@ -55,7 +55,7 @@ const RefLineChart = ({
if (!aggregatedTX.length && previousTimeData.length) {
const mockPoint1 = {
created: new Date().toISOString(),
profit: 0
profit: 0,
}
const mockPoint2 = mockPoint(mockPoint1, -timeFrameMS[timeFrame], 1)
return [[mockPoint1, mockPoint2], false]
@ -64,7 +64,7 @@ const RefLineChart = ({
if (aggregatedTX.length && !previousTimeData.length) {
const mockPoint1 = {
created: new Date().toISOString(),
profit: 1
profit: 1,
}
const mockPoint2 = mockPoint(mockPoint1, -timeFrameMS[timeFrame], 0)
return [[mockPoint1, mockPoint2], false]
@ -75,13 +75,13 @@ const RefLineChart = ({
R.append(
{
created: new Date(
Date.now() - timeFrameMS[timeFrame]
Date.now() - timeFrameMS[timeFrame],
).toISOString(),
profit: previousProfit
profit: previousProfit,
},
aggregatedTX
aggregatedTX,
),
false
false,
]
}
// the boolean value is for zeroProfit. It makes the line render at y = 0 instead of y = 50% of container height
@ -120,7 +120,7 @@ const RefLineChart = ({
.data([
{ offset: '0%', color: 'var(--zircon)' },
{ offset: '25%', color: 'var(--zircon)' },
{ offset: '100%', color: 'var(--ghost)' }
{ offset: '100%', color: 'var(--ghost)' },
])
.enter()
.append('stop')

View file

@ -17,9 +17,9 @@ const Graph = ({ data, timeFrame, timezone }) => {
top: 20,
right: 3.5,
bottom: 27,
left: 33.5
left: 33.5,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -28,7 +28,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
const periodDomains = {
Day: [NOW - DAY, NOW],
Week: [NOW - WEEK, NOW],
Month: [NOW - MONTH, NOW]
Month: [NOW - MONTH, NOW],
}
const dataPoints = useMemo(
@ -37,27 +37,27 @@ const Graph = ({ data, timeFrame, timezone }) => {
freq: 24,
step: 60 * 60 * 1000,
tick: d3.utcHour.every(4),
labelFormat: '%H:%M'
labelFormat: '%H:%M',
},
Week: {
freq: 7,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
Month: {
freq: 30,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(2),
labelFormat: '%d'
}
labelFormat: '%d',
},
}),
[]
[],
)
const filterDay = useCallback(
x => (timeFrame === 'Day' ? x.getUTCHours() === 0 : x.getUTCDate() === 1),
[timeFrame]
[timeFrame],
)
const getPastAndCurrentDayLabels = useCallback(d => {
@ -74,11 +74,11 @@ const Graph = ({ data, timeFrame, timezone }) => {
const previousDateMonth = previousDate.getUTCMonth()
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
format('EEE', add({ days: i }, startOfWeek(new Date())))
format('EEE', add({ days: i }, startOfWeek(new Date()))),
)
const months = Array.from(Array(12)).map((_, i) =>
format('LLL', add({ months: i }, startOfYear(new Date())))
format('LLL', add({ months: i }, startOfYear(new Date()))),
)
return {
@ -89,7 +89,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
current:
currentDateMonth !== previousDateMonth
? months[currentDateMonth]
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
}
}, [])
@ -111,7 +111,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
return points
},
[NOW, dataPoints, timeFrame]
[NOW, dataPoints, timeFrame],
)
const x = d3
@ -123,7 +123,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.scaleLinear()
.domain([
0,
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.05
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.05,
])
.nice()
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -137,7 +137,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.attr('height', GRAPH_HEIGHT - GRAPH_MARGIN.top - GRAPH_MARGIN.bottom)
.attr('fill', 'var(--ghost)')
},
[GRAPH_MARGIN]
[GRAPH_MARGIN],
)
const buildXAxis = useCallback(
@ -145,7 +145,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -153,12 +153,12 @@ const Graph = ({ data, timeFrame, timezone }) => {
.ticks(dataPoints[timeFrame].tick)
.tickFormat(d => {
return d3.timeFormat(dataPoints[timeFrame].labelFormat)(
d.getTime() + d.getTimezoneOffset() * MINUTE
d.getTime() + d.getTimezoneOffset() * MINUTE,
)
})
}),
)
.call(g => g.select('.domain').remove()),
[GRAPH_MARGIN, dataPoints, timeFrame, x]
[GRAPH_MARGIN, dataPoints, timeFrame, x],
)
const buildYAxis = useCallback(
@ -173,12 +173,12 @@ const Graph = ({ data, timeFrame, timezone }) => {
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
return numberToFiatAmount(d)
})
}),
)
.call(g => g.select('.domain').remove())
.selectAll('text')
.attr('dy', '-0.25rem'),
[GRAPH_MARGIN, y]
[GRAPH_MARGIN, y],
)
const buildGrid = useCallback(
@ -196,7 +196,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.attr('x2', d => 0.5 + x(d))
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('stroke-width', 1)
.attr('stroke-width', 1),
)
// Horizontal lines
.call(g =>
@ -208,7 +208,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.attr('y1', d => 0.5 + y(d))
.attr('y2', d => 0.5 + y(d))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
// Thick vertical lines
.call(g =>
@ -223,7 +223,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.attr('y1', GRAPH_MARGIN.top - 10)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('stroke-width', 2)
.join('text')
.join('text'),
)
// Left side breakpoint label
.call(g => {
@ -262,7 +262,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.text(labels.current)
})
},
[GRAPH_MARGIN, buildTicks, getPastAndCurrentDayLabels, x, y, filterDay]
[GRAPH_MARGIN, buildTicks, getPastAndCurrentDayLabels, x, y, filterDay],
)
const formatTicksText = useCallback(
@ -273,7 +273,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.style('fill', 'var(--comet)')
.style('stroke-width', 0)
.style('font-family', 'var(--museo)'),
[]
[],
)
const formatText = useCallback(
@ -284,7 +284,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
.style('fill', 'var(--comet)')
.style('stroke-width', 0)
.style('font-family', 'var(--museo)'),
[]
[],
)
const formatTicks = useCallback(() => {
@ -304,11 +304,11 @@ const Graph = ({ data, timeFrame, timezone }) => {
})
.attr('cy', d => y(new BigNumber(d.fiat).toNumber()))
.attr('fill', d =>
d.txClass === 'cashIn' ? 'var(--java)' : 'var(--neon)'
d.txClass === 'cashIn' ? 'var(--java)' : 'var(--neon)',
)
.attr('r', 3.5)
},
[data, offset, x, y]
[data, offset, x, y],
)
const drawChart = useCallback(() => {
@ -334,7 +334,7 @@ const Graph = ({ data, timeFrame, timezone }) => {
drawData,
formatText,
formatTicks,
formatTicksText
formatTicksText,
])
useEffect(() => {

View file

@ -1,5 +1,6 @@
import React from 'react'
import { Info1, Label1 } from 'src/components/typography/index'
const InfoWithLabel = ({ info, label }) => {
return (
<div className="flex flex-col">

View file

@ -27,7 +27,7 @@ const Nav = ({ handleSetRange, showPicker }) => {
className={classnames({
'cursor-pointer text-comet': true,
'font-bold text-zodiac border-b-zodiac border-b-2':
isSelected(it)
isSelected(it),
})}>
{it}
</div>

View file

@ -52,7 +52,7 @@ const GET_DATA = gql`
const SystemPerformance = () => {
const [selectedRange, setSelectedRange] = useState('Day')
const { data, loading } = useQuery(GET_DATA, {
variables: { excludeTestingCustomers: true }
variables: { excludeTestingCustomers: true },
})
const fiatLocale = fromNamespace('locale')(data?.config).fiatCurrency
const timezone = fromNamespace('locale')(data?.config).timezone
@ -62,7 +62,7 @@ const SystemPerformance = () => {
const periodDomains = {
Day: [NOW - DAY, NOW],
Week: [NOW - WEEK, NOW],
Month: [NOW - MONTH, NOW]
Month: [NOW - MONTH, NOW],
}
const isInRangeAndNoError = getLastTimePeriod => t => {
@ -74,11 +74,11 @@ const SystemPerformance = () => {
t.error === null &&
isAfter(
toTimezone(t.created, timezone),
toTimezone(periodDomains[selectedRange][1], timezone)
toTimezone(periodDomains[selectedRange][1], timezone),
) &&
isAfter(
toTimezone(periodDomains[selectedRange][0], timezone),
toTimezone(t.created, timezone)
toTimezone(t.created, timezone),
)
)
}
@ -86,11 +86,11 @@ const SystemPerformance = () => {
t.error === null &&
isAfter(
toTimezone(periodDomains[selectedRange][1], timezone),
toTimezone(t.created, timezone)
toTimezone(t.created, timezone),
) &&
isAfter(
toTimezone(t.created, timezone),
toTimezone(periodDomains[selectedRange][0], timezone)
toTimezone(periodDomains[selectedRange][0], timezone),
)
)
}
@ -104,10 +104,10 @@ const SystemPerformance = () => {
}
const transactionsToShow = R.map(convertFiatToLocale)(
R.filter(isInRangeAndNoError(false), data?.transactions ?? [])
R.filter(isInRangeAndNoError(false), data?.transactions ?? []),
)
const transactionsLastTimePeriod = R.map(convertFiatToLocale)(
R.filter(isInRangeAndNoError(true), data?.transactions ?? [])
R.filter(isInRangeAndNoError(true), data?.transactions ?? []),
)
const getNumTransactions = () => {
@ -121,7 +121,7 @@ const SystemPerformance = () => {
return R.reduce(
(acc, value) => acc.plus(value.profit),
new BigNumber(0),
transactions
transactions,
)
}
@ -141,7 +141,7 @@ const SystemPerformance = () => {
const getDirectionPercent = () => {
const [cashIn, cashOut] = R.partition(R.propEq('txClass', 'cashIn'))(
transactionsToShow
transactionsToShow,
)
const totalLength = cashIn.length + cashOut.length
if (totalLength === 0) {
@ -150,7 +150,7 @@ const SystemPerformance = () => {
return {
cashIn: Math.round((cashIn.length / totalLength) * 100),
cashOut: Math.round((cashOut.length / totalLength) * 100)
cashOut: Math.round((cashOut.length / totalLength) * 100),
}
}
@ -160,7 +160,7 @@ const SystemPerformance = () => {
'text-tomato': percentChange < 0,
'text-spring4': percentChange > 0,
'text-comet': percentChange === 0,
'flex items-center justify-center gap-1': true
'flex items-center justify-center gap-1': true,
}
const getPercentageIcon = () => {

View file

@ -1,2 +1,3 @@
import SystemPerformance from './SystemPerformance'
export default SystemPerformance

View file

@ -28,14 +28,14 @@ const GET_CONFIG = gql`
const StyledCell = styled(TableCell)({
borderBottom: '4px solid white',
padding: 0,
paddingLeft: '15px'
paddingLeft: '15px',
})
const HeaderCell = styled(TableCell)({
borderBottom: '4px solid white',
padding: 0,
paddingLeft: '15px',
backgroundColor: 'white'
backgroundColor: 'white',
})
const MachinesTable = ({ machines = [], numToRender }) => {
@ -44,7 +44,7 @@ const MachinesTable = ({ machines = [], numToRender }) => {
const { data } = useQuery(GET_CONFIG)
const fillingPercentageSettings = fromNamespace(
'notifications',
R.path(['config'], data) ?? {}
R.path(['config'], data) ?? {},
)
const getPercent = (notes, capacity = 500) => {
@ -55,7 +55,7 @@ const MachinesTable = ({ machines = [], numToRender }) => {
const percent = getPercent(notes, capacity)
const percentageThreshold = R.pipe(
R.path([`fillingPercentageCassette${cassetteIdx}`]),
R.defaultTo(PERCENTAGE_THRESHOLD)
R.defaultTo(PERCENTAGE_THRESHOLD),
)(fillingPercentageSettings)
return percent < percentageThreshold ? (
<TL2 className="text-tomato">{`${percent}%`}</TL2>
@ -66,13 +66,13 @@ const MachinesTable = ({ machines = [], numToRender }) => {
const redirect = ({ name, deviceId }) => {
return history.push(`/machines/${deviceId}`, {
selectedMachine: name
selectedMachine: name,
})
}
const maxNumberOfCassettes = Math.max(
...R.map(it => it.numberOfCassettes, machines),
0
0,
)
return (
@ -119,7 +119,7 @@ const MachinesTable = ({ machines = [], numToRender }) => {
sx={{
borderBottom: '4px solid white',
padding: 0,
paddingLeft: '15px'
paddingLeft: '15px',
}}
align="left">
<div className="flex items-center">
@ -138,14 +138,14 @@ const MachinesTable = ({ machines = [], numToRender }) => {
<StyledCell key={idx} align="left">
{makePercentageText(
it,
machine.cashUnits[`cassette${it}`]
machine.cashUnits[`cassette${it}`],
)}
</StyledCell>
) : (
<StyledCell key={idx} align="left">
<TL2>{`— %`}</TL2>
</StyledCell>
)
),
)}
</TableRow>
)

View file

@ -2,28 +2,28 @@ import {
backgroundColor,
offColor,
errorColor,
primaryColor
primaryColor,
} from 'src/styling/variables'
const styles = {
label: {
margin: 0,
color: offColor
color: offColor,
},
row: {
backgroundColor: backgroundColor,
borderBottom: 'none'
borderBottom: 'none',
},
clickableRow: {
cursor: 'pointer'
cursor: 'pointer',
},
header: {
display: 'flex',
alignItems: 'center',
whiteSpace: 'pre'
whiteSpace: 'pre',
},
error: {
color: errorColor
color: errorColor,
},
button: {
color: primaryColor,
@ -32,46 +32,46 @@ const styles = {
padding: 0,
textTransform: 'none',
'&:hover': {
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
marginBottom: -40
marginBottom: -40,
},
buttonLabel: {
position: 'absolute',
bottom: 160,
marginBottom: 0
marginBottom: 0,
},
statusHeader: {
marginLeft: 2
marginLeft: 2,
},
tableBody: {
overflow: 'auto'
overflow: 'auto',
},
tl2: {
display: 'inline'
display: 'inline',
},
label1: {
display: 'inline'
display: 'inline',
},
machinesTableContainer: {
height: 220
height: 220,
},
expandedMachinesTableContainer: {
height: 414
height: 414,
},
centerLabel: {
marginBottom: 0,
padding: 0,
textAlign: 'center'
textAlign: 'center',
},
machineNameWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
alignItems: 'center',
},
machineRedirectIcon: {
marginLeft: 10
}
marginLeft: 10,
},
}
export default styles

View file

@ -60,7 +60,7 @@ const SystemStatus = ({ onReset, onExpand, size }) => {
const machinesTableContainerClasses = {
'h-55': !showAllItems,
'h-103': showAllItems
'h-103': showAllItems,
}
// const uptime = data?.uptime ?? [{}]
return (

View file

@ -1,2 +1,3 @@
import SystemStatus from './SystemStatus'
export default SystemStatus

View file

@ -1,2 +1,3 @@
import Dashboard from './Dashboard'
export default Dashboard

View file

@ -13,7 +13,7 @@ import {
Td,
THead,
TBody,
Table
Table,
} from 'src/components/fake-table/Table.jsx'
import Sidebar from 'src/components/layout/Sidebar.jsx'
import {
@ -22,7 +22,7 @@ import {
Info2,
Info3,
Label1,
Label3
Label3,
} from 'src/components/typography/index.jsx'
import CopyToClipboard from 'src/components/CopyToClipboard.jsx'
@ -36,7 +36,7 @@ const NODE_NOT_CONNECTED_ERR =
const sizes = {
big: 165,
time: 140,
date: 130
date: 130,
}
const GET_FUNDING = gql`
@ -67,7 +67,7 @@ const getConfirmedTotal = list => {
list
.filter(it => !it.errorMsg)
.map(it => new BigNumber(it.fiatConfirmedBalance))
.reduce(sumReducer, new BigNumber(0))
.reduce(sumReducer, new BigNumber(0)),
)
}
@ -76,7 +76,7 @@ const getPendingTotal = list => {
list
.filter(it => !it.errorMsg)
.map(it => new BigNumber(it.fiatPending))
.reduce(sumReducer, new BigNumber(0))
.reduce(sumReducer, new BigNumber(0)),
)
}
@ -90,22 +90,22 @@ const Funding = () => {
fiatValue: 1000.0,
date: new Date(),
performedBy: null,
pending: true
pending: true,
},
{
cryptoAmount: 10.0,
balance: 12.23,
fiatValue: 12000.0,
date: new Date(),
performedBy: null
performedBy: null,
},
{
cryptoAmount: 5.0,
balance: 5.0,
fiatValue: 50000.0,
date: new Date(),
performedBy: null
}
performedBy: null,
},
]
const isSelected = it => {
@ -122,11 +122,11 @@ const Funding = () => {
const itemRender = (it, active) => {
const itemClass = {
[classes.item]: true,
[classes.inactiveItem]: !active
[classes.inactiveItem]: !active,
}
const wrapperClass = {
[classes.itemWrapper]: true,
[classes.error]: it.errorMsg
[classes.error]: it.errorMsg,
}
return (
@ -212,7 +212,7 @@ const Funding = () => {
</Info3>
<Label3 inline noMargin className="ml-2">
{`(${signIfPositive(selected.fiatPending)} ${formatNumber(
selected.fiatPending
selected.fiatPending,
)} pending)`}
</Label3>
</div>
@ -226,7 +226,7 @@ const Funding = () => {
key={selected.cryptoCode}>
{formatAddress(
selected.cryptoCode,
selected.fundingAddress
selected.fundingAddress,
)}
</CopyToClipboard>
</strong>

View file

@ -104,4 +104,4 @@
font-weight: 400;
width: 375px;
margin: 12px 24px;
}
}

View file

@ -20,7 +20,7 @@ import {
LocaleSchema,
OverridesSchema,
localeDefaults,
overridesDefaults
overridesDefaults,
} from './helper'
const GET_DATA = gql`
@ -113,7 +113,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
const [saveConfig] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
refetchQueries: () => ['getData'],
onError: error => setError(error)
onError: error => setError(error),
})
const [dataToSave, setDataToSave] = useState(null)
@ -229,7 +229,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
elements={overrides(data, localeOverrides, onChangeCoin)}
disableAdd={R.compose(R.isEmpty, R.difference)(
data?.machines.map(m => m.deviceId) ?? [],
localeOverrides?.map(o => o.machine) ?? []
localeOverrides?.map(o => o.machine) ?? [],
)}
setEditing={onEditingOverrides}
forceDisable={isEditingDefault}

View file

@ -7,7 +7,7 @@ import { labels as timezoneList } from 'src/utils/timezone-list'
const getFields = (getData, names, onChange, auxElements = []) => {
return R.filter(
it => R.includes(it.name, names),
allFields(getData, onChange, auxElements)
allFields(getData, onChange, auxElements),
)
}
@ -17,7 +17,7 @@ const allFields = (getData, onChange, auxElements = []) => {
return R.compose(
it => `${R.prop(code)(it)} ${it?.isBeta ? '(Beta)' : ''}`,
R.find(R.propEq(compare ?? 'code', it))
R.find(R.propEq(compare ?? 'code', it)),
)(data)
}
@ -60,8 +60,8 @@ const allFields = (getData, onChange, auxElements = []) => {
options: it =>
R.concat(findSuggestion(it))(suggestionFilter(machineData)),
valueProp: 'deviceId',
labelProp: 'name'
}
labelProp: 'name',
},
},
{
name: 'country',
@ -72,8 +72,8 @@ const allFields = (getData, onChange, auxElements = []) => {
inputProps: {
options: countryData,
valueProp: 'code',
labelProp: 'display'
}
labelProp: 'display',
},
},
{
name: 'fiatCurrency',
@ -84,8 +84,8 @@ const allFields = (getData, onChange, auxElements = []) => {
inputProps: {
options: currencyData,
valueProp: 'code',
labelProp: 'code'
}
labelProp: 'code',
},
},
{
name: 'languages',
@ -97,8 +97,8 @@ const allFields = (getData, onChange, auxElements = []) => {
options: languageData,
valueProp: 'code',
labelProp: 'display',
multiple: true
}
multiple: true,
},
},
{
name: 'cryptoCurrencies',
@ -112,8 +112,8 @@ const allFields = (getData, onChange, auxElements = []) => {
labelProp: 'codeLabel',
multiple: true,
optionsLimit: null,
onChange
}
onChange,
},
},
{
name: 'timezone',
@ -124,9 +124,9 @@ const allFields = (getData, onChange, auxElements = []) => {
inputProps: {
options: timezonesData,
valueProp: 'code',
labelProp: 'label'
}
}
labelProp: 'label',
},
},
]
}
@ -137,7 +137,7 @@ const mainFields = (auxData, configureCoin) => {
getData,
['country', 'fiatCurrency', 'languages', 'cryptoCurrencies', 'timezone'],
configureCoin,
undefined
undefined,
)
}
@ -148,7 +148,7 @@ const overrides = (auxData, auxElements, configureCoin) => {
getData,
['machine', 'country', 'languages', 'cryptoCurrencies'],
configureCoin,
auxElements
auxElements,
)
}
@ -157,14 +157,14 @@ const LocaleSchema = Yup.object().shape({
fiatCurrency: Yup.string().label('Fiat currency').required(),
languages: Yup.array().label('Languages').required().min(1).max(4),
cryptoCurrencies: Yup.array().label('Crypto currencies').required().min(1),
timezone: Yup.string().label('Timezone').required()
timezone: Yup.string().label('Timezone').required(),
})
const OverridesSchema = Yup.object().shape({
machine: Yup.string().label('Machine').required(),
country: Yup.string().label('Country').required(),
languages: Yup.array().label('Languages').required().min(1).max(4),
cryptoCurrencies: Yup.array().label('Crypto currencies').required().min(1)
cryptoCurrencies: Yup.array().label('Crypto currencies').required().min(1),
})
const localeDefaults = {
@ -172,14 +172,14 @@ const localeDefaults = {
fiatCurrency: '',
languages: [],
cryptoCurrencies: [],
timezone: ''
timezone: '',
}
const overridesDefaults = {
machine: '',
country: '',
languages: [],
cryptoCurrencies: []
cryptoCurrencies: [],
}
export {
@ -188,5 +188,5 @@ export {
LocaleSchema,
OverridesSchema,
localeDefaults,
overridesDefaults
overridesDefaults,
}

View file

@ -71,4 +71,4 @@
.buttonsWrapper > * {
margin: auto 6px;
}
}

View file

@ -12,7 +12,7 @@ import {
TableRow,
TableHeader,
TableBody,
TableCell
TableCell,
} from 'src/components/table/index.js'
import { formatDate } from 'src/utils/timezones.js'
@ -91,8 +91,8 @@ const Logs = () => {
{
variables: { deviceId, limit: NUM_LOG_RESULTS },
skip: !selected,
onCompleted: () => setSaveMessage('')
}
onCompleted: () => setSaveMessage(''),
},
)
if (machineResponse?.machines?.length && !selected) {

View file

@ -13,7 +13,7 @@ import {
TableRow,
TableHeader,
TableBody,
TableCell
TableCell,
} from 'src/components/table/index.js'
import { startCase } from 'src/utils/string.js'
import { formatDate } from 'src/utils/timezones.js'
@ -73,8 +73,8 @@ const Logs = () => {
const { data, loading: dataLoading } = useQuery(GET_SERVER_DATA, {
onCompleted: () => setSaveMessage(''),
variables: {
limit: NUM_LOG_RESULTS
}
limit: NUM_LOG_RESULTS,
},
})
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
const timezone = R.path(['config', 'locale_timezone'], configResponse)
@ -82,7 +82,7 @@ const Logs = () => {
const defaultLogLevels = [
{ code: 'error', display: 'Error' },
{ code: 'info', display: 'Info' },
{ code: 'debug', display: 'Debug' }
{ code: 'debug', display: 'Debug' },
]
const serverVersion = data?.serverVersion
const processStates = data?.uptime ?? []
@ -93,9 +93,9 @@ const Logs = () => {
R.concat(defaultLogLevels),
R.map(it => ({
code: R.path(['logLevel'])(it),
display: startCase(R.path(['logLevel'])(it))
display: startCase(R.path(['logLevel'])(it)),
})),
R.path(['serverLogs'])
R.path(['serverLogs']),
)
const handleLogLevelChange = logLevel => {
@ -166,7 +166,7 @@ const Logs = () => {
data.serverLogs
.filter(
log =>
logLevel === SHOW_ALL || log.logLevel === logLevel.code
logLevel === SHOW_ALL || log.logLevel === logLevel.code,
)
.map((log, idx) => (
<TableRow key={idx} size="sm">
@ -175,7 +175,7 @@ const Logs = () => {
formatDate(
log.timestamp,
timezone,
'yyyy-MM-dd HH:mm'
'yyyy-MM-dd HH:mm',
)}
</TableCell>
<TableCell>{log.logLevel}</TableCell>

View file

@ -17,4 +17,4 @@
.uptimeContainer {
margin: auto 0 auto 0;
}
}

View file

@ -12,7 +12,7 @@ import { NumberInput, Autocomplete } from 'src/components/inputs/formik'
const initialValues = {
customer: '',
discount: ''
discount: '',
}
const validationSchema = Yup.object().shape({
@ -20,7 +20,7 @@ const validationSchema = Yup.object().shape({
discount: Yup.number()
.required('A discount rate is required!')
.min(0, 'Discount rate should be a positive number!')
.max(100, 'Discount rate should have a maximum value of 100%!')
.max(100, 'Discount rate should have a maximum value of 100%!'),
})
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
@ -39,14 +39,14 @@ const IndividualDiscountModal = ({
onClose,
creationError,
addDiscount,
customers
customers,
}) => {
const handleAddDiscount = (customer, discount) => {
addDiscount({
variables: {
customerId: customer,
discount: parseInt(discount)
}
discount: parseInt(discount),
},
})
setShowModal(false)
}
@ -85,7 +85,7 @@ const IndividualDiscountModal = ({
it?.idCardData?.firstName && it?.idCardData?.lastName
? ` `
: ``
}${it?.idCardData?.lastName ?? ``} (${it.phone})`
}${it?.idCardData?.lastName ?? ``} (${it.phone})`,
}))(customers)}
labelProp="display"
valueProp="code"

View file

@ -69,8 +69,8 @@ const IndividualDiscounts = () => {
const [createDiscount, { error: creationError }] = useMutation(
CREATE_DISCOUNT,
{
refetchQueries: () => ['individualDiscounts']
}
refetchQueries: () => ['individualDiscounts'],
},
)
const [deleteDiscount] = useMutation(DELETE_DISCOUNT, {
@ -79,7 +79,7 @@ const IndividualDiscounts = () => {
setErrorMsg(errorMessage)
},
onCompleted: () => setDeleteDialog(false),
refetchQueries: () => ['individualDiscounts']
refetchQueries: () => ['individualDiscounts'],
})
const elements = [
@ -95,7 +95,7 @@ const IndividualDiscounts = () => {
<span>{t.customer.phone}</span>
</div>
)
}
},
},
{
header: 'Name',
@ -115,7 +115,7 @@ const IndividualDiscounts = () => {
: ``
}${customer.idCardData.lastName ?? ``}`}</>
)
}
},
},
{
header: 'Discount rate',
@ -126,7 +126,7 @@ const IndividualDiscounts = () => {
<>
<TL1 inline>{t.discount}</TL1> %
</>
)
),
},
{
header: 'Revoke',
@ -143,8 +143,8 @@ const IndividualDiscounts = () => {
<DeleteIcon />
</SvgIcon>
</IconButton>
)
}
),
},
]
return (

View file

@ -59,23 +59,23 @@ const PromoCodes = () => {
setErrorMsg(errorMessage)
},
onCompleted: () => setDeleteDialog(false),
refetchQueries: () => ['promoCodes']
refetchQueries: () => ['promoCodes'],
})
const [createCode] = useMutation(CREATE_CODE, {
refetchQueries: () => ['promoCodes']
refetchQueries: () => ['promoCodes'],
})
const addCode = (code, discount) => {
setErrorMsg(null)
createCode({
variables: { code: code, discount: discount }
variables: { code: code, discount: discount },
})
.then(res => {
if (!res.errors) return setShowModal(false)
const duplicateCodeError = R.any(it =>
R.includes('duplicate', it?.message)
R.includes('duplicate', it?.message),
)(res.errors)
const msg = duplicateCodeError ? DUPLICATE_ERROR_MSG : DEFAULT_ERROR_MSG
@ -93,7 +93,7 @@ const PromoCodes = () => {
width: 300,
textAlign: 'left',
size: 'sm',
view: t => t.code
view: t => t.code,
},
{
header: 'Discount',
@ -104,7 +104,7 @@ const PromoCodes = () => {
<>
<TL1 inline>{t.discount}</TL1> % in commissions
</>
)
),
},
{
header: 'Delete',
@ -121,8 +121,8 @@ const PromoCodes = () => {
<DeleteIcon />
</SvgIcon>
</IconButton>
)
}
),
},
]
return (

View file

@ -12,7 +12,7 @@ import { TextInput, NumberInput } from 'src/components/inputs/formik'
const initialValues = {
code: '',
discount: ''
discount: '',
}
const validationSchema = Yup.object().shape({
@ -21,7 +21,7 @@ const validationSchema = Yup.object().shape({
.trim()
.max(25)
.matches(/^\S*$/, 'No whitespace allowed'),
discount: Yup.number().required().min(0).max(100)
discount: Yup.number().required().min(0).max(100),
})
const PromoCodesModal = ({ showModal, onClose, errorMsg, addCode }) => {

View file

@ -37,7 +37,7 @@ const widths = {
name: 0,
cashbox: 175,
cassettes: 585,
edit: 90
edit: 90,
}
const CashCassettes = ({ machine, config, refetchData, bills }) => {
@ -50,11 +50,11 @@ const CashCassettes = ({ machine, config, refetchData, bills }) => {
const getCashoutSettings = deviceId => fromNamespace(deviceId)(cashout)
const elements = R.filter(it => it.name !== 'name')(
helper.getElements(config, bills, setWizard, widths)
helper.getElements(config, bills, setWizard, widths),
)
const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {
refetchQueries: () => refetchData()
refetchQueries: () => refetchData(),
})
const onSave = (_, cashUnits) =>
@ -62,8 +62,8 @@ const CashCassettes = ({ machine, config, refetchData, bills }) => {
variables: {
action: 'setCassetteBills',
deviceId: machine.deviceId,
cashUnits
}
cashUnits,
},
})
const InnerCashUnitDetails = ({ it }) => (

View file

@ -1,2 +1,3 @@
import Cassettes from './Cassettes'
export default Cassettes

View file

@ -1,4 +1,4 @@
import { useQuery, useMutation, gql } from "@apollo/client";
import { useQuery, useMutation, gql } from '@apollo/client'
import * as R from 'ramda'
import React from 'react'
@ -30,12 +30,12 @@ const SAVE_CONFIG = gql`
const Commissions = ({ name: SCREEN_KEY, id: deviceId }) => {
const { data, loading } = useQuery(GET_DATA)
const [saveConfig] = useMutation(SAVE_CONFIG, {
refetchQueries: () => ['getData']
refetchQueries: () => ['getData'],
})
const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)
const currency = R.path(['fiatCurrency'])(
fromNamespace(namespaces.LOCALE)(data?.config)
fromNamespace(namespaces.LOCALE)(data?.config),
)
const saveOverrides = it => {
@ -49,7 +49,7 @@ const Commissions = ({ name: SCREEN_KEY, id: deviceId }) => {
const overrides = config.overrides
? R.concat(
R.filter(R.propEq('machine', 'ALL_MACHINES'), config.overrides),
R.filter(R.propEq('machine', deviceId), config.overrides)
R.filter(R.propEq('machine', deviceId), config.overrides),
)
: []
@ -64,7 +64,7 @@ const Commissions = ({ name: SCREEN_KEY, id: deviceId }) => {
cashOut: config.cashOut,
fixedFee: config.fixedFee,
minimumTx: config.minimumTx,
cashOutFixedFee: config.cashOutFixedFee
cashOutFixedFee: config.cashOutFixedFee,
},
R.project(
['cashIn', 'cashOut', 'fixedFee', 'minimumTx', 'cashOutFixedFee'],
@ -72,11 +72,11 @@ const Commissions = ({ name: SCREEN_KEY, id: deviceId }) => {
o =>
R.includes(coin.code, o.cryptoCurrencies) ||
R.includes('ALL_COINS', o.cryptoCurrencies),
overrides
)
)
overrides,
),
),
),
data.cryptoCurrencies
data.cryptoCurrencies,
)
}

View file

@ -24,7 +24,7 @@ const getOverridesFields = currency => {
name: 'name',
width: 280,
size: 'sm',
view: it => `${it}`
view: it => `${it}`,
},
{
header: cashInHeader,
@ -32,7 +32,7 @@ const getOverridesFields = currency => {
display: 'Cash-in',
width: 130,
textAlign: 'right',
suffix: '%'
suffix: '%',
},
{
header: cashOutHeader,
@ -42,8 +42,8 @@ const getOverridesFields = currency => {
textAlign: 'right',
suffix: '%',
inputProps: {
decimalPlaces: 3
}
decimalPlaces: 3,
},
},
{
name: 'fixedFee',
@ -51,7 +51,7 @@ const getOverridesFields = currency => {
width: 155,
doubleHeader: 'Cash-in only',
textAlign: 'right',
suffix: currency
suffix: currency,
},
{
name: 'minimumTx',
@ -59,7 +59,7 @@ const getOverridesFields = currency => {
width: 155,
doubleHeader: 'Cash-in only',
textAlign: 'right',
suffix: currency
suffix: currency,
},
{
name: 'cashOutFixedFee',
@ -67,8 +67,8 @@ const getOverridesFields = currency => {
width: 155,
doubleHeader: 'Cash-out only',
textAlign: 'right',
suffix: currency
}
suffix: currency,
},
]
}

View file

@ -28,7 +28,7 @@ const Overview = ({ data, onActionSuccess }) => {
<P noMargin>
{data.lastPing
? formatDistance(new Date(data.lastPing), new Date(), {
addSuffix: true
addSuffix: true,
})
: 'unknown'}
</P>

View file

@ -77,9 +77,9 @@ const Transactions = ({ id }) => {
{
variables: {
limit: NUM_LOG_RESULTS,
deviceId: id
}
}
deviceId: id,
},
},
)
const { data: configData, loading: configLoading } = useQuery(GET_DATA)
@ -102,20 +102,20 @@ const Transactions = ({ id }) => {
header: '',
width: 0,
size: 'sm',
view: it => (it.txClass === 'cashOut' ? <TxOutIcon /> : <TxInIcon />)
view: it => (it.txClass === 'cashOut' ? <TxOutIcon /> : <TxInIcon />),
},
{
header: 'Customer',
width: 122,
size: 'sm',
view: Customer.displayName
view: Customer.displayName,
},
{
header: 'Cash',
width: 144,
textAlign: 'right',
size: 'sm',
view: it => `${Number.parseFloat(it.fiat)} ${it.fiatCode}`
view: it => `${Number.parseFloat(it.fiat)} ${it.fiatCode}`,
},
{
header: 'Crypto',
@ -125,7 +125,7 @@ const Transactions = ({ id }) => {
view: it =>
`${toUnit(new BigNumber(it.cryptoAtoms), it.cryptoCode).toFormat(5)} ${
it.cryptoCode
}`
}`,
},
{
header: 'Address',
@ -133,21 +133,21 @@ const Transactions = ({ id }) => {
className: 'overflow-hidden whitespace-nowrap text-ellipsis',
size: 'sm',
textAlign: 'left',
width: 140
width: 140,
},
{
header: 'Date',
view: it => formatDate(it.created, timezone, 'yyyyMMdd'),
textAlign: 'left',
size: 'sm',
width: 140
width: 140,
},
{
header: 'Status',
view: it => getStatus(it),
size: 'sm',
width: 20
}
width: 20,
},
]
const handleClick = e => {

View file

@ -1,2 +1,3 @@
import Transactions from './Transactions'
export default Transactions

View file

@ -79,9 +79,9 @@ const MachineRoute = () => {
deviceId: id,
billFilters: {
deviceId: id,
batch: 'none'
}
}
batch: 'none',
},
},
})
const reload = () => {

View file

@ -12,7 +12,7 @@ const CashUnitDetails = ({
bills,
currency,
config,
hideMachineData = false
hideMachineData = false,
}) => {
const billCount = R.countBy(it => it.fiat)(bills)
const fillingPercentageSettings = fromNamespace('notifications', config)

View file

@ -108,7 +108,7 @@ const widths = {
name: 250,
cashbox: 200,
cassettes: 575,
edit: 90
edit: 90,
}
const CashCassettes = () => {
@ -119,9 +119,9 @@ const CashCassettes = () => {
const { data, loading: dataLoading } = useQuery(GET_MACHINES_AND_CONFIG, {
variables: {
billFilters: {
batch: 'none'
}
}
batch: 'none',
},
},
})
const [wizard, setWizard] = useState(false)
const [machineId, setMachineId] = useState('')
@ -130,18 +130,18 @@ const CashCassettes = () => {
const unpairedMachines = R.path(['unpairedMachines'])(data) ?? []
const config = R.path(['config'])(data) ?? {}
const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {
refetchQueries: () => ['getData']
refetchQueries: () => ['getData'],
})
const [saveConfig] = useMutation(SAVE_CONFIG, {
onCompleted: () => setEditingSchema(false),
refetchQueries: () => ['getData']
refetchQueries: () => ['getData'],
})
const timezone = R.path(['config', 'locale_timezone'], data)
const bills = R.groupBy(bill => bill.deviceId)(R.path(['bills'])(data) ?? [])
const deviceIds = R.uniq(
R.map(R.prop('deviceId'))(R.path(['bills'])(data) ?? [])
R.map(R.prop('deviceId'))(R.path(['bills'])(data) ?? []),
)
const cashout = data?.config && fromNamespace('cashOut')(data.config)
const locale = data?.config && fromNamespace('locale')(data.config)
@ -154,8 +154,8 @@ const CashCassettes = () => {
variables: {
action: 'setCassetteBills',
deviceId: id,
cashUnits
}
cashUnits,
},
})
}
@ -176,7 +176,7 @@ const CashCassettes = () => {
const radioButtonOptions = [
{ display: 'Automatic', code: AUTOMATIC },
{ display: 'Manual', code: MANUAL }
{ display: 'Manual', code: MANUAL },
]
const handleRadioButtons = evt => {
@ -189,7 +189,7 @@ const CashCassettes = () => {
bills,
setWizard,
widths,
setMachineId
setMachineId,
)
const InnerCashUnitDetails = ({ it }) => (
@ -211,7 +211,7 @@ const CashCassettes = () => {
text: 'Cash box history',
icon: HistoryIcon,
inverseIcon: ReverseHistoryIcon,
toggle: setShowHistory
toggle: setShowHistory,
},
{
component: showHistory ? (
@ -226,8 +226,8 @@ const CashCassettes = () => {
/>
) : (
<></>
)
}
),
},
]}
className="flex items-center mr-[1px]"
appendix={

View file

@ -8,18 +8,12 @@ import TxOutIcon from 'src/styling/icons/direction/cash-out.svg?react'
import { fromNamespace } from 'src/utils/config'
import { numberToFiatAmount } from 'src/utils/number'
const CashCassettesFooter = ({
machines,
config,
currencyCode,
bills,
deviceIds
}) => {
const CashCassettesFooter = ({ machines, config, currencyCode, bills }) => {
const cashout = config && fromNamespace('cashOut')(config)
const getCashoutSettings = id => fromNamespace(id)(cashout)
const cashoutReducerFn = (
acc,
{ cashUnits: { cassette1, cassette2, cassette3, cassette4 }, id }
{ cashUnits: { cassette1, cassette2, cassette3, cassette4 }, id },
) => {
const cassette1Denomination = getCashoutSettings(id).cassette1 ?? 0
const cassette2Denomination = getCashoutSettings(id).cassette2 ?? 0
@ -29,7 +23,7 @@ const CashCassettesFooter = ({
(acc[0] += cassette1 * cassette1Denomination),
(acc[1] += cassette2 * cassette2Denomination),
(acc[2] += cassette3 * cassette3Denomination),
(acc[3] += cassette4 * cassette4Denomination)
(acc[3] += cassette4 * cassette4Denomination),
]
}
@ -42,10 +36,10 @@ const CashCassettesFooter = ({
recycler3,
recycler4,
recycler5,
recycler6
recycler6,
},
id
}
id,
},
) => {
const recycler1Denomination = getCashoutSettings(id).recycler1 ?? 0
const recycler2Denomination = getCashoutSettings(id).recycler2 ?? 0
@ -59,22 +53,22 @@ const CashCassettesFooter = ({
(acc[0] += recycler3 * recycler3Denomination),
(acc[1] += recycler4 * recycler4Denomination),
(acc[0] += recycler5 * recycler5Denomination),
(acc[1] += recycler6 * recycler6Denomination)
(acc[1] += recycler6 * recycler6Denomination),
]
}
const totalInRecyclers = R.sum(
R.reduce(recyclerReducerFn, [0, 0, 0, 0, 0, 0], machines)
R.reduce(recyclerReducerFn, [0, 0, 0, 0, 0, 0], machines),
)
const totalInCassettes = R.sum(
R.reduce(cashoutReducerFn, [0, 0, 0, 0], machines)
R.reduce(cashoutReducerFn, [0, 0, 0, 0], machines),
)
const totalInCashBox = R.sum(R.map(it => it.fiat)(bills))
const total = new BigNumber(
totalInCassettes + totalInCashBox + totalInRecyclers
totalInCassettes + totalInCashBox + totalInRecyclers,
).toFormat(0)
return (

View file

@ -38,15 +38,15 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
<>
<TxOutIcon />
<span>Cash cassette {i} refill</span>
</>
</>,
),
R.assoc(
`cash-cassette-${i}-empty`,
<>
<TxOutIcon />
<span>Cash cassette {i} emptied</span>
</>
)
</>,
),
)(ret),
{
'cash-box-empty': (
@ -54,9 +54,9 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
<TxInIcon />
<span>Cash box emptied</span>
</>
)
),
},
R.range(1, 5)
R.range(1, 5),
)
const elements = [
@ -69,7 +69,7 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
<div className="flex items-center gap-2">
{getOperationRender[it.operationType]}
</div>
)
),
},
{
name: 'machine',
@ -80,8 +80,8 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
R.prop('deviceId'),
id => R.find(R.propEq('id', id), machines),
R.defaultTo({ name: <i>Unpaired device</i> }),
R.prop('name')
)
R.prop('name'),
),
},
{
name: 'billCount',
@ -90,10 +90,10 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
textAlign: 'left',
input: NumberInput,
inputProps: {
decimalPlaces: 0
decimalPlaces: 0,
},
view: it =>
R.isNil(it.customBillCount) ? it.billCount : it.customBillCount
R.isNil(it.customBillCount) ? it.billCount : it.customBillCount,
},
{
name: 'total',
@ -104,22 +104,22 @@ const CashboxHistory = ({ machines, currency, timezone }) => {
<span>
{it.fiatTotal} {currency}
</span>
)
),
},
{
name: 'date',
header: 'Date',
width: 135,
textAlign: 'right',
view: it => formatDate(it.created, timezone, 'yyyy-MM-dd')
view: it => formatDate(it.created, timezone, 'yyyy-MM-dd'),
},
{
name: 'time',
header: 'Time (h:m)',
width: 125,
textAlign: 'right',
view: it => formatDate(it.created, timezone, 'HH:mm')
}
view: it => formatDate(it.created, timezone, 'HH:mm'),
},
]
return (

View file

@ -61,7 +61,7 @@ const MachineStatus = () => {
const {
data: machinesResponse,
refetch,
loading: machinesLoading
loading: machinesLoading,
} = useQuery(GET_MACHINES)
const { data: configResponse, configLoading } = useQuery(GET_DATA)
const timezone = R.path(['config', 'locale_timezone'], configResponse)
@ -82,14 +82,14 @@ const MachineStatus = () => {
<MachineRedirectIcon />
</div>
</div>
)
),
},
{
header: 'Status',
width: 350,
size: 'sm',
textAlign: 'left',
view: m => <MainStatus statuses={m.statuses} />
view: m => <MainStatus statuses={m.statuses} />,
},
{
header: 'Last ping',
@ -99,22 +99,22 @@ const MachineStatus = () => {
view: m =>
m.lastPing
? formatDistance(new Date(m.lastPing), new Date(), {
addSuffix: true
addSuffix: true,
})
: 'unknown'
: 'unknown',
},
{
header: 'Software version',
width: 200,
size: 'sm',
textAlign: 'left',
view: m => m.version || 'unknown'
}
view: m => m.version || 'unknown',
},
]
const machines = R.path(['machines'])(machinesResponse) ?? []
const expandedIndex = R.findIndex(R.propEq('deviceId', addedMachineId))(
machines
machines,
)
const InnerMachineDetailsRow = ({ it }) => (

View file

@ -7,7 +7,7 @@ import { MAX_NUMBER_OF_CASSETTES } from 'src/utils/constants'
import {
cashUnitCapacity,
getCashUnitCapacity,
modelPrettifier
modelPrettifier,
} from 'src/utils/machine'
import { defaultToZero } from 'src/utils/number'
@ -19,7 +19,7 @@ const MODAL_HEIGHT = 535
const CASSETTE_FIELDS = R.map(
it => `cassette${it}`,
R.range(1, MAX_NUMBER_OF_CASSETTES + 1)
R.range(1, MAX_NUMBER_OF_CASSETTES + 1),
)
const RECYCLER_FIELDS = [
@ -28,7 +28,7 @@ const RECYCLER_FIELDS = [
'recycler3',
'recycler4',
'recycler5',
'recycler6'
'recycler6',
]
const canManuallyLoadRecyclers = ({ model }) => ['grandola'].includes(model)
@ -36,7 +36,7 @@ const canManuallyLoadRecyclers = ({ model }) => ['grandola'].includes(model)
const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
const [{ step, config }, setState] = useState({
step: 0,
config: { active: true }
config: { active: true },
})
const isCashOutDisabled =
@ -60,7 +60,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
if (isLastStep) {
const wasCashboxEmptied = [
config?.wasCashboxEmptied,
it?.wasCashboxEmptied
it?.wasCashboxEmptied,
].includes('YES')
const cassettes = buildCashUnitObj(CASSETTE_FIELDS, it)
@ -71,7 +71,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
const cashUnits = {
cashbox: wasCashboxEmptied ? 0 : machine?.cashUnits.cashbox,
...cassettes,
...recyclers
...recyclers,
}
save(machine.id, cashUnits)
@ -80,7 +80,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
setState({
step: step + 1,
config: newConfig
config: newConfig,
})
}
@ -102,11 +102,11 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
modelPrettifier[machine.model]
} maximum cassette capacity is ${getCashUnitCapacity(
machine.model,
'cassette'
)} bills`
)
})
}))
'cassette',
)} bills`,
),
}),
})),
)
const makeRecyclerSteps = R.pipe(
@ -126,10 +126,10 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
`${modelPrettifier[machine.model]}
maximum recycler capacity is ${
cashUnitCapacity[machine.model].recycler
} bills`
)
})
}))
} bills`,
),
}),
})),
)
const makeCassettesInitialValues = () =>
@ -140,7 +140,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
return acc
},
{},
R.range(1, numberOfCassettes + 1)
R.range(1, numberOfCassettes + 1),
)
: {}
@ -153,7 +153,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
return acc
},
{},
R.range(1, numberOfRecyclers + 1)
R.range(1, numberOfRecyclers + 1),
)
: {}
@ -163,19 +163,19 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
const steps = R.pipe(
R.concat(
makeRecyclerSteps(
canManuallyLoadRecyclers(machine) ? numberOfRecyclers : 0
)
canManuallyLoadRecyclers(machine) ? numberOfRecyclers : 0,
),
),
R.concat(makeCassetteSteps(isCashOutDisabled ? 0 : numberOfCassettes)),
R.concat([
{
type: 'cashbox',
schema: Yup.object().shape({
wasCashboxEmptied: Yup.string().required('Select one option.')
wasCashboxEmptied: Yup.string().required('Select one option.'),
}),
cashoutRequired: false
}
])
cashoutRequired: false,
},
]),
)([])
return (

View file

@ -46,8 +46,8 @@ const cassetesArtworks = (step, numberOfCassettes, numberOfRecyclers) => {
tejo4CassetteOne,
tejo4CassetteTwo,
tejo4CassetteThree,
tejo4CassetteFour
]
tejo4CassetteFour,
],
][numberOfCassettes - 1][step - cassetteStepsStart]
: [
/* TODO: Recycler artwork */
@ -58,8 +58,8 @@ const cassetesArtworks = (step, numberOfCassettes, numberOfRecyclers) => {
tejo4CassetteOne,
tejo4CassetteTwo,
tejo4CassetteThree,
tejo4CassetteFour
]
tejo4CassetteFour,
],
][numberOfRecyclers - 1][step - cassetteStepsStart]
}
@ -69,13 +69,13 @@ const getCashUnitFieldName = (step, numberOfCassettes, numberOfRecyclers) => {
if (isCassetteStep(step, numberOfCassettes))
return {
name: `cassette${step - cassetteStepsStart + 1}`,
category: 'cassette'
category: 'cassette',
}
const recyclerStepsStart = CASHBOX_STEP + numberOfCassettes + 1
if (isRecyclerStep(step, numberOfCassettes, numberOfRecyclers))
return {
name: `recycler${Math.ceil(step - recyclerStepsStart + 1)}`,
category: 'recycler'
category: 'recycler',
}
}
@ -84,18 +84,17 @@ const WizardStep = ({
name,
machine,
cashoutSettings,
error,
lastStep,
steps,
fiatCurrency,
onContinue,
initialValues
initialValues,
}) => {
const label = lastStep ? 'Finish' : 'Confirm'
const stepOneRadioOptions = [
{ display: 'Yes', code: 'YES' },
{ display: 'No', code: 'NO' }
{ display: 'No', code: 'NO' },
]
const numberOfCassettes = machine.numberOfCassettes
@ -111,7 +110,7 @@ const WizardStep = ({
cassetteCount,
count =>
100 * (count / getCashUnitCapacity(machine.model, cashUnitCategory)),
R.clamp(0, 100)
R.clamp(0, 100),
)
return (
@ -155,7 +154,7 @@ const WizardStep = ({
<div
className={classnames(
classes.horizontalAlign,
'items-center'
'items-center',
)}>
<P>Since previous update</P>
<HelpTooltip width={215}>
@ -168,7 +167,7 @@ const WizardStep = ({
<div
className={classnames(
classes.horizontalAlign,
'items-baseline'
'items-baseline',
)}>
<Info1 noMargin className="mr-1">
{machine?.cashUnits.cashbox}
@ -203,7 +202,7 @@ const WizardStep = ({
src={cassetesArtworks(
step,
numberOfCassettes,
numberOfRecyclers
numberOfRecyclers,
)}></img>
<div className={classes.formWrapper}>
<div className={classes.verticalAlign}>
@ -232,7 +231,7 @@ const WizardStep = ({
<div
className={classnames(
classes.horizontalAlign,
'items-baseline'
'items-baseline',
)}>
<Field
component={NumberInput}

Some files were not shown because too many files have changed in this diff Show more