fix: cash out fixes

fix: on and off should have a fixed width
fix: fist screen should be two p
fix: autofocus on fields after next
fix: spacing
fix: button position
fix: make the denominations a dropdown
fix: fiat should shown input suffix
fix: wizard should have splash image
fix: add missing warning icon
fix: eslint
fix: modal fiat should be a suffix
fix: increase modal height to match the spec
fix: confirmation step has repeated title
fix: label should cover both the input and the suffix
fix: use code+display to benefit from dropdown improvements
This commit is contained in:
Mauricio Navarro Miranda 2020-07-26 17:00:10 -05:00 committed by Josh Harvey
parent b870bdd999
commit 42f19e9d02
10 changed files with 391 additions and 72 deletions

View file

@ -82,6 +82,7 @@ const Autocomplete = ({
return (
<TextInput
{...params}
autoFocus={autoFocus}
label={label}
value={outsideValue}
error={error}

View file

@ -21,7 +21,8 @@ const useStyles = makeStyles({
marginRight: 156
},
switchLabel: {
margin: 6
margin: 6,
width: 24
}
})
@ -121,6 +122,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {
onClose={() => setWizard(false)}
save={save}
error={error}
locale={locale}
/>
)}
</>

View file

@ -3,6 +3,8 @@ import React, { useState } from 'react'
import * as Yup from 'yup'
import Modal from 'src/components/Modal'
import { Autocomplete } from 'src/components/inputs/formik'
import denominations from 'src/utils/bill-denominations'
import { toNamespace } from 'src/utils/config'
import WizardSplash from './WizardSplash'
@ -11,13 +13,25 @@ import { DenominationsSchema } from './helper'
const LAST_STEP = 3
const MODAL_WIDTH = 554
const MODAL_HEIGHT = 520
const Wizard = ({ machine, onClose, save, error }) => {
const getOptions = R.curry((locale, denomiations) => {
const currency = R.prop('fiatCurrency')(locale)
return R.compose(
R.map(code => ({ code, display: code })),
R.keys,
R.path([currency])
)(denomiations)
})
const Wizard = ({ machine, locale, onClose, save, error }) => {
const [{ step, config }, setState] = useState({
step: 0,
config: { active: true }
})
const options = getOptions(locale, denominations)
const title = `Enable cash-out`
const isLastStep = step === LAST_STEP
@ -36,30 +50,31 @@ const Wizard = ({ machine, onClose, save, error }) => {
})
}
const getStepData = () => {
switch (step) {
case 1:
return {
type: 'top',
display: 'Cassete 1 (Top)',
schema: Yup.object().shape({ top: Yup.number().required() })
}
case 2:
return {
type: 'bottom',
display: 'Cassete 2',
schema: Yup.object().shape({ bottom: Yup.number().required() })
}
default:
return null
const steps = [
{
type: 'top',
display: 'Cassette 1 (Top)',
component: Autocomplete
},
{
type: 'bottom',
display: 'Cassette 2',
component: Autocomplete
}
}
]
const schema = () =>
Yup.object().shape({
top: Yup.number().required(),
bottom: step >= 2 ? Yup.number().required() : Yup.number()
})
return (
<Modal
title={step === 0 ? null : title}
handleClose={onClose}
width={MODAL_WIDTH}
height={MODAL_HEIGHT}
open={true}>
{step === 0 && (
<WizardSplash name={machine.name} onContinue={() => onContinue()} />
@ -70,7 +85,10 @@ const Wizard = ({ machine, onClose, save, error }) => {
name={machine.name}
error={error}
lastStep={isLastStep}
{...getStepData()}
steps={steps}
fiatCurrency={locale.fiatCurrency}
options={options}
schema={schema()}
onContinue={onContinue}
/>
)}

View file

@ -2,7 +2,9 @@ import { makeStyles } from '@material-ui/core'
import React from 'react'
import { Button } from 'src/components/buttons'
import { H1, P } from 'src/components/typography'
import { H1, P, Info2 } from 'src/components/typography'
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
import { neon, spacer } from 'src/styling/variables'
const styles = {
logo: {
@ -10,21 +12,37 @@ const styles = {
maxWidth: 200
},
title: {
margin: [[24, 0, 32, 0]]
margin: 0,
marginBottom: 42,
textAlign: 'center'
},
text: {
margin: 0
},
button: {
marginTop: 'auto',
marginBottom: 58
margin: [[0, 'auto']]
},
modalContent: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: [[0, 42]],
flex: 1
justifyContent: 'space-between',
flex: 1,
padding: [[0, 34, 107, 34]],
'& > div': {
paddingBottom: 72,
'& > h1': {
color: neon,
marginBottom: 12,
marginTop: 30,
textAlign: 'center',
'& > svg': {
verticalAlign: 'bottom',
marginRight: spacer * 1.5,
width: spacer * 3,
height: spacer * 3.25
}
}
}
}
}
@ -35,14 +53,21 @@ const WizardSplash = ({ name, onContinue }) => {
return (
<div className={classes.modalContent}>
<H1 className={classes.title}>Enable cash-out</H1>
<P className={classes.text}>
You are about to activate cash-out functionality on your {name} machine
which will allow your customers to sell crypto to you.
<br />
In order to activate cash-out for this machine, please enter the
denominations for the machine.
</P>
<div>
<H1>
<TxOutIcon />
<span>Enable cash-out</span>
</H1>
<Info2 className={classes.title}>{name}</Info2>
<P>
You are about to activate cash-out functionality on your {name}{' '}
machine which will allow your customers to sell crypto to you.
</P>
<P>
In order to activate cash-out for this machine, please enter the
denominations for the machine.
</P>
</div>
<Button className={classes.button} onClick={onContinue}>
Start configuration
</Button>

View file

@ -1,88 +1,125 @@
import { makeStyles } from '@material-ui/core'
import classnames from 'classnames'
import { Formik, Form, Field } from 'formik'
import * as R from 'ramda'
import React from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Stepper from 'src/components/Stepper'
import { Button } from 'src/components/buttons'
import { TextInput } from 'src/components/inputs/formik'
import { Info2, H4, P } from 'src/components/typography'
import { Info2, H4, P, Info1, Label1 } from 'src/components/typography'
import cassetteOne from 'src/styling/icons/cassettes/cashout-cassette-1.svg'
import cassetteTwo from 'src/styling/icons/cassettes/cashout-cassette-2.svg'
import { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'
import styles from './WizardStep.styles'
const useStyles = makeStyles(styles)
const WizardStep = ({
type,
name,
step,
schema,
error,
lastStep,
onContinue,
display
steps,
fiatCurrency,
options
}) => {
const classes = useStyles()
const label = lastStep ? 'Finish' : 'Next'
const subtitleClass = {
[classes.subtitle]: true,
[classes.error]: error
const cassetesArtworks = {
1: cassetteOne,
2: cassetteTwo
}
return (
<>
<Info2 className={classes.title}>{name}</Info2>
<Stepper steps={3} currentStep={step} />
{display && <H4 className={classnames(subtitleClass)}>Edit {display}</H4>}
<div className={classes.content}>
<div className={classes.titleDiv}>
<Info2 className={classes.title}>{name}</Info2>
<Stepper steps={3} currentStep={step} />
</div>
{!lastStep && (
<Formik
onSubmit={onContinue}
initialValues={{ [type]: '' }}
initialValues={{ top: '', bottom: '' }}
enableReinitialize
validationSchema={schema}>
<Form>
<Field
name={type}
component={TextInput}
label={'Choose bill denomination'}
autoFocus
InputLabelProps={{ shrink: true }}
/>
<div className={classes.submit}>
<Button className={classes.button} type="submit">
{label}
</Button>
<div className={classes.header}>
{steps.map(
({ type, display, component }, idx) =>
1 + idx === step && (
<div key={idx}>
<H4 className={classes.edit}>Edit {display}</H4>
<Label1>Choose bill denomination</Label1>
<div className={classes.bill}>
<Field
type="text"
size="lg"
autoFocus={1 + idx === step}
component={
options?.length > 0 ? component : TextInput
}
fullWidth
name={type}
options={options}
valueProp={'code'}
getLabel={R.path(['display'])}></Field>
<Info1 noMargin className={classes.suffix}>
{fiatCurrency}
</Info1>
</div>
</div>
)
)}
<img
alt="cassette"
width="148"
height="196"
src={cassetesArtworks[step]}></img>
</div>
<Button className={classes.submit} type="submit">
{label}
</Button>
</Form>
</Formik>
)}
{lastStep && (
<>
<div className={classes.disclaimer}>
<Info2 className={classes.title}>Cashout Bill Count</Info2>
<P>
<WarningIcon />
When enabling cash out, your bill count will be automatically set to
zero. Make sure you physically put cash inside the cashboxes to
allow the machine to dispense it to your users. If you already did,
make sure you set the correct cash out bill count for this machine
on your Cashboxes tab under Maintenance.
</P>
<Info2 className={classes.title}>Default Commissions</Info2>
<P>
<WarningIcon />
When enabling cash out, default commissions will be set. To change
commissions for this machine, please go to the Commissions tab under
Settings where you can set exceptions for each of the available
cryptocurrencies.
</P>
<div className={classes.submit}>
<div>
{error && <ErrorMessage>Failed to save</ErrorMessage>}
<Button className={classes.button} onClick={() => onContinue()}>
<Button className={classes.submit} onClick={() => onContinue()}>
{label}
</Button>
</div>
</>
</div>
)}
</>
</div>
)
}

View file

@ -1,4 +1,4 @@
import { errorColor } from 'src/styling/variables'
import { errorColor, spacer } from 'src/styling/variables'
const LABEL_WIDTH = 150
@ -6,21 +6,65 @@ export default {
title: {
margin: [[0, 0, 12, 0]]
},
titleDiv: {
paddingBottom: 32
},
subtitle: {
margin: [[32, 0, 21, 0]]
},
edit: {
margin: [[0, 0, 0, 0]]
},
error: {
color: errorColor
},
bill: {
width: 131,
display: 'flex',
alignItems: 'center',
justifyContent: 'end'
},
suffix: {
paddingLeft: spacer * 2
},
button: {
marginLeft: 'auto'
},
submit: {
display: 'flex',
flexDirection: 'row',
margin: [['auto', 0, 24]]
float: 'right'
},
picker: {
width: LABEL_WIDTH
},
header: {
display: 'flex',
paddingBottom: 96,
'& div': {
flex: 1
},
'& img': {
position: 'relative',
top: -20,
right: 14
}
},
content: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
flex: 1,
paddingBottom: 32
},
disclaimer: {
display: 'flex',
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
'& > p': {
'& > svg': {
float: 'left',
margin: [[-4, 16, 48, 0]]
}
}
}
}

View file

@ -21,7 +21,6 @@ const getElements = (machines, { fiatCurrency } = {}) => {
{
name: 'top',
header: 'Cassette 1 (Top)',
view: it => `${it} ${fiatCurrency}`,
size: 'sm',
stripe: true,
width: 200,
@ -29,12 +28,12 @@ const getElements = (machines, { fiatCurrency } = {}) => {
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
},
suffix: fiatCurrency
},
{
name: 'bottom',
header: 'Cassette 2 (Bottom)',
view: it => `${it} ${fiatCurrency}`,
size: 'sm',
stripe: true,
textAlign: 'right',
@ -42,7 +41,8 @@ const getElements = (machines, { fiatCurrency } = {}) => {
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
},
suffix: fiatCurrency
},
{
name: 'zeroConfLimit',
@ -54,7 +54,8 @@ const getElements = (machines, { fiatCurrency } = {}) => {
input: NumberInput,
inputProps: {
decimalPlaces: 0
}
},
suffix: fiatCurrency
}
]
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="148" height="196"><g fill="none"><path fill="#FFF" d="M23.321 124.64l85.498-48.964 31.09 17.806-85.5 48.967z" opacity=".74"/><path fill="#CCD8FF" d="M108.821 109.539l-55.927 32.04-28.04-16.058 83.967-48.098"/><path fill="#D2D8FF" d="M54.41 178.06l85.5-48.966-.002-35.612-85.497 48.965z"/><path fill="#5A67FF" d="M108.821 77.423v32.116l14.02-8.028 14.02-8.03z" opacity=".74"/><path fill="#4B5FEF" d="M93.275 73.926L52.894 97.065l-28.04-16.059 68.421-39.195"/><path fill="#7687FF" d="M23.321 80.125l69.951-40.062 31.09 17.806-69.954 40.065z"/><path fill="#EBEFFF" d="M7.77 53.416l.004 115.741 46.637 26.71-.003-115.742z"/><path fill="#D2D8FF" d="M15.546 129.094l31.092 17.807v35.612l-31.093-17.806z"/><path fill="#5A67FF" d="M0 93.481l31.092 17.807V146.9L0 129.093z"/><path fill="#4B5FEF" d="M31.092 146.9l15.547-8.903-.002-35.612-15.545 8.903zm23.318-13.355l69.954-40.064-.002-35.612L54.41 97.933z"/><path fill="#7687FF" d="M46.637 102.385l-15.545 8.903L.001 93.48l15.544-8.902"/><path fill="#4B5FEF" d="M45.111 101.51l-14.019 8.03-28.04-16.058 14.02-8.03"/><path fill="#1B2559" d="M17.072 85.451v16.059l14.02 8.03 14.019-8.03zM93.275 41.81v32.116l14.02-8.027 14.02-8.03z"/><path fill="#FFF" d="M9.905 123.401l3.388 2.233.012-8.533c0-.52.024-1.025.024-1.025l-.044-.03c-.18.205-.417.35-.682.419l-1.254.345-1.665-2.831 3.913-1.13 2.478 1.632-.01 12.98 3.388 2.232v2.407l-9.554-6.296.006-2.403z"/><path fill="#EBEFFF" d="M25.055 161.858c.023-5.73 7.312-2.347 7.316-5.607a4.505 4.505 0 0 0-2.362-3.631c-1.818-1.031-2.81.308-2.81.308l-2.097-2.643s1.435-2.388 5.153-.323c2.735 1.518 5.053 4.586 5.053 7.725 0 5.34-6.986 2.053-7.06 5.056l7.3 4.487v2.603l-10.367-6.482a13.34 13.34 0 0 1-.126-1.493z"/><path fill="#CCD8FF" d="M54.408 80.125l93.272-53.418.002 115.74-93.271 53.42z" opacity=".74"/><path fill="#DEE5FC" d="M7.77 53.416L101.047 0l46.634 26.707-93.272 53.418z" opacity=".8"/></g></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="148" height="196"><g fill="none"><path fill="#4B5FEF" d="M93.274 118.442l-40.382 23.137-28.04-16.058 68.422-39.195"/><path fill="#7687FF" d="M23.32 124.64l69.95-40.062 31.09 17.807-69.953 40.065z"/><path fill="#4B5FEF" d="M54.41 178.06l69.953-40.063-.003-35.612-69.95 40.063z"/><path fill="#1B2559" d="M93.274 86.326v32.116l14.02-8.028 14.019-8.03z"/><path fill="#FFF" d="M23.32 73.157l85.497-48.964 31.09 17.806-85.5 48.967z" opacity=".74"/><path fill="#CCD8FF" d="M108.82 58.056l-55.928 32.04-28.04-16.058L108.82 25.94"/><path fill="#D2D8FF" d="M54.41 126.577l85.499-48.966L139.907 42 54.409 90.964z"/><path fill="#5A67FF" d="M108.82 25.94v32.116l14.02-8.028 14.019-8.03z" opacity=".74"/><path fill="#EBEFFF" d="M7.77 53.416l.003 115.741 46.637 26.71-.002-115.742z"/><path fill="#D2D8FF" d="M15.545 75.676l31.092 17.806v35.612l-31.092-17.807z"/><path fill="#CCD8FF" d="M54.408 80.125l93.27-53.418.003 115.74-93.271 53.42z" opacity=".74"/><path fill="#DEE5FC" d="M7.77 53.416L101.045 0l46.634 26.707-93.271 53.418z" opacity=".8"/><path fill="#5A67FF" d="M0 137.998l31.092 17.806v35.612L0 173.61z"/><path fill="#4B5FEF" d="M31.092 191.416l15.547-8.903-.002-35.612-15.545 8.903z"/><path fill="#7687FF" d="M46.637 146.9l-15.545 8.904L.001 137.998l15.544-8.903"/><path fill="#4B5FEF" d="M45.111 146.026l-14.019 8.03-28.04-16.058 14.02-8.03"/><path fill="#1B2559" d="M17.072 129.968v16.058l14.02 8.03 14.019-8.03z"/><path fill="#FFF" d="M10.3 169.313c.024-5.73 7.312-2.348 7.316-5.608a4.505 4.505 0 0 0-2.362-3.631c-1.817-1.03-2.809.308-2.809.308l-2.098-2.643s1.435-2.388 5.154-.323c2.734 1.518 5.053 4.586 5.052 7.725 0 5.341-6.985 2.053-7.06 5.057l7.301 4.486v2.603l-10.368-6.482a13.34 13.34 0 0 1-.126-1.492z"/><path fill="#EBEFFF" d="M25.073 105.537l3.388 2.233.012-8.533c.001-.52.024-1.025.024-1.025l-.044-.03c-.18.205-.417.35-.682.419l-1.254.345-1.665-2.831 3.913-1.13 2.478 1.631-.01 12.98 3.388 2.233v2.407l-9.554-6.297.006-2.402z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,189 @@
const denomiations = {
AUD: {
5: 130,
10: 137,
20: 144,
50: 151,
100: 158
},
BBD: {
2: 150,
5: 150,
10: 150,
20: 150,
50: 150,
100: 150
},
CAD: {
5: 152,
10: 152,
20: 152,
50: 152,
100: 152
},
CHF: {
10: 126,
20: 137,
50: 148,
100: 159,
200: 170,
1000: 181
},
DKK: {
50: 125,
100: 135,
200: 145,
500: 155,
1000: 165
},
EUR: {
5: 120,
10: 127,
20: 133,
50: 140,
100: 147,
200: 153,
500: 160
},
GBP: {
5: 135,
10: 142,
20: 149,
50: 156
},
HKD: {
10: 134,
20: 143,
50: 148,
100: 153,
500: 158,
1000: 163
},
HUF: {
200: 154,
500: 154,
1000: 154,
2000: 154,
5000: 154,
10000: 154,
20000: 154
},
ILS: {
20: 129,
50: 136,
100: 143,
200: 150
},
JMD: {
50: 145,
100: 145,
500: 145,
1000: 145,
5000: 145
},
JPY: {
1000: 150,
2000: 154,
5000: 156,
10000: 160
},
KZT: {
200: 126,
500: 130,
1000: 134,
2000: 139,
5000: 144,
10000: 155,
20000: 155
},
MXN: {
20: 120,
50: 127,
100: 134,
200: 141,
500: 148,
1000: 155
},
MYR: {
1: 120,
5: 135,
10: 140,
20: 145,
50: 145,
100: 150
},
NZD: {
5: 135,
10: 140,
20: 145,
50: 150,
100: 155
},
PHP: {
20: 160,
50: 160,
100: 160,
200: 160,
500: 160,
1000: 160
},
PLN: {
10: 120,
20: 126,
50: 132,
100: 138,
200: 144,
500: 150
},
SGD: {
2: 126,
5: 133,
10: 141,
50: 156,
100: 162,
1000: 170
},
TWD: {
100: 145,
200: 150,
500: 155,
1000: 160,
2000: 165
},
UAH: {
1: 118,
2: 118,
5: 118,
10: 124,
20: 130,
50: 136,
100: 142,
200: 148,
500: 154
},
USD: {
1: 156,
5: 156,
10: 156,
20: 156,
50: 156,
100: 156
},
VND: {
10000: 132,
20000: 136,
50000: 140,
100000: 144,
200000: 148,
500000: 152
},
ZAR: {
10: 128,
20: 134,
50: 140,
100: 146,
200: 152
}
}
export default denomiations