@coorpacademy/app-review 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/es/actions/api/fetch-rank.js +5 -1
  2. package/es/actions/ui/quit-popin.d.ts +8 -0
  3. package/es/actions/ui/quit-popin.js +8 -0
  4. package/es/index.d.ts +0 -1
  5. package/es/reducers/data/rank.d.ts +4 -3
  6. package/es/reducers/data/rank.js +9 -18
  7. package/es/reducers/index.d.ts +7 -1
  8. package/es/reducers/ui/index.d.ts +11 -1
  9. package/es/reducers/ui/index.js +5 -1
  10. package/es/reducers/ui/navigation.js +0 -1
  11. package/es/reducers/ui/positions.js +3 -1
  12. package/es/reducers/ui/quit-popin.d.ts +4 -0
  13. package/es/reducers/ui/quit-popin.js +16 -0
  14. package/es/reducers/ui/show-congrats.d.ts +5 -0
  15. package/es/reducers/ui/show-congrats.js +20 -0
  16. package/es/reducers/ui/slide.js +4 -1
  17. package/es/types/common.d.ts +10 -8
  18. package/es/views/slides/index.d.ts +67 -19
  19. package/es/views/slides/index.js +122 -6
  20. package/lib/actions/api/fetch-rank.js +7 -1
  21. package/lib/actions/ui/quit-popin.d.ts +8 -0
  22. package/lib/actions/ui/quit-popin.js +8 -0
  23. package/lib/index.d.ts +0 -1
  24. package/lib/reducers/data/rank.d.ts +4 -3
  25. package/lib/reducers/data/rank.js +9 -18
  26. package/lib/reducers/index.d.ts +7 -1
  27. package/lib/reducers/ui/index.d.ts +11 -1
  28. package/lib/reducers/ui/index.js +5 -1
  29. package/lib/reducers/ui/navigation.js +0 -1
  30. package/lib/reducers/ui/positions.js +3 -1
  31. package/lib/reducers/ui/quit-popin.d.ts +4 -0
  32. package/lib/reducers/ui/quit-popin.js +17 -0
  33. package/lib/reducers/ui/show-congrats.d.ts +5 -0
  34. package/lib/reducers/ui/show-congrats.js +21 -0
  35. package/lib/reducers/ui/slide.js +4 -1
  36. package/lib/types/common.d.ts +10 -8
  37. package/lib/views/slides/index.d.ts +67 -19
  38. package/lib/views/slides/index.js +124 -6
  39. package/package.json +3 -3
  40. package/src/actions/api/fetch-rank.ts +8 -1
  41. package/src/actions/api/test/fetch-correction.test.ts +4 -2
  42. package/src/actions/api/test/fetch-rank.test.ts +17 -8
  43. package/src/actions/api/test/fetch-skills.test.ts +4 -2
  44. package/src/actions/api/test/fetch-slide.test.ts +4 -2
  45. package/src/actions/api/test/post-answer.test.ts +9 -10
  46. package/src/actions/api/test/post-progression.test.ts +4 -2
  47. package/src/actions/data/test/token.test.ts +4 -2
  48. package/src/actions/ui/quit-popin.ts +10 -0
  49. package/src/actions/ui/test/answers.test.ts +4 -2
  50. package/src/actions/ui/test/next-slide.test.ts +5 -2
  51. package/src/actions/ui/test/quit-popin.test.ts +39 -0
  52. package/src/actions/ui/test/slides.test.ts +4 -2
  53. package/src/reducers/data/rank.ts +15 -31
  54. package/src/reducers/data/test/rank.test.ts +33 -52
  55. package/src/reducers/ui/index.ts +7 -1
  56. package/src/reducers/ui/navigation.ts +0 -2
  57. package/src/reducers/ui/positions.ts +3 -1
  58. package/src/reducers/ui/quit-popin.ts +22 -0
  59. package/src/reducers/ui/show-congrats.ts +26 -0
  60. package/src/reducers/ui/slide.ts +4 -2
  61. package/src/reducers/ui/test/positions.test.ts +14 -0
  62. package/src/reducers/ui/test/quit-popin.test.ts +24 -0
  63. package/src/reducers/ui/test/show-congrats.test.ts +40 -0
  64. package/src/reducers/ui/test/slide.test.ts +21 -0
  65. package/src/types/common.ts +12 -8
  66. package/src/views/skills/test/skills.test.ts +8 -4
  67. package/src/views/slides/index.ts +207 -27
  68. package/src/views/slides/test/header.on-click.test.ts +46 -0
  69. package/src/views/slides/test/index.test.ts +335 -25
  70. package/src/views/slides/test/on-quit-popin.on-click.test.ts +65 -0
  71. package/src/views/slides/test/slide.free-text.on-change.test.ts +4 -2
  72. package/src/views/slides/test/slide.next-slide.on-click.test.ts +107 -2
  73. package/src/views/slides/test/slide.qcm-drag.on-click.test.ts +4 -2
  74. package/src/views/slides/test/slide.qcm-graphic.on-click.test.ts +4 -2
  75. package/src/views/slides/test/slide.qcm.on-click.test.ts +4 -2
  76. package/src/views/slides/test/slide.slider.on-change.test.ts +4 -2
  77. package/src/views/slides/test/slide.slider.on-slider-change.test.ts +4 -2
  78. package/src/views/slides/test/slide.template.on-change.test.ts +4 -2
