@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.
- package/README.md +3 -1
- package/dist/constructorio-ui-quizzes-bundled.js +18 -18
- package/lib/cjs/components/CioQuiz/actions.js +11 -1
- package/lib/cjs/components/CioQuiz/index.js +15 -103
- package/lib/cjs/components/CioQuiz/quizApiReducer.js +32 -0
- package/lib/cjs/components/CioQuiz/{reducer.js → quizLocalReducer.js} +2 -2
- package/lib/cjs/components/CoverTypeQuestion/CoverTypeQuestion.js +6 -12
- package/lib/cjs/components/OpenTextTypeQuestion/OpenTextTypeQuestion.js +12 -18
- package/lib/cjs/components/QuizQuestions/index.js +6 -3
- package/lib/cjs/components/ResultCard/ResultCard.js +10 -30
- package/lib/cjs/components/ResultContainer/ResultContainer.js +8 -31
- package/lib/cjs/components/ResultCtaButton/ResultCtaButton.js +7 -26
- package/lib/cjs/components/ResultFilters/ResultFilters.js +6 -23
- package/lib/cjs/components/Results/Results.js +5 -5
- package/lib/cjs/components/SelectTypeQuestion/SelectTypeQuestion.js +16 -23
- package/lib/cjs/components/ZeroResults/ZeroResults.js +2 -2
- package/lib/cjs/constants.js +5 -3
- package/lib/cjs/hooks/useCioClient.js +4 -3
- package/lib/cjs/hooks/useConsoleErrors.js +20 -0
- package/lib/cjs/hooks/useQuiz.js +48 -0
- package/lib/cjs/hooks/useQuizApiState.js +91 -0
- package/lib/cjs/hooks/useQuizEvents/index.js +36 -0
- package/lib/cjs/hooks/useQuizEvents/useQuizAddToCart.js +20 -0
- package/lib/cjs/hooks/useQuizEvents/useQuizBackClick.js +13 -0
- package/lib/cjs/hooks/useQuizEvents/useQuizNextClick.js +48 -0
- package/lib/cjs/hooks/useQuizEvents/useQuizResultClick.js +19 -0
- package/lib/cjs/hooks/useQuizEvents/useQuizResultsLoaded.js +22 -0
- package/lib/cjs/hooks/useQuizLocalState.js +20 -0
- package/lib/cjs/services/index.js +72 -0
- package/lib/cjs/utils.js +42 -21
- package/lib/mjs/components/CioQuiz/actions.js +10 -0
- package/lib/mjs/components/CioQuiz/index.js +15 -103
- package/lib/mjs/components/CioQuiz/quizApiReducer.js +49 -0
- package/lib/mjs/components/CioQuiz/{reducer.js → quizLocalReducer.js} +1 -1
- package/lib/mjs/components/CoverTypeQuestion/CoverTypeQuestion.js +6 -12
- package/lib/mjs/components/OpenTextTypeQuestion/OpenTextTypeQuestion.js +11 -17
- package/lib/mjs/components/QuizQuestions/index.js +5 -3
- package/lib/mjs/components/ResultCard/ResultCard.js +10 -29
- package/lib/mjs/components/ResultContainer/ResultContainer.js +8 -31
- package/lib/mjs/components/ResultCtaButton/ResultCtaButton.js +7 -25
- package/lib/mjs/components/ResultFilters/ResultFilters.js +5 -23
- package/lib/mjs/components/Results/Results.js +3 -3
- package/lib/mjs/components/SelectTypeQuestion/SelectTypeQuestion.js +13 -20
- package/lib/mjs/components/ZeroResults/ZeroResults.js +2 -2
- package/lib/mjs/constants.js +4 -2
- package/lib/mjs/hooks/useCioClient.js +4 -3
- package/lib/mjs/hooks/useConsoleErrors.js +18 -0
- package/lib/mjs/hooks/useQuiz.js +47 -0
- package/lib/mjs/hooks/useQuizApiState.js +87 -0
- package/lib/mjs/hooks/useQuizEvents/index.js +33 -0
- package/lib/mjs/hooks/useQuizEvents/useQuizAddToCart.js +18 -0
- package/lib/mjs/hooks/useQuizEvents/useQuizBackClick.js +11 -0
- package/lib/mjs/hooks/useQuizEvents/useQuizNextClick.js +45 -0
- package/lib/mjs/hooks/useQuizEvents/useQuizResultClick.js +17 -0
- package/lib/mjs/hooks/useQuizEvents/useQuizResultsLoaded.js +19 -0
- package/lib/mjs/hooks/useQuizLocalState.js +17 -0
- package/lib/mjs/services/index.js +60 -0
- package/lib/mjs/utils.js +39 -17
- package/lib/styles.css +23 -20
- package/lib/types/components/CioQuiz/actions.d.ts +20 -0
- package/lib/types/components/CioQuiz/context.d.ts +10 -14
- package/lib/types/components/CioQuiz/index.d.ts +1 -12
- package/lib/types/components/CioQuiz/quizApiReducer.d.ts +14 -0
- package/lib/types/components/CioQuiz/{reducer.d.ts → quizLocalReducer.d.ts} +3 -3
- package/lib/types/components/QuizQuestions/index.d.ts +1 -4
- package/lib/types/components/ResultCard/ResultCard.d.ts +2 -4
- package/lib/types/components/ResultContainer/ResultContainer.d.ts +1 -2
- package/lib/types/components/ResultCtaButton/ResultCtaButton.d.ts +2 -3
- package/lib/types/components/ResultFilters/ResultFilters.d.ts +2 -5
- package/lib/types/components/Results/Results.d.ts +1 -7
- package/lib/types/components/ZeroResults/ZeroResults.d.ts +1 -1
- package/lib/types/constants.d.ts +2 -1
- package/lib/types/hooks/useCioClient.d.ts +1 -1
- package/lib/types/hooks/useConsoleErrors.d.ts +3 -0
- package/lib/types/hooks/useQuiz.d.ts +3 -0
- package/lib/types/hooks/useQuizApiState.d.ts +10 -0
- package/lib/types/hooks/useQuizEvents/index.d.ts +15 -0
- package/lib/types/hooks/useQuizEvents/useQuizAddToCart.d.ts +5 -0
- package/lib/types/hooks/useQuizEvents/useQuizBackClick.d.ts +4 -0
- package/lib/types/hooks/useQuizEvents/useQuizNextClick.d.ts +5 -0
- package/lib/types/hooks/useQuizEvents/useQuizResultClick.d.ts +5 -0
- package/lib/types/hooks/useQuizEvents/useQuizResultsLoaded.d.ts +5 -0
- package/lib/types/hooks/useQuizLocalState.d.ts +6 -0
- package/lib/types/services/index.d.ts +8 -0
- package/lib/types/types.d.ts +63 -0
- package/lib/types/utils.d.ts +12 -7
- 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 {
|
|
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 (
|
|
18
|
-
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 =
|
|
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 =
|
|
27
|
-
const
|
|
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
|
-
|
|
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 (
|
|
57
|
-
const
|
|
58
|
-
|
|
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'}` }, (
|
|
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:
|
|
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 {
|
|
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:
|
|
11
|
+
react_1.default.createElement(CTAButton_1.default, { ctaText: 'Try Again', onClick: resetQuizClickHandler })));
|
|
12
12
|
}
|
|
13
13
|
exports.default = ZeroResults;
|
package/lib/cjs/constants.js
CHANGED
|
@@ -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
|
-
- \`
|
|
15
|
-
- \`
|
|
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
|
|
4
|
+
const services_1 = require("../services");
|
|
5
5
|
const useCioClient = ({ apiKey, cioJsClient }) => {
|
|
6
6
|
if (!apiKey && !cioJsClient) {
|
|
7
|
-
|
|
7
|
+
throw new Error('Either apiKey or cioJsClient is required');
|
|
8
8
|
}
|
|
9
|
-
|
|
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;
|