@constructor-io/constructorio-ui-quizzes 1.2.3 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +3 -1
  2. package/dist/constructorio-ui-quizzes-bundled.js +18 -18
  3. package/lib/cjs/components/CioQuiz/actions.js +11 -1
  4. package/lib/cjs/components/CioQuiz/index.js +15 -103
  5. package/lib/cjs/components/CioQuiz/quizApiReducer.js +32 -0
  6. package/lib/cjs/components/CioQuiz/{reducer.js → quizLocalReducer.js} +2 -2
  7. package/lib/cjs/components/CoverTypeQuestion/CoverTypeQuestion.js +6 -12
  8. package/lib/cjs/components/OpenTextTypeQuestion/OpenTextTypeQuestion.js +12 -18
  9. package/lib/cjs/components/QuizQuestions/index.js +6 -3
  10. package/lib/cjs/components/ResultCard/ResultCard.js +10 -30
  11. package/lib/cjs/components/ResultContainer/ResultContainer.js +8 -31
  12. package/lib/cjs/components/ResultCtaButton/ResultCtaButton.js +7 -26
  13. package/lib/cjs/components/ResultFilters/ResultFilters.js +6 -23
  14. package/lib/cjs/components/Results/Results.js +5 -5
  15. package/lib/cjs/components/SelectTypeQuestion/SelectTypeQuestion.js +16 -23
  16. package/lib/cjs/components/ZeroResults/ZeroResults.js +2 -2
  17. package/lib/cjs/constants.js +5 -3
  18. package/lib/cjs/hooks/useCioClient.js +4 -3
  19. package/lib/cjs/hooks/useConsoleErrors.js +20 -0
  20. package/lib/cjs/hooks/useQuiz.js +48 -0
  21. package/lib/cjs/hooks/useQuizApiState.js +91 -0
  22. package/lib/cjs/hooks/useQuizEvents/index.js +36 -0
  23. package/lib/cjs/hooks/useQuizEvents/useQuizAddToCart.js +20 -0
  24. package/lib/cjs/hooks/useQuizEvents/useQuizBackClick.js +13 -0
  25. package/lib/cjs/hooks/useQuizEvents/useQuizNextClick.js +48 -0
  26. package/lib/cjs/hooks/useQuizEvents/useQuizResultClick.js +19 -0
  27. package/lib/cjs/hooks/useQuizEvents/useQuizResultsLoaded.js +22 -0
  28. package/lib/cjs/hooks/useQuizLocalState.js +20 -0
  29. package/lib/cjs/services/index.js +72 -0
  30. package/lib/cjs/utils.js +42 -21
  31. package/lib/mjs/components/CioQuiz/actions.js +10 -0
  32. package/lib/mjs/components/CioQuiz/index.js +15 -103
  33. package/lib/mjs/components/CioQuiz/quizApiReducer.js +49 -0
  34. package/lib/mjs/components/CioQuiz/{reducer.js → quizLocalReducer.js} +1 -1
  35. package/lib/mjs/components/CoverTypeQuestion/CoverTypeQuestion.js +6 -12
  36. package/lib/mjs/components/OpenTextTypeQuestion/OpenTextTypeQuestion.js +11 -17
  37. package/lib/mjs/components/QuizQuestions/index.js +5 -3
  38. package/lib/mjs/components/ResultCard/ResultCard.js +10 -29
  39. package/lib/mjs/components/ResultContainer/ResultContainer.js +8 -31
  40. package/lib/mjs/components/ResultCtaButton/ResultCtaButton.js +7 -25
  41. package/lib/mjs/components/ResultFilters/ResultFilters.js +5 -23
  42. package/lib/mjs/components/Results/Results.js +3 -3
  43. package/lib/mjs/components/SelectTypeQuestion/SelectTypeQuestion.js +13 -20
  44. package/lib/mjs/components/ZeroResults/ZeroResults.js +2 -2
  45. package/lib/mjs/constants.js +4 -2
  46. package/lib/mjs/hooks/useCioClient.js +4 -3
  47. package/lib/mjs/hooks/useConsoleErrors.js +18 -0
  48. package/lib/mjs/hooks/useQuiz.js +47 -0
  49. package/lib/mjs/hooks/useQuizApiState.js +87 -0
  50. package/lib/mjs/hooks/useQuizEvents/index.js +33 -0
  51. package/lib/mjs/hooks/useQuizEvents/useQuizAddToCart.js +18 -0
  52. package/lib/mjs/hooks/useQuizEvents/useQuizBackClick.js +11 -0
  53. package/lib/mjs/hooks/useQuizEvents/useQuizNextClick.js +45 -0
  54. package/lib/mjs/hooks/useQuizEvents/useQuizResultClick.js +17 -0
  55. package/lib/mjs/hooks/useQuizEvents/useQuizResultsLoaded.js +19 -0
  56. package/lib/mjs/hooks/useQuizLocalState.js +17 -0
  57. package/lib/mjs/services/index.js +60 -0
  58. package/lib/mjs/utils.js +39 -17
  59. package/lib/styles.css +23 -20
  60. package/lib/types/components/CioQuiz/actions.d.ts +20 -0
  61. package/lib/types/components/CioQuiz/context.d.ts +10 -14
  62. package/lib/types/components/CioQuiz/index.d.ts +1 -12
  63. package/lib/types/components/CioQuiz/quizApiReducer.d.ts +14 -0
  64. package/lib/types/components/CioQuiz/{reducer.d.ts → quizLocalReducer.d.ts} +3 -3
  65. package/lib/types/components/QuizQuestions/index.d.ts +1 -4
  66. package/lib/types/components/ResultCard/ResultCard.d.ts +2 -4
  67. package/lib/types/components/ResultContainer/ResultContainer.d.ts +1 -2
  68. package/lib/types/components/ResultCtaButton/ResultCtaButton.d.ts +2 -3
  69. package/lib/types/components/ResultFilters/ResultFilters.d.ts +2 -5
  70. package/lib/types/components/Results/Results.d.ts +1 -7
  71. package/lib/types/components/ZeroResults/ZeroResults.d.ts +1 -1
  72. package/lib/types/constants.d.ts +2 -1
  73. package/lib/types/hooks/useCioClient.d.ts +1 -1
  74. package/lib/types/hooks/useConsoleErrors.d.ts +3 -0
  75. package/lib/types/hooks/useQuiz.d.ts +3 -0
  76. package/lib/types/hooks/useQuizApiState.d.ts +10 -0
  77. package/lib/types/hooks/useQuizEvents/index.d.ts +15 -0
  78. package/lib/types/hooks/useQuizEvents/useQuizAddToCart.d.ts +5 -0
  79. package/lib/types/hooks/useQuizEvents/useQuizBackClick.d.ts +4 -0
  80. package/lib/types/hooks/useQuizEvents/useQuizNextClick.d.ts +5 -0
  81. package/lib/types/hooks/useQuizEvents/useQuizResultClick.d.ts +5 -0
  82. package/lib/types/hooks/useQuizEvents/useQuizResultsLoaded.d.ts +5 -0
  83. package/lib/types/hooks/useQuizLocalState.d.ts +6 -0
  84. package/lib/types/services/index.d.ts +8 -0
  85. package/lib/types/types.d.ts +63 -0
  86. package/lib/types/utils.d.ts +12 -7
  87. package/package.json +12 -12