@@ -1,35 +1,26 @@
1
- import { get, isNull, isUndefined, pipe, set, unset, update } from 'lodash/fp';
2
- import { RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_START_FAILURE, RANK_FETCH_END_REQUEST, RANK_FETCH_END_SUCCESS, RANK_FETCH_END_FAILURE } from '../../actions/api/fetch-rank';
3
- var initialState = {};
1
+ import set from 'lodash/fp/set';
2
+ import { POST_PROGRESSION_SUCCESS } from '../../actions/api/post-progression';
3
+ import { RANK_FETCH_START_SUCCESS, RANK_FETCH_END_SUCCESS } from '../../actions/api/fetch-rank';
4
+ var initialState = {
5
+ start: Number.NaN,
6
+ end: Number.NaN
7
+ };
4
8
  var reducer = function (
5
9
  // eslint-disable-next-line default-param-last
6
10
  state, action) {
7
11
  if (state === void 0) { state = initialState; }
8
12
  switch (action.type) {
9
- case RANK_FETCH_START_REQUEST: {
10
- return update('start', function (startRank) { return (isUndefined(startRank) ? null : startRank); }, state);
13
+ case POST_PROGRESSION_SUCCESS: {
14
+ return initialState;
11
15
  }
12
16
  case RANK_FETCH_START_SUCCESS: {
13
17
  var payload = action.payload;
14
18
  return set('start', payload.rank, state);
15
19
  }
16
- case RANK_FETCH_START_FAILURE: {
17
- if (pipe(get('start'), isNull)(state))
18
- return unset('start', state);
19
- return state;
20
- }
21
- case RANK_FETCH_END_REQUEST: {
22
- return update('end', function (endRank) { return (isUndefined(endRank) ? null : endRank); }, state);
23
- }
24
20
  case RANK_FETCH_END_SUCCESS: {
25
21
  var payload = action.payload;
26
22
  return set('end', payload.rank, state);
27
23
  }
28
- case RANK_FETCH_END_FAILURE: {
29
- if (pipe(get('end'), isNull)(state))
30
- return unset('end', state);
31
- return state;
32
- }
33
24
  default:
34
25
  return state;
35
26
  }
@@ -19,6 +19,12 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
19
19
  answers: import("./ui/answers").UIAnswerState;
20
20
  slide: import("./ui/slide").UISlideState;
21
21
  positions: import("./ui/positions").UIPositionState;
22
+ showQuitPopin: boolean;
23
+ showCongrats: boolean;
22
24
  }>;
23
- }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlideAction | import("../actions/api/fetch-rank").RankAction | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/next-slide").NextSlideAction | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction>;
25
+ }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlideAction | import("../actions/api/fetch-rank").RankAction | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/next-slide").NextSlideAction | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction | {
26
+ type: "@@ui/OPEN_POPIN";
27
+ } | {
28
+ type: "@@ui/CLOSE_POPIN";
29
+ }>;
24
30
  export default _default;
@@ -3,12 +3,16 @@ import { NavigationState } from './navigation';
3
3
  import { UIAnswerState } from './answers';
