feat: add custom file/image to the wizard
This commit is contained in:
parent
c31005d6ef
commit
53f32ba49b
5 changed files with 131 additions and 36 deletions
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue