\n
\n {\n steps.map((step, index) => {\n return (\n onStepClick(index)}\n >\n \n {step.label}\n \n \n );\n })\n }\n \n
\n {\n props.children\n }\n
\n
\n );\n};\n\nNativeStepper.propTypes = {\n steps: PropTypes.array.isRequired,\n activeStep: PropTypes.number.isRequired,\n onStepClick: PropTypes.func\n};\n\nexport default NativeStepper;\n","export const checkEmailValidity = (email) => {\n const re = /^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n return re.test(email);\n}","export const checkCreditCardValidity = (creditCardNumber) => {\n const americanExpress = /^3[47][0-9]{13}$/; \n const visa = /^(?:4[0-9]{12}(?:[0-9]{3})?)$/; \n const masterCard = /^(?:5[0-9]{15})$/; \n const discover = /^(?:6[0-9]{15})$/; \n const dinnersClub = /^3[068][0-9]{12}$/;\n\n return americanExpress.test(creditCardNumber) || \n visa.test(creditCardNumber) || \n masterCard.test(creditCardNumber) || \n discover.test(creditCardNumber) || \n dinnersClub.test(creditCardNumber);\n}","export const checkCVVValidity = (cardNumber, cvv) => {\n const americanExpressCardNumber = /^3[47][0-9]{13}$/;\n const americanExpressCVV = /^[0-9]{4}$/; \n const restCVV = /^[0-9]{3}$/; \n\n if(americanExpressCardNumber.test(cardNumber)) {\n return americanExpressCVV.test(cvv);\n }\n else return restCVV.test(cvv);\n\n}","export default function validPhoneNumber(number){\n if(!number || number === ''){\n return true;\n }\n\n const chars = number.toString();\n return !isNaN(number) && chars.length === 10 && chars.slice(0,1) !== '1' ;\n}","import React, {useEffect, useState} from 'react';\nimport PropTypes from 'prop-types';\nimport {\n makeStyles,\n Button,\n Typography,\n CircularProgress,\n AppBar,\n Grid,\n Paper\n} from \"@material-ui/core\";\nimport Stepper from \"../Stepper/Stepper\";\nimport {checkEmailValidity} from \"../../helperFunctions/checkEmailValidity\";\nimport {checkCreditCardValidity} from \"../../helperFunctions/checkCreditCardValidity\";\nimport Notification from \"../../components/Notification/Notification\";\nimport {checkCVVValidity} from \"../../helperFunctions/checkCVVValidity\";\n\nimport validPhoneNumber from '../../helperFunctions/checkPhoneNumber';\n\nconst useStyles = makeStyles({\n appBar: {\n textAlign: 'right',\n backgroundColor: \"white\",\n bottom: 0,\n padding:10,\n top:\"auto\"\n },\n stepContainer: {\n padding: '20px',\n height: 'auto'\n }\n});\n\nconst DEFAULT_NOTIFICATION = {\n type: \"success\",\n message: \"\",\n open: false\n}\n\nconst FormWizard = props => {\n const {steps, onSubmit, handleNextClick, allowAnotherSubmit, resetAllowAnotherSubmit} = props; \n const classes = useStyles();\n\n const [data, setData] = useState(steps.map(i => i.data));\n const [errors, setErrors] = useState({});\n const [activeStep, setActiveStep] = useState(0);\n const [clonedComponents, setClonedComponents] = useState([]);\n const [disableSubmit, setDisableSubmit] = useState(false);\n const [submitLoading, setSubmitLoading] = useState(false);\n const [nextLoading, setNextLoading] = useState(false);\n const [notification, setNotification] = useState({...DEFAULT_NOTIFICATION});\n const [noWayBack, setNoWayBack] = useState(false);\n\n useEffect(() => {\n setData(steps.map(i => i.data));\n }, [steps])\n\n useEffect(() => {\n if(allowAnotherSubmit) {\n setDisableSubmit(false);\n setSubmitLoading(false);\n if(resetAllowAnotherSubmit) resetAllowAnotherSubmit(); \n }\n }, [allowAnotherSubmit])\n\n useEffect(() => {\n const newErrors = {}\n for(let i = 0; i < steps.length; i++) {\n const activeStepData = data[i];\n for (let key in errors) {\n if (activeStepData[key]) {\n newErrors[key] = errors[key];\n }\n }\n\n for (let key in activeStepData) {\n if (activeStepData[key].required) {\n if (Array.isArray(activeStepData[key].value)) {\n if (activeStepData[key].value.length < 1) {\n newErrors[key] = 'Field is required!';\n } else {\n delete newErrors[key];\n }\n } else if (activeStepData[key]?.value === null || \n activeStepData?.[key]?.value?.toString()?.trim()?.length === 0 ||\n (key === 'address' && typeof activeStepData[key].value === 'object' && !activeStepData[key].value.isValid) ||\n (key === 'email' && !checkEmailValidity(activeStepData[key].value))\n ) {\n newErrors[key] = 'Field is required!';\n } else if ( key === 'cardNumber' && !checkCreditCardValidity(activeStepData[key].value) ) {\n newErrors[key] = 'Invalid CC number';\n } else if ( key === 'cardCVVNumber' && !checkCVVValidity(activeStepData['cardNumber'].value, activeStepData[key].value) ) {\n newErrors[key] = 'Invalid CVV';\n }else if ((key === \"emergencyPhone\" || key === \"primaryPhone\") && !validPhoneNumber(activeStepData[key].value)){\n newErrors[key] = `Invalid ${key === \"emergencyPhone\" ? 'Emergency Phone Number' : 'Primary Phone Number'}` ;\n }\n else {\n delete newErrors[key];\n }\n }\n }\n }\n if(Object.keys(newErrors).length > 0) setDisableSubmit(true);\n else setDisableSubmit(false);\n\n }, [data, steps, errors]);\n\n useEffect(() => {\n const activeStepData = data[activeStep];\n const newErrors = {};\n\n for (let key in errors) {\n if (activeStepData[key]) {\n newErrors[key] = errors[key];\n }\n }\n\n for (let key in activeStepData) {\n if (activeStepData[key].required) {\n if (Array.isArray(activeStepData[key].value)) {\n if (activeStepData[key].value.length < 1) {\n newErrors[key] = 'Field is required!';\n } else {\n delete newErrors[key];\n }\n } else if (activeStepData[key].value === null || \n activeStepData[key]?.value?.toString().trim().length === 0 ||\n (key === 'address' && typeof activeStepData[key].value === 'object' && !activeStepData[key].value.isValid) ||\n (key === 'email' && !checkEmailValidity(activeStepData[key].value))\n ) {\n newErrors[key] = 'Field is required!';\n } else if ( key === 'cardNumber' && !checkCreditCardValidity(activeStepData[key].value) ) {\n newErrors[key] = 'Invalid CC number';\n } else if ( key === 'cardCVVNumber' && !checkCVVValidity(activeStepData['cardNumber'].value, activeStepData[key].value) ) {\n newErrors[key] = 'Invalid CVV';\n } else if ((key === \"emergencyPhone\" || key === \"primaryPhone\") && !validPhoneNumber(activeStepData[key].value)){\n newErrors[key] = `Invalid ${key === \"emergencyPhone\" ? 'Emergency Phone Number' : 'Primary Phone Number'}` ;\n }\n else {\n delete newErrors[key];\n }\n }\n }\n\n setErrors(newErrors);\n\n }, [data, activeStep]);\n\n useEffect(() => {\n const arr = steps.map((step, i) => {\n return React.cloneElement(step.component,\n {\n data: data,\n stepNum: i,\n activeStep: activeStep,\n errors: errors,\n setErrors: setErrors,\n hasError: hasError,\n getErrorMessage: getErrorMessage,\n onChange: handleFieldChange,\n onRequiredChange: handleRequiredChange\n });\n });\n setClonedComponents(arr);\n }, [data, steps, errors]);\n\n const handleStepBack = () => {\n setActiveStep((prevActiveStep) => prevActiveStep - 1);\n };\n\n const handleStepNext = () => {\n setNextLoading(true);\n const result = {};\n data.forEach(arr => {\n for (let key in arr) {\n if (Array.isArray(arr[key].value)) {\n if (arr[key].value.length >= 1) {\n result[key] = arr[key].value;\n } \n } else if ( !( arr?.[key].value === null || \n arr?.[key]?.value?.toString()?.trim()?.length === 0 ||\n (key === 'address' && typeof arr[key].value === 'object' && !arr[key].value.isValid) ||\n (key === 'email' && !checkEmailValidity(arr[key].value)) ||\n (key === 'cardNumber' && !checkCreditCardValidity(arr[key].value)) ||\n (key === 'cardCVVNumber' && !checkCVVValidity(arr[key].value))\n )) {\n result[key] = arr[key].value;\n }\n }\n });\n handleNextClick(result)\n .then(response => {\n if(response && response.data && response.data.length) {\n handleFieldChange('applicationId', response.data[0].applicationId, 0);\n handleFieldChange('memberId', response.data[0].members[0].memberId, 0);\n handleFieldChange('dependents', \n response.data[0].members\n .filter(it => it.relationshipTypeId !== 'P')\n .map((mem, memIndex) => {\n return {\n applicationId: response.data[0].applicationId,\n memberId: mem.memberId,\n dateOfBirth: new Date(mem.dateOfBirth),\n firstName: mem.firstName,\n lastName: mem.lastName,\n phone: mem.phoneNumber,\n gender: mem.genderId,\n relationship: data[0].dependents.value[memIndex].relationship\n }\n }), 0);\n }\n setNextLoading(false);\n setActiveStep((prevActiveStep) => prevActiveStep + 1);\n })\n .catch(error => {\n console.log('Failed to save partial application', error);\n setNextLoading(false);\n setNotification({\n open: true,\n type: \"error\",\n message: \"We couldn't save partial application, please try again\"\n }); \n });\n };\n\n const handleFieldChange = (field, value, stepIndex) => {\n setData(prevState => {\n return prevState.map((step, i) => {\n if (((stepIndex && stepIndex === i) || activeStep === i) && step[field]) {\n return {\n ...step,\n [field]: {\n ...step[field],\n value: value\n }\n }\n }\n return step;\n });\n });\n };\n\n const handleRequiredChange = (field, value, stepIndex) => {\n setData(prevState => {\n return prevState.map((step, i) => {\n if (((stepIndex && stepIndex === i) || activeStep === i) && step[field]) {\n return {\n ...step,\n [field]: {\n ...step[field],\n required: value\n }\n }\n }\n return step;\n });\n });\n }\n\n const handleStepClick = (index) => {\n if (!disableSubmit && !Object.keys(errors).length > 0) {\n setActiveStep(index)\n }\n }\n\n const handleSubmit = () => { \n setDisableSubmit(true);\n setSubmitLoading(true);\n\n const result = {};\n data.forEach(arr => {\n for (let key in arr) {\n result[key] = arr[key].value;\n } \n });\n\n onSubmit(result);\n };\n\n const hasError = (key) => {\n if (errors[key]) {\n return true;\n }\n return false;\n };\n\n const getErrorMessage = (key) => {\n if (errors[key]) {\n return errors[key];\n }\n return null;\n };\n\n return (\n