4
4
  import { UIPositionState } from './positions';
5
5
  import { UISlideState } from './slide';
6
+ import { type ShowQuitPopinState } from './quit-popin';
7
+ import { UIShowCongratsState } from './show-congrats';
6
8
  export declare type UIState = {
7
9
  currentSlideRef: CurrentSlideRefState;
8
10
  navigation: NavigationState;
9
11
  answers: UIAnswerState;
10
12
  slide: UISlideState;
11
13
  positions: UIPositionState;
14
+ showQuitPopin: ShowQuitPopinState;
15
+ showCongrats: UIShowCongratsState;
12
16
  };
13
17
  declare const _default: import("redux").Reducer<import("redux").CombinedState<{
14
18
  currentSlideRef: string;
@@ -16,5 +20,11 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
16
20
  answers: UIAnswerState;
17
21
  slide: UISlideState;
18
22
  positions: UIPositionState;
19
- }>, import("../../actions/api/fetch-correction").ReceivedCorrection | import("../../actions/ui/slides").SetCurrentSlideAction | import("../../actions/api/fetch-slide").FetchSlide | import("../../actions/api/post-answer").PostAnswerRequestAction | import("../../actions/api/post-progression").ReceivedProgression | import("../../actions/ui/next-slide").NextSlideAction | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/answers").EditAnswerAction>;
23
+ showQuitPopin: boolean;
24
+ showCongrats: boolean;
25
+ }>, import("../../actions/api/fetch-correction").ReceivedCorrection | import("../../actions/ui/slides").SetCurrentSlideAction | import("../../actions/api/fetch-slide").FetchSlide | import("../../actions/api/post-answer").PostAnswerRequestAction | import("../../actions/api/post-progression").ReceivedProgression | import("../../actions/ui/next-slide").NextSlideAction | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/answers").EditAnswerAction | {
26
+ type: "@@ui/OPEN_POPIN";
27
+ } | {
28
+ type: "@@ui/CLOSE_POPIN";
29
+ }>;
20
30
  export default _default;
@@ -4,10 +4,14 @@ import navigation from './navigation';
4
4
  import answers from './answers';
5
5
  import positions from './positions';
6
6
  import slide from './slide';
7
+ import showQuitPopin from './quit-popin';
8
+ import showCongrats from './show-congrats';
7
9
  export default combineReducers({
8
10
  currentSlideRef: currentSlideRef,
9
11
  navigation: navigation,
10
12
  answers: answers,
11
13
  slide: slide,
12
- positions: positions
14
+ positions: positions,
15
+ showQuitPopin: showQuitPopin,
16
+ showCongrats: showCongrats
13
17
  });
@@ -25,5 +25,4 @@ state, action) {
25
25
  return state;
26
26
  }
27
27
  };
28
- // -----------------------------------------------------------------------------
29
28
  export default reducer;
@@ -13,7 +13,9 @@ state, action) {
13
13
  return initialState;
14
14
  }