@@ -9,29 +9,31 @@ const utils_1 = require("../../utils");
9
9
  const actions_1 = require("../CioQuiz/actions");
10
10
  const ControlBar_1 = tslib_1.__importDefault(require("../ControlBar/ControlBar"));
11
11
  function SelectTypeQuestion() {
12
- var _a;
13
- const { questionResponse, state, quizNextHandler, quizBackHandler, isFirstQuestion } = (0, react_1.useContext)(context_1.default);
12
+ var _a, _b;
13
+ const { state, nextQuestion, previousQuestion } = (0, react_1.useContext)(context_1.default);
14
14
  let question;
15
15
  let type;
16
16
  let hasImages = false;
17
- if (questionResponse) {
18
- question = questionResponse.next_question;
17
+ if (state === null || state === void 0 ? void 0 : state.quiz.currentQuestion) {
18
+ question = state.quiz.currentQuestion.next_question;
19
19
  type = question.type;
20
- hasImages = questionResponse.next_question.options.some((option) => option.images);
20
+ hasImages = question.options.some((option) => option.images);
21
21
  }
22
22
  const [selected, setSelected] = (0, react_1.useState)({});
23
23
  const isDisabled = Object.keys(selected).length === 0;
24
24
  (0, react_1.useEffect)(() => {
25
- var _a, _b;
26
- if ((_a = questionResponse === null || questionResponse === void 0 ? void 0 : questionResponse.next_question) === null || _a === void 0 ? void 0 : _a.type) {
27
- const answers = ((_b = state === null || state === void 0 ? void 0 : state.answerInputs) === null || _b === void 0 ? void 0 : _b[questionResponse.next_question.id]) || [];
25
+ var _a, _b, _c, _d;
26
+ if ((_b = (_a = state === null || state === void 0 ? void 0 : state.quiz.currentQuestion) === null || _a === void 0 ? void 0 : _a.next_question) === null || _b === void 0 ? void 0 : _b.type) {
27
+ const nextQuestionId = state.quiz.currentQuestion.next_question.id;
28
+ const answers = ((_d = (_c = state.answers) === null || _c === void 0 ? void 0 : _c.inputs) === null || _d === void 0 ? void 0 : _d[nextQuestionId]) || [];
28
29
  const prevSelected = {};
29
30
  answers === null || answers === void 0 ? void 0 : answers.forEach((answer) => {
30
31
  prevSelected[Number(answer)] = true;
31
32
  });
32
33
  setSelected(prevSelected);
33
34
  }
34
- }, [questionResponse, state === null || state === void 0 ? void 0 : state.answerInputs]);
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ }, [(_a = state === null || state === void 0 ? void 0 : state.quiz.currentQuestion) === null || _a === void 0 ? void 0 : _a.next_question.id]);
35
37
  const toggleIdSelected = (id) => {
36
38
  if (type === actions_1.QuestionTypes.SingleSelect) {
37
39
  setSelected({ [id]: true });
@@ -53,18 +55,9 @@ function SelectTypeQuestion() {
53
55
  }
54
56
  };
55
57
  const onNextClick = () => {
56
- if (quizNextHandler && !isDisabled && questionResponse) {
57
- const questionType = type === actions_1.QuestionTypes.SingleSelect
58
- ? actions_1.QuestionTypes.SingleSelect
59
- : actions_1.QuestionTypes.MultipleSelect;
60
- quizNextHandler({
61
- type: questionType,
62
- payload: {
63
- questionId: questionResponse === null || questionResponse === void 0 ? void 0 : questionResponse.next_question.id,
64
- input: Object.keys(selected).filter((key) => selected[Number(key)]),
65
- isLastQuestion: questionResponse.is_last_question,
66
- },
67
- });
58
+ if (nextQuestion && !isDisabled && (state === null || state === void 0 ? void 0 : state.quiz.currentQuestion)) {
59
+ const selectedAnswers = Object.keys(selected).filter((key) => selected[Number(key)]);
60
+ nextQuestion(selectedAnswers);
68
61
  }
69
62
  };
70
63
  if (question) {
@@ -74,7 +67,7 @@ function SelectTypeQuestion() {
74
67
  (question === null || question === void 0 ? void 0 : question.description) ? react_1.default.createElement(QuestionDescription_1.default, { description: question.description }) : ''),
75
68
  react_1.default.createElement("div", { className: `${!hasImages
76
69
  ? 'cio-question-options-container-text-only'
77
- : 'cio-question-options-container'}` }, (_a = question === null || question === void 0 ? void 0 : question.options) === null || _a === void 0 ? void 0 : _a.map((option) => (react_1.default.createElement("div", { className: `${!hasImages
70
+ : 'cio-question-options-container'}` }, (_b = question === null || question === void 0 ? void 0 : question.options) === null || _b === void 0 ? void 0 : _b.map((option) => (react_1.default.createElement("div", { className: `${!hasImages
78
71
  ? 'cio-question-option-container-text-only'
79
72
  : 'cio-question-option-container'} ${selected[option.id] ? 'selected' : ''}`, onClick: () => {
80
73
  toggleIdSelected(option.id);
@@ -83,7 +76,7 @@ function SelectTypeQuestion() {
83
76
  }, role: 'button', tabIndex: 0, key: option.id },
84
77
  option.images ? (0, utils_1.renderImages)(option.images, 'cio-question-option-image') : '',
85
78
  react_1.default.createElement("div", { className: 'cio-question-option-value' }, option === null || option === void 0 ? void 0 : option.value))))),
86
- react_1.default.createElement(ControlBar_1.default, { nextButtonHandler: onNextClick, isNextButtonDisabled: isDisabled, backButtonHandler: quizBackHandler, showBackButton: !isFirstQuestion, ctaButtonText: question === null || question === void 0 ? void 0 : question.cta_text })));
79
+ react_1.default.createElement(ControlBar_1.default, { nextButtonHandler: onNextClick, isNextButtonDisabled: isDisabled, backButtonHandler: previousQuestion, showBackButton: !(state === null || state === void 0 ? void 0 : state.quiz.isFirstQuestion), ctaButtonText: question === null || question === void 0 ? void 0 : question.cta_text })));
87
80
  }
88
81
  return null;
89
82
  }
@@ -4,10 +4,10 @@ const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importDefault(require("react"));
5
5
  const CTAButton_1 = tslib_1.__importDefault(require("../CTAButton/CTAButton"));
6
6
  function ZeroResults(props) {
7
- const { onResetClick } = props;
7
+ const { resetQuizClickHandler } = props;
8
8
  return (react_1.default.createElement("div", { className: 'cio-zero-results' },
9
9
  react_1.default.createElement("h3", { className: 'cio-zero-results-subtitle' }, "Sorry, it seems like we couldn\u2019t find results based on your answers."),
10
10
  react_1.default.createElement("p", { className: 'cio-zero-results-description' }, "This is embarrassing \uD83D\uDE22. It might be that some of the questions are not properly set up from our end. Would you give us another try?"),
11
- react_1.default.createElement(CTAButton_1.default, { ctaText: 'Try Again', onClick: onResetClick })));
11
+ react_1.default.createElement(CTAButton_1.default, { ctaText: 'Try Again', onClick: resetQuizClickHandler })));
12
12
  }
