Skip to content

Commit 50f0c23

Browse files
refactor(client): use generic comp for multiple choice (freeCodeCamp#56825)
Co-authored-by: moT01 <[email protected]>
1 parent 9c73159 commit 50f0c23

File tree

7 files changed

+74
-495
lines changed

7 files changed

+74
-495
lines changed

client/src/templates/Challenges/fill-in-the-blank/show.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ import {
3232
import Scene from '../components/scene/scene';
3333
import { isChallengeCompletedSelector } from '../redux/selectors';
3434

35-
// Styles
36-
import '../video.css';
3735
import './show.css';
3836

3937
// Redux Setup
File renamed without changes.

client/src/templates/Challenges/generic/show.tsx

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Helmet from 'react-helmet';
44
import { useTranslation } from 'react-i18next';
55
import { connect } from 'react-redux';
66
import { Container, Col, Row, Button, Spacer } from '@freecodecamp/ui';
7+
import { isEqual } from 'lodash';
78

89
// Local Utilities
910
import LearnLayout from '../../../components/layouts/learn';
@@ -24,6 +25,13 @@ import {
2425
import { isChallengeCompletedSelector } from '../redux/selectors';
2526
import { BlockTypes } from '../../../../../shared/config/blocks';
2627
import Scene from '../components/scene/scene';
28+
import MultipleChoiceQuestions from '../components/multiple-choice-questions';
29+
import ChallengeExplanation from '../components/challenge-explanation';
30+
import HelpModal from '../components/help-modal';
31+
32+
// Styles
33+
import './show.css';
34+
import '../video.css';
2735

2836
// Redux Setup
2937
const mapStateToProps = (state: unknown) => ({
@@ -35,7 +43,8 @@ const mapDispatchToProps = {
3543
updateChallengeMeta,
3644
challengeMounted,
3745
updateSolutionFormValues,
38-
openCompletionModal: () => openModal('completion')
46+
openCompletionModal: () => openModal('completion'),
47+
openHelpModal: () => openModal('help')
3948
};
4049

4150
// Types
@@ -46,6 +55,7 @@ interface ShowQuizProps {
4655
initTests: (xs: Test[]) => void;
4756
isChallengeCompleted: boolean;
4857
openCompletionModal: () => void;
58+
openHelpModal: () => void;
4959
pageContext: {
5060
challengeMeta: ChallengeMeta;
5161
};
@@ -63,10 +73,12 @@ const ShowGeneric = ({
6373
block,
6474
blockType,
6575
description,
76+
explanation,
6677
challengeType,
67-
fields: { tests },
78+
fields: { blockName, tests },
6879
helpCategory,
6980
instructions,
81+
questions,
7082
title,
7183
translationPending,
7284
scene,
@@ -80,6 +92,7 @@ const ShowGeneric = ({
8092
initTests,
8193
updateChallengeMeta,
8294
openCompletionModal,
95+
openHelpModal,
8396
isChallengeCompleted
8497
}: ShowQuizProps) => {
8598
const { t } = useTranslation();
@@ -142,9 +155,36 @@ const ShowGeneric = ({
142155
setAssignmentsCompleted(a => (isCompleted ? a + 1 : a - 1));
143156
};
144157

158+
// multiple choice questions
159+
const [selectedMcqOptions, setSelectedMcqOptions] = useState(
160+
questions.map<number | null>(() => null)
161+
);
162+
const [submittedMcqAnswers, setSubmittedMcqAnswers] = useState(
163+
questions.map<number | null>(() => null)
164+
);
165+
const [showFeedback, setShowFeedback] = useState(false);
166+
167+
const handleMcqOptionChange = (
168+
questionIndex: number,
169+
answerIndex: number
170+
): void => {
171+
setSelectedMcqOptions(prev =>
172+
prev.map((option, index) =>
173+
index === questionIndex ? answerIndex : option
174+
)
175+
);
176+
};
177+
145178
// submit
146179
const handleSubmit = () => {
147-
if (assignments.length == 0 || allAssignmentsCompleted) {
180+
const hasCompletedAssignments =
181+
assignments.length === 0 || allAssignmentsCompleted;
182+
const mcqSolutions = questions.map(question => question.solution - 1);
183+
const mcqCorrect = isEqual(mcqSolutions, selectedMcqOptions);
184+
185+
setSubmittedMcqAnswers(selectedMcqOptions);
186+
setShowFeedback(true);
187+
if (hasCompletedAssignments && mcqCorrect) {
148188
openCompletionModal();
149189
}
150190
};
@@ -214,15 +254,34 @@ const ShowGeneric = ({
214254
/>
215255
)}
216256

257+
{!!questions && (
258+
<MultipleChoiceQuestions
259+
questions={questions}
260+
selectedOptions={selectedMcqOptions}
261+
handleOptionChange={handleMcqOptionChange}
262+
submittedMcqAnswers={submittedMcqAnswers}
263+
showFeedback={showFeedback}
264+
/>
265+
)}
266+
267+
{explanation ? (
268+
<ChallengeExplanation explanation={explanation} />
269+
) : null}
270+
217271
<Button block={true} variant='primary' onClick={handleSubmit}>
218272
{blockType === BlockTypes.review
219273
? t('buttons.submit')
220274
: t('buttons.check-answer')}
221275
</Button>
276+
<Spacer size='xxs' />
277+
<Button block={true} variant='primary' onClick={openHelpModal}>
278+
{t('buttons.ask-for-help')}
279+
</Button>
222280

223281
<Spacer size='l' />
224282
</Col>
225283
<CompletionModal />
284+
<HelpModal challengeTitle={title} challengeBlock={blockName} />
226285
</Row>
227286
</Container>
228287
</LearnLayout>
@@ -248,6 +307,7 @@ export const query = graphql`
248307
blockType
249308
challengeType
250309
description
310+
explanation
251311
helpCategory
252312
instructions
253313
fields {
@@ -258,6 +318,14 @@ export const query = graphql`
258318
testString
259319
}
260320
}
321+
questions {
322+
text
323+
answers {
324+
answer
325+
feedback
326+
}
327+
solution
328+
}
261329
scene {
262330
setup {
263331
background

0 commit comments

Comments
 (0)