15
15
  case NEXT_SLIDE: {
16
- var _a = action.payload, totalCorrectAnswers = _a.totalCorrectAnswers, answeredSlides = _a.answeredSlides, currentSlideRef_1 = _a.currentSlideRef, animationType = _a.animationType;
16
+ var _a = action.payload, totalCorrectAnswers = _a.totalCorrectAnswers, answeredSlides = _a.answeredSlides, currentSlideRef_1 = _a.currentSlideRef, animationType = _a.animationType, nextSlideRef = _a.nextSlideRef;
17
+ if (nextSlideRef === 'successExitNode')
18
+ return state;
17
19
  var nextCurrentSlidePosition = animationType === 'unstack' ? -1 : 4 - totalCorrectAnswers;
18
20
  var currentSlideIndex = findIndex(function (ref) { return ref === currentSlideRef_1; }, answeredSlides);
19
21
  var newState = map(function (position) { return (position === -1 ? position : position - 1); }, state);
@@ -0,0 +1,4 @@
1
+ import { closeQuitPopin, openQuitPopin } from '../../actions/ui/quit-popin';
2
+ export declare type ShowQuitPopinState = boolean;
3
+ declare const reducer: (state: boolean | undefined, action: typeof openQuitPopin | typeof closeQuitPopin) => ShowQuitPopinState;
4
+ export default reducer;
@@ -0,0 +1,17 @@
1
+ import { CLOSE_POPIN, OPEN_POPIN } from '../../actions/ui/quit-popin';
2
+ var reducer = function (
3
+ // eslint-disable-next-line default-param-last
4
+ state, action) {
5
+ if (state === void 0) { state = false; }
6
+ switch (action.type) {
7
+ case OPEN_POPIN: {
8
+ return true;
9
+ }
10
+ case CLOSE_POPIN: {
11
+ return false;
12
+ }
13
+ default:
14
+ return state;
15
+ }
16
+ };
17
+ export default reducer;
@@ -0,0 +1,5 @@
1
+ import { NextSlideAction } from '../../actions/ui/next-slide';
2
+ import { ReceivedProgression } from '../../actions/api/post-progression';
3
+ export declare type UIShowCongratsState = boolean;
4
+ declare const reducer: (state: boolean | undefined, action: NextSlideAction | ReceivedProgression) => UIShowCongratsState;
5
+ export default reducer;
@@ -0,0 +1,21 @@
1
+ import { NEXT_SLIDE } from '../../actions/ui/next-slide';
2
+ import { POST_PROGRESSION_SUCCESS } from '../../actions/api/post-progression';
3
+ var reducer = function (
4
+ // eslint-disable-next-line default-param-last
5
+ state, action) {
6
+ if (state === void 0) { state = false; }
7
+ switch (action.type) {
8
+ case POST_PROGRESSION_SUCCESS: {
9
+ return false;
10
+ }
11
+ case NEXT_SLIDE: {
12
+ var nextSlideRef = action.payload.nextSlideRef;
13
+ if (nextSlideRef === 'successExitNode')
14
+ return true;
15
+ return false;
16
+ }
17
+ default:
18
+ return state;
19
+ }
20
+ };
21
+ export default reducer;
@@ -36,7 +36,10 @@ state, action) {
36
36
  return pipe(set([action.meta.slideRef, 'animateCorrectionPopin'], true), set([action.meta.slideRef, 'showCorrectionPopin'], true))(state);
37
37
  }
38
38
  case NEXT_SLIDE: {
39
- return pipe(set([action.payload.currentSlideRef, 'animateCorrectionPopin'], false), set([action.payload.currentSlideRef, 'animationType'], action.payload.animationType))(state);
39
+ var _a = action.payload, currentSlideRef = _a.currentSlideRef, nextSlideRef = _a.nextSlideRef;
40
+ if (nextSlideRef === 'successExitNode')
41
+ return state;
42
+ return pipe(set([currentSlideRef, 'animateCorrectionPopin'], false), set([currentSlideRef, 'animationType'], action.payload.animationType))(state);
40
43
  }
41
44
  default:
42
45
  return state;
@@ -77,17 +77,19 @@ export declare type ProgressionAnswerItem = {
77
77
  slideRef: string;
78
78
  answer: string[];
79
79
  };