13
13
  exports.default = ZeroResults;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RequestStates = exports.cioJsClientDescription = exports.basicDescription = exports.componentDescription = exports.quizId = exports.apiKey = void 0;
3
+ exports.RequestStates = exports.smallContainerDescription = exports.cioJsClientDescription = exports.basicDescription = exports.componentDescription = exports.quizId = exports.apiKey = void 0;
4
4
  // Autocomplete key index
5
5
  exports.apiKey = 'key_wJSdZSiesX5hiVLt';
6
6
  exports.quizId = 'coffee-quiz';
@@ -11,8 +11,9 @@ exports.componentDescription = `- import \`CioQuiz\` to render in your JSX.
11
11
  - This component handles state management, data fetching, and rendering logic.
12
12
  - To use this component, \`quizId\`, \`resultsPageOptions\`, and one of \`apiKey\` or \`cioJsClient\` are required.
13
13
  - \`resultsPageOptions\` lets you configure the results page
14
- - \`addToCartCallback\` is a callback function that will be called when the "Add to cart" button is clicked
15
- - \`clickItemCallback\` is an optional callback function that will be called when the result card is clicked. The default behavior is redirecting the user to the item's URL
14
+ - \`onAddToCartClick\` is a callback function that will be called when the "Add to cart" button is clicked
15
+ - \`onQuizResultClick\` is an optional callback function that will be called when the result card is clicked. The default behavior is redirecting the user to the item's URL
16
+ - \`onQuizResultsLoaded\` is an optional callback function that will be called when the quiz results are loaded
16
17
  - \`resultCardRegularPriceKey\` is a parameter that specifies the metadata field name for the regular price
17
18
  - \`resultCardSalePriceKey\` is an optional parameter that specifies the metadata field name for the sale price
18
19
  - Use different props to configure the behavior of this component.
@@ -27,6 +28,7 @@ exports.basicDescription = `Pass an \`apiKey\` and a \`quizId\` to request quest
27
28
  exports.cioJsClientDescription = `If you are already using an instance of the \`ConstructorIOClient\`, you can pass a \`cioJsClient\` instead of an \`apiKey\` to request results from Constructor's servers
28
29
 
29
30
  > Note: \`cioJsClient\` refers to an instance of the [constructorio-client-javascript](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)`;
