@constructor-io/constructorio-ui-quizzes 1.4.3 → 1.4.5
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/dist/constructorio-ui-quizzes-bundled.js +14 -14
- package/lib/cjs/components/CioQuiz/actions.js +1 -0
- package/lib/cjs/components/CioQuiz/index.js +7 -5
- package/lib/cjs/components/CioQuiz/quizLocalReducer.js +9 -6
- package/lib/cjs/components/ResultCard/ResultCard.js +21 -10
- package/lib/cjs/components/ResultContainer/ResultContainer.js +5 -3
- package/lib/cjs/components/Results/Results.js +2 -2
- package/lib/cjs/constants.js +7 -1
- package/lib/cjs/hooks/useQuiz.js +2 -2
- package/lib/cjs/hooks/useQuizEvents/index.js +1 -1
- package/lib/cjs/hooks/useQuizEvents/useQuizResetClick.js +3 -4
- package/lib/cjs/hooks/useQuizState/index.js +3 -2
- package/lib/cjs/hooks/useQuizState/useQuizApiState.js +8 -2
- package/lib/cjs/hooks/useQuizState/useQuizLocalState.js +6 -2
- package/lib/cjs/stories/Quiz/tests/mocks.js +10 -3
- package/lib/mjs/components/CioQuiz/actions.js +1 -0
- package/lib/mjs/components/CioQuiz/index.js +7 -5
- package/lib/mjs/components/CioQuiz/quizLocalReducer.js +12 -0
- package/lib/mjs/components/ResultCard/ResultCard.js +20 -9
- package/lib/mjs/components/ResultContainer/ResultContainer.js +5 -3
- package/lib/mjs/components/Results/Results.js +2 -2
- package/lib/mjs/constants.js +7 -1
- package/lib/mjs/hooks/useQuiz.js +2 -2
- package/lib/mjs/hooks/useQuizEvents/index.js +1 -1
- package/lib/mjs/hooks/useQuizEvents/useQuizResetClick.js +3 -4
- package/lib/mjs/hooks/useQuizState/index.js +3 -2
- package/lib/mjs/hooks/useQuizState/useQuizApiState.js +8 -2
- package/lib/mjs/hooks/useQuizState/useQuizLocalState.js +5 -2
- package/lib/mjs/stories/Quiz/tests/mocks.js +10 -3
- package/lib/styles.css +6 -0
- package/lib/types/components/CioQuiz/actions.d.ts +3 -2
- package/lib/types/components/CioQuiz/quizLocalReducer.d.ts +1 -0
- package/lib/types/components/ResultCard/ResultCard.d.ts +2 -0
- package/lib/types/components/ResultContainer/ResultContainer.d.ts +2 -2
- package/lib/types/components/Results/Results.d.ts +3 -1
- package/lib/types/constants.d.ts +1 -1
- package/lib/types/hooks/useQuizEvents/useQuizResetClick.d.ts +1 -1
- package/lib/types/hooks/useQuizState/index.d.ts +1 -0
- package/lib/types/hooks/useQuizState/useQuizApiState.d.ts +1 -1
- package/lib/types/hooks/useQuizState/useQuizLocalState.d.ts +3 -1
- package/lib/types/types.d.ts +6 -2
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ var QuestionTypes;
|
|
|
12
12
|
QuestionTypes["Back"] = "back";
|
|
13
13
|
QuestionTypes["Reset"] = "reset";
|
|
14
14
|
QuestionTypes["Hydrate"] = "hydrate";
|
|
15
|
+
QuestionTypes["Complete"] = "complete";
|
|
15
16
|
})(QuestionTypes = exports.QuestionTypes || (exports.QuestionTypes = {}));
|
|
16
17
|
// API actions
|
|
17
18
|
var QuizAPIActionTypes;
|
|
@@ -17,11 +17,15 @@ function CioQuiz(props) {
|
|
|
17
17
|
(0, react_1.useEffect)(() => {
|
|
18
18
|
// Respect showSessionModal if defined, else default to true.
|
|
19
19
|
if ((sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModal) !== undefined) {
|
|
20
|
-
setShowSessionPrompt((sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModal) &&
|
|
20
|
+
setShowSessionPrompt((sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModal) &&
|
|
21
|
+
hasSessionStorageState() &&
|
|
22
|
+
!state.quiz.skipToResults);
|
|
21
23
|
}
|
|
22
24
|
else {
|
|
23
|
-
setShowSessionPrompt(hasSessionStorageState());
|
|
25
|
+
setShowSessionPrompt(hasSessionStorageState() && !state.quiz.skipToResults);
|
|
24
26
|
}
|
|
27
|
+
if (state.quiz.skipToResults)
|
|
28
|
+
hydrateQuiz();
|
|
25
29
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26
30
|
}, []);
|
|
27
31
|
const contextValue = {
|
|
@@ -51,9 +55,7 @@ function CioQuiz(props) {
|
|
|
51
55
|
".cio-quiz ",
|
|
52
56
|
(0, utils_1.convertPrimaryColorsToString)(primaryColorStyles)),
|
|
53
57
|
react_1.default.createElement(SessionPromptModal_1.default, { resetStoredState: resetSessionStorageState, continueSession: hydrateQuiz, showSessionPrompt: showSessionPrompt, setShowSessionPrompt: setShowSessionPrompt }),
|
|
54
|
-
react_1.default.createElement(context_1.default.Provider, { value: contextValue },
|
|
55
|
-
state.quiz.results && react_1.default.createElement(ResultContainer_1.default, { options: resultsPageOptions }),
|
|
56
|
-
state.quiz.currentQuestion && react_1.default.createElement(QuizQuestions_1.default, null))));
|
|
58
|
+
react_1.default.createElement(context_1.default.Provider, { value: contextValue }, state.quiz.results || state.quiz.skipToResults ? (react_1.default.createElement(ResultContainer_1.default, { options: resultsPageOptions })) : (state.quiz.currentQuestion && react_1.default.createElement(QuizQuestions_1.default, null)))));
|
|
57
59
|
}
|
|
58
60
|
return null;
|
|
59
61
|
}
|
|
@@ -6,6 +6,7 @@ exports.initialState = {
|
|
|
6
6
|
answers: [],
|
|
7
7
|
answerInputs: {},
|
|
8
8
|
isLastAnswer: false,
|
|
9
|
+
isQuizCompleted: false,
|
|
9
10
|
};
|
|
10
11
|
function answerInputReducer(state, action) {
|
|
11
12
|
return Object.assign(Object.assign({}, state), { [String(action.payload.questionId)]: {
|
|
@@ -17,13 +18,13 @@ function quizLocalReducer(state, action) {
|
|
|
17
18
|
var _a, _b, _c, _d, _e;
|
|
18
19
|
switch (action.type) {
|
|
19
20
|
case actions_1.QuestionTypes.OpenText:
|
|
20
|
-
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_a = action.payload) === null || _a === void 0 ? void 0 : _a.isLastQuestion) });
|
|
21
|
+
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_a = action.payload) === null || _a === void 0 ? void 0 : _a.isLastQuestion), isQuizCompleted: false });
|
|
21
22
|
case actions_1.QuestionTypes.Cover:
|
|
22
|
-
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_b = action.payload) === null || _b === void 0 ? void 0 : _b.isLastQuestion) });
|
|
23
|
+
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_b = action.payload) === null || _b === void 0 ? void 0 : _b.isLastQuestion), isQuizCompleted: false });
|
|
23
24
|
case actions_1.QuestionTypes.SingleSelect:
|
|
24
|
-
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_c = action.payload) === null || _c === void 0 ? void 0 : _c.isLastQuestion) });
|
|
25
|
+
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_c = action.payload) === null || _c === void 0 ? void 0 : _c.isLastQuestion), isQuizCompleted: false });
|
|
25
26
|
case actions_1.QuestionTypes.MultipleSelect:
|
|
26
|
-
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_d = action.payload) === null || _d === void 0 ? void 0 : _d.isLastQuestion) });
|
|
27
|
+
return Object.assign(Object.assign({}, state), { answerInputs: answerInputReducer(state.answerInputs, action), isLastAnswer: !!((_d = action.payload) === null || _d === void 0 ? void 0 : _d.isLastQuestion), isQuizCompleted: false });
|
|
27
28
|
case actions_1.QuestionTypes.Next: {
|
|
28
29
|
const { answers } = state;
|
|
29
30
|
const newAnswers = [...answers];
|
|
@@ -45,16 +46,18 @@ function quizLocalReducer(state, action) {
|
|
|
45
46
|
default:
|
|
46
47
|
newAnswers.push([]);
|
|
47
48
|
}
|
|
48
|
-
return Object.assign(Object.assign({}, state), { answers: newAnswers });
|
|
49
|
+
return Object.assign(Object.assign({}, state), { answers: newAnswers, isQuizCompleted: false });
|
|
49
50
|
}
|
|
50
51
|
case actions_1.QuestionTypes.Back: {
|
|
51
52
|
const newAnswerInputs = Object.assign({}, state.answerInputs);
|
|
52
|
-
return Object.assign(Object.assign({}, state), { answerInputs: newAnswerInputs, answers: [...state.answers.slice(0, -1)], isLastAnswer: false });
|
|
53
|
+
return Object.assign(Object.assign({}, state), { answerInputs: newAnswerInputs, answers: [...state.answers.slice(0, -1)], isLastAnswer: false, isQuizCompleted: false });
|
|
53
54
|
}
|
|
54
55
|
case actions_1.QuestionTypes.Reset:
|
|
55
56
|
return Object.assign({}, exports.initialState);
|
|
56
57
|
case actions_1.QuestionTypes.Hydrate:
|
|
57
58
|
return Object.assign(Object.assign({}, state), action.payload);
|
|
59
|
+
case actions_1.QuestionTypes.Complete:
|
|
60
|
+
return Object.assign(Object.assign({}, state), { isQuizCompleted: true });
|
|
58
61
|
default:
|
|
59
62
|
return state;
|
|
60
63
|
}
|
|
@@ -5,11 +5,13 @@ const react_1 = tslib_1.__importStar(require("react"));
|
|
|
5
5
|
const ResultCtaButton_1 = tslib_1.__importDefault(require("../ResultCtaButton/ResultCtaButton"));
|
|
6
6
|
const context_1 = tslib_1.__importDefault(require("../CioQuiz/context"));
|
|
7
7
|
function ResultCard(props) {
|
|
8
|
-
var _a, _b;
|
|
9
|
-
const { result, salePriceKey, regularPriceKey, resultPosition } = props;
|
|
8
|
+
var _a, _b, _c, _d;
|
|
9
|
+
const { result, salePriceKey, regularPriceKey, resultPosition, ratingCountKey, ratingScoreKey } = props;
|
|
10
10
|
const { customClickItemCallback, getQuizResultButtonProps, getQuizResultLinkProps } = (0, react_1.useContext)(context_1.default);
|
|
11
11
|
const salePrice = salePriceKey && ((_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a[salePriceKey]);
|
|
12
12
|
const regularPrice = regularPriceKey && ((_b = result === null || result === void 0 ? void 0 : result.data) === null || _b === void 0 ? void 0 : _b[regularPriceKey]);
|
|
13
|
+
const ratingCount = ratingCountKey && ((_c = result === null || result === void 0 ? void 0 : result.data) === null || _c === void 0 ? void 0 : _c[ratingCountKey]);
|
|
14
|
+
const ratingScore = ratingScoreKey && ((_d = result === null || result === void 0 ? void 0 : result.data) === null || _d === void 0 ? void 0 : _d[ratingScoreKey]);
|
|
13
15
|
const resultCardContent = () => {
|
|
14
16
|
var _a;
|
|
15
17
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
@@ -17,16 +19,25 @@ function ResultCard(props) {
|
|
|
17
19
|
react_1.default.createElement("img", { src: (_a = result.data) === null || _a === void 0 ? void 0 : _a.image_url, alt: 'product' })),
|
|
18
20
|
react_1.default.createElement("div", { className: 'cio-result-card-text' },
|
|
19
21
|
react_1.default.createElement("p", { className: 'cio-result-card-title' }, result.value),
|
|
20
|
-
react_1.default.createElement("div", { className: 'cio-result-card-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
22
|
+
react_1.default.createElement("div", { className: 'cio-result-card-details' },
|
|
23
|
+
react_1.default.createElement("div", { className: 'cio-result-card-rating' },
|
|
24
|
+
ratingScore && (react_1.default.createElement("span", { className: 'cio-result-card-rating-score' },
|
|
25
|
+
Array(Number(ratingScore)).fill('★'),
|
|
26
|
+
Array(5 - Number(ratingScore)).fill('☆'))),
|
|
27
|
+
ratingCount && react_1.default.createElement("span", { className: 'cio-result-card-rating-count' },
|
|
28
|
+
"(",
|
|
29
|
+
ratingCount,
|
|
30
|
+
")")),
|
|
31
|
+
react_1.default.createElement("div", { className: 'cio-result-card-prices' },
|
|
32
|
+
salePrice && react_1.default.createElement("span", { className: 'cio-result-card-sale-price' },
|
|
33
|
+
"$",
|
|
34
|
+
salePrice),
|
|
35
|
+
regularPrice && (react_1.default.createElement("span", { className: `cio-result-card-regular-price${salePrice ? '--strike-through' : ''}` },
|
|
36
|
+
"$",
|
|
37
|
+
regularPrice)))))));
|
|
27
38
|
};
|
|
28
39
|
const resultCardContentWithoutLink = () => getQuizResultButtonProps && (react_1.default.createElement("div", Object.assign({}, getQuizResultButtonProps({ result, position: resultPosition, type: 'button' })), resultCardContent()));
|
|
29
|
-
const resultCardContentWithLink = () => getQuizResultLinkProps && (react_1.default.createElement("a", Object.assign({ className: 'cio-result-card-anchor' }, getQuizResultLinkProps({ result, position: resultPosition, type: 'link' })), resultCardContent()));
|
|
40
|
+
const resultCardContentWithLink = () => getQuizResultLinkProps && (react_1.default.createElement("a", Object.assign({ className: 'cio-result-card-anchor', rel: 'noreferrer', target: '_blank' }, getQuizResultLinkProps({ result, position: resultPosition, type: 'link' })), resultCardContent()));
|
|
30
41
|
return (react_1.default.createElement("div", { className: 'cio-result-card' },
|
|
31
42
|
!customClickItemCallback ? resultCardContentWithLink() : resultCardContentWithoutLink(),
|
|
32
43
|
react_1.default.createElement(ResultCtaButton_1.default, { item: result, price: salePrice || regularPrice })));
|
|
@@ -7,10 +7,11 @@ const context_1 = tslib_1.__importDefault(require("../CioQuiz/context"));
|
|
|
7
7
|
const ResultFilters_1 = tslib_1.__importDefault(require("../ResultFilters/ResultFilters"));
|
|
8
8
|
const ZeroResults_1 = tslib_1.__importDefault(require("../ZeroResults/ZeroResults"));
|
|
9
9
|
const Results_1 = tslib_1.__importDefault(require("../Results/Results"));
|
|
10
|
+
const Spinner_1 = tslib_1.__importDefault(require("../Spinner/Spinner"));
|
|
10
11
|
function ResultContainer(props) {
|
|
11
12
|
var _a, _b, _c;
|
|
12
13
|
const { options } = props;
|
|
13
|
-
const { resultCardSalePriceKey, resultCardRegularPriceKey } = options;
|
|
14
|
+
const { resultCardSalePriceKey, resultCardRegularPriceKey, resultCardRatingCountKey, resultCardRatingScoreKey, } = options;
|
|
14
15
|
const { state } = (0, react_1.useContext)(context_1.default);
|
|
15
16
|
const zeroResults = !((_c = (_b = (_a = state === null || state === void 0 ? void 0 : state.quiz.results) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.results) === null || _c === void 0 ? void 0 : _c.length);
|
|
16
17
|
const resultsTitle = zeroResults ? '' : 'Here are your results';
|
|
@@ -20,9 +21,10 @@ function ResultContainer(props) {
|
|
|
20
21
|
react_1.default.createElement("div", { className: 'cio-results-filter-and-redo-container' },
|
|
21
22
|
react_1.default.createElement(ResultFilters_1.default, { hasNoResults: zeroResults }),
|
|
22
23
|
react_1.default.createElement(RedoButton_1.default, null)),
|
|
23
|
-
!zeroResults && (react_1.default.createElement(Results_1.default, { resultCardSalePriceKey: resultCardSalePriceKey, resultCardRegularPriceKey: resultCardRegularPriceKey })),
|
|
24
|
+
!zeroResults && (react_1.default.createElement(Results_1.default, { resultCardSalePriceKey: resultCardSalePriceKey, resultCardRegularPriceKey: resultCardRegularPriceKey, resultCardRatingCountKey: resultCardRatingCountKey, resultCardRatingScoreKey: resultCardRatingScoreKey })),
|
|
24
25
|
zeroResults && react_1.default.createElement(ZeroResults_1.default, null)));
|
|
25
26
|
}
|
|
26
|
-
return react_1.default.createElement("div",
|
|
27
|
+
return (react_1.default.createElement("div", { className: 'cio-results-container' },
|
|
28
|
+
react_1.default.createElement(Spinner_1.default, null)));
|
|
27
29
|
}
|
|
28
30
|
exports.default = ResultContainer;
|
|
@@ -6,11 +6,11 @@ const context_1 = tslib_1.__importDefault(require("../CioQuiz/context"));
|
|
|
6
6
|
const ResultCard_1 = tslib_1.__importDefault(require("../ResultCard/ResultCard"));
|
|
7
7
|
function Results(props) {
|
|
8
8
|
var _a, _b, _c, _d;
|
|
9
|
-
const { resultCardSalePriceKey, resultCardRegularPriceKey } = props;
|
|
9
|
+
const { resultCardSalePriceKey, resultCardRegularPriceKey, resultCardRatingCountKey, resultCardRatingScoreKey, } = props;
|
|
10
10
|
const { state } = (0, react_1.useContext)(context_1.default);
|
|
11
11
|
return (react_1.default.createElement("div", { className: 'cio-results' }, (_d = (_c = (_b = (_a = state === null || state === void 0 ? void 0 : state.quiz) === null || _a === void 0 ? void 0 : _a.results) === null || _b === void 0 ? void 0 : _b.response) === null || _c === void 0 ? void 0 : _c.results) === null || _d === void 0 ? void 0 : _d.map((result, index) => {
|
|
12
12
|
var _a;
|
|
13
|
-
return (react_1.default.createElement(ResultCard_1.default, { result: result, key: (_a = result.data) === null || _a === void 0 ? void 0 : _a.id, salePriceKey: resultCardSalePriceKey, regularPriceKey: resultCardRegularPriceKey, resultPosition: index + 1 }));
|
|
13
|
+
return (react_1.default.createElement(ResultCard_1.default, { result: result, key: (_a = result.data) === null || _a === void 0 ? void 0 : _a.id, salePriceKey: resultCardSalePriceKey, regularPriceKey: resultCardRegularPriceKey, ratingCountKey: resultCardRatingCountKey, ratingScoreKey: resultCardRatingScoreKey, resultPosition: index + 1 }));
|
|
14
14
|
})));
|
|
15
15
|
}
|
|
16
16
|
exports.default = Results;
|
package/lib/cjs/constants.js
CHANGED
|
@@ -17,7 +17,13 @@ exports.componentDescription = `- import \`CioQuiz\` to render in your JSX.
|
|
|
17
17
|
- \`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
|
|
18
18
|
- \`onQuizResultsLoaded\` is an optional callback function that will be called when the quiz results are loaded
|
|
19
19
|
- \`resultCardRegularPriceKey\` is a parameter that specifies the metadata field name for the regular price
|
|
20
|
-
- \`resultCardSalePriceKey\` is an optional parameter that specifies the metadata field name for the sale price
|
|
20
|
+
- \`resultCardSalePriceKey\` is an optional parameter that specifies the metadata field name for the sale price
|
|
21
|
+
- \`resultCardRatingCountKey\` is an optional parameter that specifies the metadata field name for the ratings count
|
|
22
|
+
- \`resultCardRatingScoreKey\` is an optional parameter that specifies the metadata field name for the ratings score
|
|
23
|
+
- \`sessionStateOptions\` lets you configure the session modal behavior
|
|
24
|
+
- \`showSessionModal\` is a boolean used to decide whether to show the session modal. The default behavior is to show the session modal
|
|
25
|
+
- \`showSessionModalOnResults\` is a boolean to decide whether to show the session modal after reaching the results page. The default behavior is to not show the session modal
|
|
26
|
+
- \`sessionStateKey\` is a custom string that will be used as a session storage key
|
|
21
27
|
- Use different props to configure the behavior of this component.
|
|
22
28
|
- The following stories show how different props affect the component's behavior
|
|
23
29
|
|
package/lib/cjs/hooks/useQuiz.js
CHANGED
|
@@ -18,10 +18,9 @@ const useQuiz = (quizOptions) => {
|
|
|
18
18
|
// Quiz callback events
|
|
19
19
|
const quizEvents = (0, useQuizEvents_1.default)(quizOptions, cioClient, quizState);
|
|
20
20
|
// Props getters
|
|
21
|
-
const { quizApiState, quizLocalState } = quizState;
|
|
21
|
+
const { quizApiState, quizLocalState, skipToResults } = quizState;
|
|
22
22
|
const propGetters = (0, usePropsGetters_1.default)(quizEvents, quizApiState, quizLocalState);
|
|
23
23
|
const primaryColorStyles = (0, usePrimaryColorStyles_1.default)(primaryColor);
|
|
24
|
-
console.log('quizLocalState.answerInputs', quizLocalState.answerInputs);
|
|
25
24
|
return Object.assign(Object.assign({ cioClient, state: {
|
|
26
25
|
answers: {
|
|
27
26
|
inputs: quizLocalState.answerInputs,
|
|
@@ -31,6 +30,7 @@ const useQuiz = (quizOptions) => {
|
|
|
31
30
|
requestState: quizApiState.quizRequestState,
|
|
32
31
|
versionId: quizLocalState.quizVersionId,
|
|
33
32
|
sessionId: quizLocalState.quizSessionId,
|
|
33
|
+
skipToResults,
|
|
34
34
|
currentQuestion: quizApiState.quizCurrentQuestion,
|
|
35
35
|
results: quizApiState.quizResults,
|
|
36
36
|
selectedOptionsWithAttributes: quizApiState.selectedOptionsWithAttributes,
|
|
@@ -27,7 +27,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
|
27
27
|
// Quiz results loaded event
|
|
28
28
|
(0, useQuizResultsLoaded_1.default)(cioClient, quizApiState, onQuizResultsLoaded);
|
|
29
29
|
// Quiz reset
|
|
30
|
-
const resetQuiz = (0, useQuizResetClick_1.default)(quizStateKey, dispatchLocalState, dispatchApiState, quizApiState.quizResults);
|
|
30
|
+
const resetQuiz = (0, useQuizResetClick_1.default)((0, utils_1.resetQuizSessionStorageState)(quizStateKey), dispatchLocalState, dispatchApiState, quizApiState.quizResults);
|
|
31
31
|
// Quiz rehydrate
|
|
32
32
|
const hydrateQuizLocalState = (0, useHydrateQuizLocalState_1.default)(quizStateKey, dispatchLocalState);
|
|
33
33
|
return {
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const react_1 = require("react");
|
|
4
4
|
const actions_1 = require("../../components/CioQuiz/actions");
|
|
5
|
-
const
|
|
6
|
-
const useQuizResetClick = (quizStateKey, dispatchLocalState, dispatchApiState, quizResults) => {
|
|
5
|
+
const useQuizResetClick = (resetQuizSessionStorageState, dispatchLocalState, dispatchApiState, quizResults) => {
|
|
7
6
|
const quizResetClickHandler = (0, react_1.useCallback)(() => {
|
|
8
7
|
if (quizResults) {
|
|
9
8
|
dispatchLocalState({
|
|
@@ -12,9 +11,9 @@ const useQuizResetClick = (quizStateKey, dispatchLocalState, dispatchApiState, q
|
|
|
12
11
|
dispatchApiState({
|
|
13
12
|
type: actions_1.QuizAPIActionTypes.RESET_QUIZ,
|
|
14
13
|
});
|
|
15
|
-
|
|
14
|
+
resetQuizSessionStorageState();
|
|
16
15
|
}
|
|
17
|
-
}, [dispatchLocalState, dispatchApiState,
|
|
16
|
+
}, [dispatchLocalState, dispatchApiState, resetQuizSessionStorageState, quizResults]);
|
|
18
17
|
return quizResetClickHandler;
|
|
19
18
|
};
|
|
20
19
|
exports.default = useQuizResetClick;
|
|
@@ -6,15 +6,16 @@ const useQuizLocalState_1 = tslib_1.__importDefault(require("./useQuizLocalState
|
|
|
6
6
|
const useQuizState = (quizOptions, cioClient) => {
|
|
7
7
|
const { sessionStateOptions } = quizOptions;
|
|
8
8
|
// Quiz Local state
|
|
9
|
-
const { quizLocalState, dispatchLocalState, hasQuizStoredState, quizStateKey } = (0, useQuizLocalState_1.default)(sessionStateOptions
|
|
9
|
+
const { quizLocalState, dispatchLocalState, hasQuizStoredState, skipToResults, quizStateKey } = (0, useQuizLocalState_1.default)(sessionStateOptions);
|
|
10
10
|
// Quiz API state
|
|
11
|
-
const { quizApiState, dispatchApiState } = (0, useQuizApiState_1.default)(quizOptions, cioClient, quizLocalState, dispatchLocalState);
|
|
11
|
+
const { quizApiState, dispatchApiState } = (0, useQuizApiState_1.default)(quizOptions, cioClient, quizLocalState, skipToResults, dispatchLocalState);
|
|
12
12
|
return {
|
|
13
13
|
quizApiState,
|
|
14
14
|
quizLocalState,
|
|
15
15
|
dispatchApiState,
|
|
16
16
|
dispatchLocalState,
|
|
17
17
|
hasQuizStoredState,
|
|
18
|
+
skipToResults,
|
|
18
19
|
quizStateKey,
|
|
19
20
|
};
|
|
20
21
|
};
|
|
@@ -5,7 +5,9 @@ const react_1 = require("react");
|
|
|
5
5
|
const actions_1 = require("../../components/CioQuiz/actions");
|
|
6
6
|
const quizApiReducer_1 = tslib_1.__importStar(require("../../components/CioQuiz/quizApiReducer"));
|
|
7
7
|
const services_1 = require("../../services");
|
|
8
|
-
const useQuizApiState = (quizOptions, cioClient, quizLocalState, dispatchLocalState
|
|
8
|
+
const useQuizApiState = (quizOptions, cioClient, quizLocalState, skipToResults, dispatchLocalState
|
|
9
|
+
// eslint-disable-next-line max-params
|
|
10
|
+
) => {
|
|
9
11
|
const [quizApiState, dispatchApiState] = (0, react_1.useReducer)(quizApiReducer_1.default, quizApiReducer_1.initialState);
|
|
10
12
|
const { quizId, quizVersionId: quizVersionIdProp, resultsPageOptions } = quizOptions;
|
|
11
13
|
(0, react_1.useEffect)(() => {
|
|
@@ -13,7 +15,7 @@ const useQuizApiState = (quizOptions, cioClient, quizLocalState, dispatchLocalSt
|
|
|
13
15
|
dispatchApiState({
|
|
14
16
|
type: actions_1.QuizAPIActionTypes.SET_IS_LOADING,
|
|
15
17
|
});
|
|
16
|
-
if (quizLocalState.isLastAnswer) {
|
|
18
|
+
if (quizLocalState.isLastAnswer || skipToResults) {
|
|
17
19
|
try {
|
|
18
20
|
const quizResults = yield (0, services_1.getQuizResults)(cioClient, quizId, {
|
|
19
21
|
answers: quizLocalState.answers,
|
|
@@ -28,6 +30,10 @@ const useQuizApiState = (quizOptions, cioClient, quizLocalState, dispatchLocalSt
|
|
|
28
30
|
quizResults,
|
|
29
31
|
},
|
|
30
32
|
});
|
|
33
|
+
if (!quizLocalState.isQuizCompleted)
|
|
34
|
+
dispatchLocalState({
|
|
35
|
+
type: actions_1.QuestionTypes.Complete,
|
|
36
|
+
});
|
|
31
37
|
}
|
|
32
38
|
catch (error) {
|
|
33
39
|
dispatchApiState({
|
|
@@ -5,9 +5,10 @@ const react_1 = require("react");
|
|
|
5
5
|
const quizLocalReducer_1 = tslib_1.__importStar(require("../../components/CioQuiz/quizLocalReducer"));
|
|
6
6
|
const constants_1 = require("../../constants");
|
|
7
7
|
const utils_1 = require("../../utils");
|
|
8
|
-
const useQuizLocalState = (
|
|
8
|
+
const useQuizLocalState = (sessionStateOptions) => {
|
|
9
|
+
var _a;
|
|
9
10
|
const [quizLocalState, dispatch] = (0, react_1.useReducer)(quizLocalReducer_1.default, quizLocalReducer_1.initialState);
|
|
10
|
-
const quizStateKey = sessionStateKey || constants_1.quizSessionStateKey;
|
|
11
|
+
const quizStateKey = (sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.sessionStateKey) || constants_1.quizSessionStateKey;
|
|
11
12
|
(0, react_1.useEffect)(() => {
|
|
12
13
|
var _a, _b;
|
|
13
14
|
// don't save state if initial state
|
|
@@ -16,6 +17,8 @@ const useQuizLocalState = (sessionStateKey) => {
|
|
|
16
17
|
}
|
|
17
18
|
}, [quizLocalState, quizStateKey]);
|
|
18
19
|
const hasQuizStoredState = () => (0, utils_1.getStateFromSessionStorage)(quizStateKey) !== null;
|
|
20
|
+
const skipToResults = !!((_a = (0, utils_1.getStateFromSessionStorage)(quizStateKey)) === null || _a === void 0 ? void 0 : _a.isQuizCompleted) &&
|
|
21
|
+
!(sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModalOnResults);
|
|
19
22
|
const dispatchLocalState = (0, react_1.useCallback)((action) => {
|
|
20
23
|
(0, utils_1.logger)(action);
|
|
21
24
|
dispatch(action);
|
|
@@ -24,6 +27,7 @@ const useQuizLocalState = (sessionStateKey) => {
|
|
|
24
27
|
quizLocalState,
|
|
25
28
|
hasQuizStoredState,
|
|
26
29
|
dispatchLocalState,
|
|
30
|
+
skipToResults,
|
|
27
31
|
quizStateKey,
|
|
28
32
|
};
|
|
29
33
|
};
|
|
@@ -55,6 +55,7 @@ const getMockState = (question) => ({
|
|
|
55
55
|
requestState: constants_1.RequestStates.Success,
|
|
56
56
|
versionId: '',
|
|
57
57
|
sessionId: '',
|
|
58
|
+
skipToResults: false,
|
|
58
59
|
currentQuestion: {
|
|
59
60
|
next_question: question,
|
|
60
61
|
isFirstQuestion: false,
|
|
@@ -72,6 +73,8 @@ const getMockState = (question) => ({
|
|
|
72
73
|
data: {
|
|
73
74
|
id: '0',
|
|
74
75
|
price: 100,
|
|
76
|
+
ratingCount: '12',
|
|
77
|
+
ratingScore: '4',
|
|
75
78
|
image_url: 'https://demo.constructor.io/sandbox_files/farmstandquizassets/HiThereNameInput.png',
|
|
76
79
|
},
|
|
77
80
|
},
|
|
@@ -81,6 +84,8 @@ const getMockState = (question) => ({
|
|
|
81
84
|
id: '1',
|
|
82
85
|
price: 200,
|
|
83
86
|
salePrice: 150,
|
|
87
|
+
ratingCount: '6',
|
|
88
|
+
ratingScore: '3',
|
|
84
89
|
image_url: 'https://demo.constructor.io/sandbox_files/farmstandquizassets/HiThereNameInput.png',
|
|
85
90
|
},
|
|
86
91
|
},
|
|
@@ -90,6 +95,8 @@ const getMockState = (question) => ({
|
|
|
90
95
|
id: '2',
|
|
91
96
|
price: 300,
|
|
92
97
|
salePrice: 250,
|
|
98
|
+
ratingCount: '2',
|
|
99
|
+
ratingScore: '5',
|
|
93
100
|
image_url: 'https://demo.constructor.io/sandbox_files/farmstandquizassets/HiThereNameInput.png',
|
|
94
101
|
},
|
|
95
102
|
},
|
|
@@ -106,11 +113,11 @@ const getMockState = (question) => ({
|
|
|
106
113
|
quiz_session_id: '',
|
|
107
114
|
quiz_version_id: '',
|
|
108
115
|
quiz_selected_options: [
|
|
109
|
-
{ value: '
|
|
110
|
-
{ value: '
|
|
116
|
+
{ value: 'Chocolate', has_attribute: true },
|
|
117
|
+
{ value: 'Medium', has_attribute: true },
|
|
111
118
|
],
|
|
112
119
|
},
|
|
113
|
-
selectedOptionsWithAttributes: ['
|
|
120
|
+
selectedOptionsWithAttributes: ['Chocolate', 'Medium'],
|
|
114
121
|
},
|
|
115
122
|
});
|
|
116
123
|
exports.getMockState = getMockState;
|
|
@@ -9,6 +9,7 @@ export var QuestionTypes;
|
|
|
9
9
|
QuestionTypes["Back"] = "back";
|
|
10
10
|
QuestionTypes["Reset"] = "reset";
|
|
11
11
|
QuestionTypes["Hydrate"] = "hydrate";
|
|
12
|
+
QuestionTypes["Complete"] = "complete";
|
|
12
13
|
})(QuestionTypes || (QuestionTypes = {}));
|
|
13
14
|
// API actions
|
|
14
15
|
export var QuizAPIActionTypes;
|
|
@@ -14,11 +14,15 @@ export default function CioQuiz(props) {
|
|
|
14
14
|
useEffect(() => {
|
|
15
15
|
// Respect showSessionModal if defined, else default to true.
|
|
16
16
|
if (sessionStateOptions?.showSessionModal !== undefined) {
|
|
17
|
-
setShowSessionPrompt(sessionStateOptions?.showSessionModal &&
|
|
17
|
+
setShowSessionPrompt(sessionStateOptions?.showSessionModal &&
|
|
18
|
+
hasSessionStorageState() &&
|
|
19
|
+
!state.quiz.skipToResults);
|
|
18
20
|
}
|
|
19
21
|
else {
|
|
20
|
-
setShowSessionPrompt(hasSessionStorageState());
|
|
22
|
+
setShowSessionPrompt(hasSessionStorageState() && !state.quiz.skipToResults);
|
|
21
23
|
}
|
|
24
|
+
if (state.quiz.skipToResults)
|
|
25
|
+
hydrateQuiz();
|
|
22
26
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23
27
|
}, []);
|
|
24
28
|
const contextValue = {
|
|
@@ -48,9 +52,7 @@ export default function CioQuiz(props) {
|
|
|
48
52
|
".cio-quiz ",
|
|
49
53
|
convertPrimaryColorsToString(primaryColorStyles)),
|
|
50
54
|
React.createElement(SessionPromptModal, { resetStoredState: resetSessionStorageState, continueSession: hydrateQuiz, showSessionPrompt: showSessionPrompt, setShowSessionPrompt: setShowSessionPrompt }),
|
|
51
|
-
React.createElement(QuizContext.Provider, { value: contextValue },
|
|
52
|
-
state.quiz.results && React.createElement(ResultContainer, { options: resultsPageOptions }),
|
|
53
|
-
state.quiz.currentQuestion && React.createElement(QuizQuestions, null))));
|
|
55
|
+
React.createElement(QuizContext.Provider, { value: contextValue }, state.quiz.results || state.quiz.skipToResults ? (React.createElement(ResultContainer, { options: resultsPageOptions })) : (state.quiz.currentQuestion && React.createElement(QuizQuestions, null)))));
|
|
54
56
|
}
|
|
55
57
|
return null;
|
|
56
58
|
}
|
|
@@ -3,6 +3,7 @@ export const initialState = {
|
|
|
3
3
|
answers: [],
|
|
4
4
|
answerInputs: {},
|
|
5
5
|
isLastAnswer: false,
|
|
6
|
+
isQuizCompleted: false,
|
|
6
7
|
};
|
|
7
8
|
function answerInputReducer(state, action) {
|
|
8
9
|
return {
|
|
@@ -20,24 +21,28 @@ export default function quizLocalReducer(state, action) {
|
|
|
20
21
|
...state,
|
|
21
22
|
answerInputs: answerInputReducer(state.answerInputs, action),
|
|
22
23
|
isLastAnswer: !!action.payload?.isLastQuestion,
|
|
24
|
+
isQuizCompleted: false,
|
|
23
25
|
};
|
|
24
26
|
case QuestionTypes.Cover:
|
|
25
27
|
return {
|
|
26
28
|
...state,
|
|
27
29
|
answerInputs: answerInputReducer(state.answerInputs, action),
|
|
28
30
|
isLastAnswer: !!action.payload?.isLastQuestion,
|
|
31
|
+
isQuizCompleted: false,
|
|
29
32
|
};
|
|
30
33
|
case QuestionTypes.SingleSelect:
|
|
31
34
|
return {
|
|
32
35
|
...state,
|
|
33
36
|
answerInputs: answerInputReducer(state.answerInputs, action),
|
|
34
37
|
isLastAnswer: !!action.payload?.isLastQuestion,
|
|
38
|
+
isQuizCompleted: false,
|
|
35
39
|
};
|
|
36
40
|
case QuestionTypes.MultipleSelect:
|
|
37
41
|
return {
|
|
38
42
|
...state,
|
|
39
43
|
answerInputs: answerInputReducer(state.answerInputs, action),
|
|
40
44
|
isLastAnswer: !!action.payload?.isLastQuestion,
|
|
45
|
+
isQuizCompleted: false,
|
|
41
46
|
};
|
|
42
47
|
case QuestionTypes.Next: {
|
|
43
48
|
const { answers } = state;
|
|
@@ -63,6 +68,7 @@ export default function quizLocalReducer(state, action) {
|
|
|
63
68
|
return {
|
|
64
69
|
...state,
|
|
65
70
|
answers: newAnswers,
|
|
71
|
+
isQuizCompleted: false,
|
|
66
72
|
};
|
|
67
73
|
}
|
|
68
74
|
case QuestionTypes.Back: {
|
|
@@ -72,6 +78,7 @@ export default function quizLocalReducer(state, action) {
|
|
|
72
78
|
answerInputs: newAnswerInputs,
|
|
73
79
|
answers: [...state.answers.slice(0, -1)],
|
|
74
80
|
isLastAnswer: false,
|
|
81
|
+
isQuizCompleted: false,
|
|
75
82
|
};
|
|
76
83
|
}
|
|
77
84
|
case QuestionTypes.Reset:
|
|
@@ -83,6 +90,11 @@ export default function quizLocalReducer(state, action) {
|
|
|
83
90
|
...state,
|
|
84
91
|
...action.payload,
|
|
85
92
|
};
|
|
93
|
+
case QuestionTypes.Complete:
|
|
94
|
+
return {
|
|
95
|
+
...state,
|
|
96
|
+
isQuizCompleted: true,
|
|
97
|
+
};
|
|
86
98
|
default:
|
|
87
99
|
return state;
|
|
88
100
|
}
|
|
@@ -2,24 +2,35 @@ import React, { useContext } from 'react';
|
|
|
2
2
|
import ResultCtaButton from '../ResultCtaButton/ResultCtaButton';
|
|
3
3
|
import QuizContext from '../CioQuiz/context';
|
|
4
4
|
export default function ResultCard(props) {
|
|
5
|
-
const { result, salePriceKey, regularPriceKey, resultPosition } = props;
|
|
5
|
+
const { result, salePriceKey, regularPriceKey, resultPosition, ratingCountKey, ratingScoreKey } = props;
|
|
6
6
|
const { customClickItemCallback, getQuizResultButtonProps, getQuizResultLinkProps } = useContext(QuizContext);
|
|
7
7
|
const salePrice = salePriceKey && result?.data?.[salePriceKey];
|
|
8
8
|
const regularPrice = regularPriceKey && result?.data?.[regularPriceKey];
|
|
9
|
+
const ratingCount = ratingCountKey && result?.data?.[ratingCountKey];
|
|
10
|
+
const ratingScore = ratingScoreKey && result?.data?.[ratingScoreKey];
|
|
9
11
|
const resultCardContent = () => (React.createElement(React.Fragment, null,
|
|
10
12
|
React.createElement("div", { className: 'cio-result-card-image' },
|
|
11
13
|
React.createElement("img", { src: result.data?.image_url, alt: 'product' })),
|
|
12
14
|
React.createElement("div", { className: 'cio-result-card-text' },
|
|
13
15
|
React.createElement("p", { className: 'cio-result-card-title' }, result.value),
|
|
14
|
-
React.createElement("div", { className: 'cio-result-card-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
16
|
+
React.createElement("div", { className: 'cio-result-card-details' },
|
|
17
|
+
React.createElement("div", { className: 'cio-result-card-rating' },
|
|
18
|
+
ratingScore && (React.createElement("span", { className: 'cio-result-card-rating-score' },
|
|
19
|
+
Array(Number(ratingScore)).fill('★'),
|
|
20
|
+
Array(5 - Number(ratingScore)).fill('☆'))),
|
|
21
|
+
ratingCount && React.createElement("span", { className: 'cio-result-card-rating-count' },
|
|
22
|
+
"(",
|
|
23
|
+
ratingCount,
|
|
24
|
+
")")),
|
|
25
|
+
React.createElement("div", { className: 'cio-result-card-prices' },
|
|
26
|
+
salePrice && React.createElement("span", { className: 'cio-result-card-sale-price' },
|
|
27
|
+
"$",
|
|
28
|
+
salePrice),
|
|
29
|
+
regularPrice && (React.createElement("span", { className: `cio-result-card-regular-price${salePrice ? '--strike-through' : ''}` },
|
|
30
|
+
"$",
|
|
31
|
+
regularPrice)))))));
|
|
21
32
|
const resultCardContentWithoutLink = () => getQuizResultButtonProps && (React.createElement("div", { ...getQuizResultButtonProps({ result, position: resultPosition, type: 'button' }) }, resultCardContent()));
|
|
22
|
-
const resultCardContentWithLink = () => getQuizResultLinkProps && (React.createElement("a", { className: 'cio-result-card-anchor', ...getQuizResultLinkProps({ result, position: resultPosition, type: 'link' }) }, resultCardContent()));
|
|
33
|
+
const resultCardContentWithLink = () => getQuizResultLinkProps && (React.createElement("a", { className: 'cio-result-card-anchor', rel: 'noreferrer', target: '_blank', ...getQuizResultLinkProps({ result, position: resultPosition, type: 'link' }) }, resultCardContent()));
|
|
23
34
|
return (React.createElement("div", { className: 'cio-result-card' },
|
|
24
35
|
!customClickItemCallback ? resultCardContentWithLink() : resultCardContentWithoutLink(),
|
|
25
36
|
React.createElement(ResultCtaButton, { item: result, price: salePrice || regularPrice })));
|
|
@@ -4,9 +4,10 @@ import QuizContext from '../CioQuiz/context';
|
|
|
4
4
|
import ResultFilters from '../ResultFilters/ResultFilters';
|
|
5
5
|
import ZeroResults from '../ZeroResults/ZeroResults';
|
|
6
6
|
import Results from '../Results/Results';
|
|
7
|
+
import Spinner from '../Spinner/Spinner';
|
|
7
8
|
export default function ResultContainer(props) {
|
|
8
9
|
const { options } = props;
|
|
9
|
-
const { resultCardSalePriceKey, resultCardRegularPriceKey } = options;
|
|
10
|
+
const { resultCardSalePriceKey, resultCardRegularPriceKey, resultCardRatingCountKey, resultCardRatingScoreKey, } = options;
|
|
10
11
|
const { state } = useContext(QuizContext);
|
|
11
12
|
const zeroResults = !state?.quiz.results?.response?.results?.length;
|
|
12
13
|
const resultsTitle = zeroResults ? '' : 'Here are your results';
|
|
@@ -16,8 +17,9 @@ export default function ResultContainer(props) {
|
|
|
16
17
|
React.createElement("div", { className: 'cio-results-filter-and-redo-container' },
|
|
17
18
|
React.createElement(ResultFilters, { hasNoResults: zeroResults }),
|
|
18
19
|
React.createElement(RedoButton, null)),
|
|
19
|
-
!zeroResults && (React.createElement(Results, { resultCardSalePriceKey: resultCardSalePriceKey, resultCardRegularPriceKey: resultCardRegularPriceKey })),
|
|
20
|
+
!zeroResults && (React.createElement(Results, { resultCardSalePriceKey: resultCardSalePriceKey, resultCardRegularPriceKey: resultCardRegularPriceKey, resultCardRatingCountKey: resultCardRatingCountKey, resultCardRatingScoreKey: resultCardRatingScoreKey })),
|
|
20
21
|
zeroResults && React.createElement(ZeroResults, null)));
|
|
21
22
|
}
|
|
22
|
-
return React.createElement("div",
|
|
23
|
+
return (React.createElement("div", { className: 'cio-results-container' },
|
|
24
|
+
React.createElement(Spinner, null)));
|
|
23
25
|
}
|
|
@@ -2,8 +2,8 @@ import React, { useContext } from 'react';
|
|
|
2
2
|
import QuizContext from '../CioQuiz/context';
|
|
3
3
|
import ResultCard from '../ResultCard/ResultCard';
|
|
4
4
|
function Results(props) {
|
|
5
|
-
const { resultCardSalePriceKey, resultCardRegularPriceKey } = props;
|
|
5
|
+
const { resultCardSalePriceKey, resultCardRegularPriceKey, resultCardRatingCountKey, resultCardRatingScoreKey, } = props;
|
|
6
6
|
const { state } = useContext(QuizContext);
|
|
7
|
-
return (React.createElement("div", { className: 'cio-results' }, state?.quiz?.results?.response?.results?.map((result, index) => (React.createElement(ResultCard, { result: result, key: result.data?.id, salePriceKey: resultCardSalePriceKey, regularPriceKey: resultCardRegularPriceKey, resultPosition: index + 1 })))));
|
|
7
|
+
return (React.createElement("div", { className: 'cio-results' }, state?.quiz?.results?.response?.results?.map((result, index) => (React.createElement(ResultCard, { result: result, key: result.data?.id, salePriceKey: resultCardSalePriceKey, regularPriceKey: resultCardRegularPriceKey, ratingCountKey: resultCardRatingCountKey, ratingScoreKey: resultCardRatingScoreKey, resultPosition: index + 1 })))));
|
|
8
8
|
}
|
|
9
9
|
export default Results;
|
package/lib/mjs/constants.js
CHANGED
|
@@ -14,7 +14,13 @@ export const componentDescription = `- import \`CioQuiz\` to render in your JSX.
|
|
|
14
14
|
- \`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
|
|
15
15
|
- \`onQuizResultsLoaded\` is an optional callback function that will be called when the quiz results are loaded
|
|
16
16
|
- \`resultCardRegularPriceKey\` is a parameter that specifies the metadata field name for the regular price
|
|
17
|
-
- \`resultCardSalePriceKey\` is an optional parameter that specifies the metadata field name for the sale price
|
|
17
|
+
- \`resultCardSalePriceKey\` is an optional parameter that specifies the metadata field name for the sale price
|
|
18
|
+
- \`resultCardRatingCountKey\` is an optional parameter that specifies the metadata field name for the ratings count
|
|
19
|
+
- \`resultCardRatingScoreKey\` is an optional parameter that specifies the metadata field name for the ratings score
|
|
20
|
+
- \`sessionStateOptions\` lets you configure the session modal behavior
|
|
21
|
+
- \`showSessionModal\` is a boolean used to decide whether to show the session modal. The default behavior is to show the session modal
|
|
22
|
+
- \`showSessionModalOnResults\` is a boolean to decide whether to show the session modal after reaching the results page. The default behavior is to not show the session modal
|
|
23
|
+
- \`sessionStateKey\` is a custom string that will be used as a session storage key
|
|
18
24
|
- Use different props to configure the behavior of this component.
|
|
19
25
|
- The following stories show how different props affect the component's behavior
|
|
20
26
|
|
package/lib/mjs/hooks/useQuiz.js
CHANGED
|
@@ -15,10 +15,9 @@ const useQuiz = (quizOptions) => {
|
|
|
15
15
|
// Quiz callback events
|
|
16
16
|
const quizEvents = useQuizEvents(quizOptions, cioClient, quizState);
|
|
17
17
|
// Props getters
|
|
18
|
-
const { quizApiState, quizLocalState } = quizState;
|
|
18
|
+
const { quizApiState, quizLocalState, skipToResults } = quizState;
|
|
19
19
|
const propGetters = usePropsGetters(quizEvents, quizApiState, quizLocalState);
|
|
20
20
|
const primaryColorStyles = usePrimaryColorStyles(primaryColor);
|
|
21
|
-
console.log('quizLocalState.answerInputs', quizLocalState.answerInputs);
|
|
22
21
|
return {
|
|
23
22
|
cioClient,
|
|
24
23
|
state: {
|
|
@@ -30,6 +29,7 @@ const useQuiz = (quizOptions) => {
|
|
|
30
29
|
requestState: quizApiState.quizRequestState,
|
|
31
30
|
versionId: quizLocalState.quizVersionId,
|
|
32
31
|
sessionId: quizLocalState.quizSessionId,
|
|
32
|
+
skipToResults,
|
|
33
33
|
currentQuestion: quizApiState.quizCurrentQuestion,
|
|
34
34
|
results: quizApiState.quizResults,
|
|
35
35
|
selectedOptionsWithAttributes: quizApiState.selectedOptionsWithAttributes,
|
|
@@ -24,7 +24,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
|
24
24
|
// Quiz results loaded event
|
|
25
25
|
useQuizResultsLoaded(cioClient, quizApiState, onQuizResultsLoaded);
|
|
26
26
|
// Quiz reset
|
|
27
|
-
const resetQuiz = useQuizResetClick(quizStateKey, dispatchLocalState, dispatchApiState, quizApiState.quizResults);
|
|
27
|
+
const resetQuiz = useQuizResetClick(resetQuizSessionStorageState(quizStateKey), dispatchLocalState, dispatchApiState, quizApiState.quizResults);
|
|
28
28
|
// Quiz rehydrate
|
|
29
29
|
const hydrateQuizLocalState = useHydrateQuizLocalState(quizStateKey, dispatchLocalState);
|
|
30
30
|
return {
|