80
+ export declare type SlideContent = {
81
+ type: 'slide';
82
+ ref: string;
83
+ };
84
+ export declare type SuccessNodeContent = {
85
+ type: 'success';
86
+ ref: 'successExitNode';
87
+ };
80
88
  export declare type ProgressionState = {
81
89
  allAnswers: ProgressionAnswerItem[];
82
- content?: {
83
- ref: string;
84
- type: string;
85
- };
90
+ content?: SlideContent;
86
91
  isCorrect: boolean;
87
- nextContent: {
88
- type: 'success' | 'slide';
89
- ref: 'successExitNode' | string;
90
- };
92
+ nextContent: SlideContent | SuccessNodeContent;
91
93
  pendingSlides: string[];
92
94
  slides: string[];
93
95
  step: {
@@ -40,6 +40,15 @@ declare type CorrectionPopinNext = {
40
40
  ariaLabel: string;
41
41
  onClick: Function;
42
42
  };
43
+ declare type QuitPopinButton = {
44
+ label: string;
45
+ type: string;
46
+ customStyle?: {
47
+ color: string;
48
+ };
49
+ handleOnclick: Function;
50
+ ariaLabel: string;
51
+ };
43
52
  export declare type CorrectionPopinProps = {
44
53
  klf?: CorrectionPopinKlf;
45
54
  information: CorrectionPopinInformation;
@@ -47,6 +56,14 @@ export declare type CorrectionPopinProps = {
47
56
  resultLabel: string;
48
57
  type: 'right' | 'wrong';
49
58
  };
59
+ export declare type QuitPopinProps = {
60
+ content: string;
61
+ icon: string;
62
+ mode: string;
63
+ descriptionText: string;
64
+ firstButton: QuitPopinButton;
65
+ secondButton: QuitPopinButton;
66
+ };
50
67
  export declare type SlidesViewProps = {
51
68
  header: {
52
69
  mode: string;
@@ -67,25 +84,56 @@ export declare type SlidesViewProps = {
67
84
  endReview: boolean;
68
85
  };
69
86
  reviewBackgroundAriaLabel?: string;
70
- congrats?: {
71
- 'aria-label'?: string;
72
- 'data-name'?: string;
73
- animationLottie: unknown;
74
- title: string;
75
- cardCongratsStar: unknown;
76
- cardCongratsRank: unknown;
77
- buttonRevising: {
78
- 'aria-label'?: string;
79
- label: string;
80
- onClick: Function;
81
- type: string;
82
- };
83
- buttonRevisingSkill: {
84
- 'aria-label'?: string;
85
- label: string;
86
- onClick: Function;
87
- type: string;
88
- };
87
+ congrats?: CongratsProps;
88
+ quitPopin?: QuitPopinProps;
89
+ };
90
+ declare type LottieAnimationProps = {
91
+ 'aria-label': string;
92
+ 'data-name'?: string;
93
+ animationSrc: string;
94
+ loop?: boolean;
95
+ rendererSettings?: {
96
+ hideOnTransparent?: boolean;
97
+ className?: string;
98
+ };
99
+ height?: number;
100
+ width?: number;
101
+ className?: number;
102
+ ie11ImageBackup: string;
103
+ backupImageClassName?: string;
104
+ autoplay?: boolean;
105
+ animationControl?: 'play' | 'pause' | 'stop' | 'loading';
106
+ };
107
+ export declare type CongratsCardProps = {
108
+ 'aria-label': string;
109
+ 'data-name': string;
110
+ animationLottie: LottieAnimationProps;
111
+ iconAriaLabel: string;
112
+ className?: string;
113
+ cardType: string;
114
+ reviewCardTitle: string;
115
+ reviewCardValue: string;
116
+ rankSuffix?: string;
117
+ timerAnimation: number;
118
+ };
119
+ export declare type CongratsProps = {
120
+ 'aria-label': string;
121
+ 'data-name': 'review-congrats';
122
+ animationLottie: LottieAnimationProps;
123
+ title: string;
124
+ cardCongratsStar: CongratsCardProps;
125
+ cardCongratsRank?: CongratsCardProps;
126
+ buttonRevising?: {
127
+ 'aria-label': string;
128
+ label: string;
129
+ onClick: Function;
130
+ type: string;
131
+ };
132
+ buttonRevisingSkill?: {
133
+ label: string;
134
+ 'aria-label': string;
135
+ onClick: Function;
136
+ type: string;
89
137
  };
90
138
  };
91
139
  export declare const initialState: SlidesStack;
@@ -17,6 +17,7 @@ import reduce from 'lodash/fp/reduce';
17
17
  import set from 'lodash/fp/set';
18
18
  import toInteger from 'lodash/fp/toInteger';
19
19
  import join from 'lodash/fp/join';
20
+ import { closeQuitPopin, openQuitPopin } from '../../actions/ui/quit-popin';
20
21
  import { getProgressionSlidesRefs } from '../../common';
21
22
  import { postAnswer } from '../../actions/api/post-answer';
22
23
  import { nextSlide } from '../../actions/ui/next-slide';
@@ -26,7 +27,18 @@ var ICON_VALUES = {
26
27
  wrong: 'wrong',
27
28
  'no-answer': 'no-answer'
28
29
  };
29
- // TODO replace this, position no more needed
30
+ var confettiAnimation = {
31
+ 'aria-label': 'aria lottie',
32
+ 'data-name': 'default-lottie',
33
+ className: undefined,
34
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/confetti.json',
35
+ loop: undefined,
36
+ autoplay: true,
37
+ rendererSettings: {
38
+ hideOnTransparent: false
39
+ },
40
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/conffeti_congrats.svg'
41
+ };
30
42
  export var initialState = {
31
43
  '0': {
32
44
  position: 0,
@@ -49,8 +61,17 @@ export var initialState = {
49
61
  loading: true
50
62
  }
51
63
  };
64
+ var getCurrentSlideRef = function (state) {
65
+ var currentSlideRef = get(['ui', 'currentSlideRef'], state);
66
+ var endReview = currentSlideRef === 'successExitNode';
67
+ if (!endReview)
68
+ return currentSlideRef;
69
+ var progression = state.data.progression;
70
+ var content = progression.state.content;
71
+ return content.ref;
72
+ };
52
73
  var buildStackSlides = function (state, dispatch) {
53
- var currentSlideRef = state.ui.currentSlideRef;
74
+ var currentSlideRef = getCurrentSlideRef(state);
54
75
  var progression = state.data.progression;
55
76
  if (!currentSlideRef || !progression)
56
77
  return initialState;
@@ -164,16 +185,112 @@ var getCorrectionPopinProps = function (dispatch) {
164
185
  };
165
186
  };
166
187
  };
188
+ var buildQuitPopinProps = function (dispatch) {
189
+ return function (onQuitClick) {
190
+ return {
191
+ content: "Tu t'en vas d\u00E9j\u00E0 ?",
192
+ icon: "MoonRocket",
193
+ mode: 'alert',
194
+ descriptionText: "Tu vas t'en sortir ! Si tu arr\u00EAtes maintenant, tu vas perdre ta progression.",
195
+ firstButton: {
196
+ label: 'Arrêter ma session',
197
+ type: 'tertiary',
198
+ customStyle: {
199
+ color: '#ED3436'
200
+ },
201
+ handleOnclick: onQuitClick,
202
+ ariaLabel: 'Stop session'
203
+ },
204
+ secondButton: {
205
+ label: "Continuer d'apprendre",
206
+ type: 'primary',
207
+ handleOnclick: function () {
208
+ dispatch(closeQuitPopin);
209
+ },
210
+ ariaLabel: 'Continue review'
211
+ }
212
+ };
213
+ };
214
+ };
215
+ var buildRankCard = function (rank) {
216
+ return {
217
+ 'aria-label': 'Review Card Congrats Container',
218
+ 'data-name': 'card-rank',
219
+ animationLottie: {
220
+ 'aria-label': 'aria lottie',
221
+ 'data-name': 'default-lottie',
222
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/rank.json',
223
+ loop: true,
224
+ autoplay: true,
225
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/rank_icon_congrats.svg'
226
+ },
227
+ cardType: 'card-rank',
228
+ iconAriaLabel: 'Image without information',
229
+ className: undefined,
230
+ reviewCardTitle: 'You are now',
231
+ reviewCardValue: "".concat(rank),
232
+ rankSuffix: 'th',
233
+ timerAnimation: 200
234
+ };
235
+ };
236
+ var buildCongratsProps = function (state) {
237
+ if (!state.ui.showCongrats)
238
+ return;
239
+ var progression = state.data.progression;
240
+ var stars = progression.state.stars;
241
+ var cardCongratsStar = {
242
+ 'aria-label': 'Review Card Congrats Container',
243
+ 'data-name': 'card-star',
244
+ animationLottie: {
245
+ 'aria-label': 'aria lottie',
246
+ 'data-name': 'default-lottie',
247
+ className: undefined,
248
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/star.json',
249
+ loop: false,
250
+ autoplay: undefined,
251
+ rendererSettings: {
252
+ hideOnTransparent: false
253
+ },
254
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/stars_icon_congrats.svg'
255
+ },
256
+ iconAriaLabel: 'Image without information',
257
+ className: undefined,
258
+ cardType: 'card-star',
259
+ reviewCardTitle: 'You have won',
260
+ reviewCardValue: "".concat(stars),
261
+ timerAnimation: 200
262
+ };
263
+ var _a = state.data.rank, start = _a.start, end = _a.end;
264
+ var newRank = start - end;
265
+ var cardCongratsRank = !Number.isNaN(newRank) && newRank > 0 ? buildRankCard(end) : undefined;
266
+ return {
267
+ 'aria-label': 'Review Congratulations',
268
+ 'data-name': 'review-congrats',
269
+ animationLottie: confettiAnimation,
270
+ title: 'Congratulations!',
271
+ cardCongratsStar: cardCongratsStar,
272
+ cardCongratsRank: cardCongratsRank,
273
+ buttonRevising: undefined,
274
+ buttonRevisingSkill: undefined // TODO make boutons and actions
275
+ };
276
+ };
277
+ var isEndOfProgression = function (progression) {
278
+ if (!progression)
279
+ return false;
280
+ return progression.state.nextContent.ref === 'successExitNode';
281
+ };
167
282
  export var mapStateToSlidesProps = function (state, dispatch, onQuitClick) {
168
- var currentSlideRef = get(['ui', 'currentSlideRef'], state);
283
+ var currentSlideRef = getCurrentSlideRef(state);
284
+ var endReview = isEndOfProgression(state.data.progression);
169
285
  var correction = get(['data', 'corrections', currentSlideRef], state);
170
286
  var isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
171
287
  var klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
288
+ var showQuitPopin = get(['ui', 'showQuitPopin'], state);
172
289
  return {
173
290
  header: {
174
291
  mode: '__revision_mode',
175
292
  skillName: '__agility',
176
- onQuitClick: onQuitClick,
293
+ onQuitClick: function () { return dispatch(openQuitPopin); },
177
294
  'aria-label': 'aria-header-wrapper',
178
295
  closeButtonAriaLabel: 'aria-close-button',
179
296
  steps: buildStepItems(state)
@@ -188,8 +305,9 @@ export var mapStateToSlidesProps = function (state, dispatch, onQuitClick) {
188
305
  }
189
306
  },
190
307
  correctionPopinProps: correction && getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf),
191
- endReview: false
308
+ endReview: endReview && state.ui.showCongrats
192
309
  },
193
- congrats: undefined
310
+ congrats: buildCongratsProps(state),
311
+ quitPopin: showQuitPopin ? buildQuitPopinProps(dispatch)(onQuitClick) : undefined
194
312
  };
195
313
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coorpacademy/app-review",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=16.15.0"
@@ -42,7 +42,7 @@
42
42
  "./package.json": "./package.json"
43
43
  },
44
44
  "dependencies": {
45
- "@coorpacademy/components": "10.24.2",
45
+ "@coorpacademy/components": "10.24.3",
46
46
  "@coorpacademy/redux-task": "1.1.6",
47
47
  "cross-fetch": "^3.1.5",
48
48
  "jwt-decode": "^3.1.2",
@@ -77,5 +77,5 @@
77
77
  "webpack-cli": "^4.10.0",
78
78
  "webpack-dev-server": "^4.11.1"
79
79
  },
80
- "gitHead": "90d579426a1435f4eb29884b34623ec4adbb4d70"
80
+ "gitHead": "9e64ba973f7219fca6b39876f2e64d423356c721"
81
81
  }
@@ -37,6 +37,13 @@ export type RankAction = RankRequestAction | RankSuccessAction | RankFailureActi
37
37
  type RankStart = [RankFetchStartRequestType, RankFetchStartSuccessType, RankFetchStartFailureType];
38
38
  type RankEnd = [RankFetchEndRequestType, RankFetchEndSuccessType, RankFetchEndFailureType];
39
39
 
40
+ const bailout =
41
+ (path: string) =>
42
+ (state: StoreState): boolean => {
43
+ const value = get(path, state);
44
+ return !Number.isNaN(value);
45
+ };
46
+
40
47
  export const fetchRank = (
41
48
  dispatch: Dispatch,
42
49
  getState: () => StoreState,
@@ -51,7 +58,7 @@ export const fetchRank = (
51
58
  const token = get(['data', 'token'], state);
52
59
  return services.fetchRank(token);
53
60
  },
54
- bailout: path ? (state: StoreState): boolean => !!get(path, state) : undefined
61
+ bailout: path ? bailout(path) : undefined
55
62
  });
56
63
 
57
64
  return dispatch(action);
@@ -30,9 +30,10 @@ const initialState: StoreState = {
30
30
  skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
31
31
  token: '1234',
32
32
  corrections: {},
33
- rank: {}
33
+ rank: {start: 10, end: Number.NaN}
34
34
  },
35
35
  ui: {
36
+ showCongrats: false,
36
37
  currentSlideRef: freeTextSlide._id,
37
38
  navigation: ['skills', 'slides'],
38
39
  answers: {[freeTextSlide.universalRef]: answer},
@@ -43,7 +44,8 @@ const initialState: StoreState = {
43
44
  animateCorrectionPopin: false,
44
45
  showCorrectionPopin: false
45
46
  }
46
- }
47
+ },
48
+ showQuitPopin: false
47
49
  }
