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