feat: add custom file/image to the wizard

This commit is contained in:
José Oliveira 2021-10-19 19:00:05 +01:00
parent c31005d6ef
commit 53f32ba49b
5 changed files with 131 additions and 36 deletions

View file

@ -256,7 +256,8 @@ const CustomerData = ({ customer, updateCustomer }) => {
} }
] ]
const editableCard = ({ const editableCard = (
{
title, title,
authorize, authorize,
reject, reject,
@ -267,10 +268,13 @@ const CustomerData = ({ customer, updateCustomer }) => {
children, children,
validationSchema, validationSchema,
initialValues initialValues
}) => { },
idx
) => {
return ( return (
<EditableCard <EditableCard
title={title} title={title}
key={idx}
authorize={authorize} authorize={authorize}
reject={reject} reject={reject}
state={state} state={state}
@ -308,12 +312,12 @@ const CustomerData = ({ customer, updateCustomer }) => {
<Grid container> <Grid container>
<Grid container direction="column" item xs={6}> <Grid container direction="column" item xs={6}>
{visibleCards.map((elem, idx) => { {visibleCards.map((elem, idx) => {
return isEven(idx) ? editableCard(elem) : null return isEven(idx) ? editableCard(elem, idx) : null
})} })}
</Grid> </Grid>
<Grid container direction="column" item xs={6}> <Grid container direction="column" item xs={6}>
{visibleCards.map((elem, idx) => { {visibleCards.map((elem, idx) => {
return !isEven(idx) ? editableCard(elem) : null return !isEven(idx) ? editableCard(elem, idx) : null
})} })}
</Grid> </Grid>
</Grid> </Grid>

View file

@ -1,7 +1,7 @@
import { makeStyles } from '@material-ui/core' import { makeStyles } from '@material-ui/core'
import { Form, Formik } from 'formik' import { Form, Formik, useFormikContext } from 'formik'
import * as R from 'ramda' import * as R from 'ramda'
import React, { useState } from 'react' import React, { useState, Fragment, useEffect } from 'react'
import ErrorMessage from 'src/components/ErrorMessage' import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal' import Modal from 'src/components/Modal'
@ -9,7 +9,7 @@ import Stepper from 'src/components/Stepper'
import { Button } from 'src/components/buttons' import { Button } from 'src/components/buttons'
import { comet } from 'src/styling/variables' import { comet } from 'src/styling/variables'
import { entryType } from './helper' import { entryType, customElements } from './helper'
const LAST_STEP = 2 const LAST_STEP = 2
@ -46,26 +46,44 @@ const styles = {
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const getStep = step => { const getStep = (step, selectedValues) => {
switch (step) { switch (step) {
case 1: case 1:
return entryType return entryType
case 2:
return customElements[selectedValues?.dataType]
default: default:
return entryType return Fragment
} }
} }
const GetValues = ({ setValues }) => {
const { values, touched, errors } = useFormikContext()
console.log(touched, errors, values)
useEffect(() => {
setValues && values && setValues(values)
}, [setValues, values])
return null
}
const Wizard = ({ onClose, save, error }) => { const Wizard = ({ onClose, save, error }) => {
const classes = useStyles() const classes = useStyles()
const [selectedValues, setSelectedValues] = useState(null)
const [liveValues, setLiveValues] = useState({})
const [{ step, config }, setState] = useState({ const [{ step, config }, setState] = useState({
step: 1 step: 1
}) })
console.log(liveValues)
const isLastStep = step === LAST_STEP const isLastStep = step === LAST_STEP
const stepOptions = getStep(step) const stepOptions = getStep(step, selectedValues)
const onContinue = async it => { const onContinue = async it => {
const newConfig = R.merge(config, stepOptions.schema.cast(it)) const newConfig = R.merge(config, stepOptions.schema.cast(it))
setSelectedValues(newConfig)
if (isLastStep) { if (isLastStep) {
return save(newConfig) return save(newConfig)
@ -98,11 +116,15 @@ const Wizard = ({ onClose, save, error }) => {
initialValues={stepOptions.initialValues} initialValues={stepOptions.initialValues}
validationSchema={stepOptions.schema}> validationSchema={stepOptions.schema}>
<Form className={classes.form}> <Form className={classes.form}>
<stepOptions.Component {...stepOptions.props} /> <GetValues setValues={setLiveValues} />
<stepOptions.Component
selectedValues={selectedValues}
{...stepOptions.props}
/>
<div className={classes.submit}> <div className={classes.submit}>
{error && <ErrorMessage>Failed to save</ErrorMessage>} {error && <ErrorMessage>Failed to save</ErrorMessage>}
<Button className={classes.button} type="submit"> <Button className={classes.button} type="submit">
{isLastStep ? 'Finish' : 'Next'} {isLastStep ? 'Add Data' : 'Next'}
</Button> </Button>
</div> </div>
</Form> </Form>

View file

@ -38,7 +38,7 @@ const fieldStyles = {
}, },
label: { label: {
color: comet, color: comet,
margin: [[0, 3]] margin: [[0, 0, 0, 0]]
}, },
notEditing: { notEditing: {
display: 'flex', display: 'flex',
@ -58,10 +58,12 @@ const fieldStyles = {
} }
}, },
editing: { editing: {
'& > div': {
'& > input': { '& > input': {
padding: 0 padding: 0
} }
} }
}
} }
const fieldUseStyles = makeStyles(fieldStyles) const fieldUseStyles = makeStyles(fieldStyles)
@ -88,9 +90,7 @@ const EditableField = ({ editing, field, size, ...props }) => {
<FormikField <FormikField
className={classes.editing} className={classes.editing}
id={field.name} id={field.name}
name={field.name}
component={field.component} component={field.component}
placeholder={field.placeholder}
value={field.value} value={field.value}
type={field.type} type={field.type}
width={size} width={size}

View file

@ -5,7 +5,7 @@ import { parsePhoneNumberFromString } from 'libphonenumber-js'
import * as R from 'ramda' import * as R from 'ramda'
import * as Yup from 'yup' import * as Yup from 'yup'
import { RadioGroup } from 'src/components/inputs/formik' import { RadioGroup, TextInput } from 'src/components/inputs/formik'
import { H4 } from 'src/components/typography' import { H4 } from 'src/components/typography'
import { errorColor } from 'src/styling/variables' import { errorColor } from 'src/styling/variables'
@ -122,16 +122,41 @@ const requirementOptions = [
{ display: 'US SSN', code: 'usSsn' } { display: 'US SSN', code: 'usSsn' }
] ]
const customTextOptions = [
{ display: 'Data entry title', code: 'title' },
{ display: 'Data entry', code: 'data' }
]
const customUploadOptions = [{ display: 'Data entry title', code: 'title' }]
const entryTypeSchema = Yup.object().shape({ const entryTypeSchema = Yup.object().shape({
entryType: Yup.object({
entryType: Yup.string().required() entryType: Yup.string().required()
})
const customFileSchema = Yup.object().shape({
file: Yup.mixed().required()
})
const customImageSchema = Yup.object().shape({
image: Yup.mixed().required()
})
const customTextSchema = Yup.object().shape({
text: Yup.object({
title: Yup.string().required(),
data: Yup.string().required()
}).required() }).required()
}) })
const EntryType = () => { const EntryType = () => {
const classes = useStyles() const classes = useStyles()
const { values } = useFormikContext() const { values } = useFormikContext()
const displayCustom = values.entryType === 'custom'
const CUSTOM = 'custom'
const REQUIREMENT = 'requirement'
const displayCustomOptions = values.entryType === CUSTOM
const displayRequirementOptions = values.entryType === REQUIREMENT
return ( return (
<> <>
@ -146,7 +171,7 @@ const EntryType = () => {
radioClassName={classes.radio} radioClassName={classes.radio}
className={classnames(classes.radioGroup, classes.specialGrid)} className={classnames(classes.radioGroup, classes.specialGrid)}
/> />
{displayCustom && ( {displayCustomOptions && (
<div> <div>
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<H4>Type of data</H4> <H4>Type of data</H4>
@ -161,7 +186,7 @@ const EntryType = () => {
/> />
</div> </div>
)} )}
{!displayCustom && ( {displayRequirementOptions && (
<div> <div>
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<H4>Requirements</H4> <H4>Requirements</H4>
@ -180,11 +205,55 @@ const EntryType = () => {
) )
} }
const CustomData = ({ selectedValues }) => {
const dataTypeSelected = selectedValues?.dataType
const upload = dataTypeSelected === 'file' || dataTypeSelected === 'image'
console.log(dataTypeSelected, 'LAWDOIUHJAWIDUAW', selectedValues)
return (
<>
<Box display="flex" alignItems="center">
<H4>{`Custom ${dataTypeSelected} entry`}</H4>
</Box>
{customElements[dataTypeSelected].options.map(({ display, code }) => (
<Field name={code} label={display} component={TextInput} width={390} />
))}
{upload && <H4 type="image">{'OI'}</H4>}
</>
)
}
const customElements = {
text: {
schema: customTextSchema,
options: customTextOptions,
Component: CustomData,
initialValues: { text: { title: '', data: '' } }
},
file: {
schema: customFileSchema,
options: customUploadOptions,
Component: CustomData,
initialValues: { file: { title: '', file: '' } }
},
image: {
schema: customImageSchema,
options: customUploadOptions,
Component: CustomData,
initialValues: { image: { title: '', image: '' } }
}
}
const entryType = { const entryType = {
schema: entryTypeSchema, schema: entryTypeSchema,
options: entryOptions, options: entryOptions,
Component: EntryType, Component: EntryType,
initialValues: { entryType: { entryType: '' } } initialValues: { entryType: '' }
} }
export { getAuthorizedStatus, getFormattedPhone, getName, entryType } export {
getAuthorizedStatus,
getFormattedPhone,
getName,
entryType,
customElements
}