48
50
  };
49
51
 
@@ -1,4 +1,5 @@
1
1
  import test from 'ava';
2
+ import set from 'lodash/fp/set';
2
3
  import type {Services} from '../../../types/common';
3
4
  import type {StoreState} from '../../../reducers';
4
5
  import {
@@ -21,19 +22,21 @@ const initialState: StoreState = {
21
22
  skills: [],
22
23
  token: '1234',
23
24
  corrections: {},
24
- rank: {}
25
+ rank: {start: Number.NaN, end: Number.NaN}
25
26
  },
26
27
  ui: {
28
+ showCongrats: false,
27
29
  positions: [0, 1, 2, 3, 4],
28
30
  currentSlideRef: '',
29
31
  navigation: [],
30
32
  answers: {},
31
- slide: {}
33
+ slide: {},
34
+ showQuitPopin: false
32
35
  }
33
36
  };
34
37
 
35
38
  test('should dispatch FETCH_START_SUCCESS action when fetchStartRank returns the start rank', async t => {
36
- t.plan(3);
39
+ t.plan(4);
37
40
 
38
41
  const services: Services = {
39
42
  ...mockedServices,
@@ -50,8 +53,11 @@ test('should dispatch FETCH_START_SUCCESS action when fetchStartRank returns the
50
53
  }
51
54
  ];
52
55
 
53
- const {dispatch} = createTestStore(t, initialState, services, expectedActions);
56
+ const {dispatch, getState} = createTestStore(t, initialState, services, expectedActions);
54
57
  await dispatch(fetchStartRank);
58
+
59
+ const newState = getState();
60
+ t.deepEqual(newState.data.rank, {start: 93, end: Number.NaN});
55
61
  });
56
62
 
57
63
  test('should dispatch FETCH_START_FAILURE action when fetchStartRank fails', async t => {
@@ -80,13 +86,13 @@ test('should dispatch FETCH_START_FAILURE action when fetchStartRank fails', asy
80
86
  });
81
87
 
82
88
  test('should dispatch FETCH_END_SUCCESS action when fetchEndRank returns the end rank', async t => {
83
- t.plan(3);
89
+ t.plan(4);
84
90
 
85
91
  const services: Services = {
86
92
  ...mockedServices,
87
93
  fetchRank: token => {
88
94
  t.is(token, '1234');
89
- return Promise.resolve({rank: 93});
95
+ return Promise.resolve({rank: 90});
90
96
  }
91
97
  };
92
98
 
@@ -94,13 +100,16 @@ test('should dispatch FETCH_END_SUCCESS action when fetchEndRank returns the end
94
100
  {type: RANK_FETCH_END_REQUEST},
95
101
  {
96
102
  type: RANK_FETCH_END_SUCCESS,
97
- payload: {rank: 93}
103
+ payload: {rank: 90}
98
104
  }
99
105
  ];
100
106
 
101
- const {dispatch} = createTestStore(t, initialState, services, expectedActions);
107
+ const _initialState = set('data.rank.start', 93, initialState);
108
+ const {dispatch, getState} = createTestStore(t, _initialState, services, expectedActions);
102
109
 
103
110
  await dispatch(fetchEndRank);
111
+ const newState = getState();
112
+ t.deepEqual(newState.data.rank, {start: 93, end: 90});
104
113
  });
105
114
 
106
115
  test('should dispatch FETCH_END_FAILURE action when fetchEndRank fails', async t => {