31
+ exports.smallContainerDescription = `If you are using the provided styles, CioQuiz component will respect the height and width of its parent container and use responsive styles based on the parent container's dimensions`;
30
32
  var RequestStates;
31
33
  (function (RequestStates) {
32
34
  RequestStates[RequestStates["Stale"] = 0] = "Stale";
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const react_1 = require("react");
4
- const utils_1 = require("../utils");
4
+ const services_1 = require("../services");
5
5
  const useCioClient = ({ apiKey, cioJsClient }) => {
6
6
  if (!apiKey && !cioJsClient) {
7
- console.error('Either apiKey or cioJsClient is required');
7
+ throw new Error('Either apiKey or cioJsClient is required');
8
8
  }
9
- return (0, react_1.useMemo)(() => cioJsClient || (0, utils_1.getCioClient)(apiKey), [apiKey, cioJsClient]);
9
+ const memoizedCioClient = (0, react_1.useMemo)(() => cioJsClient || (0, services_1.getCioClient)(apiKey), [apiKey, cioJsClient]);
10
+ return memoizedCioClient;
10
11
  };
11
12
  exports.default = useCioClient;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const useConsoleErrors = (quizId, resultsPageOptions) => {
5
+ (0, react_1.useEffect)(() => {
6
+ if (!quizId) {
7
+ // eslint-disable-next-line no-console
8
+ console.error('quizId is a required field of type string');
9
+ }
10
+ if (!resultsPageOptions || Object.keys(resultsPageOptions).length === 0) {
11
+ // eslint-disable-next-line no-console
12
+ console.error('resultsPageOptions is a required field of type object');
13
+ }
14
+ if (resultsPageOptions && !(resultsPageOptions === null || resultsPageOptions === void 0 ? void 0 : resultsPageOptions.onAddToCartClick)) {
15
+ // eslint-disable-next-line no-console
16
+ console.error('resultsPageOptions.onAddToCartClick is a required field of type function');
17
+ }
18
+ }, [quizId, resultsPageOptions, resultsPageOptions === null || resultsPageOptions === void 0 ? void 0 : resultsPageOptions.onAddToCartClick]);
19
+ };
20
+ exports.default = useConsoleErrors;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const useCioClient_1 = tslib_1.__importDefault(require("./useCioClient"));
5
+ const useConsoleErrors_1 = tslib_1.__importDefault(require("./useConsoleErrors"));
6
+ const useQuizApiState_1 = tslib_1.__importDefault(require("./useQuizApiState"));
7
+ const useQuizEvents_1 = tslib_1.__importDefault(require("./useQuizEvents"));
8
+ const useQuizLocalState_1 = tslib_1.__importDefault(require("./useQuizLocalState"));
9
+ const useQuiz = ({ quizId, apiKey, cioJsClient, quizVersionId, resultsPageOptions }) => {
10
+ // Log console errors for required parameters quizId and resultsPageOptions
11
+ (0, useConsoleErrors_1.default)(quizId, resultsPageOptions);
12
+ // Quiz Local state
13
+ const { quizLocalState, resetQuizLocalState, dispatchLocalState } = (0, useQuizLocalState_1.default)();
14
+ // Quiz Cio Client
15
+ const cioClient = (0, useCioClient_1.default)({ apiKey, cioJsClient });
16
+ // Quiz API state
17
+ const { isFirstQuestion, quizApiState, resetQuizApiState } = (0, useQuizApiState_1.default)(quizId, quizLocalState, resultsPageOptions, quizVersionId, cioClient);
18
+ // Quiz callback events
19
+ const quizEvents = (0, useQuizEvents_1.default)({
20
+ cioClient,
21
+ quizApiState,
22
+ resultsPageOptions,
23
+ dispatchLocalState,
24
+ resetQuizApiState,
25
+ resetQuizLocalState,
26
+ });
27
+ return {
28
+ cioClient,
29
+ state: {
30
+ answers: {
31
+ inputs: quizLocalState.answerInputs,
32
+ isLastAnswer: quizLocalState.isLastAnswer,
33
+ },
34
+ quiz: {
35
+ requestState: quizApiState.quizRequestState,
36
+ versionId: quizApiState.quizVersionId,
37
+ sessionId: quizApiState.quizSessionId,
38
+ firstQuestion: quizApiState.quizFirstQuestion,
39
+ currentQuestion: quizApiState.quizCurrentQuestion,
40
+ results: quizApiState.quizResults,
41
+ resultsFilters: quizApiState.quizResultsFilters,
42
+ isFirstQuestion,
43
+ },
44
+ },
45
+ events: Object.assign({}, quizEvents),
46
+ };
47
+ };
48
+ exports.default = useQuiz;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = require("react");
5
+ const actions_1 = require("../components/CioQuiz/actions");
6
+ const quizApiReducer_1 = tslib_1.__importStar(require("../components/CioQuiz/quizApiReducer"));
7
+ const services_1 = require("../services");
8
+ const useFetchQuiz = (quizId, quizLocalState, resultsPageOptions, quizVersionIdProp, cioClient) => {
9
+ var _a, _b;
10
+ const [quizApiState, dispatch] = (0, react_1.useReducer)(quizApiReducer_1.default, quizApiReducer_1.initialState);
11
+ const firstQuestionId = (_a = quizApiState.quizFirstQuestion) === null || _a === void 0 ? void 0 : _a.next_question.id;
12
+ const currentQuestionId = (_b = quizApiState.quizCurrentQuestion) === null || _b === void 0 ? void 0 : _b.next_question.id;
13
+ const isFirstQuestion = firstQuestionId === currentQuestionId;
14
+ (0, react_1.useEffect)(() => {
15
+ (() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
16
+ dispatch({
17
+ type: actions_1.QuizAPIActionTypes.SET_IS_LOADING,
18
+ });
19
+ if (quizLocalState.isLastAnswer) {
20
+ try {
21
+ const quizResults = yield (0, services_1.getQuizResults)(cioClient, quizId, {
22
+ answers: quizLocalState.answers,
23
+ resultsPerPage: resultsPageOptions === null || resultsPageOptions === void 0 ? void 0 : resultsPageOptions.numResultsToDisplay,
24
+ quizVersionId: quizApiState.quizVersionId,
25
+ quizSessionId: quizApiState.quizSessionId,
26
+ });
27
+ // Set quiz results state
28
+ dispatch({
29
+ type: actions_1.QuizAPIActionTypes.SET_QUIZ_RESULTS,
30
+ payload: {
31
+ quizResults,
32
+ },
33
+ });
34
+ }
35
+ catch (error) {
36
+ dispatch({
37
+ type: actions_1.QuizAPIActionTypes.SET_IS_ERROR,
38
+ });
39
+ }
40
+ }
41
+ else {
42
+ try {
43
+ let quizVersionId = quizApiState.quizVersionId || quizVersionIdProp;
44
+ let { quizSessionId } = quizApiState;
45
+ const questionResult = yield (0, services_1.nextQuestion)(cioClient, quizId, {
46
+ answers: quizLocalState.answers,
47
+ quizVersionId,
48
+ quizSessionId,
49
+ });
50
+ if (!quizVersionId && (questionResult === null || questionResult === void 0 ? void 0 : questionResult.quiz_version_id)) {
51
+ quizVersionId = questionResult.quiz_version_id;
52
+ }
53
+ if (!quizSessionId && (questionResult === null || questionResult === void 0 ? void 0 : questionResult.quiz_session_id)) {
54
+ quizSessionId = questionResult.quiz_session_id;
55
+ }
56
+ // Set current question state
57
+ dispatch({
58
+ type: actions_1.QuizAPIActionTypes.SET_CURRENT_QUESTION,
59
+ payload: {
60
+ quizSessionId,
61
+ quizVersionId,
62
+ quizCurrentQuestion: questionResult,
63
+ },
64
+ });
65
+ }
66
+ catch (error) {
67
+ dispatch({
68
+ type: actions_1.QuizAPIActionTypes.SET_IS_ERROR,
69
+ });
70
+ }
71
+ }
72
+ }))();
73
+ // eslint-disable-next-line react-hooks/exhaustive-deps
74
+ }, [
75
+ cioClient,
76
+ quizId,
77
+ quizLocalState,
78
+ quizLocalState.isLastAnswer,
79
+ resultsPageOptions === null || resultsPageOptions === void 0 ? void 0 : resultsPageOptions.numResultsToDisplay,
80
+ ]);
81
+ const resetQuizApiState = () => {
82
+ dispatch({ type: actions_1.QuizAPIActionTypes.RESET_QUIZ });
83
+ };
84
+ return {
85
+ cioClient,
86
+ quizApiState,
87
+ isFirstQuestion,
88
+ resetQuizApiState,
89
+ };
90
+ };
91
+ exports.default = useFetchQuiz;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const useQuizResultsLoaded_1 = tslib_1.__importDefault(require("./useQuizResultsLoaded"));
5
+ const useQuizResultClick_1 = tslib_1.__importDefault(require("./useQuizResultClick"));
6
+ const useQuizAddToCart_1 = tslib_1.__importDefault(require("./useQuizAddToCart"));
7
+ const useQuizNextClick_1 = tslib_1.__importDefault(require("./useQuizNextClick"));
8
+ const useQuizBackClick_1 = tslib_1.__importDefault(require("./useQuizBackClick"));
9
+ const useQuizEvents = (options) => {
10
+ const { cioClient, quizApiState, resultsPageOptions, dispatchLocalState, resetQuizApiState, resetQuizLocalState, } = options;
11
+ const { onAddToCartClick, onQuizResultClick, onQuizResultsLoaded } = resultsPageOptions;
12
+ // Quiz Next button click
13
+ const nextQuestion = (0, useQuizNextClick_1.default)(quizApiState, dispatchLocalState);
14
+ // Quiz Back button click callback
15
+ const previousQuestion = (0, useQuizBackClick_1.default)(dispatchLocalState);
16
+ // Quiz result add to cart callback
17
+ const addToCart = (0, useQuizAddToCart_1.default)(cioClient, quizApiState, onAddToCartClick);
18
+ // Quiz result click callback
19
+ const resultClick = (0, useQuizResultClick_1.default)(cioClient, quizApiState, onQuizResultClick);
20
+ // Quiz results loaded event
21
+ (0, useQuizResultsLoaded_1.default)(cioClient, quizApiState, onQuizResultsLoaded);
22
+ const resetQuiz = () => {
23
+ if (quizApiState.quizResults) {
24
+ resetQuizApiState();
25
+ resetQuizLocalState();
26
+ }
27
+ };
28
+ return {
29
+ addToCart,
30
+ resultClick,
31
+ nextQuestion,
32
+ previousQuestion,
33
+ resetQuiz,
34
+ };
35
+ };
36
+ exports.default = useQuizEvents;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const services_1 = require("../../services");
5
+ const utils_1 = require("../../utils");
6
+ const useQuizAddToCart = (cioClient, quizApiState, onAddToCartClick) => {
7
+ const addToCartClickHandler = (0, react_1.useCallback)((e, result, price) => {
8
+ e.preventDefault();
9
+ if (quizApiState.quizResults) {
10
+ // Tracking call
11
+ (0, services_1.trackQuizConversion)(cioClient, quizApiState.quizResults, result, price);
12
+ // User custom callback function
13
+ if ((0, utils_1.isFunction)(onAddToCartClick)) {
14
+ onAddToCartClick(result);
15
+ }
16
+ }
17
+ }, [quizApiState, cioClient, onAddToCartClick]);
18
+ return addToCartClickHandler;
19
+ };
20
+ exports.default = useQuizAddToCart;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const actions_1 = require("../../components/CioQuiz/actions");
5
+ const useQuizBackClick = (dispatchLocalState) => {
6
+ const quizBackHandler = (0, react_1.useCallback)(() => {
7
+ if (dispatchLocalState) {
8
+ dispatchLocalState({ type: actions_1.QuestionTypes.Back });
9
+ }
10
+ }, [dispatchLocalState]);
11
+ return quizBackHandler;
12
+ };
13
+ exports.default = useQuizBackClick;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const actions_1 = require("../../components/CioQuiz/actions");
5
+ const useQuizNextClick = (quizApiState, dispatchLocalState) => {
6
+ const quizNextHandler = (0, react_1.useCallback)((payload) => {
7
+ var _a;
8
+ const questionType = (_a = quizApiState.quizCurrentQuestion) === null || _a === void 0 ? void 0 : _a.next_question.type;
9
+ const currentQuestion = quizApiState.quizCurrentQuestion;
10
+ switch (questionType) {
11
+ case actions_1.QuestionTypes.Cover:
12
+ dispatchLocalState({
13
+ type: actions_1.QuestionTypes.Cover,
14
+ payload: {
15
+ isLastQuestion: currentQuestion.is_last_question,
16
+ },
17
+ });
18
+ break;
19
+ case actions_1.QuestionTypes.OpenText:
20
+ dispatchLocalState({
21
+ type: actions_1.QuestionTypes.OpenText,
22
+ payload: {
23
+ questionId: currentQuestion.next_question.id,
24
+ input: payload,
25
+ isLastQuestion: currentQuestion.is_last_question,
26
+ },
27
+ });
28
+ break;
29
+ case actions_1.QuestionTypes.SingleSelect:
30
+ case actions_1.QuestionTypes.MultipleSelect:
31
+ dispatchLocalState({
32
+ type: currentQuestion.next_question.type === actions_1.QuestionTypes.SingleSelect
33
+ ? actions_1.QuestionTypes.SingleSelect
34
+ : actions_1.QuestionTypes.MultipleSelect,
35
+ payload: {
36
+ questionId: currentQuestion.next_question.id,
37
+ input: payload,
38
+ isLastQuestion: currentQuestion.is_last_question,
39
+ },
40
+ });
41
+ break;
42
+ default:
43
+ break;
44
+ }
45
+ }, [quizApiState, dispatchLocalState]);
46
+ return quizNextHandler;
47
+ };
48
+ exports.default = useQuizNextClick;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const services_1 = require("../../services");
5
+ const utils_1 = require("../../utils");
6
+ const useQuizResultClick = (cioClient, quizApiState, onQuizResultClick) => {
7
+ const resultClickHandler = (0, react_1.useCallback)((result, position) => {
8
+ if (quizApiState.quizResults) {
9
+ // Tracking call
10
+ (0, services_1.trackQuizResultClick)(cioClient, quizApiState.quizResults, result, position);
11
+ // User custom callback function
12
+ if ((0, utils_1.isFunction)(onQuizResultClick)) {
13
+ onQuizResultClick(result, position);
14
+ }
15
+ }
16
+ }, [quizApiState, cioClient, onQuizResultClick]);
17
+ return resultClickHandler;
18
+ };
19
+ exports.default = useQuizResultClick;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const services_1 = require("../../services");
5
+ const utils_1 = require("../../utils");
6
+ const useQuizResultsLoaded = (cioClient, quizApiState, onQuizResultsLoaded) => {
7
+ // Quiz results loaded
8
+ (0, react_1.useEffect)(() => {
9
+ var _a;
10
+ if (quizApiState.quizResults) {
11
+ // Tracking call
12
+ (0, services_1.trackQuizResultsLoaded)(cioClient, quizApiState.quizResults);
13
+ // User custom callback function
14
+ if (onQuizResultsLoaded &&
15
+ (0, utils_1.isFunction)(onQuizResultsLoaded) &&
16
+ ((_a = quizApiState.quizResults.response) === null || _a === void 0 ? void 0 : _a.results)) {
17
+ onQuizResultsLoaded(quizApiState.quizResults.response.results);
18
+ }
19
+ }
20
+ }, [quizApiState, cioClient, onQuizResultsLoaded]);
21
+ };
22
+ exports.default = useQuizResultsLoaded;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = require("react");
5
+ const actions_1 = require("../components/CioQuiz/actions");
6
+ const quizLocalReducer_1 = tslib_1.__importStar(require("../components/CioQuiz/quizLocalReducer"));
7
+ const useQuizLocalState = () => {
8
+ const [quizLocalState, dispatch] = (0, react_1.useReducer)(quizLocalReducer_1.default, quizLocalReducer_1.initialState);
9
+ const resetQuizLocalState = () => {
10
+ dispatch({
11
+ type: actions_1.QuestionTypes.Reset,
12
+ });
13
+ };
14
+ return {
15
+ quizLocalState,
16
+ resetQuizLocalState,
17
+ dispatchLocalState: dispatch,
18
+ };
19
+ };
20
+ exports.default = useQuizLocalState;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.trackQuizConversion = exports.trackQuizResultClick = exports.trackQuizResultsLoaded = exports.getQuizResults = exports.nextQuestion = exports.getCioClient = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /* eslint-disable @typescript-eslint/naming-convention */
6
+ const constructorio_client_javascript_1 = tslib_1.__importDefault(require("@constructor-io/constructorio-client-javascript"));
7
+ const getCioClient = (apiKey) => {
8
+ if (apiKey) {
9
+ return new constructorio_client_javascript_1.default({
10
+ apiKey,
11
+ sendTrackingEvents: true,
12
+ });
13
+ }
14
+ return undefined;
15
+ };
16
+ exports.getCioClient = getCioClient;
17
+ const nextQuestion = (cioClient, quizId, parameters) => cioClient === null || cioClient === void 0 ? void 0 : cioClient.quizzes.getQuizNextQuestion(quizId, parameters);
18
+ exports.nextQuestion = nextQuestion;
19
+ const getQuizResults = (cioClient, quizId, parameters) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return cioClient === null || cioClient === void 0 ? void 0 : cioClient.quizzes.getQuizResults(quizId, parameters); });
20
+ exports.getQuizResults = getQuizResults;
21
+ // Tracking requests
22
+ const trackQuizResultsLoaded = (cioClient, quizResults) => {
23
+ const { quiz_id, quiz_session_id, quiz_version_id, result_id, request, response } = quizResults;
24
+ cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker.trackQuizResultsLoaded({
25
+ quiz_id,
26
+ quiz_version_id,
27
+ quiz_session_id,
28
+ url: window.location.href,
29
+ section: request === null || request === void 0 ? void 0 : request.section,
30
+ result_count: response === null || response === void 0 ? void 0 : response.total_num_results,
31
+ result_page: request === null || request === void 0 ? void 0 : request.page,
32
+ result_id,
33
+ });
34
+ };
35
+ exports.trackQuizResultsLoaded = trackQuizResultsLoaded;
36
+ const trackQuizResultClick = (cioClient, quizResults, result, position) => {
37
+ var _a;
38
+ if (quizResults.request && quizResults.response) {
39
+ const { quiz_id, quiz_session_id, quiz_version_id, result_id, request: { section, page, num_results_per_page }, response: { total_num_results }, } = quizResults;
40
+ cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker.trackQuizResultClick({
41
+ quiz_id,
42
+ quiz_version_id,
43
+ quiz_session_id,
44
+ item_id: (_a = result.data) === null || _a === void 0 ? void 0 : _a.id,
45
+ item_name: result === null || result === void 0 ? void 0 : result.value,
46
+ section,
47
+ result_count: total_num_results,
48
+ result_page: page,
49
+ result_id,
50
+ result_position_on_page: position,
51
+ num_results_per_page,
52
+ });
53
+ }
54
+ };
55
+ exports.trackQuizResultClick = trackQuizResultClick;
56
+ const trackQuizConversion = (cioClient, quizResults, result, price) => {
57
+ var _a, _b;
58
+ if (quizResults.request) {
59
+ const { quiz_id, quiz_session_id, quiz_version_id, request: { section }, } = quizResults;
60
+ cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker.trackQuizConversion({
61
+ quiz_id,
62
+ quiz_version_id,
63
+ quiz_session_id,
64
+ item_id: (_a = result.data) === null || _a === void 0 ? void 0 : _a.id,
65
+ item_name: result.value,
66
+ section,
67
+ variation_id: (_b = result.data) === null || _b === void 0 ? void 0 : _b.variation_id,
68
+ revenue: (price && String(price)) || undefined,
69
+ });
70
+ }
71
+ };
72
+ exports.trackQuizConversion = trackQuizConversion;