Created
February 6, 2020 04:49
-
-
Save flybayer/7d335c34294f9cda5b4784409daeaa4f 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 checkoutAppMachine = Machine( | |
{ | |
id: "checkoutApp", | |
initial: "studentEntry", | |
strict: true, | |
context: { | |
currentStepNumber: 0, | |
account: { | |
authenticated: false, | |
}, | |
customer: { | |
first_name: "", | |
last_name: "", | |
timezone: "", | |
email: "", | |
phone: "", | |
address1: "", | |
city: "", | |
state: "", | |
zip_code: "", | |
agree_to_terms: false, | |
}, | |
students: [], | |
bookings: { | |
reading: undefined, | |
math: undefined, | |
language: undefined, | |
science: undefined, | |
screening: undefined, | |
}, | |
existingOrders: [], | |
someoneTakingLanguage: false, | |
someoneTakingScience: false, | |
editingExistingOrder: undefined, | |
isScreeningMode: false, | |
addons: { | |
resultsConsultation: false, | |
}, | |
}, | |
states: { | |
studentEntry: { | |
type: "atomic", | |
entry: assign({ currentStepNumber: 0 }), | |
on: { | |
CHANGE_STUDENTS: { | |
actions: assign((context, event) => { | |
const students = event.value | |
const someoneTakingLanguage = | |
students.some(student => student.tests.language) && !context.isScreeningMode | |
const someoneTakingScience = | |
students.some(student => student.tests.science) && !context.isScreeningMode | |
const newBookings = {} | |
// This ensures bookings are cleared if someone | |
// selected one of these tests and later remove it | |
// But only if not joining a group which already has bookings | |
if (!context.joinGroup) { | |
if (!someoneTakingLanguage) newBookings.language = undefined | |
if (!someoneTakingScience) newBookings.science = undefined | |
} | |
return { | |
students, | |
someoneTakingLanguage, | |
someoneTakingScience, | |
bookings: { | |
...context.bookings, | |
...newBookings, | |
}, | |
} | |
}), | |
}, | |
CHANGE_ACCOUNT: { | |
actions: assign((context, event) => { | |
return { | |
account: { | |
...context.account, | |
...event.value, | |
}, | |
} | |
}), | |
}, | |
CHANGE_CUSTOMER: { | |
actions: assign((context, event) => { | |
return { | |
customer: { | |
...context.customer, | |
...event.value, | |
}, | |
} | |
}), | |
}, | |
CHANGE_ORDERS: { | |
actions: assign((context, event) => { | |
return { | |
existingOrders: event.value, | |
} | |
}), | |
}, | |
CHANGE_BOOKINGS: { | |
actions: assign((context, event) => { | |
return { | |
bookings: { ...context.bookings, ...event.bookings }, | |
} | |
}), | |
}, | |
EDIT_EXISTING_ORDER: { | |
actions: assign((context, event) => { | |
return { | |
editingExistingOrder: event.value, | |
isScreeningMode: !!event.value.bookings.screening, | |
addons: event.value.addons, | |
} | |
}), | |
}, | |
CHANGE_BOOK_GROUP: { | |
target: "scheduling", | |
actions: assign((context, event) => { | |
return { bookGroup: event.value, students: [] } | |
}), | |
}, | |
CHANGE_JOIN_GROUP: { | |
actions: assign((context, event) => { | |
return { joinGroup: event.value } | |
}), | |
}, | |
CHANGE_SCREENING_MODE: { | |
actions: assign((context, event) => { | |
return { isScreeningMode: event.value } | |
}), | |
}, | |
CHANGE_CONSULTATION_ADDON: { | |
actions: assign((context, event) => { | |
return { addons: { ...context.addons, resultsConsultation: event.value } } | |
}), | |
}, | |
NEXT: "scheduling", | |
}, | |
}, | |
scheduling: { | |
type: "compound", | |
entry: assign({ currentStepNumber: 1 }), | |
on: { | |
CHANGE_BOOKINGS: { | |
actions: assign({ | |
bookings: (context, event) => ({ ...context.bookings, ...event.bookings }), | |
}), | |
}, | |
CHANGE_NEED_LANGUAGE: { | |
target: ".default", | |
actions: assign((context, event) => { | |
return { | |
someoneTakingLanguage: event.value, | |
bookings: { ...context.bookings, language: undefined }, | |
} | |
}), | |
}, | |
CHANGE_NEED_SCIENCE: { | |
target: ".default", | |
actions: assign((context, event) => { | |
return { | |
someoneTakingScience: event.value, | |
bookings: { ...context.bookings, science: undefined }, | |
} | |
}), | |
}, | |
NEXT: "checkout", | |
"SCHEDULE.READING": "scheduling.reading", | |
"SCHEDULE.MATH": "scheduling.math", | |
"SCHEDULE.LANGUAGE": "scheduling.language", | |
"SCHEDULE.SCIENCE": "scheduling.science", | |
"NAVIGATE.STUDENT_ENTRY": { target: "studentEntry", cond: "notBookingGroup" }, | |
}, | |
initial: "default", | |
states: { | |
default: { | |
on: { | |
"": [ | |
{ target: "review", cond: "bookingComplete" }, | |
{ | |
target: "screening", | |
cond: { | |
type: "needTestAndNeedScheduled", | |
testName: "screening", | |
}, | |
}, | |
{ | |
target: "reading", | |
cond: { | |
type: "needTestAndNeedScheduled", | |
testName: "reading", | |
}, | |
}, | |
{ | |
target: "math", | |
cond: { | |
type: "needTestAndNeedScheduled", | |
testName: "math", | |
}, | |
}, | |
{ | |
target: "language", | |
cond: { | |
type: "needTestAndNeedScheduled", | |
testName: "language", | |
}, | |
}, | |
{ | |
target: "science", | |
cond: { | |
type: "needTestAndNeedScheduled", | |
testName: "science", | |
}, | |
}, | |
], | |
}, | |
}, | |
screening: { | |
entry: assign({ | |
bookings: (context, event) => | |
context.editingExistingOrder | |
? context.bookings | |
: ({ | |
...context.bookings, | |
screening: undefined, | |
}), | |
}), | |
on: { | |
NEXT: "review", | |
}, | |
}, | |
reading: { | |
entry: assign({ | |
bookings: (context, event) => | |
context.editingExistingOrder | |
? context.bookings | |
: ({ | |
...context.bookings, | |
math: undefined, | |
language: undefined, | |
science: undefined, | |
screening: undefined, | |
}), | |
}), | |
on: { | |
NEXT: [{ target: "review", cond: "bookingComplete" }, { target: "math" }], | |
}, | |
}, | |
math: { | |
entry: assign({ | |
bookings: (context, event) => | |
context.editingExistingOrder | |
? context.bookings | |
: ({ | |
...context.bookings, | |
language: undefined, | |
science: undefined, | |
}), | |
}), | |
on: { | |
NEXT: [ | |
{ target: "review", cond: "bookingComplete" }, | |
{ | |
target: "language", | |
cond: { | |
type: "needTest", | |
testName: "language", | |
}, | |
}, | |
{ | |
target: "science", | |
cond: { | |
type: "needTest", | |
testName: "science", | |
}, | |
}, | |
], | |
}, | |
}, | |
language: { | |
entry: assign({ | |
bookings: (context, event) => | |
context.editingExistingOrder | |
? context.bookings | |
: ({ | |
...context.bookings, | |
science: undefined, | |
}), | |
}), | |
on: { | |
NEXT: [ | |
{ target: "review", cond: "bookingComplete" }, | |
{ | |
target: "science", | |
cond: { | |
type: "needTest", | |
testName: "science", | |
}, | |
}, | |
], | |
}, | |
}, | |
science: { | |
on: { | |
NEXT: "review", | |
}, | |
}, | |
review: {}, | |
}, | |
}, | |
checkout: { | |
type: "atomic", | |
entry: assign({ currentStepNumber: 2 }), | |
on: { | |
CHANGE_CONSULTATION_ADDON: { | |
actions: assign((context, event) => { | |
return { addons: { ...context.addons, resultsConsultation: event.value } } | |
}), | |
}, | |
"NAVIGATE.STUDENT_ENTRY": { target: "studentEntry", cond: "notBookingGroup" }, | |
"NAVIGATE.SCHEDULING": "scheduling.review", | |
SUCCESS: "checkoutSuccess", | |
}, | |
}, | |
checkoutSuccess: { | |
type: "final", | |
}, | |
}, | |
}, | |
{ | |
actions: {}, | |
guards: { | |
needTest: (context, event, { cond }) => { | |
switch (cond.testName) { | |
case "screening": | |
if (context.isScreeningMode) { | |
return true | |
} | |
return false | |
case "language": | |
return context.someoneTakingLanguage | |
case "science": | |
return context.someoneTakingScience | |
default: | |
return true | |
} | |
}, | |
needTestAndNeedScheduled: (context, event, { cond }) => { | |
let needTest | |
switch (cond.testName) { | |
case "screening": | |
if (context.isScreeningMode) { | |
needTest = true | |
} | |
break | |
case "language": | |
needTest = context.someoneTakingLanguage | |
break | |
case "science": | |
needTest = context.someoneTakingScience | |
break | |
default: | |
needTest = true | |
} | |
return needTest && !context.bookings[cond.testName] | |
}, | |
bookingComplete: (context, event) => { | |
if (context.isScreeningMode && context.bookings.screening) return true | |
if (!context.bookings.reading) return false | |
if (!context.bookings.math) return false | |
if (context.someoneTakingLanguage && !context.bookings.language) return false | |
if (context.someoneTakingScience && !context.bookings.science) return false | |
return true | |
}, | |
isBookingGroup: (context, event) => { | |
return !!context.bookGroup | |
}, | |
notBookingGroup: (context, event) => { | |
return !context.bookGroup | |
}, | |
isJoiningGroup: (context, event) => { | |
return !!context.joinGroup | |
}, | |
}, | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment