1- import React , { useCallback } from 'react'
1+ import React , { useCallback , useMemo } from 'react'
2+ import { Trans } from 'react-i18next'
23import { Modal } from '../Modal'
34import { ExerciseIcon } from '../../common'
45import { ConceptProgression } from './exercise-completed-modal/ConceptProgression'
56import { Unlocks } from './exercise-completed-modal/Unlocks'
67import { ExerciseCompletion } from '../CompleteExerciseModal'
78import { redirectTo } from '../../../utils/redirect-to'
8- import pluralize from 'pluralize'
99import { useAppTranslation } from '@/i18n/useAppTranslation'
1010
11- export const ExerciseCompletedModal = ( {
11+ type Props = {
12+ open : boolean
13+ completion : ExerciseCompletion
14+ }
15+
16+ export const ExerciseCompletedModal : React . FC < Props > = ( {
1217 open,
1318 completion,
1419 ...props
15- } : {
16- open : boolean
17- completion : ExerciseCompletion
18- } ) : JSX . Element => {
20+ } ) => {
1921 const { t } = useAppTranslation ( 'components/modals/complete-exercise-modal' )
2022 const {
2123 track,
@@ -29,111 +31,139 @@ export const ExerciseCompletedModal = ({
2931 redirectTo ( exercise . links . self )
3032 } , [ exercise . links . self ] )
3133
32- const content =
33- exercise . type == 'concept' ? (
34- < >
35- < h3 >
36- { t ( 'exerciseCompletedModal.awesomeWorkLearning' , {
37- trackTitle : track . title ,
38- } ) }
39- </ h3 >
40- { conceptProgressions . length > 0 ? (
41- < div className = "info" >
42- { t ( 'exerciseCompletedModal.learntConcepts' ) }
43- < strong >
44- { conceptProgressions . length } { ' ' }
45- { t ( 'exerciseCompletedModal.conceptsCount' , {
46- count : conceptProgressions . length ,
47- } ) }
48- </ strong >
49- { unlockedExercises . length > 0
50- ? t ( 'exerciseCompletedModal.unlockedExercises' , {
51- unlockedExercisesCount : unlockedExercises . length ,
52- } ) + t ( 'exerciseCompletedModal.byCompleting' )
53- : null } { ' ' }
54- </ div >
55- ) : null }
56- < div className = "progressed-concepts" >
57- { conceptProgressions . map ( ( progression ) => (
58- < ConceptProgression key = { progression . name } { ...progression } />
59- ) ) }
60- </ div >
61- { unlockedExercises . length !== 0 || unlockedConcepts . length !== 0 ? (
62- < Unlocks
63- unlockedExercises = { unlockedExercises }
64- unlockedConcepts = { unlockedConcepts }
65- />
66- ) : null }
67-
68- < div className = "btns" >
69- { track . numConcepts > 0 ? (
70- < a href = { track . links . concepts } className = "btn-primary btn-m" >
71- { t ( 'exerciseCompletedModal.showMeMoreConcepts' ) }
72- </ a >
73- ) : null }
74- < button onClick = { handleContinue } className = "btn" >
75- { t ( 'exerciseCompletedModal.returnToExercise' ) }
76- </ button >
77- </ div >
78- </ >
79- ) : (
80- < >
81- < h3 >
82- { t ( 'exerciseCompletedModal.awesomeWorkMastering' , {
83- trackTitle : track . title ,
84- } ) }
85- </ h3 >
86- { conceptProgressions . length > 0 ? (
87- < >
88- < div className = "info" >
89- { t ( 'exerciseCompletedModal.progressedWith' ) }
90- < strong >
91- { conceptProgressions . length } { ' ' }
92- { t ( 'exerciseCompletedModal.conceptsCount' , {
93- count : conceptProgressions . length ,
94- } ) }
95- </ strong > { ' ' }
96- by completing this exercise.
97- </ div >
98- < div className = "progressed-concepts" >
99- { conceptProgressions . map ( ( progression ) => (
100- < ConceptProgression key = { progression . name } { ...progression } />
101- ) ) }
102- </ div >
103- </ >
104- ) : (
105- < div className = "info" >
106- { t ( 'exerciseCompletedModal.oncePracticedMore' , {
107- trackTitle : track . title ,
108- } ) }
109- </ div >
110- ) }
111-
112- < div className = "btns" >
113- < a href = { track . links . exercises } className = "btn-primary btn-m" >
114- { t ( 'exerciseCompletedModal.showMeMoreExercises' ) }
115- </ a >
116- < button onClick = { handleContinue } className = "btn" >
117- { t ( 'exerciseCompletedModal.returnToExercise' ) }
118- </ button >
119- </ div >
120- </ >
121- )
34+ const conceptCount = conceptProgressions . length
35+ const unlockedExercisesCount = unlockedExercises . length
36+
37+ const conceptInfoKey = useMemo ( ( ) => {
38+ if ( exercise . type === 'concept' ) {
39+ if ( conceptCount > 0 ) {
40+ if ( unlockedExercisesCount > 0 ) {
41+ if ( conceptCount === 1 && unlockedExercisesCount === 1 )
42+ return 'exerciseCompletedModal.concept.info_1_1'
43+ if ( conceptCount === 1 && unlockedExercisesCount > 1 )
44+ return 'exerciseCompletedModal.concept.info_1_many'
45+ if ( conceptCount > 1 && unlockedExercisesCount === 1 )
46+ return 'exerciseCompletedModal.concept.info_many_1'
47+ return 'exerciseCompletedModal.concept.info_many_many'
48+ }
49+
50+ return conceptCount === 1
51+ ? 'exerciseCompletedModal.concept.info_1'
52+ : 'exerciseCompletedModal.concept.info_many'
53+ }
54+ return null
55+ } else {
56+ if ( conceptCount > 0 ) {
57+ return conceptCount === 1
58+ ? 'exerciseCompletedModal.practice.info_1'
59+ : 'exerciseCompletedModal.practice.info_many'
60+ }
61+ return 'exerciseCompletedModal.practice.info_none'
62+ }
63+ } , [ exercise . type , conceptCount , unlockedExercisesCount ] )
64+
12265 return (
12366 < Modal
124- cover = { true }
67+ cover
12568 open = { open }
12669 className = "m-completed-exercise c-completed-exercise-progress"
12770 onClose = { ( ) => null }
12871 { ...props }
12972 >
13073 < ExerciseIcon iconUrl = { exercise . iconUrl } />
74+
13175 < h2 >
13276 { t ( 'exerciseCompletedModal.youCompleted' , {
13377 exerciseTitle : exercise . title ,
13478 } ) }
13579 </ h2 >
136- { content }
80+
81+ { exercise . type === 'concept' ? (
82+ < >
83+ < h3 >
84+ { t ( 'exerciseCompletedModal.awesomeWorkLearning' , {
85+ trackTitle : track . title ,
86+ } ) }
87+ </ h3 >
88+
89+ { conceptInfoKey ? (
90+ < div className = "info" >
91+ < Trans
92+ t = { t }
93+ i18nKey = { conceptInfoKey }
94+ values = { {
95+ count : conceptCount ,
96+ unlockedExercisesCount,
97+ } }
98+ components = { { strong : < strong /> } }
99+ />
100+ </ div >
101+ ) : null }
102+
103+ { conceptCount > 0 && (
104+ < div className = "progressed-concepts" >
105+ { conceptProgressions . map ( ( progression ) => (
106+ < ConceptProgression key = { progression . name } { ...progression } />
107+ ) ) }
108+ </ div >
109+ ) }
110+
111+ { ( unlockedExercises . length !== 0 ||
112+ unlockedConcepts . length !== 0 ) && (
113+ < Unlocks
114+ unlockedExercises = { unlockedExercises }
115+ unlockedConcepts = { unlockedConcepts }
116+ />
117+ ) }
118+
119+ < div className = "btns" >
120+ { track . numConcepts > 0 && (
121+ < a href = { track . links . concepts } className = "btn-primary btn-m" >
122+ { t ( 'exerciseCompletedModal.showMeMoreConcepts' ) }
123+ </ a >
124+ ) }
125+ < button onClick = { handleContinue } className = "btn" >
126+ { t ( 'exerciseCompletedModal.returnToExercise' ) }
127+ </ button >
128+ </ div >
129+ </ >
130+ ) : (
131+ < >
132+ < h3 >
133+ { t ( 'exerciseCompletedModal.awesomeWorkMastering' , {
134+ trackTitle : track . title ,
135+ } ) }
136+ </ h3 >
137+
138+ < div className = "info" >
139+ < Trans
140+ t = { t }
141+ i18nKey = {
142+ conceptInfoKey ?? 'exerciseCompletedModal.practice.info_none'
143+ }
144+ values = { { count : conceptCount , trackTitle : track . title } }
145+ components = { { strong : < strong /> } }
146+ />
147+ </ div >
148+
149+ { conceptCount > 0 && (
150+ < div className = "progressed-concepts" >
151+ { conceptProgressions . map ( ( progression ) => (
152+ < ConceptProgression key = { progression . name } { ...progression } />
153+ ) ) }
154+ </ div >
155+ ) }
156+
157+ < div className = "btns" >
158+ < a href = { track . links . exercises } className = "btn-primary btn-m" >
159+ { t ( 'exerciseCompletedModal.showMeMoreExercises' ) }
160+ </ a >
161+ < button onClick = { handleContinue } className = "btn" >
162+ { t ( 'exerciseCompletedModal.returnToExercise' ) }
163+ </ button >
164+ </ div >
165+ </ >
166+ ) }
137167 </ Modal >
138168 )
139169}
0 commit comments