@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
@@ -6,6 +6,10 @@ export const RANK_FETCH_START_FAILURE = '@@rank/FETCH_START_FAILURE';
6
6
  export const RANK_FETCH_END_REQUEST = '@@rank/FETCH_END_REQUEST';
7
7
  export const RANK_FETCH_END_SUCCESS = '@@rank/FETCH_END_SUCCESS';
8
8
  export const RANK_FETCH_END_FAILURE = '@@rank/FETCH_END_FAILURE';
9
+ const bailout = (path) => (state) => {
10
+ const value = get(path, state);
11
+ return !Number.isNaN(value);
12
+ };
9
13
  export const fetchRank = (dispatch, getState, services, types, path) => {
10
14
  const action = buildTask({
11
15
  types,
@@ -14,7 +18,7 @@ export const fetchRank = (dispatch, getState, services, types, path) => {
14
18
  const token = get(['data', 'token'], state);
15
19
  return services.fetchRank(token);
16
20
  },
17
- bailout: path ? (state) => !!get(path, state) : undefined
21
+ bailout: path ? bailout(path) : undefined
18
22
  });
19
23
  return dispatch(action);
20
24
  };
@@ -0,0 +1,8 @@
1
+ export declare const OPEN_POPIN: "@@ui/OPEN_POPIN";
2
+ export declare const CLOSE_POPIN: "@@ui/CLOSE_POPIN";
3
+ export declare const openQuitPopin: {
4
+ type: "@@ui/OPEN_POPIN";
5
+ };
6
+ export declare const closeQuitPopin: {
7
+ type: "@@ui/CLOSE_POPIN";
8
+ };
@@ -0,0 +1,8 @@
1
+ export const OPEN_POPIN = '@@ui/OPEN_POPIN';
2
+ export const CLOSE_POPIN = '@@ui/CLOSE_POPIN';
3
+ export const openQuitPopin = {
4
+ type: OPEN_POPIN
5
+ };
6
+ export const closeQuitPopin = {
7
+ type: CLOSE_POPIN
8
+ };
package/es/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import type { AppOptions } from './types/common';
3
2
  declare const AppReview: ({ options }: {
4
3
  options: AppOptions;
@@ -1,7 +1,8 @@
1
+ import { type ReceivedProgression } from '../../actions/api/post-progression';
1
2
  import { RankAction } from '../../actions/api/fetch-rank';
2
3
  export declare type RankState = {
3
- start?: number | null;
4
- end?: number | null;
4
+ start: number;
5
+ end: number;
5
6
  };
6
- declare const reducer: (state: RankState | undefined, action: RankAction) => RankState;
7
+ declare const reducer: (state: RankState | undefined, action: RankAction | ReceivedProgression) => RankState;
7
8
  export default reducer;
@@ -1,34 +1,25 @@
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
- const 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
+ const initialState = {
5
+ start: Number.NaN,
6
+ end: Number.NaN
7
+ };
4
8
  const reducer = (
5
9
  // eslint-disable-next-line default-param-last
6
10
  state = initialState, action) => {
7
11
  switch (action.type) {
8
- case RANK_FETCH_START_REQUEST: {
9
- return update('start', (startRank) => (isUndefined(startRank) ? null : startRank), state);
12
+ case POST_PROGRESSION_SUCCESS: {
13
+ return initialState;
10
14
  }
11
15
  case RANK_FETCH_START_SUCCESS: {
12
16
  const { payload } = action;
13
17
  return set('start', payload.rank, state);
14
18
  }
15
- case RANK_FETCH_START_FAILURE: {
16
- if (pipe(get('start'), isNull)(state))
17
- return unset('start', state);
18
- return state;
19
- }
20
- case RANK_FETCH_END_REQUEST: {
21
- return update('end', (endRank) => (isUndefined(endRank) ? null : endRank), state);
22
- }
23
19
  case RANK_FETCH_END_SUCCESS: {
24
20
  const { payload } = action;
25
21
  return set('end', payload.rank, state);
26
22
  }
27
- case RANK_FETCH_END_FAILURE: {
28
- if (pipe(get('end'), isNull)(state))
29
- return unset('end', state);
30
- return state;
31
- }
32
23
  default:
33
24
  return state;
34
25
  }
@@ -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,
9
11
  navigation,
10
12
  answers,
11
13
  slide,
12
- positions
14
+ positions,
15
+ showQuitPopin,
16
+ showCongrats
13
17
  });
@@ -15,5 +15,4 @@ state = [], action) => {
15
15
  return state;
16
16
  }
17
17
  };
18
- // -----------------------------------------------------------------------------
19
18
  export default reducer;
@@ -12,7 +12,9 @@ state = initialState, action) => {
12
12
  return initialState;
13
13
  }
14
14
  case NEXT_SLIDE: {
15
- const { totalCorrectAnswers, answeredSlides, currentSlideRef, animationType } = action.payload;
15
+ const { totalCorrectAnswers, answeredSlides, currentSlideRef, animationType, nextSlideRef } = action.payload;
16
+ if (nextSlideRef === 'successExitNode')
17
+ return state;
16
18
  const nextCurrentSlidePosition = animationType === 'unstack' ? -1 : 4 - totalCorrectAnswers;
17
19
  const currentSlideIndex = findIndex(ref => ref === currentSlideRef, answeredSlides);
18
20
  const newState = map(position => (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,16 @@
1
+ import { CLOSE_POPIN, OPEN_POPIN } from '../../actions/ui/quit-popin';
2
+ const reducer = (
3
+ // eslint-disable-next-line default-param-last
4
+ state = false, action) => {
5
+ switch (action.type) {
6
+ case OPEN_POPIN: {
7
+ return true;
8
+ }
9
+ case CLOSE_POPIN: {
10
+ return false;
11
+ }
12
+ default:
13
+ return state;
14
+ }
15
+ };
16
+ 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,20 @@
1
+ import { NEXT_SLIDE } from '../../actions/ui/next-slide';
2
+ import { POST_PROGRESSION_SUCCESS } from '../../actions/api/post-progression';
3
+ const reducer = (
4
+ // eslint-disable-next-line default-param-last
5
+ state = false, action) => {
6
+ switch (action.type) {
7
+ case POST_PROGRESSION_SUCCESS: {
8
+ return false;
9
+ }
10
+ case NEXT_SLIDE: {
11
+ const { nextSlideRef } = action.payload;
12
+ if (nextSlideRef === 'successExitNode')
13
+ return true;
14
+ return false;
15
+ }
16
+ default:
17
+ return state;
18
+ }
19
+ };
20
+ export default reducer;
@@ -35,7 +35,10 @@ state = initialState, action) => {
35
35
  return pipe(set([action.meta.slideRef, 'animateCorrectionPopin'], true), set([action.meta.slideRef, 'showCorrectionPopin'], true))(state);
36
36
  }
37
37
  case NEXT_SLIDE: {
38
- return pipe(set([action.payload.currentSlideRef, 'animateCorrectionPopin'], false), set([action.payload.currentSlideRef, 'animationType'], action.payload.animationType))(state);
38
+ const { currentSlideRef, nextSlideRef } = action.payload;
39
+ if (nextSlideRef === 'successExitNode')
40
+ return state;
41
+ return pipe(set([currentSlideRef, 'animateCorrectionPopin'], false), set([currentSlideRef, 'animationType'], action.payload.animationType))(state);
39
42
  }
40
43
  default:
41
44
  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;
@@ -6,6 +6,7 @@ import reduce from 'lodash/fp/reduce';
6
6
  import set from 'lodash/fp/set';
7
7
  import toInteger from 'lodash/fp/toInteger';
8
8
  import join from 'lodash/fp/join';
9
+ import { closeQuitPopin, openQuitPopin } from '../../actions/ui/quit-popin';
9
10
  import { getProgressionSlidesRefs } from '../../common';
10
11
  import { postAnswer } from '../../actions/api/post-answer';
11
12
  import { nextSlide } from '../../actions/ui/next-slide';
@@ -15,7 +16,18 @@ const ICON_VALUES = {
15
16
  wrong: 'wrong',
16
17
  'no-answer': 'no-answer'
17
18
  };
18
- // 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
+ };
19
31
  export const initialState = {
20
32
  '0': {
21
33
  position: 0,
@@ -38,8 +50,17 @@ export const initialState = {
38
50
  loading: true
39
51
  }
40
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
+ };
41
62
  const buildStackSlides = (state, dispatch) => {
42
- const currentSlideRef = state.ui.currentSlideRef;
63
+ const currentSlideRef = getCurrentSlideRef(state);
43
64
  const progression = state.data.progression;
44
65
  if (!currentSlideRef || !progression)
45
66
  return initialState;
@@ -168,16 +189,110 @@ const getCorrectionPopinProps = (dispatch) => (isCorrect, correctAnswer, klf) =>
168
189
  type: isCorrect ? 'right' : 'wrong'
169
190
  };
170
191
  };
192
+ const buildQuitPopinProps = (dispatch) => (onQuitClick) => {
193
+ return {
194
+ content: `Tu t'en vas déjà ?`,
195
+ icon: `MoonRocket`,
196
+ mode: 'alert',
197
+ descriptionText: `Tu vas t'en sortir ! Si tu arrêtes maintenant, tu vas perdre ta progression.`,
198
+ firstButton: {
199
+ label: 'Arrêter ma session',
200
+ type: 'tertiary',
201
+ customStyle: {
202
+ color: '#ED3436'
203
+ },
204
+ handleOnclick: onQuitClick,
205
+ ariaLabel: 'Stop session'
206
+ },
207
+ secondButton: {
208
+ label: `Continuer d'apprendre`,
209
+ type: 'primary',
210
+ handleOnclick: () => {
211
+ dispatch(closeQuitPopin);
212
+ },
213
+ ariaLabel: 'Continue review'
214
+ }
215
+ };
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
+ };
171
284
  export const mapStateToSlidesProps = (state, dispatch, onQuitClick) => {
172
- const currentSlideRef = get(['ui', 'currentSlideRef'], state);
285
+ const currentSlideRef = getCurrentSlideRef(state);
286
+ const endReview = isEndOfProgression(state.data.progression);
173
287
  const correction = get(['data', 'corrections', currentSlideRef], state);
174
288
  const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
175
289
  const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
290
+ const showQuitPopin = get(['ui', 'showQuitPopin'], state);
176
291
  return {
177
292
  header: {
178
293
  mode: '__revision_mode',
179
294
  skillName: '__agility',
180
- onQuitClick,
295
+ onQuitClick: () => dispatch(openQuitPopin),
181
296
  'aria-label': 'aria-header-wrapper',
182
297
  closeButtonAriaLabel: 'aria-close-button',
183
298
  steps: buildStepItems(state)
@@ -192,8 +307,9 @@ export const mapStateToSlidesProps = (state, dispatch, onQuitClick) => {
192
307
  }
193
308
  },
194
309
  correctionPopinProps: correction && getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf),
195
- endReview: false
310
+ endReview: endReview && state.ui.showCongrats
196
311
  },
197
- congrats: undefined
312
+ congrats: buildCongratsProps(state),
313
+ quitPopin: showQuitPopin ? buildQuitPopinProps(dispatch)(onQuitClick) : undefined
198
314
  };
199
315
  };
@@ -6,6 +6,12 @@ export var RANK_FETCH_START_FAILURE = '@@rank/FETCH_START_FAILURE';
6
6
  export var RANK_FETCH_END_REQUEST = '@@rank/FETCH_END_REQUEST';
7
7
  export var RANK_FETCH_END_SUCCESS = '@@rank/FETCH_END_SUCCESS';
8
8
  export var RANK_FETCH_END_FAILURE = '@@rank/FETCH_END_FAILURE';
9
+ var bailout = function (path) {
10
+ return function (state) {
11
+ var value = get(path, state);
12
+ return !Number.isNaN(value);
13
+ };
14
+ };
9
15
  export var fetchRank = function (dispatch, getState, services, types, path) {
10
16
  var action = buildTask({
11
17
  types: types,
@@ -14,7 +20,7 @@ export var fetchRank = function (dispatch, getState, services, types, path) {
14
20
  var token = get(['data', 'token'], state);
15
21
  return services.fetchRank(token);
16
22
  },
17
- bailout: path ? function (state) { return !!get(path, state); } : undefined
23
+ bailout: path ? bailout(path) : undefined
18
24
  });
19
25
  return dispatch(action);
20
26
  };
@@ -0,0 +1,8 @@
1
+ export declare const OPEN_POPIN: "@@ui/OPEN_POPIN";
2
+ export declare const CLOSE_POPIN: "@@ui/CLOSE_POPIN";
3
+ export declare const openQuitPopin: {
4
+ type: "@@ui/OPEN_POPIN";
5
+ };
6
+ export declare const closeQuitPopin: {
7
+ type: "@@ui/CLOSE_POPIN";
8
+ };
@@ -0,0 +1,8 @@
1
+ export var OPEN_POPIN = '@@ui/OPEN_POPIN';
2
+ export var CLOSE_POPIN = '@@ui/CLOSE_POPIN';
3
+ export var openQuitPopin = {
4
+ type: OPEN_POPIN
5
+ };
6
+ export var closeQuitPopin = {
7
+ type: CLOSE_POPIN
8
+ };
package/lib/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import type { AppOptions } from './types/common';
3
2
  declare const AppReview: ({ options }: {
4
3
  options: AppOptions;
@@ -1,7 +1,8 @@
1
+ import { type ReceivedProgression } from '../../actions/api/post-progression';
1
2
  import { RankAction } from '../../actions/api/fetch-rank';
2
3
  export declare type RankState = {
3
- start?: number | null;
4
- end?: number | null;
4
+ start: number;
5
+ end: number;
5
6
  };
6
- declare const reducer: (state: RankState | undefined, action: RankAction) => RankState;
7
+ declare const reducer: (state: RankState | undefined, action: RankAction | ReceivedProgression) => RankState;
7
8
  export default reducer;