fix: get triggers up to spec
This commit is contained in:
parent
b07c0e180a
commit
0b28e7f98a
22 changed files with 347 additions and 95 deletions
|
|
@ -9,13 +9,14 @@ import React, { useEffect, useState, memo } from 'react'
|
|||
|
||||
import { Button, IconButton } from 'src/components/buttons'
|
||||
import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'
|
||||
import { fontSize3 } from 'src/styling/variables'
|
||||
|
||||
import { TextInput } from './inputs'
|
||||
import { H4, P } from './typography'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
label: {
|
||||
fontSize: 16
|
||||
fontSize: fontSize3
|
||||
},
|
||||
spacing: {
|
||||
padding: 32
|
||||
|
|
|
|||
|
|
@ -24,6 +24,25 @@ const styles = {
|
|||
borderRadius: 8,
|
||||
outline: 0
|
||||
}),
|
||||
infoPanelWrapper: ({ width, infoPanelHeight }) => ({
|
||||
width,
|
||||
height: infoPanelHeight,
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
minHeight: infoPanelHeight ?? 200,
|
||||
maxHeight: '90vh',
|
||||
overflowY: 'auto',
|
||||
borderRadius: 8,
|
||||
outline: 0
|
||||
}),
|
||||
panelContent: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
padding: [[0, 24]]
|
||||
},
|
||||
content: ({ small }) => ({
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
|
|
@ -48,17 +67,24 @@ const useStyles = makeStyles(styles)
|
|||
const Modal = ({
|
||||
width,
|
||||
height,
|
||||
infoPanelHeight,
|
||||
title,
|
||||
small,
|
||||
infoPanel,
|
||||
handleClose,
|
||||
children,
|
||||
secondaryModal,
|
||||
className,
|
||||
closeOnEscape,
|
||||
closeOnBackdropClick,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles({ width, height, small })
|
||||
const classes = useStyles({
|
||||
width,
|
||||
height,
|
||||
small,
|
||||
infoPanelHeight
|
||||
})
|
||||
const TitleCase = small ? H4 : H1
|
||||
const closeSize = small ? 16 : 20
|
||||
|
||||
|
|
@ -84,8 +110,8 @@ const Modal = ({
|
|||
<div className={classes.content}>{children}</div>
|
||||
</Paper>
|
||||
{infoPanel && (
|
||||
<Paper className={classnames(classes.wrapper, className)}>
|
||||
{infoPanel}
|
||||
<Paper className={classnames(classes.infoPanelWrapper, className)}>
|
||||
<div className={classes.panelContent}>{infoPanel}</div>
|
||||
</Paper>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { makeStyles } from '@material-ui/core'
|
||||
import classnames from 'classnames'
|
||||
import { Field, useFormikContext } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
|
|
@ -158,7 +159,7 @@ const groupStriped = elements => {
|
|||
)
|
||||
}
|
||||
|
||||
const ERow = ({ editing, disabled }) => {
|
||||
const ERow = ({ editing, disabled, lastOfGroup }) => {
|
||||
const { errors } = useFormikContext()
|
||||
const {
|
||||
elements,
|
||||
|
|
@ -169,6 +170,8 @@ const ERow = ({ editing, disabled }) => {
|
|||
stripeWhen
|
||||
} = useContext(TableCtx)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const { values } = useFormikContext()
|
||||
const shouldStripe = stripeWhen && stripeWhen(values) && !editing
|
||||
|
||||
|
|
@ -187,8 +190,13 @@ const ERow = ({ editing, disabled }) => {
|
|||
it => it.editable === undefined || it.editable
|
||||
)
|
||||
|
||||
const classNames = {
|
||||
[classes.lastOfGroup]: lastOfGroup
|
||||
}
|
||||
|
||||
return (
|
||||
<Tr
|
||||
className={classnames(classNames)}
|
||||
size={rowSize}
|
||||
error={errors && errors.length}
|
||||
errorMessage={errors && errors.toString()}>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ export default {
|
|||
cancelButton: {
|
||||
marginRight: 20
|
||||
},
|
||||
lastOfGroup: {
|
||||
marginBottom: 24
|
||||
},
|
||||
extraPaddingLeft: {
|
||||
paddingLeft: 35
|
||||
},
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ const ETable = ({
|
|||
setEditing,
|
||||
stripeWhen,
|
||||
disableRowEdit,
|
||||
groupBy,
|
||||
sortBy,
|
||||
createText = 'Add override'
|
||||
}) => {
|
||||
const [editingId, setEditingId] = useState(null)
|
||||
|
|
@ -102,6 +104,8 @@ const ETable = ({
|
|||
const canAdd = !forceDisable && !editingId && !disableAdd && !adding
|
||||
const showTable = adding || data.length !== 0
|
||||
|
||||
const innerData = sortBy ? R.sortWith(sortBy)(data) : data
|
||||
|
||||
const ctxValue = {
|
||||
elements,
|
||||
enableEdit,
|
||||
|
|
@ -159,7 +163,14 @@ const ETable = ({
|
|||
</Form>
|
||||
</Formik>
|
||||
)}
|
||||
{data.map((it, idx) => (
|
||||
{innerData.map((it, idx) => {
|
||||
const nextElement = innerData[idx + 1]
|
||||
const isLastOfGroup =
|
||||
groupBy &&
|
||||
nextElement &&
|
||||
nextElement[groupBy] !== it[groupBy]
|
||||
|
||||
return (
|
||||
<Formik
|
||||
key={it.id ?? idx}
|
||||
enableReinitialize
|
||||
|
|
@ -169,6 +180,7 @@ const ETable = ({
|
|||
onSubmit={innerSave}>
|
||||
<Form>
|
||||
<ERow
|
||||
lastOfGroup={isLastOfGroup}
|
||||
editing={editingId === it.id}
|
||||
disabled={
|
||||
forceDisable || (editingId && editingId !== it.id)
|
||||
|
|
@ -176,7 +188,8 @@ const ETable = ({
|
|||
/>
|
||||
</Form>
|
||||
</Formik>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
</TBody>
|
||||
</Table>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import CheckBoxIcon from '@material-ui/icons/CheckBox'
|
|||
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'
|
||||
import React from 'react'
|
||||
|
||||
import { secondaryColor } from '../../../styling/variables'
|
||||
import { fontSize2, fontSize3, secondaryColor } from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
|
|
@ -30,9 +30,11 @@ const CheckboxInput = ({ name, onChange, value, label, ...props }) => {
|
|||
value={value}
|
||||
checked={value}
|
||||
icon={
|
||||
<CheckBoxOutlineBlankIcon style={{ marginLeft: 2, fontSize: 16 }} />
|
||||
<CheckBoxOutlineBlankIcon
|
||||
style={{ marginLeft: 2, fontSize: fontSize3 }}
|
||||
/>
|
||||
}
|
||||
checkedIcon={<CheckBoxIcon style={{ fontSize: 20 }} />}
|
||||
checkedIcon={<CheckBoxIcon style={{ fontSize: fontSize2 }} />}
|
||||
disableRipple
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { secondaryColor } from 'src/styling/variables'
|
|||
|
||||
export default {
|
||||
size: ({ size }) => ({
|
||||
marginTop: size === 'lg' ? -2 : 0,
|
||||
marginTop: size === 'lg' ? 0 : 2,
|
||||
...bySize(size)
|
||||
}),
|
||||
bold,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const Row = ({
|
|||
|
||||
return (
|
||||
<div className={classes.rowWrapper}>
|
||||
<div className={classnames({ [classes.before]: expanded })}>
|
||||
<div className={classnames({ [classes.before]: expanded && id !== 0 })}>
|
||||
<Tr
|
||||
className={classnames(trClasses)}
|
||||
onClick={() => {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export default {
|
|||
padding: 1
|
||||
},
|
||||
row: {
|
||||
border: [[2, 'solid', 'transparent']],
|
||||
borderRadius: 0
|
||||
},
|
||||
expanded: {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,21 @@ function H4({ children, noMargin, className, ...props }) {
|
|||
)
|
||||
}
|
||||
|
||||
function H5({ children, noMargin, className, ...props }) {
|
||||
const classes = useStyles()
|
||||
const classNames = {
|
||||
[classes.h5]: true,
|
||||
[classes.noMargin]: noMargin,
|
||||
[className]: !!className
|
||||
}
|
||||
|
||||
return (
|
||||
<h5 className={classnames(classNames)} {...props}>
|
||||
{children}
|
||||
</h5>
|
||||
)
|
||||
}
|
||||
|
||||
const P = pBuilder('p')
|
||||
const Info1 = pBuilder('info1')
|
||||
const Info2 = pBuilder('info2')
|
||||
|
|
@ -99,6 +114,7 @@ export {
|
|||
H2,
|
||||
H3,
|
||||
H4,
|
||||
H5,
|
||||
TL1,
|
||||
TL2,
|
||||
P,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from 'src/styling/variables'
|
||||
|
||||
const base = {
|
||||
lineHeight: '110%',
|
||||
lineHeight: '120%',
|
||||
color: fontColor
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +40,12 @@ export default {
|
|||
fontFamily: fontPrimary,
|
||||
fontWeight: 700
|
||||
},
|
||||
h5: {
|
||||
extend: base,
|
||||
fontSize: fontSize3,
|
||||
fontFamily: fontPrimary,
|
||||
fontWeight: 700
|
||||
},
|
||||
p: {
|
||||
extend: base,
|
||||
fontSize: fontSize4,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ const getOverridesFields = (getData, currency) => {
|
|||
{
|
||||
name: 'fixedFee',
|
||||
display: 'Fixed fee',
|
||||
width: 140,
|
||||
width: 144,
|
||||
input: NumberInput,
|
||||
doubleHeader: 'Cash-in only',
|
||||
textAlign: 'right',
|
||||
|
|
@ -87,7 +87,7 @@ const getOverridesFields = (getData, currency) => {
|
|||
{
|
||||
name: 'minimumTx',
|
||||
display: 'Minimun Tx',
|
||||
width: 140,
|
||||
width: 144,
|
||||
input: NumberInput,
|
||||
doubleHeader: 'Cash-in only',
|
||||
textAlign: 'right',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import baseStyles from 'src/pages/Logs.styles'
|
||||
import { zircon, primaryColor } from 'src/styling/variables'
|
||||
import { zircon, primaryColor, fontSize4 } from 'src/styling/variables'
|
||||
|
||||
const { label1 } = typographyStyles
|
||||
const { titleWrapper, titleAndButtonsContainer } = baseStyles
|
||||
|
|
@ -30,7 +30,7 @@ export default {
|
|||
},
|
||||
p: {
|
||||
fontFamily: 'MuseoSans',
|
||||
fontSize: 14,
|
||||
fontSize: fontSize4,
|
||||
fontWeight: 500,
|
||||
fontStretch: 'normal',
|
||||
fontStyle: 'normal',
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ import {
|
|||
tomato,
|
||||
spring3,
|
||||
spring4,
|
||||
comet
|
||||
comet,
|
||||
fontSize5
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const propertyCardStyles = {
|
||||
|
|
@ -25,7 +26,7 @@ const propertyCardStyles = {
|
|||
},
|
||||
label1: {
|
||||
fontFamily: 'MuseoSans',
|
||||
fontSize: 12,
|
||||
fontSize: fontSize5,
|
||||
fontWeight: 500,
|
||||
fontStretch: 'normal',
|
||||
fontStyle: 'normal',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { fontSize5 } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
titleWrapper: {
|
||||
display: 'flex',
|
||||
|
|
@ -41,7 +43,7 @@ export default {
|
|||
margin: 8,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
fontSize: 12,
|
||||
fontSize: fontSize5,
|
||||
padding: [[0, 12]]
|
||||
},
|
||||
shareIcon: {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { fade } from '@material-ui/core/styles/colorManipulator'
|
||||
|
||||
import { offColor, comet } from 'src/styling/variables'
|
||||
import { fontSize4, offColor, comet } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
marginTop: 24,
|
||||
marginBottom: 32,
|
||||
fontSize: 14
|
||||
fontSize: fontSize4
|
||||
},
|
||||
column1: {
|
||||
width: 600
|
||||
|
|
|
|||
|
|
@ -118,17 +118,17 @@ const Transactions = () => {
|
|||
},
|
||||
{
|
||||
header: 'Date (UTC)',
|
||||
view: it => moment.utc(it.created).format('YYYY-MM-D'),
|
||||
view: it => moment.utc(it.created).format('YYYY-MM-DD'),
|
||||
textAlign: 'right',
|
||||
size: 'sm',
|
||||
width: 124
|
||||
width: 144
|
||||
},
|
||||
{
|
||||
header: 'Time (UTC)',
|
||||
view: it => moment.utc(it.created).format('HH:mm:ss'),
|
||||
textAlign: 'right',
|
||||
size: 'sm',
|
||||
width: 124
|
||||
width: 144
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ import { v4 } from 'uuid'
|
|||
import Title from 'src/components/Title'
|
||||
import { Link } from 'src/components/buttons'
|
||||
import { Table as EditableTable } from 'src/components/editableTable'
|
||||
import { fromNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import { mainStyles } from './Triggers.styles'
|
||||
import Wizard from './Wizard'
|
||||
import { Schema, elements } from './helper'
|
||||
import { Schema, elements, sortBy } from './helper'
|
||||
|
||||
const useStyles = makeStyles(mainStyles)
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ const GET_INFO = gql`
|
|||
`
|
||||
|
||||
const Triggers = () => {
|
||||
const classes = useStyles()
|
||||
const [wizard, setWizard] = useState(false)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
|
|
@ -51,7 +53,9 @@ const Triggers = () => {
|
|||
return saveConfig({ variables: { config } })
|
||||
}
|
||||
|
||||
const classes = useStyles()
|
||||
const currency = R.path(['fiatCurrency'])(
|
||||
fromNamespace(namespaces.LOCALE)(data?.config)
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -69,13 +73,20 @@ const Triggers = () => {
|
|||
data={triggers}
|
||||
name="triggers"
|
||||
enableEdit
|
||||
sortBy={sortBy}
|
||||
groupBy="triggerType"
|
||||
enableDelete
|
||||
save={save}
|
||||
validationSchema={Schema}
|
||||
elements={elements}
|
||||
/>
|
||||
{wizard && (
|
||||
<Wizard error={error} save={add} onClose={() => setWizard(null)} />
|
||||
<Wizard
|
||||
currency={currency}
|
||||
error={error}
|
||||
save={add}
|
||||
onClose={() => setWizard(null)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { makeStyles } from '@material-ui/core'
|
||||
import { Form, Formik } from 'formik'
|
||||
import { Form, Formik, useFormikContext } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, Fragment } from 'react'
|
||||
import React, { useState, Fragment, useEffect } from 'react'
|
||||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import Stepper from 'src/components/Stepper'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { H5, Info3 } from 'src/components/typography'
|
||||
import { comet } from 'src/styling/variables'
|
||||
|
||||
import { direction, type, requirements } from './helper'
|
||||
|
||||
|
|
@ -28,6 +30,12 @@ const styles = {
|
|||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
},
|
||||
infoTitle: {
|
||||
margin: [[18, 0, 20, 0]]
|
||||
},
|
||||
infoCurrentText: {
|
||||
color: comet
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,9 +54,118 @@ const getStep = step => {
|
|||
}
|
||||
}
|
||||
|
||||
const Wizard = ({ machine, onClose, save, error }) => {
|
||||
const getText = (step, config, currency) => {
|
||||
switch (step) {
|
||||
case 1:
|
||||
return `In ${getDirectionText(config)} transactions`
|
||||
case 2:
|
||||
return `if the user ${getTypeText(config, currency)}`
|
||||
case 3:
|
||||
return `the user will be ${getRequirementText(config)}.`
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const orUnderline = value => {
|
||||
return R.isEmpty(value) || R.isNil(value) ? '⎼⎼⎼⎼⎼ ' : value
|
||||
}
|
||||
|
||||
const getDirectionText = config => {
|
||||
switch (config.cashDirection) {
|
||||
case 'both':
|
||||
return 'both cash-in and cash-out'
|
||||
case 'cashIn':
|
||||
return 'cash-in'
|
||||
case 'cashOut':
|
||||
return 'cash-out'
|
||||
default:
|
||||
return orUnderline(null)
|
||||
}
|
||||
}
|
||||
|
||||
const getTypeText = (config, currency) => {
|
||||
switch (config.triggerType) {
|
||||
case 'txAmount':
|
||||
return `makes a single transaction over ${orUnderline(
|
||||
config.threshold
|
||||
)} ${currency}`
|
||||
case 'txVolume':
|
||||
return `makes transactions over ${orUnderline(
|
||||
config.threshold
|
||||
)} ${currency} in ${orUnderline(config.days)} days`
|
||||
case 'txVelocity':
|
||||
return `makes ${orUnderline(
|
||||
config.threshold
|
||||
)} transactions in ${orUnderline(config.days)} days`
|
||||
case 'consecutiveDays':
|
||||
return `at least one transaction every day for ${orUnderline(
|
||||
config.days
|
||||
)} days`
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const getRequirementText = config => {
|
||||
switch (config.requirement) {
|
||||
case 'sms':
|
||||
return 'asked to enter code provided through SMS verification'
|
||||
case 'idPhoto':
|
||||
return 'asked to scan a ID with photo'
|
||||
case 'idData':
|
||||
return 'asked to scan a ID'
|
||||
case 'facephoto':
|
||||
return 'asked to have a photo taken'
|
||||
case 'sanctions':
|
||||
return 'matched against the OFAC sanctions list'
|
||||
case 'superuser':
|
||||
return ''
|
||||
case 'suspend':
|
||||
return 'suspended'
|
||||
case 'block':
|
||||
return 'blocked'
|
||||
default:
|
||||
return orUnderline(null)
|
||||
}
|
||||
}
|
||||
|
||||
const InfoPanel = ({ step, config = {}, liveValues = {}, currency }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const oldText = R.range(1, step)
|
||||
.map(it => getText(it, config, currency))
|
||||
.join(', ')
|
||||
const newText = getText(step, liveValues, currency)
|
||||
const isLastStep = step === LAST_STEP
|
||||
|
||||
return (
|
||||
<>
|
||||
<H5 className={classes.infoTitle}>Trigger overview so far</H5>
|
||||
<Info3 noMargin>
|
||||
{oldText}
|
||||
{step !== 1 && ', '}
|
||||
<span className={classes.infoCurrentText}>{newText}</span>
|
||||
{!isLastStep && '...'}
|
||||
</Info3>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const GetValues = ({ setValues }) => {
|
||||
const { values } = useFormikContext()
|
||||
useEffect(() => {
|
||||
console.log('triggered')
|
||||
setValues && values && setValues(values)
|
||||
}, [setValues, values])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const Wizard = ({ onClose, save, error, currency }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [liveValues, setLiveValues] = useState({})
|
||||
const [{ step, config }, setState] = useState({
|
||||
step: 1
|
||||
})
|
||||
|
|
@ -70,11 +187,21 @@ const Wizard = ({ machine, onClose, save, error }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title="New compliance trigger"
|
||||
handleClose={onClose}
|
||||
width={520}
|
||||
height={480}
|
||||
infoPanel={
|
||||
<InfoPanel
|
||||
currency={currency}
|
||||
step={step}
|
||||
config={config}
|
||||
liveValues={liveValues}
|
||||
/>
|
||||
}
|
||||
infoPanelHeight={172}
|
||||
open={true}>
|
||||
<Stepper
|
||||
className={classes.stepper}
|
||||
|
|
@ -86,7 +213,8 @@ const Wizard = ({ machine, onClose, save, error }) => {
|
|||
onSubmit={onContinue}
|
||||
initialValues={stepOptions.initialValues}
|
||||
validationSchema={stepOptions.schema}>
|
||||
<Form className={classes.form}>
|
||||
<Form onChange={console.log} className={classes.form}>
|
||||
<GetValues setValues={setLiveValues} />
|
||||
<stepOptions.Component />
|
||||
<div className={classes.submit}>
|
||||
{error && <ErrorMessage>Failed to save</ErrorMessage>}
|
||||
|
|
@ -97,6 +225,7 @@ const Wizard = ({ machine, onClose, save, error }) => {
|
|||
</Form>
|
||||
</Formik>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import * as Yup from 'yup'
|
|||
import { TextInput, RadioGroup } from 'src/components/inputs/formik'
|
||||
import Autocomplete from 'src/components/inputs/formik/Autocomplete'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
||||
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
||||
import { errorColor } from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
|
|
@ -32,6 +34,12 @@ const useStyles = makeStyles({
|
|||
specialGrid: {
|
||||
display: 'grid',
|
||||
gridTemplateColumns: [[182, 162, 141]]
|
||||
},
|
||||
directionIcon: {
|
||||
marginRight: 2
|
||||
},
|
||||
directionName: {
|
||||
marginLeft: 6
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -98,8 +106,8 @@ const typeSchema = Yup.object().shape({
|
|||
|
||||
const typeOptions = [
|
||||
{ display: 'Transaction amount', code: 'txAmount' },
|
||||
{ display: 'Transaction velocity', code: 'txVelocity' },
|
||||
{ display: 'Transaction volume', code: 'txVolume' },
|
||||
{ display: 'Transaction velocity', code: 'txVelocity' },
|
||||
{ display: 'Consecutive days', code: 'consecutiveDays' }
|
||||
]
|
||||
|
||||
|
|
@ -131,9 +139,6 @@ const Type = () => {
|
|||
size="lg"
|
||||
name="threshold"
|
||||
options={typeOptions}
|
||||
labelClassName={classes.radioLabel}
|
||||
radioClassName={classes.radio}
|
||||
className={classes.radioGroup}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
|
@ -199,12 +204,29 @@ const getView = (data, code, compare) => it => {
|
|||
return R.compose(R.prop(code), R.find(R.propEq(compare ?? 'code', it)))(data)
|
||||
}
|
||||
|
||||
const DirectionDisplay = ({ code }) => {
|
||||
const classes = useStyles()
|
||||
const displayName = getView(directionOptions, 'display')(code)
|
||||
const showCashIn = code === 'cashIn' || code === 'both'
|
||||
const showCashOut = code === 'cashOut' || code === 'both'
|
||||
|
||||
return (
|
||||
<div>
|
||||
{showCashOut && <TxOutIcon className={classes.directionIcon} />}
|
||||
{showCashIn && <TxInIcon className={classes.directionIcon} />}
|
||||
<span className={classes.directionName}>{displayName}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const elements = [
|
||||
{
|
||||
name: 'triggerType',
|
||||
size: 'sm',
|
||||
width: 271,
|
||||
input: Autocomplete,
|
||||
width: 230,
|
||||
input: ({ field: { value: name } }) => (
|
||||
<>{getView(typeOptions, 'display')(name)}</>
|
||||
),
|
||||
view: getView(typeOptions, 'display'),
|
||||
inputProps: {
|
||||
options: typeOptions,
|
||||
|
|
@ -216,8 +238,10 @@ const elements = [
|
|||
{
|
||||
name: 'requirement',
|
||||
size: 'sm',
|
||||
width: 271,
|
||||
input: Autocomplete,
|
||||
width: 230,
|
||||
input: ({ field: { value: name } }) => (
|
||||
<>{getView(requirementOptions, 'display')(name)}</>
|
||||
),
|
||||
view: getView(requirementOptions, 'display'),
|
||||
inputProps: {
|
||||
options: requirementOptions,
|
||||
|
|
@ -229,14 +253,15 @@ const elements = [
|
|||
{
|
||||
name: 'threshold',
|
||||
size: 'sm',
|
||||
width: 271,
|
||||
width: 260,
|
||||
textAlign: 'right',
|
||||
input: TextInput
|
||||
},
|
||||
{
|
||||
name: 'cashDirection',
|
||||
size: 'sm',
|
||||
width: 200,
|
||||
view: getView(directionOptions, 'display'),
|
||||
width: 282,
|
||||
view: it => <DirectionDisplay code={it} />,
|
||||
input: Autocomplete,
|
||||
inputProps: {
|
||||
options: directionOptions,
|
||||
|
|
@ -247,4 +272,12 @@ const elements = [
|
|||
}
|
||||
]
|
||||
|
||||
export { Schema, elements, direction, type, requirements }
|
||||
const triggerOrder = R.map(R.prop('code'))(typeOptions)
|
||||
const sortBy = [
|
||||
R.comparator(
|
||||
(a, b) =>
|
||||
triggerOrder.indexOf(a.triggerType) < triggerOrder.indexOf(b.triggerType)
|
||||
)
|
||||
]
|
||||
|
||||
export { Schema, elements, direction, type, requirements, sortBy }
|
||||
|
|
|
|||
|
|
@ -63,11 +63,11 @@ const fontPrimary = 'Mont'
|
|||
const fontSecondary = 'MuseoSans'
|
||||
const fontMonospaced = 'BPmono'
|
||||
|
||||
let fontSize1 = 24
|
||||
let fontSize2 = 20
|
||||
let fontSize3 = 16
|
||||
let fontSize4 = 14
|
||||
let fontSize5 = 12
|
||||
let fontSize1 = 25
|
||||
let fontSize2 = 21
|
||||
let fontSize3 = 17
|
||||
let fontSize4 = 15
|
||||
let fontSize5 = 13
|
||||
|
||||
if (version === 8) {
|
||||
fontSize1 = 32
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ Overall:
|
|||
- validation is bad rn, negatives being allowed
|
||||
- locale based mil separators 1.000 1,000
|
||||
- Table should be loaded on slow internet (we want to load the table with no data)
|
||||
- font sizes could be better
|
||||
- tooltip like components should close on esc
|
||||
- saving should be a one time thing. disable buttons so user doesnt spam it
|
||||
- disable edit on non-everrides => overrides
|
||||
|
|
@ -21,9 +20,6 @@ Locale:
|
|||
Notifications:
|
||||
- one of the crypto balance alerts has to be optional because of migration
|
||||
|
||||
Machine status:
|
||||
- font-size of the 'write to confirm'
|
||||
|
||||
Server:
|
||||
- Takes too long to load. Investigate
|
||||
|
||||
|
|
@ -47,3 +43,7 @@ Compliance:
|
|||
Ideas
|
||||
- Transactions could have a link to the customer
|
||||
- Transactions table on customer should have a link to "transactions"
|
||||
|
||||
|
||||
Feedback needed
|
||||
- font sizes could be better (I've bumped all font sizes by 1px, looks pretty good as fonts do a good vertical bump in size. Maybe some of the fonts don't like even values)
|
||||
Loading…
Add table
Add a link
Reference in a new issue