Skip to content

Commit b4a19f9

Browse files
authored
More i18n fixes (#8146)
* Fix seniority survey modal * Rework ExerciseCompletedModal * Fix next slot unlocks at * Start fixing mentoring session request * Fix wrong nesting * Fix delete iteration modal * Extract translators page * Use `Track.num_active`
1 parent 668b148 commit b4a19f9

12 files changed

Lines changed: 283 additions & 183 deletions

File tree

Lines changed: 129 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
import React, { useCallback } from 'react'
1+
import React, { useCallback, useMemo } from 'react'
2+
import { Trans } from 'react-i18next'
23
import { Modal } from '../Modal'
34
import { ExerciseIcon } from '../../common'
45
import { ConceptProgression } from './exercise-completed-modal/ConceptProgression'
56
import { Unlocks } from './exercise-completed-modal/Unlocks'
67
import { ExerciseCompletion } from '../CompleteExerciseModal'
78
import { redirectTo } from '../../../utils/redirect-to'
8-
import pluralize from 'pluralize'
99
import { 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
}

app/javascript/components/modals/seniority-survey-modal/InitialView.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,33 @@ import { useAppTranslation } from '@/i18n/useAppTranslation'
1313

1414
const DEFAULT_ERROR = new Error('Unable to save seniority level.')
1515

16-
export const SENIORITIES: { label: string; value: SeniorityLevel }[] = [
16+
export const SENIORITIES: {
17+
key: string
18+
label: string
19+
value: SeniorityLevel
20+
}[] = [
1721
{
22+
key: 'absoluteBeginner',
1823
label: 'Absolute Beginner',
1924
value: 'absolute_beginner',
2025
},
2126
{
27+
key: 'beginner',
2228
label: 'Beginner',
2329
value: 'beginner',
2430
},
2531
{
32+
key: 'juniorDeveloper',
2633
label: 'Junior Developer',
2734
value: 'junior',
2835
},
2936
{
37+
key: 'midLevelDeveloper',
3038
label: 'Mid-level Developer',
3139
value: 'mid',
3240
},
3341
{
42+
key: 'seniorDeveloper',
3443
label: 'Senior Developer',
3544
value: 'senior',
3645
},
@@ -91,7 +100,7 @@ export function InitialView() {
91100
)}
92101
onClick={() => setSelected(seniority.value)}
93102
>
94-
{t(`initialView.${seniority.label.replace(' ', '')}`)}
103+
{t(`initialView.${seniority.key}`)}
95104
</button>
96105
))}
97106
</div>

app/javascript/components/student/iterations-list/DeleteIterationModal.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,13 @@ export const DeleteIterationModal = ({
6767
<h3>
6868
{t('deleteIterationModal.areYouSure', { iterationIdx: iteration.idx })}
6969
</h3>
70-
<p>{t('deleteIterationModal.deletedIterationsRemoved')}</p>
70+
<p>
71+
<Trans
72+
i18nKey="deleteIterationModal.deletedIterationsRemoved"
73+
ns="components/student/iterations-list"
74+
components={{ strong: <strong /> }}
75+
/>
76+
</p>
7177
<form data-turbo="false" onSubmit={handleSubmit} className="buttons">
7278
<FormButton type="submit" status={status} className="btn-warning btn-s">
7379
{t('deleteIterationModal.deleteIteration')}

app/javascript/components/student/mentoring-session/mentoring-request/MentoringRequestInfo.tsx

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export const MentoringRequestInfo = ({
7272
</div>
7373
<CancelRequestButton request={request} />
7474
</div>
75+
7576
<div className="placeholder">
7677
<div className="info">
7778
<div className="title">
@@ -98,21 +99,17 @@ export const MentoringRequestInfo = ({
9899
<Trans
99100
ns="components/student/mentoring-session/mentoring-request"
100101
i18nKey="mentoringRequestInfo.readOurGuide"
101-
components={{
102-
link: (
103-
<a
104-
href={links.mentoringGuide}
105-
target="_blank"
106-
rel="noreferrer"
107-
/>
108-
),
109-
icon: (
110-
<Icon
111-
icon="external-link"
112-
alt="The link opens in a new window or tab"
113-
/>
114-
),
115-
}}
102+
components={[
103+
<a
104+
href={links.mentoringGuide}
105+
target="_blank"
106+
rel="noreferrer"
107+
/>,
108+
<Icon
109+
icon="external-link"
110+
alt="The link opens in a new window or tab"
111+
/>,
112+
]}
116113
/>
117114
</p>
118115
<div className="videos">
@@ -121,11 +118,12 @@ export const MentoringRequestInfo = ({
121118
))}
122119
</div>
123120
</div>
124-
<div className="direct">
125-
<h3>{t('mentoringRequestInfo.wantAFriend')}</h3>
126-
<p>{t('mentoringRequestInfo.sendThisLink')}</p>
127-
<CopyToClipboardButton textToCopy={links.privateMentoring} />
128-
</div>
121+
</div>
122+
123+
<div className="direct">
124+
<h3>{t('mentoringRequestInfo.wantAFriend')}</h3>
125+
<p>{t('mentoringRequestInfo.sendThisLink')}</p>
126+
<CopyToClipboardButton textToCopy={links.privateMentoring} />
129127
</div>
130128
</div>
131129
)

0 commit comments

Comments
 (0)