Skip to content

Instantly share code, notes, and snippets.

@jeasmith
Last active May 16, 2021 17:11
Show Gist options
  • Save jeasmith/aec7d926a8e9087e439cfb93a8f9a183 to your computer and use it in GitHub Desktop.
Save jeasmith/aec7d926a8e9087e439cfb93a8f9a183 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// https://xstate.js.org/viz/?gist=66802ba675c8a5e1431d2544af455f1f
const funnelJourneyMachine = Machine(
{
id: "funnelJourney",
type: 'parallel',
states: {
journey: {
id: "journey",
initial: "flights",
context: {},
states: {
flights: {
on: {
CONTINUE: {
target: "seats",
cond: (context) => context.flightId,
},
},
initial: "pageLoad",
states: {
pageLoad: {
always: [{
target: "selectFlight",
cond: !"hasFlight"
}, {
target: "selectFlight",
cond: "hasFlight"
}],
},
selectFlight: {
on: {
ADD_STANDARD_FLIGHT: {
target: "flightSelected",
actions: ["initializeBasketWithStandardFare", "printBasket"],
},
ADD_STANDARD_PLUS_FLIGHT: {
target: "flightSelected",
actions: ["initializeBasketWithStandardPlusFare", "printBasket"],
},
ADD_FLEXI_FLIGHT: {
target: "flightSelected",
actions: ["initializeBasketWithFlexiFare", "printBasket"],
},
},
},
flightSelected:
{
on: {
REMOVE_FLIGHT: {
target: "selectFlight"
},
},
},
},
},
seats: {
always: {
target: "flights",
cond: !"hasFlight"
},
on: {
CONTINUE: {
target: "cabinBags",
cond: (context) => context.seat !== "none",
},
SKIP: {
target: "cabinBags",
cond: (context) => context.seat === "none",
},
EDIT_FLIGHTS: "flights",
},
initial: "pageLoad",
states: {
pageLoad: {
after: {
100: { target: "selectSeats" },
},
},
selectSeats: {
on: {
ADD_STANDARD_SEAT: {
target: "selectSeats",
cond: (context) => context.seat !== "standard",
actions: [
assign({
seat: "standard",
}),
"printBasket",
],
},
ADD_PREMIUM_SEAT: {
target: "selectSeats",
cond: (context) => context.seat !== "premium",
actions: [
assign({
seat: "premium",
cabinBag: false,
}),
"printBasket",
],
},
REMOVE_SEAT: {
target: "selectSeats",
cond: (context) => context.seat !== "none",
actions: [
assign({
seat: "none",
}),
"printBasket",
],
},
},
},
},
},
cabinBags: {
on: {
CONTINUE: {
target: "checkout",
cond: (context) => context.cabinBag,
},
SKIP: {
target: "checkout",
cond: (context) => !context.cabinBag,
},
EDIT_FLIGHTS: "flights",
EDIT_SEATS: "seats",
},
initial: "pageLoad",
states: {
pageLoad: {
after: {
100: { target: "getCabinBagsResponse" },
},
},
getCabinBagsResponse: {
on: {
AVAILABLE: "selectCabinBags",
SOLD_OUT: "unavalable",
LOW_INVENTORY: "selectCabinBags",
ERROR: "unavalable",
},
},
unavalable: {},
selectCabinBags: {
on: {
ADD_CABIN_BAG_SEAT: {
target: "selectCabinBags",
cond: (context) =>
context.seat !== "premium" && !context.cabinBag,
actions: [
assign({
cabinBag: true,
}),
"printBasket",
],
},
REMOVE_CABIN_BAG_SEAT: {
target: "selectCabinBags",
cond: (context) => context.cabinBag,
actions: [
assign({
cabinBag: false,
}),
"printBasket",
],
},
},
},
},
},
checkout: {
on: {
CONTINUE: "payment",
EDIT_FLIGHTS: "flights",
EDIT_SEATS: "seats",
EDIT_CABIN_BAGS: "cabinBags",
},
initial: "pageLoad",
states: {
pageLoad: {
after: {
100: { target: "completeCheckout" },
},
},
completeCheckout: {
on: {
ADD_EJ_PLUS: {
target: "completeCheckout",
cond: !"hasEjPlus",
actions: [
assign({
ejPlus: true,
}),
"printBasket",
],
},
REMOVE_EJ_PLUS: {
target: "completeCheckout",
cond: (context) => context.ejPlus,
actions: [
assign({
ejPlus: false,
}),
"printBasket",
],
},
},
},
},
},
payment: {
type: "final",
},
},
},
basket: {}
},
id: "journey",
initial: "flights",
context: {},
states: {
flights: {
on: {
CONTINUE: {
target: "seats",
cond: (context) => context.flightId,
},
},
initial: "pageLoad",
states: {
pageLoad: {
always: [{
target: "selectFlight",
cond: !"hasFlight"
}, {
target: "selectFlight",
cond: "hasFlight"
}],
},
selectFlight: {
on: {
ADD_STANDARD_FLIGHT: {
target: "flightSelected",
actions: ["initializeBasketWithStandardFare", "printBasket"],
},
ADD_STANDARD_PLUS_FLIGHT: {
target: "flightSelected",
actions: ["initializeBasketWithStandardPlusFare", "printBasket"],
},
ADD_FLEXI_FLIGHT: {
target: "flightSelected",
actions: ["initializeBasketWithFlexiFare", "printBasket"],
},
},
},
flightSelected:
{
on: {
REMOVE_FLIGHT: {
target: "selectFlight"
},
},
},
},
},
seats: {
always: {
target: "flights",
cond: !"hasFlight"
},
on: {
CONTINUE: {
target: "cabinBags",
cond: (context) => context.seat !== "none",
},
SKIP: {
target: "cabinBags",
cond: (context) => context.seat === "none",
},
EDIT_FLIGHTS: "flights",
},
initial: "pageLoad",
states: {
pageLoad: {
after: {
100: { target: "selectSeats" },
},
},
selectSeats: {
on: {
ADD_STANDARD_SEAT: {
target: "selectSeats",
cond: (context) => context.seat !== "standard",
actions: [
assign({
seat: "standard",
}),
"printBasket",
],
},
ADD_PREMIUM_SEAT: {
target: "selectSeats",
cond: (context) => context.seat !== "premium",
actions: [
assign({
seat: "premium",
cabinBag: false,
}),
"printBasket",
],
},
REMOVE_SEAT: {
target: "selectSeats",
cond: (context) => context.seat !== "none",
actions: [
assign({
seat: "none",
}),
"printBasket",
],
},
},
},
},
},
cabinBags: {
on: {
CONTINUE: {
target: "checkout",
cond: (context) => context.cabinBag,
},
SKIP: {
target: "checkout",
cond: (context) => !context.cabinBag,
},
EDIT_FLIGHTS: "flights",
EDIT_SEATS: "seats",
},
initial: "pageLoad",
states: {
pageLoad: {
after: {
100: { target: "getCabinBagsResponse" },
},
},
getCabinBagsResponse: {
on: {
AVAILABLE: "selectCabinBags",
SOLD_OUT: "unavalable",
LOW_INVENTORY: "selectCabinBags",
ERROR: "unavalable",
},
},
unavalable: {},
selectCabinBags: {
on: {
ADD_CABIN_BAG_SEAT: {
target: "selectCabinBags",
cond: (context) =>
context.seat !== "premium" && !context.cabinBag,
actions: [
assign({
cabinBag: true,
}),
"printBasket",
],
},
REMOVE_CABIN_BAG_SEAT: {
target: "selectCabinBags",
cond: (context) => context.cabinBag,
actions: [
assign({
cabinBag: false,
}),
"printBasket",
],
},
},
},
},
},
checkout: {
on: {
CONTINUE: "payment",
EDIT_FLIGHTS: "flights",
EDIT_SEATS: "seats",
EDIT_CABIN_BAGS: "cabinBags",
},
initial: "pageLoad",
states: {
pageLoad: {
after: {
100: { target: "completeCheckout" },
},
},
completeCheckout: {
on: {
ADD_EJ_PLUS: {
target: "completeCheckout",
cond: !"hasEjPlus",
actions: [
assign({
ejPlus: true,
}),
"printBasket",
],
},
REMOVE_EJ_PLUS: {
target: "completeCheckout",
cond: (context) => context.ejPlus,
actions: [
assign({
ejPlus: false,
}),
"printBasket",
],
},
},
},
},
},
payment: {
type: "final",
},
},
},
{
actions: {
printBasket: (context, event) => {
const cabinBagBenefit = context.seat === "premium"
? "free"
: context.cabinBag
? "purchased"
: context.ejPlus || context.fare === "flexi"
? "conditional"
: null;
console.log("====== BASKET ======");
console.log(`Flight ${context.flightId} (${context.fare})`);
if (context.seat != "none") console.log(`Seats: ${context.seat}`);
if (cabinBagBenefit) console.log(`Cabin Bags: ${cabinBagBenefit}`);
console.log("====================");
console.log("");
},
initializeBasketWithStandardFare: assign({
flightId: 1234,
fare: "standard",
seat: "none",
cabinBag: false,
ejPlus: false,
}),
initializeBasketWithStandardPlusFare: assign({
flightId: 1234,
fare: "standardplus",
seat: "none",
cabinBag: false,
ejPlus: false,
}),
initializeBasketWithFlexiFare: assign({
flightId: 1234,
fare: "flexi",
seat: "none",
cabinBag: false,
ejPlus: false,
}),
removeFlight: assign({
flightId: null,
fare: null,
seat: null,
cabinBag: false,
ejPlus: false,
}),
},
guards: {
hasFlight: (context) => context.flightId,
hasEjPlus: (context) => context.ejPlus
}
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment