Last active
October 14, 2019 15:33
-
-
Save BBB/e3fb9395c311c5d7b9bd488ef147cad4 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const hasPropCond = (onboardingDataPropName) => ({ | |
| type: 'hasProp', | |
| onboardingDataPropName | |
| }); | |
| const notHasPropCond = ( | |
| onboardingDataPropName, | |
| validator | |
| ) => ({ | |
| type: 'notHasProp', | |
| onboardingDataPropName, | |
| validator | |
| }); | |
| const nextStageEvents = ( | |
| prop, | |
| target | |
| ) => ({ | |
| '': { | |
| cond: hasPropCond(prop), | |
| target | |
| }, | |
| COMPLETE: { | |
| actions: assign({ [prop]: (ctx, e) => true }) | |
| } | |
| }); | |
| const takePhotoStages = (propName, targetState) => ({ | |
| OnboardingVerificationInstructions: { | |
| on: { | |
| TAKE_PHOTO: { | |
| target: 'OnboardingVerificationPhoto' | |
| } | |
| } | |
| }, | |
| OnboardingVerificationPhoto: { | |
| on: { | |
| COMPLETE: { | |
| target: 'OnboardingVerficationPhotoPreview' | |
| } | |
| } | |
| }, | |
| OnboardingVerficationPhotoPreview: { | |
| on: { | |
| COMPLETE: { | |
| target: targetState, | |
| actions: assign({ [propName]: true }) | |
| }, | |
| RETAKE: { | |
| target: 'OnboardingVerificationPhoto' | |
| } | |
| } | |
| } | |
| }); | |
| const states = { | |
| Start: { | |
| initial: 'Splash', | |
| states: { | |
| Splash: { | |
| on: { | |
| COMPLETE: [ | |
| { | |
| cond: notHasPropCond('__disabled'), | |
| target: '#onboarding.OnboardingApplying' | |
| }, | |
| { | |
| cond: hasPropCond('__disabled'), | |
| target: 'OnboardingUnavailable' | |
| } | |
| ] | |
| } | |
| }, | |
| OnboardingUnavailable: { | |
| on: {} | |
| } | |
| } | |
| }, | |
| OnboardingApplying: { | |
| on: { | |
| ...nextStageEvents('__applying', 'OnboardingPrivacy') | |
| } | |
| }, | |
| OnboardingPrivacy: { | |
| on: { | |
| ...nextStageEvents('__privacy', 'OnboardingAccountFees') | |
| } | |
| }, | |
| OnboardingAccountFees: { | |
| id: 'OnboardingAccountFees', | |
| on: { | |
| ...nextStageEvents('__accountFees', 'Terms') | |
| } | |
| }, | |
| Terms: { | |
| initial: 'Picker', | |
| states: { | |
| Picker: { | |
| on: { | |
| '': [ | |
| { | |
| cond: hasPropCond('__upcomingTerms'), | |
| target: 'OnboardingTermsAndConditions' | |
| }, | |
| { | |
| cond: notHasPropCond('__upcomingTerms'), | |
| target: 'OnboardingUpcomingTermsAndConditions' | |
| } | |
| ] | |
| } | |
| }, | |
| OnboardingTermsAndConditions: { | |
| on: { | |
| ...nextStageEvents('__terms', '#OnboardingFirstName') | |
| } | |
| }, | |
| OnboardingUpcomingTermsAndConditions: { | |
| on: { | |
| ...nextStageEvents('__upcomingTerms', '#OnboardingAccountFees') | |
| } | |
| } | |
| } | |
| }, | |
| OnboardingFirstName: { | |
| id: 'OnboardingFirstName', | |
| on: { | |
| ...nextStageEvents('firstName', 'OnboardingLastName') | |
| } | |
| }, | |
| OnboardingLastName: { | |
| on: { | |
| ...nextStageEvents('lastName', 'OnboardingDateOfBirth') | |
| } | |
| }, | |
| OnboardingDateOfBirth: { | |
| on: { | |
| ...nextStageEvents('dateOfBirth', 'PhoneNumber') | |
| } | |
| }, | |
| PhoneNumber: { | |
| initial: 'Picker', | |
| states: { | |
| Picker: { | |
| on: { | |
| '': [ | |
| { | |
| cond: notHasPropCond('mobileNumber'), | |
| target: 'OnboardingPhoneNumber' | |
| }, | |
| { | |
| cond: notHasPropCond('__confirmMobileNumber'), | |
| target: 'OnboardingPhoneNumberConfirm' | |
| }, | |
| { | |
| cond: hasPropCond('__confirmMobileNumber'), | |
| target: '#onboarding.OnboardingEmail' | |
| } | |
| ] | |
| } | |
| }, | |
| OnboardingPhoneNumber: { | |
| on: { | |
| ...nextStageEvents('mobileNumber', 'Picker') | |
| } | |
| }, | |
| OnboardingPhoneNumberConfirm: { | |
| on: { | |
| ...nextStageEvents('__confirmMobileNumber', 'Picker'), | |
| ALREADY_REGISTERED: { | |
| target: 'OnboardingDuplicateFeatureLogin' | |
| }, | |
| RESEND_CODE: { | |
| target: 'OnboardingResendCode' | |
| } | |
| } | |
| }, | |
| OnboardingResendCode: { | |
| on: {} | |
| }, | |
| OnboardingDuplicateFeatureLogin: { | |
| on: { | |
| LOGIN: { | |
| target: 'OnboardingAccessingBoAccount' | |
| } | |
| } | |
| }, | |
| OnboardingAccessingBoAccount: { | |
| on: { | |
| RECOVER: { | |
| target: 'RecoverEmail' | |
| } | |
| } | |
| }, | |
| // Just a dead end for now | |
| RecoverEmail: { | |
| on: {} | |
| } | |
| } | |
| }, | |
| OnboardingEmail: { | |
| on: { | |
| ...nextStageEvents('email', 'Address') | |
| } | |
| }, | |
| Address: { | |
| initial: 'Picker', | |
| states: { | |
| Picker: { | |
| on: { | |
| '': [ | |
| { | |
| cond: notHasPropCond('addressPostcode'), | |
| target: 'Postcode' | |
| }, | |
| { | |
| cond: notHasPropCond('__addressComplete'), | |
| target: 'OnboardingAddress' | |
| }, | |
| { | |
| cond: hasPropCond('__addressComplete'), | |
| target: 'OnboardingConfirmAddress' | |
| } | |
| ] | |
| } | |
| }, | |
| Postcode: { | |
| initial: 'Picker', | |
| states: { | |
| Picker: { | |
| on: { | |
| '': [ | |
| { | |
| cond: notHasPropCond('addressPostcode'), | |
| target: 'OnboardingPostcode' | |
| }, | |
| { | |
| cond: notHasPropCond('__addressComplete'), | |
| target: 'OnboardingPostcodeResults' | |
| } | |
| ] | |
| } | |
| }, | |
| OnboardingPostcode: { | |
| on: { | |
| ...nextStageEvents('addressPostcode', 'Picker') | |
| } | |
| }, | |
| OnboardingPostcodeResults: { | |
| on: { | |
| ...nextStageEvents('__addressComplete', '#onboarding.Address'), | |
| MANUAL_ENTRY: { | |
| target: '#onboarding.Address.OnboardingAddress' | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| OnboardingAddress: { | |
| on: { | |
| ...nextStageEvents('__addressComplete', 'Picker') | |
| } | |
| }, | |
| OnboardingConfirmAddress: { | |
| on: { | |
| ...nextStageEvents( | |
| '__confirmAddress', | |
| '#onboarding.OnboardingNationality' | |
| ), | |
| EDIT_ADDRESS: { | |
| target: 'Picker', | |
| actions: assign({ __addressComplete: (_ctx, _e) => false }) | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| OnboardingNationality: { | |
| on: { | |
| ...nextStageEvents('nationalities', 'OnboardingTax', val => { | |
| if (Array.isArray(val)) { | |
| return val.length > 0; | |
| } | |
| return false; | |
| }), | |
| INVALID_NATIONALITY: { | |
| target: 'OnboardingDenied' | |
| } | |
| } | |
| }, | |
| OnboardingTax: { | |
| on: { | |
| ...nextStageEvents('taxResidencies', 'PassCode'), | |
| INVALID_TAX: { | |
| target: 'OnboardingDenied' | |
| } | |
| } | |
| }, | |
| OnboardingDenied: { | |
| on: {} | |
| }, | |
| PassCode: { | |
| initial: 'Picker', | |
| states: { | |
| Picker: { | |
| on: { | |
| '': [ | |
| { | |
| cond: notHasPropCond('__passCode'), | |
| target: 'OnboardingPassCode' | |
| }, | |
| { | |
| cond: notHasPropCond('__passCodeConfirm'), | |
| target: 'OnboardingPassCodeConfirm' | |
| }, | |
| { | |
| cond: hasPropCond('__passCodeConfirm'), | |
| target: '#onboarding.OnboardingNotifications' | |
| } | |
| ] | |
| } | |
| }, | |
| OnboardingPassCode: { | |
| on: { | |
| ...nextStageEvents('__passCode', 'Picker') | |
| } | |
| }, | |
| OnboardingPassCodeConfirm: { | |
| on: { | |
| ...nextStageEvents('__passCodeConfirm', 'Picker') | |
| } | |
| } | |
| } | |
| }, | |
| OnboardingNotifications: { | |
| on: { | |
| COMPLETE: { | |
| target: 'OnboardingFSCS' | |
| } | |
| } | |
| }, | |
| OnboardingFSCS: { | |
| on: { | |
| COMPLETE: { | |
| target: 'HooyuApi' | |
| } | |
| } | |
| }, | |
| HooyuApi: { | |
| initial: 'OnboardingVerificationHome', | |
| states: { | |
| OnboardingVerificationHome: { | |
| on: { | |
| ENTER_ID: { | |
| target: 'ID', | |
| cond: notHasPropCond('__idPhoto') | |
| }, | |
| ENTER_ADDRESS: { | |
| target: 'ADDRESS', | |
| cond: notHasPropCond('__addressPhoto') | |
| }, | |
| ENTER_SELFIE: { | |
| target: 'SELFIE', | |
| cond: notHasPropCond('__selfiePhoto') | |
| }, | |
| '': [ | |
| { | |
| target: 'OnboardingVerificationWaiting', | |
| cond: context => | |
| context.__idPhoto && | |
| context.__addressPhoto && | |
| context.__selfiePhoto && | |
| !context.__hooyuVerificationComplete | |
| }, | |
| { | |
| target: '#onboarding.OnboardingSuccess', | |
| cond: context => | |
| context.__idPhoto && | |
| context.__addressPhoto && | |
| context.__selfiePhoto && | |
| context.__hooyuVerificationComplete | |
| } | |
| ] | |
| } | |
| }, | |
| ID: { | |
| initial: 'OnboardingVerificationOfficialID', | |
| states: { | |
| OnboardingVerificationOfficialID: { | |
| on: { | |
| TAKE_PHOTO: { | |
| target: 'OnboardingVerificationInstructions' | |
| }, | |
| COMPLETE: { | |
| target: 'OnboardingVerificationOfficialIDCountry' | |
| } | |
| } | |
| }, | |
| OnboardingVerificationOfficialIDCountry: { | |
| on: { | |
| TAKE_PHOTO: { | |
| target: 'OnboardingVerificationInstructions' | |
| } | |
| } | |
| }, | |
| ...takePhotoStages( | |
| '__idPhoto', | |
| '#onboarding.HooyuApi.OnboardingVerificationHome' | |
| ) | |
| } | |
| }, | |
| ADDRESS: { | |
| initial: 'OnboardingVerificationProofAddress', | |
| states: { | |
| OnboardingVerificationProofAddress: { | |
| on: { | |
| COMPLETE: { | |
| target: 'OnboardingVerificationProofAddressSelection' | |
| } | |
| } | |
| }, | |
| OnboardingVerificationProofAddressSelection: { | |
| on: { | |
| COMPLETE: { | |
| target: 'OnboardingVerficationProofOfAddressChecklist' | |
| } | |
| } | |
| }, | |
| OnboardingVerficationProofOfAddressChecklist: { | |
| on: { | |
| TAKE_PHOTO: { | |
| target: 'OnboardingVerificationInstructions' | |
| } | |
| } | |
| }, | |
| ...takePhotoStages( | |
| '__addressPhoto', | |
| '#onboarding.HooyuApi.OnboardingVerificationHome' | |
| ) | |
| } | |
| }, | |
| SELFIE: { | |
| initial: 'OnboardingVerificationSelfie', | |
| states: { | |
| OnboardingVerificationSelfie: { | |
| on: { | |
| TAKE_PHOTO: { | |
| target: 'OnboardingVerificationInstructions' | |
| } | |
| } | |
| }, | |
| ...takePhotoStages( | |
| '__selfiePhoto', | |
| '#onboarding.HooyuApi.OnboardingVerificationHome' | |
| ) | |
| } | |
| }, | |
| // this polls for success | |
| OnboardingVerificationWaiting: { | |
| on: { | |
| FAIL: { | |
| target: 'OnboardingVerificationHome' | |
| }, | |
| N_1: { | |
| target: '#onboarding.Start', | |
| actions: assign((_ctx, _e) => ({ ...emptyContext })) | |
| }, | |
| COMPLETE: { | |
| target: '#onboarding.HooyuApi.OnboardingVerificationHome', | |
| actions: assign({ | |
| __hooyuVerificationComplete: (_ctx, _e) => true | |
| }) | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| OnboardingSuccess: { | |
| on: { | |
| COMPLETE: { | |
| target: 'PostOnboardingMarketingOptIn' | |
| } | |
| } | |
| }, | |
| PostOnboardingMarketingOptIn: { | |
| on: { | |
| COMPLETE: { | |
| target: 'PostOnboardingEmail' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmailVerified: { | |
| on: { | |
| N_0: { | |
| target: 'App' | |
| }, | |
| N_1: { | |
| target: 'PostOnboardingSupport' | |
| } | |
| } | |
| }, | |
| PostOnboardingSupport: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingWelcome' | |
| } | |
| } | |
| }, | |
| PostOnboardingTour: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingWelcome' | |
| } | |
| } | |
| }, | |
| PostOnboardingLivingStatus: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingEmployment' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmployment: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingOccupation' | |
| }, | |
| N_1: { | |
| target: 'PostOnboardingIncome' | |
| } | |
| } | |
| }, | |
| PostOnboardingOccupation: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingIncome' | |
| } | |
| } | |
| }, | |
| PostOnboardingIncome: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingSums' | |
| } | |
| } | |
| }, | |
| PostOnboardingSums: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingCalculator' | |
| } | |
| } | |
| }, | |
| PostOnboardingCalculator: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingAddMoney' | |
| } | |
| } | |
| }, | |
| PostOnboardingAddMoney: { | |
| on: { | |
| N_0: { | |
| target: 'App' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmail: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingEmailEdit' | |
| }, | |
| N_1: { | |
| target: 'PostOnboardingEmailSent' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmailSent: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingEmailIncorrect' | |
| }, | |
| N_1: { | |
| target: 'ExternalOpenEmail' | |
| } | |
| } | |
| }, | |
| ExternalOpenEmail: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingEmailVerified' | |
| } | |
| } | |
| }, | |
| PostOnboardingWelcome: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingLivingStatus' | |
| }, | |
| N_1: { | |
| target: 'PostOnboardingTour' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmailIncorrect: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingEmailEdit' | |
| }, | |
| N_1: { | |
| target: 'PostOnboardingSupport' | |
| }, | |
| N_2: { | |
| target: 'PostOnboardingEmailSent' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmailVerifiedRoute: { | |
| on: { | |
| N_0: { | |
| target: 'App' | |
| }, | |
| N_1: { | |
| target: 'PostOnboardingSupport' | |
| } | |
| } | |
| }, | |
| PostOnboardingEmailEdit: { | |
| on: { | |
| N_0: { | |
| target: 'PostOnboardingEmailSent' | |
| } | |
| } | |
| }, | |
| App: { | |
| on: {} | |
| } | |
| }; | |
| const onboardingMachine = Machine( | |
| { | |
| id: 'onboarding', | |
| initial: 'Start', | |
| context: { | |
| firstName: true, | |
| lastName: true, | |
| dateOfBirth: true, | |
| mobileCountryCode: true, | |
| mobileNumber: true, | |
| email: true, | |
| addressLine1: undefined, | |
| addressLine2: undefined, | |
| addressLine3: undefined, | |
| addressTown: undefined, | |
| addressCounty: undefined, | |
| addressCountry: undefined, | |
| addressPostcode: true, | |
| equifaxAddressId: undefined, | |
| nationalities: ['one'], | |
| taxResidencies: ['one'], | |
| hooyuUrl: undefined, | |
| documents: [], | |
| mobileNumberConfirmed: false, | |
| upcomingTermsAndConditionsAcknowledged: null, | |
| error: null, | |
| verification: null, | |
| // different | |
| applying: false, | |
| confirmAddress: false, | |
| terms: false, | |
| privacy: false, | |
| accountFees: false, | |
| addressPostcodeResults: false, | |
| __applying: true, | |
| __privacy: true, | |
| __accountFees: true, | |
| __upcomingTerms: true, | |
| __terms: true, | |
| __addressComplete: true, | |
| __passCode: true, | |
| __passCodeConfirm: true, | |
| __confirmMobileNumber: true, | |
| __confirmAddress: true, | |
| }, | |
| states | |
| }, | |
| { | |
| guards: { | |
| hasProp: (context, _event, guard) => { | |
| const cond = guard.cond; | |
| const val = context[cond.onboardingDataPropName]; | |
| if (Array.isArray(val)) { | |
| return val.length > 0; | |
| } | |
| return !!context[cond.onboardingDataPropName]; | |
| }, | |
| notHasProp: (context, _event, guard) => { | |
| const cond = guard.cond; | |
| const val = context[cond.onboardingDataPropName]; | |
| if (Array.isArray(val)) { | |
| return val.length === 0; | |
| } | |
| return !context[cond.onboardingDataPropName]; | |
| } | |
| } | |
| } | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment