chore: reformat code
This commit is contained in:
parent
3d930aa73b
commit
aedabcbdee
509 changed files with 6030 additions and 4266 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
/*}*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const GraphWrapper = ({
|
|||
selectedMachine,
|
||||
machines,
|
||||
selectedDay,
|
||||
log
|
||||
log,
|
||||
}) => {
|
||||
const [selectionCoords, setSelectionCoords] = useState(null)
|
||||
const [selectionDateInterval, setSelectionDateInterval] = useState(null)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }) => (
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ const STATES = {
|
|||
LOGIN: 'LOGIN',
|
||||
SETUP_2FA: 'SETUP2FA',
|
||||
INPUT_2FA: 'INPUT2FA',
|
||||
FIDO: 'FIDO'
|
||||
FIDO: 'FIDO',
|
||||
}
|
||||
|
||||
export { STATES }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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={
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export const PhotoCard = ({
|
|||
date,
|
||||
src,
|
||||
setPhotosDialog,
|
||||
setPhotoClickIndex
|
||||
setPhotoClickIndex,
|
||||
}) => {
|
||||
return (
|
||||
<Paper
|
||||
|
|
|
|||
|
|
@ -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`}
|
||||
|
|
|
|||
|
|
@ -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 && (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }) => (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -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, 'yyyy‑MM‑dd')
|
||||
view: it => formatDate(it.created, timezone, 'yyyy‑MM‑dd'),
|
||||
},
|
||||
{
|
||||
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 (
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ export {
|
|||
CustomerSidebar,
|
||||
EditableCard,
|
||||
Wizard,
|
||||
Upload
|
||||
Upload,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }) => {
|
||||
|
|
|
|||
|
|
@ -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}>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }) => {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import Alerts from './Alerts'
|
||||
|
||||
export default Alerts
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import Footer from './Footer'
|
||||
|
||||
export default Footer
|
||||
|
|
|
|||
|
|
@ -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={
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import SystemPerformance from './SystemPerformance'
|
||||
|
||||
export default SystemPerformance
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import SystemStatus from './SystemStatus'
|
||||
|
||||
export default SystemStatus
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import Dashboard from './Dashboard'
|
||||
|
||||
export default Dashboard
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -104,4 +104,4 @@
|
|||
font-weight: 400;
|
||||
width: 375px;
|
||||
margin: 12px 24px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,4 +71,4 @@
|
|||
|
||||
.buttonsWrapper > * {
|
||||
margin: auto 6px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@
|
|||
|
||||
.uptimeContainer {
|
||||
margin: auto 0 auto 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 }) => {
|
||||
|
|
|
|||
|
|
@ -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 }) => (
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import Cassettes from './Cassettes'
|
||||
|
||||
export default Cassettes
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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, 'yyyy‑MM‑dd'),
|
||||
textAlign: 'left',
|
||||
size: 'sm',
|
||||
width: 140
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
header: 'Status',
|
||||
view: it => getStatus(it),
|
||||
size: 'sm',
|
||||
width: 20
|
||||
}
|
||||
width: 20,
|
||||
},
|
||||
]
|
||||
|
||||
const handleClick = e => {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
import Transactions from './Transactions'
|
||||
|
||||
export default Transactions
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ const MachineRoute = () => {
|
|||
deviceId: id,
|
||||
billFilters: {
|
||||
deviceId: id,
|
||||
batch: 'none'
|
||||
}
|
||||
}
|
||||
batch: 'none',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const reload = () => {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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={
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 }) => (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue