@coorpacademy/app-review 0.5.4-alpha.8 → 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.
@@ -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: {
@@ -84,28 +84,58 @@ export declare type SlidesViewProps = {
84
84
  endReview: boolean;
85
85
  };
86
86
  reviewBackgroundAriaLabel?: string;
87
- congrats?: {
88
- 'aria-label'?: string;
89
- 'data-name'?: string;
90
- animationLottie: unknown;
91
- title: string;
92
- cardCongratsStar: unknown;
93
- cardCongratsRank: unknown;
94
- buttonRevising: {
95
- 'aria-label'?: string;
96
- label: string;
97
- onClick: Function;
98
- type: string;
99
- };
100
- buttonRevisingSkill: {
101
- 'aria-label'?: string;
102
- label: string;
103
- onClick: Function;
104
- type: string;
105
- };
106
- };
87
+ congrats?: CongratsProps;
107
88
  quitPopin?: QuitPopinProps;
108
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;
137
+ };
138
+ };
109
139
  export declare const initialState: SlidesStack;
110
140
  export declare const buildStepItems: (state: StoreState) => StepItem[];
111
141
  export declare const mapStateToSlidesProps: (state: StoreState, dispatch: Dispatch, onQuitClick: Function) => SlidesViewProps;
@@ -16,7 +16,18 @@ const ICON_VALUES = {
16
16
  wrong: 'wrong',
17
17
  'no-answer': 'no-answer'
18
18
  };
19
- // TODO replace this, position no more needed
19
+ const confettiAnimation = {
20
+ 'aria-label': 'aria lottie',
21
+ 'data-name': 'default-lottie',
22
+ className: undefined,
23
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/confetti.json',
24
+ loop: undefined,
25
+ autoplay: true,
26
+ rendererSettings: {
27
+ hideOnTransparent: false
28
+ },
29
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/conffeti_congrats.svg'
30
+ };
20
31
  export const initialState = {
21
32
  '0': {
22
33
  position: 0,
@@ -39,8 +50,17 @@ export const initialState = {
39
50
  loading: true
40
51
  }
41
52
  };
53
+ const getCurrentSlideRef = (state) => {
54
+ const currentSlideRef = get(['ui', 'currentSlideRef'], state);
55
+ const endReview = currentSlideRef === 'successExitNode';
56
+ if (!endReview)
57
+ return currentSlideRef;
58
+ const progression = state.data.progression;
59
+ const content = progression.state.content;
60
+ return content.ref;
61
+ };
42
62
  const buildStackSlides = (state, dispatch) => {
43
- const currentSlideRef = state.ui.currentSlideRef;
63
+ const currentSlideRef = getCurrentSlideRef(state);
44
64
  const progression = state.data.progression;
45
65
  if (!currentSlideRef || !progression)
46
66
  return initialState;
@@ -194,8 +214,76 @@ const buildQuitPopinProps = (dispatch) => (onQuitClick) => {
194
214
  }
195
215
  };
196
216
  };
217
+ const buildRankCard = (rank) => {
218
+ return {
219
+ 'aria-label': 'Review Card Congrats Container',
220
+ 'data-name': 'card-rank',
221
+ animationLottie: {
222
+ 'aria-label': 'aria lottie',
223
+ 'data-name': 'default-lottie',
224
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/rank.json',
225
+ loop: true,
226
+ autoplay: true,
227
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/rank_icon_congrats.svg'
228
+ },
229
+ cardType: 'card-rank',
230
+ iconAriaLabel: 'Image without information',
231
+ className: undefined,
232
+ reviewCardTitle: 'You are now',
233
+ reviewCardValue: `${rank}`,
234
+ rankSuffix: 'th',
235
+ timerAnimation: 200
236
+ };
237
+ };
238
+ const buildCongratsProps = (state) => {
239
+ if (!state.ui.showCongrats)
240
+ return;
241
+ const progression = state.data.progression;
242
+ const stars = progression.state.stars;
243
+ const cardCongratsStar = {
244
+ 'aria-label': 'Review Card Congrats Container',
245
+ 'data-name': 'card-star',
246
+ animationLottie: {
247
+ 'aria-label': 'aria lottie',
248
+ 'data-name': 'default-lottie',
249
+ className: undefined,
250
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/star.json',
251
+ loop: false,
252
+ autoplay: undefined,
253
+ rendererSettings: {
254
+ hideOnTransparent: false
255
+ },
256
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/stars_icon_congrats.svg'
257
+ },
258
+ iconAriaLabel: 'Image without information',
259
+ className: undefined,
260
+ cardType: 'card-star',
261
+ reviewCardTitle: 'You have won',
262
+ reviewCardValue: `${stars}`,
263
+ timerAnimation: 200
264
+ };
265
+ const { start, end } = state.data.rank;
266
+ const newRank = start - end;
267
+ const cardCongratsRank = !Number.isNaN(newRank) && newRank > 0 ? buildRankCard(end) : undefined;
268
+ return {
269
+ 'aria-label': 'Review Congratulations',
270
+ 'data-name': 'review-congrats',
271
+ animationLottie: confettiAnimation,
272
+ title: 'Congratulations!',
273
+ cardCongratsStar,
274
+ cardCongratsRank,
275
+ buttonRevising: undefined,
276
+ buttonRevisingSkill: undefined // TODO make boutons and actions
277
+ };
278
+ };
279
+ const isEndOfProgression = (progression) => {
280
+ if (!progression)
281
+ return false;
282
+ return progression.state.nextContent.ref === 'successExitNode';
283
+ };
197
284
  export const mapStateToSlidesProps = (state, dispatch, onQuitClick) => {
198
- const currentSlideRef = get(['ui', 'currentSlideRef'], state);
285
+ const currentSlideRef = getCurrentSlideRef(state);
286
+ const endReview = isEndOfProgression(state.data.progression);
199
287
  const correction = get(['data', 'corrections', currentSlideRef], state);
200
288
  const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
201
289
  const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
@@ -219,9 +307,9 @@ export const mapStateToSlidesProps = (state, dispatch, onQuitClick) => {
219
307
  }
220
308
  },
221
309
  correctionPopinProps: correction && getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf),
222
- endReview: false
310
+ endReview: endReview && state.ui.showCongrats
223
311
  },
224
- congrats: undefined,
312
+ congrats: buildCongratsProps(state),
225
313
  quitPopin: showQuitPopin ? buildQuitPopinProps(dispatch)(onQuitClick) : undefined
226
314
  };
227
315
  };
@@ -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: {
@@ -84,28 +84,58 @@ export declare type SlidesViewProps = {
84
84
  endReview: boolean;
85
85
  };
86
86
  reviewBackgroundAriaLabel?: string;
87
- congrats?: {
88
- 'aria-label'?: string;
89
- 'data-name'?: string;
90
- animationLottie: unknown;
91
- title: string;
92
- cardCongratsStar: unknown;
93
- cardCongratsRank: unknown;
94
- buttonRevising: {
95
- 'aria-label'?: string;
96
- label: string;
97
- onClick: Function;
98
- type: string;
99
- };
100
- buttonRevisingSkill: {
101
- 'aria-label'?: string;
102
- label: string;
103
- onClick: Function;
104
- type: string;
105
- };
106
- };
87
+ congrats?: CongratsProps;
107
88
  quitPopin?: QuitPopinProps;
108
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;
137
+ };
138
+ };
109
139
  export declare const initialState: SlidesStack;
110
140
  export declare const buildStepItems: (state: StoreState) => StepItem[];
111
141
  export declare const mapStateToSlidesProps: (state: StoreState, dispatch: Dispatch, onQuitClick: Function) => SlidesViewProps;
@@ -27,7 +27,18 @@ var ICON_VALUES = {
27
27
  wrong: 'wrong',
28
28
  'no-answer': 'no-answer'
29
29
  };
30
- // 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
+ };
31
42
  export var initialState = {
32
43
  '0': {
33
44
  position: 0,
@@ -50,8 +61,17 @@ export var initialState = {
50
61
  loading: true
51
62
  }
52
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
+ };
53
73
  var buildStackSlides = function (state, dispatch) {
54
- var currentSlideRef = state.ui.currentSlideRef;
74
+ var currentSlideRef = getCurrentSlideRef(state);
55
75
  var progression = state.data.progression;
56
76
  if (!currentSlideRef || !progression)
57
77
  return initialState;
@@ -192,8 +212,76 @@ var buildQuitPopinProps = function (dispatch) {
192
212
  };
193
213
  };
194
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
+ };
195
282
  export var mapStateToSlidesProps = function (state, dispatch, onQuitClick) {
196
- var currentSlideRef = get(['ui', 'currentSlideRef'], state);
283
+ var currentSlideRef = getCurrentSlideRef(state);
284
+ var endReview = isEndOfProgression(state.data.progression);
197
285
  var correction = get(['data', 'corrections', currentSlideRef], state);
198
286
  var isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
199
287
  var klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
@@ -217,9 +305,9 @@ export var mapStateToSlidesProps = function (state, dispatch, onQuitClick) {
217
305
  }
218
306
  },
219
307
  correctionPopinProps: correction && getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf),
220
- endReview: false
308
+ endReview: endReview && state.ui.showCongrats
221
309
  },
222
- congrats: undefined,
310
+ congrats: buildCongratsProps(state),
223
311
  quitPopin: showQuitPopin ? buildQuitPopinProps(dispatch)(onQuitClick) : undefined
224
312
  };
225
313
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coorpacademy/app-review",
3
- "version": "0.5.4-alpha.8+085f42ee1",
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.3-alpha.8+085f42ee1",
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",
@@ -55,9 +55,9 @@
55
55
  "react": "^17.0.2"
56
56
  },
57
57
  "devDependencies": {
58
- "@coorpacademy/css-modules-require-hook": "2.1.6-alpha.193+085f42ee1",
58
+ "@coorpacademy/css-modules-require-hook": "2.1.5",
59
59
  "@coorpacademy/eslint-plugin-coorpacademy": "^11.0.0",
60
- "@coorpacademy/webpack-config": "11.0.1-alpha.10+085f42ee1",
60
+ "@coorpacademy/webpack-config": "11.0.0",
61
61
  "@testing-library/react": "^12.1.5",
62
62
  "@types/lodash": "^4.14.182",
63
63
  "@typescript-eslint/eslint-plugin": "^5.28.0",
@@ -77,5 +77,5 @@
77
77
  "webpack-cli": "^4.10.0",
78
78
  "webpack-dev-server": "^4.11.1"
79
79
  },
80
- "gitHead": "085f42ee17112db779e2499778858cd65901d316"
80
+ "gitHead": "9e64ba973f7219fca6b39876f2e64d423356c721"
81
81
  }
@@ -92,17 +92,21 @@ export type ProgressionAnswerItem = {
92
92
  answer: string[];
93
93
  };
94
94
 
95
+ export type SlideContent = {
96
+ type: 'slide';
97
+ ref: string;
98
+ };
99
+
100
+ export type SuccessNodeContent = {
101
+ type: 'success';
102
+ ref: 'successExitNode';
103
+ };
104
+
95
105
  export type ProgressionState = {
96
106
  allAnswers: ProgressionAnswerItem[];
97
- content?: {
98
- ref: string;
99
- type: string;
100
- };
107
+ content?: SlideContent;
101
108
  isCorrect: boolean;
102
- nextContent: {
103
- type: 'success' | 'slide';
104
- ref: 'successExitNode' | string;
105
- };
109
+ nextContent: SlideContent | SuccessNodeContent;
106
110
  pendingSlides: string[];
107
111
  slides: string[];
108
112
  step: {
@@ -8,12 +8,13 @@ import toInteger from 'lodash/fp/toInteger';
8
8
  import type {Dispatch} from 'redux';
9
9
  import join from 'lodash/fp/join';
10
10
  import {closeQuitPopin, openQuitPopin} from '../../actions/ui/quit-popin';
11
- import type {ProgressionAnswerItem} from '../../types/common';
11
+ import type {ProgressionAnswerItem, ProgressionFromAPI, SlideContent} from '../../types/common';
12
12
  import {getProgressionSlidesRefs, type SlideIndexes} from '../../common';
13
13
  import type {StoreState} from '../../reducers';
14
14
  import type {AnswerUI} from '../../types/slides';
15
15
  import {postAnswer} from '../../actions/api/post-answer';
16
16
  import {nextSlide} from '../../actions/ui/next-slide';
17
+ import {ProgressionState} from '../../reducers/data/progression';
17
18
  import {mapApiSlideToUi} from './map-api-slide-to-ui';
18
19
 
19
20
  const ICON_VALUES = {
@@ -110,30 +111,75 @@ export type SlidesViewProps = {
110
111
  endReview: boolean;
111
112
  };
112
113
  reviewBackgroundAriaLabel?: string;
113
- congrats?: {
114
- 'aria-label'?: string;
115
- 'data-name'?: string;
116
- animationLottie: unknown;
117
- title: string;
118
- cardCongratsStar: unknown;
119
- cardCongratsRank: unknown;
120
- buttonRevising: {
121
- 'aria-label'?: string;
122
- label: string;
123
- onClick: Function;
124
- type: string;
125
- };
126
- buttonRevisingSkill: {
127
- 'aria-label'?: string;
128
- label: string;
129
- onClick: Function;
130
- type: string;
131
- };
132
- };
114
+ congrats?: CongratsProps;
133
115
  quitPopin?: QuitPopinProps;
134
116
  };
135
117
 
136
- // TODO replace this, position no more needed
118
+ type LottieAnimationProps = {
119
+ 'aria-label': string;
120
+ 'data-name'?: string;
121
+ animationSrc: string;
122
+ loop?: boolean;
123
+ rendererSettings?: {
124
+ hideOnTransparent?: boolean;
125
+ className?: string;
126
+ };
127
+ height?: number;
128
+ width?: number;
129
+ className?: number;
130
+ ie11ImageBackup: string;
131
+ backupImageClassName?: string;
132
+ autoplay?: boolean;
133
+ animationControl?: 'play' | 'pause' | 'stop' | 'loading';
134
+ };
135
+
136
+ export type CongratsCardProps = {
137
+ 'aria-label': string;
138
+ 'data-name': string;
139
+ animationLottie: LottieAnimationProps;
140
+ iconAriaLabel: string;
141
+ className?: string;
142
+ cardType: string;
143
+ reviewCardTitle: string;
144
+ reviewCardValue: string;
145
+ rankSuffix?: string;
146
+ timerAnimation: number;
147
+ };
148
+
149
+ export type CongratsProps = {
150
+ 'aria-label': string;
151
+ 'data-name': 'review-congrats';
152
+ animationLottie: LottieAnimationProps;
153
+ title: string;
154
+ cardCongratsStar: CongratsCardProps;
155
+ cardCongratsRank?: CongratsCardProps;
156
+ buttonRevising?: {
157
+ 'aria-label': string;
158
+ label: string;
159
+ onClick: Function;
160
+ type: string;
161
+ };
162
+ buttonRevisingSkill?: {
163
+ label: string;
164
+ 'aria-label': string;
165
+ onClick: Function;
166
+ type: string;
167
+ };
168
+ };
169
+
170
+ const confettiAnimation: LottieAnimationProps = {
171
+ 'aria-label': 'aria lottie',
172
+ 'data-name': 'default-lottie',
173
+ className: undefined,
174
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/confetti.json',
175
+ loop: undefined,
176
+ autoplay: true,
177
+ rendererSettings: {
178
+ hideOnTransparent: false
179
+ },
180
+ ie11ImageBackup: 'https://static-staging.coorpacademy.com/animations/review/conffeti_congrats.svg'
181
+ };
182
+
137
183
  export const initialState: SlidesStack = {
138
184
  '0': {
139
185
  position: 0,
@@ -157,8 +203,18 @@ export const initialState: SlidesStack = {
157
203
  }
158
204
  };
159
205
 
206
+ const getCurrentSlideRef = (state: StoreState): string => {
207
+ const currentSlideRef = get(['ui', 'currentSlideRef'], state);
208
+ const endReview = currentSlideRef === 'successExitNode';
209
+
210
+ if (!endReview) return currentSlideRef;
211
+ const progression = state.data.progression as ProgressionFromAPI;
212
+ const content = progression.state.content as SlideContent;
213
+ return content.ref;
214
+ };
215
+
160
216
  const buildStackSlides = (state: StoreState, dispatch: Dispatch): SlidesStack => {
161
- const currentSlideRef = state.ui.currentSlideRef;
217
+ const currentSlideRef = getCurrentSlideRef(state);
162
218
  const progression = state.data.progression;
163
219
 
164
220
  if (!currentSlideRef || !progression) return initialState;
@@ -341,12 +397,87 @@ const buildQuitPopinProps =
341
397
  }
342
398
  };
343
399
  };
400
+
401
+ const buildRankCard = (rank: number): CongratsCardProps => {
402
+ return {
403
+ 'aria-label': 'Review Card Congrats Container',
404
+ 'data-name': 'card-rank',
405
+ animationLottie: {
406
+ 'aria-label': 'aria lottie',
407
+ 'data-name': 'default-lottie',
408
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/rank.json',
409
+ loop: true,
410
+ autoplay: true,
411
+ ie11ImageBackup:
412
+ 'https://static-staging.coorpacademy.com/animations/review/rank_icon_congrats.svg'
413
+ },
414
+ cardType: 'card-rank',
415
+ iconAriaLabel: 'Image without information',
416
+ className: undefined,
417
+ reviewCardTitle: 'You are now',
418
+ reviewCardValue: `${rank}`,
419
+ rankSuffix: 'th',
420
+ timerAnimation: 200
421
+ };
422
+ };
423
+
424
+ const buildCongratsProps = (state: StoreState): CongratsProps | undefined => {
425
+ if (!state.ui.showCongrats) return;
426
+
427
+ const progression = state.data.progression as ProgressionFromAPI;
428
+ const stars = progression.state.stars;
429
+ const cardCongratsStar: CongratsCardProps = {
430
+ 'aria-label': 'Review Card Congrats Container',
431
+ 'data-name': 'card-star',
432
+ animationLottie: {
433
+ 'aria-label': 'aria lottie',
434
+ 'data-name': 'default-lottie',
435
+ className: undefined,
436
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/star.json',
437
+ loop: false,
438
+ autoplay: undefined,
439
+ rendererSettings: {
440
+ hideOnTransparent: false
441
+ },
442
+ ie11ImageBackup:
443
+ 'https://static-staging.coorpacademy.com/animations/review/stars_icon_congrats.svg'
444
+ },
445
+ iconAriaLabel: 'Image without information',
446
+ className: undefined,
447
+ cardType: 'card-star',
448
+ reviewCardTitle: 'You have won',
449
+ reviewCardValue: `${stars}`,
450
+ timerAnimation: 200
451
+ };
452
+
453
+ const {start, end} = state.data.rank;
454
+ const newRank = start - end;
455
+ const cardCongratsRank = !Number.isNaN(newRank) && newRank > 0 ? buildRankCard(end) : undefined;
456
+
457
+ return {
458
+ 'aria-label': 'Review Congratulations',
459
+ 'data-name': 'review-congrats',
460
+ animationLottie: confettiAnimation,
461
+ title: 'Congratulations!',
462
+ cardCongratsStar,
463
+ cardCongratsRank,
464
+ buttonRevising: undefined, // TODO make boutons and actions
465
+ buttonRevisingSkill: undefined // TODO make boutons and actions
466
+ };
467
+ };
468
+
469
+ const isEndOfProgression = (progression: ProgressionState): boolean => {
470
+ if (!progression) return false;
471
+ return progression.state.nextContent.ref === 'successExitNode';
472
+ };
473
+
344
474
  export const mapStateToSlidesProps = (
345
475
  state: StoreState,
346
476
  dispatch: Dispatch,
347
477
  onQuitClick: Function
348
478
  ): SlidesViewProps => {
349
- const currentSlideRef = get(['ui', 'currentSlideRef'], state);
479
+ const currentSlideRef = getCurrentSlideRef(state);
480
+ const endReview = isEndOfProgression(state.data.progression);
350
481
  const correction = get(['data', 'corrections', currentSlideRef], state);
351
482
  const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
352
483
  const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
@@ -371,9 +502,9 @@ export const mapStateToSlidesProps = (
371
502
  },
372
503
  correctionPopinProps:
373
504
  correction && getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf),
374
- endReview: false
505
+ endReview: endReview && state.ui.showCongrats
375
506
  },
376
- congrats: undefined,
507
+ congrats: buildCongratsProps(state),
377
508
  quitPopin: showQuitPopin ? buildQuitPopinProps(dispatch)(onQuitClick) : undefined
378
509
  };
379
510
  };
@@ -10,7 +10,7 @@ import {
10
10
  getChoicesCorrection,
11
11
  incorrectFreeTextPostAnswerResponse
12
12
  } from '../../../test/util/services.mock';
13
- import {mapStateToSlidesProps} from '..';
13
+ import {CongratsCardProps, CongratsProps, mapStateToSlidesProps} from '..';
14
14
  import type {StoreState} from '../../../reducers';
15
15
  import {freeTextSlide} from './fixtures/free-text';
16
16
  import {qcmGraphicSlide} from './fixtures/qcm-graphic';
@@ -890,7 +890,7 @@ test('should verify props when currentSlideRef has changed to nextContent of pro
890
890
  });
891
891
  });
892
892
 
893
- test('should verify props when progression is in success', t => {
893
+ test('should verify props when progression is in success, showing last correction popin', t => {
894
894
  // state after receive last POST_ANSWER_SUCCESS and before last NEXT_SLIDE
895
895
  const state: StoreState = {
896
896
  data: {
@@ -996,7 +996,263 @@ test('should verify props when progression is in success', t => {
996
996
  ]
997
997
  });
998
998
 
999
- // TODO update test with props.stack validations when NEXT_SLIDE implemented
999
+ t.deepEqual(omit(['next.onClick'], props.stack.correctionPopinProps), {
1000
+ information: {
1001
+ label: '_klf',
1002
+ message:
1003
+ 'L’apprenant peut aussi évaluer sa performance grâce à un classement disponible sur la vue leaderboard. Elle compare sa position par rapport à celle des autres apprenants de la plateforme.'
1004
+ },
1005
+ klf: undefined,
1006
+ next: {
1007
+ ariaLabel: '_correctionNextAriaLabel',
1008
+ label: '_correctionNextLabel'
1009
+ },
1010
+ resultLabel: '_right',
1011
+ type: 'right'
1012
+ });
1013
+ });
1014
+
1015
+ test('should verify props showing congrats', t => {
1016
+ const state: StoreState = {
1017
+ data: {
1018
+ progression: postAnswerResponses[templateSlide.universalRef],
1019
+ skills: [],
1020
+ slides: {
1021
+ [freeTextSlide.universalRef]: freeTextSlide,
1022
+ [qcmGraphicSlide.universalRef]: qcmGraphicSlide,
1023
+ [qcmSlide.universalRef]: qcmSlide,
1024
+ [sliderSlide.universalRef]: sliderSlide,
1025
+ [templateSlide.universalRef]: templateSlide
1026
+ },
1027
+ token: '1234',
1028
+ corrections: {
1029
+ [freeTextSlide._id]: getChoicesCorrection(freeTextSlide._id),
1030
+ [qcmGraphicSlide.universalRef]: getChoicesCorrection(qcmGraphicSlide._id),
1031
+ [qcmSlide.universalRef]: getChoicesCorrection(qcmSlide._id),
1032
+ [sliderSlide.universalRef]: getChoicesCorrection(sliderSlide._id),
1033
+ [templateSlide.universalRef]: getChoicesCorrection(templateSlide._id)
1034
+ },
1035
+ rank: {start: 10, end: 9}
1036
+ },
1037
+ ui: {
1038
+ showCongrats: true,
1039
+ showQuitPopin: false,
1040
+ currentSlideRef: 'successExitNode',
1041
+ navigation: ['loader', 'slides'],
1042
+ answers: {
1043
+ sli_VJYjJnJhg: ['Benchmark'],
1044
+ sli_VkSQroQnx: ['Faux'],
1045
+ sli_N1XACJobn: ['Le créateur peut fixer un pourcentage pour chaque transaction future'],
1046
+ sli_VkAzsCLKb: ['7'],
1047
+ 'sli_N13-hG3kX': ['Leaderboard', 'utilisateurs', 'étoiles']
1048
+ },
1049
+ positions: [-1, -1, -1, -1, 0],
1050
+ slide: {
1051
+ sli_VJYjJnJhg: {
1052
+ validateButton: false,
1053
+ animateCorrectionPopin: false,
1054
+ showCorrectionPopin: false,
1055
+ animationType: 'unstack'
1056
+ },
1057
+ sli_VkSQroQnx: {
1058
+ validateButton: false,
1059
+ animateCorrectionPopin: false,
1060
+ showCorrectionPopin: false,
1061
+ animationType: 'unstack'
1062
+ },
1063
+ sli_N1XACJobn: {
1064
+ validateButton: false,
1065
+ animateCorrectionPopin: false,
1066
+ showCorrectionPopin: false,
1067
+ animationType: 'unstack'
1068
+ },
1069
+ sli_VkAzsCLKb: {
1070
+ validateButton: false,
1071
+ animateCorrectionPopin: false,
1072
+ showCorrectionPopin: false,
1073
+ animationType: 'unstack'
1074
+ },
1075
+ 'sli_N13-hG3kX': {
1076
+ validateButton: false,
1077
+ animateCorrectionPopin: true,
1078
+ showCorrectionPopin: false,
1079
+ animationType: 'unstack'
1080
+ }
1081
+ }
1082
+ }
1083
+ };
1084
+
1085
+ const props = mapStateToSlidesProps(state, identity, identity);
1086
+ const congrats = props.congrats as CongratsProps;
1087
+ t.is(congrats.title, 'Congratulations!');
1088
+ t.is(
1089
+ congrats.animationLottie.animationSrc,
1090
+ 'https://static-staging.coorpacademy.com/animations/review/confetti.json'
1091
+ );
1092
+ const {cardCongratsStar, buttonRevising, buttonRevisingSkill} = congrats;
1093
+ const cardCongratsRank = congrats.cardCongratsRank as CongratsCardProps;
1094
+ t.deepEqual(
1095
+ {
1096
+ animationLottie: cardCongratsRank.animationLottie,
1097
+ rankSuffix: cardCongratsRank.rankSuffix,
1098
+ reviewCardTitle: cardCongratsRank.reviewCardTitle,
1099
+ reviewCardValue: cardCongratsRank.reviewCardValue
1100
+ },
1101
+ {
1102
+ animationLottie: {
1103
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/rank.json',
1104
+ 'aria-label': 'aria lottie',
1105
+ autoplay: true,
1106
+ 'data-name': 'default-lottie',
1107
+ ie11ImageBackup:
1108
+ 'https://static-staging.coorpacademy.com/animations/review/rank_icon_congrats.svg',
1109
+ loop: true
1110
+ },
1111
+ rankSuffix: 'th',
1112
+ reviewCardTitle: 'You are now',
1113
+ reviewCardValue: '9'
1114
+ }
1115
+ );
1116
+ t.deepEqual(
1117
+ {
1118
+ animationLottie: cardCongratsStar.animationLottie,
1119
+ rankSuffix: cardCongratsStar.rankSuffix,
1120
+ reviewCardTitle: cardCongratsStar.reviewCardTitle,
1121
+ reviewCardValue: cardCongratsStar.reviewCardValue
1122
+ },
1123
+ {
1124
+ animationLottie: {
1125
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/star.json',
1126
+ 'aria-label': 'aria lottie',
1127
+ autoplay: undefined,
1128
+ className: undefined,
1129
+ 'data-name': 'default-lottie',
1130
+ ie11ImageBackup:
1131
+ 'https://static-staging.coorpacademy.com/animations/review/stars_icon_congrats.svg',
1132
+ loop: false,
1133
+ rendererSettings: {
1134
+ hideOnTransparent: false
1135
+ }
1136
+ },
1137
+ rankSuffix: undefined,
1138
+ reviewCardTitle: 'You have won',
1139
+ reviewCardValue: '40'
1140
+ }
1141
+ );
1142
+
1143
+ t.is(buttonRevising, undefined);
1144
+ t.is(buttonRevisingSkill, undefined);
1145
+ });
1146
+
1147
+ test('should verify props showing congrats, with only stars card, if user has no earn positions on raking', t => {
1148
+ const state: StoreState = {
1149
+ data: {
1150
+ progression: postAnswerResponses[templateSlide.universalRef],
1151
+ skills: [],
1152
+ slides: {
1153
+ [freeTextSlide.universalRef]: freeTextSlide,
1154
+ [qcmGraphicSlide.universalRef]: qcmGraphicSlide,
1155
+ [qcmSlide.universalRef]: qcmSlide,
1156
+ [sliderSlide.universalRef]: sliderSlide,
1157
+ [templateSlide.universalRef]: templateSlide
1158
+ },
1159
+ token: '1234',
1160
+ corrections: {
1161
+ [freeTextSlide._id]: getChoicesCorrection(freeTextSlide._id),
1162
+ [qcmGraphicSlide.universalRef]: getChoicesCorrection(qcmGraphicSlide._id),
1163
+ [qcmSlide.universalRef]: getChoicesCorrection(qcmSlide._id),
1164
+ [sliderSlide.universalRef]: getChoicesCorrection(sliderSlide._id),
1165
+ [templateSlide.universalRef]: getChoicesCorrection(templateSlide._id)
1166
+ },
1167
+ rank: {start: 10, end: 10}
1168
+ },
1169
+ ui: {
1170
+ showCongrats: true,
1171
+ showQuitPopin: false,
1172
+ currentSlideRef: 'successExitNode',
1173
+ navigation: ['loader', 'slides'],
1174
+ answers: {
1175
+ sli_VJYjJnJhg: ['Benchmark'],
1176
+ sli_VkSQroQnx: ['Faux'],
1177
+ sli_N1XACJobn: ['Le créateur peut fixer un pourcentage pour chaque transaction future'],
1178
+ sli_VkAzsCLKb: ['7'],
1179
+ 'sli_N13-hG3kX': ['Leaderboard', 'utilisateurs', 'étoiles']
1180
+ },
1181
+ positions: [-1, -1, -1, -1, 0],
1182
+ slide: {
1183
+ sli_VJYjJnJhg: {
1184
+ validateButton: false,
1185
+ animateCorrectionPopin: false,
1186
+ showCorrectionPopin: false,
1187
+ animationType: 'unstack'
1188
+ },
1189
+ sli_VkSQroQnx: {
1190
+ validateButton: false,
1191
+ animateCorrectionPopin: false,
1192
+ showCorrectionPopin: false,
1193
+ animationType: 'unstack'
1194
+ },
1195
+ sli_N1XACJobn: {
1196
+ validateButton: false,
1197
+ animateCorrectionPopin: false,
1198
+ showCorrectionPopin: false,
1199
+ animationType: 'unstack'
1200
+ },
1201
+ sli_VkAzsCLKb: {
1202
+ validateButton: false,
1203
+ animateCorrectionPopin: false,
1204
+ showCorrectionPopin: false,
1205
+ animationType: 'unstack'
1206
+ },
1207
+ 'sli_N13-hG3kX': {
1208
+ validateButton: false,
1209
+ animateCorrectionPopin: true,
1210
+ showCorrectionPopin: false,
1211
+ animationType: 'unstack'
1212
+ }
1213
+ }
1214
+ }
1215
+ };
1216
+
1217
+ const props = mapStateToSlidesProps(state, identity, identity);
1218
+ const congrats = props.congrats as CongratsProps;
1219
+ t.is(congrats.title, 'Congratulations!');
1220
+ t.is(
1221
+ congrats.animationLottie.animationSrc,
1222
+ 'https://static-staging.coorpacademy.com/animations/review/confetti.json'
1223
+ );
1224
+ const {cardCongratsStar, buttonRevising, buttonRevisingSkill} = congrats;
1225
+ t.deepEqual(
1226
+ {
1227
+ animationLottie: cardCongratsStar.animationLottie,
1228
+ rankSuffix: cardCongratsStar.rankSuffix,
1229
+ reviewCardTitle: cardCongratsStar.reviewCardTitle,
1230
+ reviewCardValue: cardCongratsStar.reviewCardValue
1231
+ },
1232
+ {
1233
+ animationLottie: {
1234
+ animationSrc: 'https://static-staging.coorpacademy.com/animations/review/star.json',
1235
+ 'aria-label': 'aria lottie',
1236
+ autoplay: undefined,
1237
+ className: undefined,
1238
+ 'data-name': 'default-lottie',
1239
+ ie11ImageBackup:
1240
+ 'https://static-staging.coorpacademy.com/animations/review/stars_icon_congrats.svg',
1241
+ loop: false,
1242
+ rendererSettings: {
1243
+ hideOnTransparent: false
1244
+ }
1245
+ },
1246
+ rankSuffix: undefined,
1247
+ reviewCardTitle: 'You have won',
1248
+ reviewCardValue: '40'
1249
+ }
1250
+ );
1251
+ const cardCongratsRank = congrats.cardCongratsRank;
1252
+ t.is(cardCongratsRank, undefined);
1253
+
1254
+ t.is(buttonRevising, undefined);
1255
+ t.is(buttonRevisingSkill, undefined);
1000
1256
  });
1001
1257
 
1002
1258
  test('should verify props when progression has answered a current pendingSlide', t => {