Skip to content

Instantly share code, notes, and snippets.

@BBB
Last active October 14, 2019 15:33
Show Gist options
  • Save BBB/e3fb9395c311c5d7b9bd488ef147cad4 to your computer and use it in GitHub Desktop.
Save BBB/e3fb9395c311c5d7b9bd488ef147cad4 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
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