@constructor-io/constructorio-ui-quizzes 1.7.3 → 1.8.0

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.
@@ -14,21 +14,18 @@ const utils_1 = require("../../utils");
14
14
  const ProgressBar_1 = tslib_1.__importDefault(require("../ProgressBar/ProgressBar"));
15
15
  function CioQuiz(props) {
16
16
  var _a;
17
- const { cioClient, state, events: { hydrateQuiz, hasSessionStorageState, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = (0, useQuiz_1.default)(props);
17
+ const { cioClient, state, events: { hydrateQuiz, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = (0, useQuiz_1.default)(props);
18
18
  const [showSessionPrompt, setShowSessionPrompt] = (0, react_1.useState)(false);
19
19
  const { resultsPageOptions, sessionStateOptions } = props;
20
+ const { quizSessionStorageState: { hasSessionStorageState, skipToResults }, } = state;
20
21
  (0, react_1.useEffect)(() => {
21
22
  // Respect showSessionModal if defined, else default to true.
22
23
  if ((sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModal) !== undefined) {
23
- setShowSessionPrompt((sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModal) &&
24
- hasSessionStorageState() &&
25
- !state.quiz.skipToResults);
24
+ setShowSessionPrompt((sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModal) && hasSessionStorageState() && !skipToResults);
26
25
  }
27
26
  else {
28
- setShowSessionPrompt(hasSessionStorageState() && !state.quiz.skipToResults);
27
+ setShowSessionPrompt(hasSessionStorageState() && !skipToResults);
29
28
  }
30
- if (state.quiz.skipToResults)
31
- hydrateQuiz();
32
29
  // eslint-disable-next-line react-hooks/exhaustive-deps
33
30
  }, []);
34
31
  const contextValue = {
@@ -65,7 +62,7 @@ function CioQuiz(props) {
65
62
  ".cio-quiz ",
66
63
  (0, utils_1.convertPrimaryColorsToString)(primaryColorStyles)),
67
64
  react_1.default.createElement(SessionPromptModal_1.default, { resetStoredState: resetSessionStorageState, continueSession: hydrateQuiz, showSessionPrompt: showSessionPrompt, setShowSessionPrompt: setShowSessionPrompt }),
68
- 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(react_1.default.Fragment, null,
65
+ react_1.default.createElement(context_1.default.Provider, { value: contextValue }, state.quiz.results || skipToResults ? (react_1.default.createElement(ResultContainer_1.default, { options: resultsPageOptions })) : (state.quiz.currentQuestion && (react_1.default.createElement(react_1.default.Fragment, null,
69
66
  react_1.default.createElement(ProgressBar_1.default, null),
70
67
  react_1.default.createElement(QuizQuestions_1.default, null),
71
68
  react_1.default.createElement(ControlBar_1.default, { ctaButtonText: (questionData === null || questionData === void 0 ? void 0 : questionData.cta_text) || undefined })))))));
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ const react_1 = require("react");
4
5
  const useCioClient_1 = tslib_1.__importDefault(require("./useCioClient"));
5
6
  const useConsoleErrors_1 = tslib_1.__importDefault(require("./useConsoleErrors"));
6
7
  const usePropsGetters_1 = tslib_1.__importDefault(require("./usePropsGetters"));
@@ -18,9 +19,15 @@ const useQuiz = (quizOptions) => {
18
19
  // Quiz callback events
19
20
  const quizEvents = (0, useQuizEvents_1.default)(quizOptions, cioClient, quizState);
20
21
  // Props getters
21
- const { quizApiState, quizLocalState, skipToResults } = quizState;
22
+ const { quizApiState, quizLocalState, quizSessionStorageState } = quizState;
23
+ const { skipToResults } = quizSessionStorageState;
22
24
  const propGetters = (0, usePropsGetters_1.default)(quizEvents, quizApiState, quizLocalState);
23
25
  const primaryColorStyles = (0, usePrimaryColorStyles_1.default)(primaryColor);
26
+ (0, react_1.useEffect)(() => {
27
+ if (skipToResults)
28
+ quizEvents.hydrateQuiz();
29
+ // eslint-disable-next-line react-hooks/exhaustive-deps
30
+ }, []);
24
31
  return Object.assign(Object.assign({ cioClient, state: {
25
32
  answers: {
26
33
  inputs: quizLocalState.answerInputs,
@@ -30,11 +37,11 @@ const useQuiz = (quizOptions) => {
30
37
  requestState: quizApiState.quizRequestState,
31
38
  versionId: quizLocalState.quizVersionId,
32
39
  sessionId: quizLocalState.quizSessionId,
33
- skipToResults,
34
40
  currentQuestion: quizApiState.quizCurrentQuestion,
35
41
  results: quizApiState.quizResults,
36
42
  selectedOptionsWithAttributes: quizApiState.selectedOptionsWithAttributes,
37
43
  },
44
+ quizSessionStorageState,
38
45
  }, events: Object.assign({}, quizEvents) }, propGetters), { primaryColorStyles });
39
46
  };
40
47
  exports.default = useQuiz;
@@ -12,7 +12,7 @@ const useHydrateQuizLocalState_1 = tslib_1.__importDefault(require("./useHydrate
12
12
  const utils_1 = require("../../utils");
13
13
  const useQuizAddToFavorites_1 = tslib_1.__importDefault(require("./useQuizAddToFavorites"));
14
14
  const useQuizEvents = (quizOptions, cioClient, quizState) => {
15
- const { quizApiState, dispatchLocalState, dispatchApiState, hasQuizStoredState, quizStateKey, quizLocalState, } = quizState;
15
+ const { quizApiState, dispatchLocalState, dispatchApiState, quizLocalState, quizSessionStorageState, } = quizState;
16
16
  const { resultsPageOptions, callbacks } = quizOptions;
17
17
  const { onAddToCartClick, onQuizResultClick, onQuizResultsLoaded, onAddToFavoritesClick } = resultsPageOptions;
18
18
  // Quiz answer change
@@ -29,9 +29,9 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
29
29
  // Quiz results loaded event
30
30
  (0, useQuizResultsLoaded_1.default)(cioClient, quizApiState, onQuizResultsLoaded);
31
31
  // Quiz reset
32
- const resetQuiz = (0, useQuizResetClick_1.default)((0, utils_1.resetQuizSessionStorageState)(quizStateKey), dispatchLocalState, dispatchApiState, quizApiState.quizResults);
32
+ const resetQuiz = (0, useQuizResetClick_1.default)((0, utils_1.resetQuizSessionStorageState)(quizSessionStorageState.key), dispatchLocalState, dispatchApiState, quizApiState.quizResults);
33
33
  // Quiz rehydrate
34
- const hydrateQuizLocalState = (0, useHydrateQuizLocalState_1.default)(quizStateKey, dispatchLocalState);
34
+ const hydrateQuizLocalState = (0, useHydrateQuizLocalState_1.default)(quizSessionStorageState.key, dispatchLocalState);
35
35
  return {
36
36
  addToCart,
37
37
  addToFavorites,
@@ -41,8 +41,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
41
41
  nextQuestion,
42
42
  resetQuiz,
43
43
  hydrateQuiz: hydrateQuizLocalState,
44
- hasSessionStorageState: hasQuizStoredState,
45
- resetSessionStorageState: (0, utils_1.resetQuizSessionStorageState)(quizStateKey),
44
+ resetSessionStorageState: (0, utils_1.resetQuizSessionStorageState)(quizSessionStorageState.key),
46
45
  };
47
46
  };
48
47
  exports.default = useQuizEvents;
@@ -3,16 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const react_1 = require("react");
4
4
  const actions_1 = require("../../components/CioQuiz/actions");
5
5
  const utils_1 = require("../../utils");
6
- const useHydrateQuizLocalState = (quizStateKey, dispatchLocalState) => {
7
- const quizState = (0, utils_1.getStateFromSessionStorage)(quizStateKey);
6
+ const useHydrateQuizLocalState = (quizSessionStorageStateKey, dispatchLocalState) => {
7
+ const sessionStorageQuizState = (0, utils_1.getStateFromSessionStorage)(quizSessionStorageStateKey);
8
8
  const hydrateQuizLocalStateHandler = (0, react_1.useCallback)(() => {
9
- if (quizState) {
9
+ if (sessionStorageQuizState) {
10
10
  dispatchLocalState({
11
11
  type: actions_1.QuestionTypes.Hydrate,
12
- payload: quizState,
12
+ payload: sessionStorageQuizState,
13
13
  });
14
14
  }
15
- }, [dispatchLocalState, quizState]);
15
+ }, [dispatchLocalState, sessionStorageQuizState]);
16
16
  return hydrateQuizLocalStateHandler;
17
17
  };
18
18
  exports.default = useHydrateQuizLocalState;
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const useQuizApiState_1 = tslib_1.__importDefault(require("./useQuizApiState"));
5
5
  const useQuizLocalState_1 = tslib_1.__importDefault(require("./useQuizLocalState"));
6
+ const useSessionStorageState_1 = tslib_1.__importDefault(require("./useSessionStorageState"));
6
7
  const useQuizState = (quizOptions, cioClient) => {
7
- const { sessionStateOptions } = quizOptions;
8
+ const { sessionStateOptions, enableHydration } = quizOptions;
8
9
  // Quiz Local state
9
- const { quizLocalState, dispatchLocalState, hasQuizStoredState, skipToResults, quizStateKey } = (0, useQuizLocalState_1.default)(sessionStateOptions);
10
+ const { quizLocalState, dispatchLocalState } = (0, useQuizLocalState_1.default)();
11
+ // Quiz Session Storage state
12
+ const { skipToResults, quizSessionStorageStateKey, hasSessionStorageState } = (0, useSessionStorageState_1.default)(quizLocalState, sessionStateOptions, enableHydration === undefined ? true : enableHydration);
10
13
  // Quiz API state
11
14
  const { quizApiState, dispatchApiState } = (0, useQuizApiState_1.default)(quizOptions, cioClient, quizLocalState, skipToResults, dispatchLocalState);
12
15
  return {
@@ -14,9 +17,11 @@ const useQuizState = (quizOptions, cioClient) => {
14
17
  quizLocalState,
15
18
  dispatchApiState,
16
19
  dispatchLocalState,
17
- hasQuizStoredState,
18
- skipToResults,
19
- quizStateKey,
20
+ quizSessionStorageState: {
21
+ skipToResults,
22
+ key: quizSessionStorageStateKey,
23
+ hasSessionStorageState,
24
+ },
20
25
  };
21
26
  };
22
27
  exports.default = useQuizState;
@@ -3,32 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = require("react");
5
5
  const quizLocalReducer_1 = tslib_1.__importStar(require("../../components/CioQuiz/quizLocalReducer"));
6
- const constants_1 = require("../../constants");
7
6
  const utils_1 = require("../../utils");
8
- const useQuizLocalState = (sessionStateOptions) => {
9
- var _a;
7
+ const useQuizLocalState = () => {
10
8
  const [quizLocalState, dispatch] = (0, react_1.useReducer)(quizLocalReducer_1.default, quizLocalReducer_1.initialState);
11
- const quizStateKey = (sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.sessionStateKey) || constants_1.quizSessionStateKey;
12
- (0, react_1.useEffect)(() => {
13
- var _a, _b;
14
- // don't save state if initial state
15
- if ((_a = quizLocalState === null || quizLocalState === void 0 ? void 0 : quizLocalState.answers) === null || _a === void 0 ? void 0 : _a.length) {
16
- (_b = window === null || window === void 0 ? void 0 : window.sessionStorage) === null || _b === void 0 ? void 0 : _b.setItem(quizStateKey, JSON.stringify(quizLocalState));
17
- }
18
- }, [quizLocalState, quizStateKey]);
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);
22
9
  const dispatchLocalState = (0, react_1.useCallback)((action) => {
23
10
  (0, utils_1.logger)(action);
24
11
  dispatch(action);
25
12
  }, []);
26
13
  return {
27
14
  quizLocalState,
28
- hasQuizStoredState,
29
15
  dispatchLocalState,
30
- skipToResults,
31
- quizStateKey,
32
16
  };
33
17
  };
34
18
  exports.default = useQuizLocalState;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const utils_1 = require("../../utils");
5
+ const constants_1 = require("../../constants");
6
+ const useSessionStorageState = (quizLocalState, sessionStateOptions, enableHydration) => {
7
+ var _a;
8
+ const quizSessionStorageStateKey = (sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.sessionStateKey) || constants_1.quizSessionStateKey;
9
+ // Save state to session storage
10
+ (0, react_1.useEffect)(() => {
11
+ var _a, _b;
12
+ // don't save state if initial state
13
+ if (enableHydration && ((_a = quizLocalState === null || quizLocalState === void 0 ? void 0 : quizLocalState.answers) === null || _a === void 0 ? void 0 : _a.length)) {
14
+ (_b = window === null || window === void 0 ? void 0 : window.sessionStorage) === null || _b === void 0 ? void 0 : _b.setItem(quizSessionStorageStateKey, JSON.stringify(quizLocalState));
15
+ }
16
+ }, [quizLocalState, quizSessionStorageStateKey, enableHydration]);
17
+ const skipToResults = !!enableHydration &&
18
+ !!((_a = (0, utils_1.getStateFromSessionStorage)(quizSessionStorageStateKey)) === null || _a === void 0 ? void 0 : _a.isQuizCompleted) &&
19
+ !(sessionStateOptions === null || sessionStateOptions === void 0 ? void 0 : sessionStateOptions.showSessionModalOnResults);
20
+ return {
21
+ skipToResults,
22
+ quizSessionStorageStateKey,
23
+ hasSessionStorageState: () => (0, utils_1.getStateFromSessionStorage)(quizSessionStorageStateKey) !== null,
24
+ };
25
+ };
26
+ exports.default = useSessionStorageState;
@@ -55,7 +55,6 @@ const getMockState = (question) => ({
55
55
  requestState: constants_1.RequestStates.Success,
56
56
  versionId: '',
57
57
  sessionId: '',
58
- skipToResults: false,
59
58
  currentQuestion: {
60
59
  next_question: question,
61
60
  isFirstQuestion: false,
@@ -121,6 +120,11 @@ const getMockState = (question) => ({
121
120
  },
122
121
  selectedOptionsWithAttributes: ['Chocolate', 'Medium'],
123
122
  },
123
+ quizSessionStorageState: {
124
+ key: constants_1.quizSessionStateKey,
125
+ skipToResults: true,
126
+ hasSessionStorageState: () => true,
127
+ },
124
128
  });
125
129
  exports.getMockState = getMockState;
126
130
  const mockElementProps = {
@@ -10,21 +10,18 @@ import SessionPromptModal from '../SessionPromptModal/SessionPromptModal';
10
10
  import { convertPrimaryColorsToString, renderImages } from '../../utils';
11
11
  import ProgressBar from '../ProgressBar/ProgressBar';
12
12
  export default function CioQuiz(props) {
13
- const { cioClient, state, events: { hydrateQuiz, hasSessionStorageState, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = useQuiz(props);
13
+ const { cioClient, state, events: { hydrateQuiz, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = useQuiz(props);
14
14
  const [showSessionPrompt, setShowSessionPrompt] = useState(false);
15
15
  const { resultsPageOptions, sessionStateOptions } = props;
16
+ const { quizSessionStorageState: { hasSessionStorageState, skipToResults }, } = state;
16
17
  useEffect(() => {
17
18
  // Respect showSessionModal if defined, else default to true.
18
19
  if (sessionStateOptions?.showSessionModal !== undefined) {
19
- setShowSessionPrompt(sessionStateOptions?.showSessionModal &&
20
- hasSessionStorageState() &&
21
- !state.quiz.skipToResults);
20
+ setShowSessionPrompt(sessionStateOptions?.showSessionModal && hasSessionStorageState() && !skipToResults);
22
21
  }
23
22
  else {
24
- setShowSessionPrompt(hasSessionStorageState() && !state.quiz.skipToResults);
23
+ setShowSessionPrompt(hasSessionStorageState() && !skipToResults);
25
24
  }
26
- if (state.quiz.skipToResults)
27
- hydrateQuiz();
28
25
  // eslint-disable-next-line react-hooks/exhaustive-deps
29
26
  }, []);
30
27
  const contextValue = {
@@ -61,7 +58,7 @@ export default function CioQuiz(props) {
61
58
  ".cio-quiz ",
62
59
  convertPrimaryColorsToString(primaryColorStyles)),
63
60
  React.createElement(SessionPromptModal, { resetStoredState: resetSessionStorageState, continueSession: hydrateQuiz, showSessionPrompt: showSessionPrompt, setShowSessionPrompt: setShowSessionPrompt }),
64
- React.createElement(QuizContext.Provider, { value: contextValue }, state.quiz.results || state.quiz.skipToResults ? (React.createElement(ResultContainer, { options: resultsPageOptions })) : (state.quiz.currentQuestion && (React.createElement(React.Fragment, null,
61
+ React.createElement(QuizContext.Provider, { value: contextValue }, state.quiz.results || skipToResults ? (React.createElement(ResultContainer, { options: resultsPageOptions })) : (state.quiz.currentQuestion && (React.createElement(React.Fragment, null,
65
62
  React.createElement(ProgressBar, null),
66
63
  React.createElement(QuizQuestions, null),
67
64
  React.createElement(ControlBar, { ctaButtonText: questionData?.cta_text || undefined })))))));
@@ -1,3 +1,4 @@
1
+ import { useEffect } from 'react';
1
2
  import useCioClient from './useCioClient';
2
3
  import useConsoleErrors from './useConsoleErrors';
3
4
  import usePropsGetters from './usePropsGetters';
@@ -15,9 +16,15 @@ const useQuiz = (quizOptions) => {
15
16
  // Quiz callback events
16
17
  const quizEvents = useQuizEvents(quizOptions, cioClient, quizState);
17
18
  // Props getters
18
- const { quizApiState, quizLocalState, skipToResults } = quizState;
19
+ const { quizApiState, quizLocalState, quizSessionStorageState } = quizState;
20
+ const { skipToResults } = quizSessionStorageState;
19
21
  const propGetters = usePropsGetters(quizEvents, quizApiState, quizLocalState);
20
22
  const primaryColorStyles = usePrimaryColorStyles(primaryColor);
23
+ useEffect(() => {
24
+ if (skipToResults)
25
+ quizEvents.hydrateQuiz();
26
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27
+ }, []);
21
28
  return {
22
29
  cioClient,
23
30
  state: {
@@ -29,11 +36,11 @@ const useQuiz = (quizOptions) => {
29
36
  requestState: quizApiState.quizRequestState,
30
37
  versionId: quizLocalState.quizVersionId,
31
38
  sessionId: quizLocalState.quizSessionId,
32
- skipToResults,
33
39
  currentQuestion: quizApiState.quizCurrentQuestion,
34
40
  results: quizApiState.quizResults,
35
41
  selectedOptionsWithAttributes: quizApiState.selectedOptionsWithAttributes,
36
42
  },
43
+ quizSessionStorageState,
37
44
  },
38
45
  events: {
39
46
  ...quizEvents,
@@ -9,7 +9,7 @@ import useHydrateQuizLocalState from './useHydrateQuizLocalState';
9
9
  import { resetQuizSessionStorageState } from '../../utils';
10
10
  import useQuizAddToFavorites from './useQuizAddToFavorites';
11
11
  const useQuizEvents = (quizOptions, cioClient, quizState) => {
12
- const { quizApiState, dispatchLocalState, dispatchApiState, hasQuizStoredState, quizStateKey, quizLocalState, } = quizState;
12
+ const { quizApiState, dispatchLocalState, dispatchApiState, quizLocalState, quizSessionStorageState, } = quizState;
13
13
  const { resultsPageOptions, callbacks } = quizOptions;
14
14
  const { onAddToCartClick, onQuizResultClick, onQuizResultsLoaded, onAddToFavoritesClick } = resultsPageOptions;
15
15
  // Quiz answer change
@@ -26,9 +26,9 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
26
26
  // Quiz results loaded event
27
27
  useQuizResultsLoaded(cioClient, quizApiState, onQuizResultsLoaded);
28
28
  // Quiz reset
29
- const resetQuiz = useQuizResetClick(resetQuizSessionStorageState(quizStateKey), dispatchLocalState, dispatchApiState, quizApiState.quizResults);
29
+ const resetQuiz = useQuizResetClick(resetQuizSessionStorageState(quizSessionStorageState.key), dispatchLocalState, dispatchApiState, quizApiState.quizResults);
30
30
  // Quiz rehydrate
31
- const hydrateQuizLocalState = useHydrateQuizLocalState(quizStateKey, dispatchLocalState);
31
+ const hydrateQuizLocalState = useHydrateQuizLocalState(quizSessionStorageState.key, dispatchLocalState);
32
32
  return {
33
33
  addToCart,
34
34
  addToFavorites,
@@ -38,8 +38,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
38
38
  nextQuestion,
39
39
  resetQuiz,
40
40
  hydrateQuiz: hydrateQuizLocalState,
41
- hasSessionStorageState: hasQuizStoredState,
42
- resetSessionStorageState: resetQuizSessionStorageState(quizStateKey),
41
+ resetSessionStorageState: resetQuizSessionStorageState(quizSessionStorageState.key),
43
42
  };
44
43
  };
45
44
  export default useQuizEvents;
@@ -1,16 +1,16 @@
1
1
  import { useCallback } from 'react';
2
2
  import { QuestionTypes } from '../../components/CioQuiz/actions';
3
3
  import { getStateFromSessionStorage } from '../../utils';
4
- const useHydrateQuizLocalState = (quizStateKey, dispatchLocalState) => {
5
- const quizState = getStateFromSessionStorage(quizStateKey);
4
+ const useHydrateQuizLocalState = (quizSessionStorageStateKey, dispatchLocalState) => {
5
+ const sessionStorageQuizState = getStateFromSessionStorage(quizSessionStorageStateKey);
6
6
  const hydrateQuizLocalStateHandler = useCallback(() => {
7
- if (quizState) {
7
+ if (sessionStorageQuizState) {
8
8
  dispatchLocalState({
9
9
  type: QuestionTypes.Hydrate,
10
- payload: quizState,
10
+ payload: sessionStorageQuizState,
11
11
  });
12
12
  }
13
- }, [dispatchLocalState, quizState]);
13
+ }, [dispatchLocalState, sessionStorageQuizState]);
14
14
  return hydrateQuizLocalStateHandler;
15
15
  };
16
16
  export default useHydrateQuizLocalState;
@@ -1,9 +1,12 @@
1
1
  import useQuizApiState from './useQuizApiState';
2
2
  import useQuizLocalState from './useQuizLocalState';
3
+ import useSessionStorageState from './useSessionStorageState';
3
4
  const useQuizState = (quizOptions, cioClient) => {
4
- const { sessionStateOptions } = quizOptions;
5
+ const { sessionStateOptions, enableHydration } = quizOptions;
5
6
  // Quiz Local state
6
- const { quizLocalState, dispatchLocalState, hasQuizStoredState, skipToResults, quizStateKey } = useQuizLocalState(sessionStateOptions);
7
+ const { quizLocalState, dispatchLocalState } = useQuizLocalState();
8
+ // Quiz Session Storage state
9
+ const { skipToResults, quizSessionStorageStateKey, hasSessionStorageState } = useSessionStorageState(quizLocalState, sessionStateOptions, enableHydration === undefined ? true : enableHydration);
7
10
  // Quiz API state
8
11
  const { quizApiState, dispatchApiState } = useQuizApiState(quizOptions, cioClient, quizLocalState, skipToResults, dispatchLocalState);
9
12
  return {
@@ -11,9 +14,11 @@ const useQuizState = (quizOptions, cioClient) => {
11
14
  quizLocalState,
12
15
  dispatchApiState,
13
16
  dispatchLocalState,
14
- hasQuizStoredState,
15
- skipToResults,
16
- quizStateKey,
17
+ quizSessionStorageState: {
18
+ skipToResults,
19
+ key: quizSessionStorageStateKey,
20
+ hasSessionStorageState,
21
+ },
17
22
  };
18
23
  };
19
24
  export default useQuizState;
@@ -1,29 +1,15 @@
1
- import { useCallback, useEffect, useReducer } from 'react';
1
+ import { useCallback, useReducer } from 'react';
2
2
  import quizLocalReducer, { initialState } from '../../components/CioQuiz/quizLocalReducer';
3
- import { quizSessionStateKey } from '../../constants';
4
- import { getStateFromSessionStorage, logger } from '../../utils';
5
- const useQuizLocalState = (sessionStateOptions) => {
3
+ import { logger } from '../../utils';
4
+ const useQuizLocalState = () => {
6
5
  const [quizLocalState, dispatch] = useReducer(quizLocalReducer, initialState);
7
- const quizStateKey = sessionStateOptions?.sessionStateKey || quizSessionStateKey;
8
- useEffect(() => {
9
- // don't save state if initial state
10
- if (quizLocalState?.answers?.length) {
11
- window?.sessionStorage?.setItem(quizStateKey, JSON.stringify(quizLocalState));
12
- }
13
- }, [quizLocalState, quizStateKey]);
14
- const hasQuizStoredState = () => getStateFromSessionStorage(quizStateKey) !== null;
15
- const skipToResults = !!getStateFromSessionStorage(quizStateKey)?.isQuizCompleted &&
16
- !sessionStateOptions?.showSessionModalOnResults;
17
6
  const dispatchLocalState = useCallback((action) => {
18
7
  logger(action);
19
8
  dispatch(action);
20
9
  }, []);
21
10
  return {
22
11
  quizLocalState,
23
- hasQuizStoredState,
24
12
  dispatchLocalState,
25
- skipToResults,
26
- quizStateKey,
27
13
  };
28
14
  };
29
15
  export default useQuizLocalState;
@@ -0,0 +1,22 @@
1
+ import { useEffect } from 'react';
2
+ import { getStateFromSessionStorage } from '../../utils';
3
+ import { quizSessionStateKey } from '../../constants';
4
+ const useSessionStorageState = (quizLocalState, sessionStateOptions, enableHydration) => {
5
+ const quizSessionStorageStateKey = sessionStateOptions?.sessionStateKey || quizSessionStateKey;
6
+ // Save state to session storage
7
+ useEffect(() => {
8
+ // don't save state if initial state
9
+ if (enableHydration && quizLocalState?.answers?.length) {
10
+ window?.sessionStorage?.setItem(quizSessionStorageStateKey, JSON.stringify(quizLocalState));
11
+ }
12
+ }, [quizLocalState, quizSessionStorageStateKey, enableHydration]);
13
+ const skipToResults = !!enableHydration &&
14
+ !!getStateFromSessionStorage(quizSessionStorageStateKey)?.isQuizCompleted &&
15
+ !sessionStateOptions?.showSessionModalOnResults;
16
+ return {
17
+ skipToResults,
18
+ quizSessionStorageStateKey,
19
+ hasSessionStorageState: () => getStateFromSessionStorage(quizSessionStorageStateKey) !== null,
20
+ };
21
+ };
22
+ export default useSessionStorageState;
@@ -1,4 +1,4 @@
1
- import { RequestStates } from '../../../constants';
1
+ import { quizSessionStateKey, RequestStates } from '../../../constants';
2
2
  import useOpenTextInputProps from '../../../hooks/usePropsGetters/useOpenTextInputProps';
3
3
  import useCoverQuestionProps from '../../../hooks/usePropsGetters/useCoverQuestionProps';
4
4
  import useSelectInputProps from '../../../hooks/usePropsGetters/useSelectInputProps';
@@ -67,7 +67,6 @@ export const getMockState = (question) => ({
67
67
  requestState: RequestStates.Success,
68
68
  versionId: '',
69
69
  sessionId: '',
70
- skipToResults: false,
71
70
  currentQuestion: {
72
71
  next_question: question,
73
72
  isFirstQuestion: false,
@@ -133,6 +132,11 @@ export const getMockState = (question) => ({
133
132
  },
134
133
  selectedOptionsWithAttributes: ['Chocolate', 'Medium'],
135
134
  },
135
+ quizSessionStorageState: {
136
+ key: quizSessionStateKey,
137
+ skipToResults: true,
138
+ hasSessionStorageState: () => true,
139
+ },
136
140
  });
137
141
  const mockElementProps = {
138
142
  className: '',
@@ -1,4 +1,4 @@
1
1
  import { ActionAnswerQuestion } from '../../components/CioQuiz/actions';
2
2
  import { QuizEventsReturn } from '../../types';
3
- declare const useHydrateQuizLocalState: (quizStateKey: string, dispatchLocalState: React.Dispatch<ActionAnswerQuestion>) => QuizEventsReturn.NextQuestion;
3
+ declare const useHydrateQuizLocalState: (quizSessionStorageStateKey: string, dispatchLocalState: React.Dispatch<ActionAnswerQuestion>) => QuizEventsReturn.NextQuestion;
4
4
  export default useHydrateQuizLocalState;
@@ -3,15 +3,13 @@ import ConstructorIOClient from '@constructor-io/constructorio-client-javascript
3
3
  import { ActionAnswerQuestion, ActionQuizAPI } from '../../components/CioQuiz/actions';
4
4
  import { QuizAPIReducerState } from '../../components/CioQuiz/quizApiReducer';
5
5
  import { QuizLocalReducerState } from '../../components/CioQuiz/quizLocalReducer';
6
- import { IQuizProps } from '../../types';
6
+ import { IQuizProps, QuizSessionStorageState } from '../../types';
7
7
  type UseQuizState = (quizOptions: IQuizProps, cioClient: ConstructorIOClient) => {
8
8
  quizApiState: QuizAPIReducerState;
9
9
  quizLocalState: QuizLocalReducerState;
10
10
  dispatchApiState: React.Dispatch<ActionQuizAPI>;
11
11
  dispatchLocalState: React.Dispatch<ActionAnswerQuestion>;
12
- hasQuizStoredState: () => boolean;
13
- skipToResults: boolean;
14
- quizStateKey: string;
12
+ quizSessionStorageState: QuizSessionStorageState;
15
13
  };
16
14
  declare const useQuizState: UseQuizState;
17
15
  export default useQuizState;
@@ -1,10 +1,6 @@
1
1
  import { ActionAnswerQuestion } from '../../components/CioQuiz/actions';
2
- import { SessionStateOptions } from '../../types';
3
- declare const useQuizLocalState: (sessionStateOptions?: SessionStateOptions) => {
2
+ declare const useQuizLocalState: () => {
4
3
  quizLocalState: import("../../components/CioQuiz/quizLocalReducer").QuizLocalReducerState;
5
- hasQuizStoredState: () => boolean;
6
4
  dispatchLocalState: (action: ActionAnswerQuestion) => void;
7
- skipToResults: boolean;
8
- quizStateKey: string;
9
5
  };
10
6
  export default useQuizLocalState;
@@ -0,0 +1,8 @@
1
+ import { SessionStateOptions } from '../../types';
2
+ import { QuizLocalReducerState } from '../../components/CioQuiz/quizLocalReducer';
3
+ declare const useSessionStorageState: (quizLocalState?: QuizLocalReducerState, sessionStateOptions?: SessionStateOptions, enableHydration?: boolean) => {
4
+ skipToResults: boolean;
5
+ quizSessionStorageStateKey: string;
6
+ hasSessionStorageState: () => boolean;
7
+ };
8
+ export default useSessionStorageState;
@@ -45,6 +45,7 @@ export interface IQuizProps {
45
45
  resultsPageOptions: ResultsPageOptions;
46
46
  sessionStateOptions?: SessionStateOptions;
47
47
  primaryColor?: string;
48
+ enableHydration?: boolean;
48
49
  callbacks?: Callbacks;
49
50
  }
50
51
  export interface QuizReturnState {
@@ -58,9 +59,9 @@ export interface QuizReturnState {
58
59
  sessionId?: string;
59
60
  currentQuestion?: CurrentQuestion | undefined;
60
61
  results?: QuizResultsResponse | undefined;
61
- skipToResults: boolean;
62
62
  selectedOptionsWithAttributes?: string[];
63
63
  };
64
+ quizSessionStorageState: QuizSessionStorageState;
64
65
  }
65
66
  export type AnswerInput = {
66
67
  type: InputQuestionsTypes;
@@ -69,6 +70,11 @@ export type AnswerInput = {
69
70
  export type AnswerInputState = {
70
71
  [key: string]: AnswerInput;
71
72
  };
73
+ export interface QuizSessionStorageState {
74
+ key: string;
75
+ skipToResults: boolean;
76
+ hasSessionStorageState: () => boolean;
77
+ }
72
78
  export type InputQuestionsTypes = QuestionTypes.OpenText | QuestionTypes.Cover | QuestionTypes.SingleSelect | QuestionTypes.MultipleSelect;
73
79
  export type CurrentQuestion = NextQuestionResponse & {
74
80
  isFirstQuestion: boolean;
@@ -87,7 +93,6 @@ export declare namespace QuizEventsReturn {
87
93
  type AddToCart = (e: React.MouseEvent<HTMLElement>, result: QuizResultDataPartial, price?: number) => void;
88
94
  type AddToFavorites = (e: React.MouseEvent<HTMLElement>, result: QuizResultDataPartial, price?: number, sendEvent?: boolean) => void;
89
95
  type HydrateQuiz = () => void;
90
- type HasSessionStorageState = () => boolean;
91
96
  type ResetSessionStorageState = () => void;
92
97
  }
93
98
  export interface QuizEventsReturn {
@@ -99,7 +104,6 @@ export interface QuizEventsReturn {
99
104
  addToCart: QuizEventsReturn.AddToCart;
100
105
  addToFavorites: QuizEventsReturn.AddToFavorites;
101
106
  hydrateQuiz: QuizEventsReturn.HydrateQuiz;
102
- hasSessionStorageState: QuizEventsReturn.HasSessionStorageState;
103
107
  resetSessionStorageState: QuizEventsReturn.ResetSessionStorageState;
104
108
  }
105
109
  export interface OpenTextInputProps {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-ui-quizzes",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "Constructor.io Quizzes UI library for web applications",
5
5
  "author": "constructor.io",
6
6
  "license": "MIT",