From bce1b9915b52ebcd716f71a03b7d962e51535eb6 Mon Sep 17 00:00:00 2001 From: Tom <20648924+moT01@users.noreply.github.com> Date: Thu, 2 Nov 2023 01:28:53 -0500 Subject: [PATCH] feat(challenge-parser): add feedback to mc questions (#51942) --- client/src/redux/prop-types.ts | 7 ++- client/src/templates/Challenges/odin/show.tsx | 26 ++++++++-- client/src/templates/Challenges/video.css | 4 ++ .../src/templates/Challenges/video/show.tsx | 26 ++++++++-- curriculum/challenges/.markdownlint.yaml | 1 + .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ .../introduction-why-program.md | 8 ++++ curriculum/schema/challenge-schema.js | 9 +++- docs/how-to-work-on-coding-challenges.md | 12 +++++ pnpm-lock.yaml | 47 ++++++++++++------- tools/challenge-parser/package.json | 1 + .../__fixtures__/ast-video-challenge.json | 39 +++++++++++++++ .../__fixtures__/with-video-question.md | 4 ++ .../index.acceptance.test.js.snap | 15 ++++-- .../add-video-question.test.js.snap | 15 ++++-- .../parser/plugins/add-video-question.js | 24 +++++++++- .../parser/plugins/add-video-question.test.js | 25 ++++++---- .../parser/plugins/utils/before-heading.js | 21 +++++++++ .../plugins/utils/before-heading.test.js | 24 ++++++++++ 28 files changed, 346 insertions(+), 42 deletions(-) create mode 100644 tools/challenge-parser/parser/plugins/utils/before-heading.js create mode 100644 tools/challenge-parser/parser/plugins/utils/before-heading.test.js diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index 46a8b5c26f5..f56d469f8fb 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -47,9 +47,14 @@ export type MarkdownRemark = { }; }; +export type MultipleChoiceAnswer = { + answer: string; + feedback: string | null; +}; + export type Question = { text: string; - answers: string[]; + answers: MultipleChoiceAnswer[]; solution: number; }; export type Fields = { diff --git a/client/src/templates/Challenges/odin/show.tsx b/client/src/templates/Challenges/odin/show.tsx index 37a90abe6eb..d8d44cd1994 100644 --- a/client/src/templates/Challenges/odin/show.tsx +++ b/client/src/templates/Challenges/odin/show.tsx @@ -231,6 +231,12 @@ class ShowOdin extends Component { const blockNameTitle = `${t( `intro:${superBlock}.blocks.${block}.title` )} - ${title}`; + + const feedback = + this.state.selectedOption !== null + ? answers[this.state.selectedOption].feedback + : undefined; + return ( { @@ -307,7 +313,7 @@ class ShowOdin extends Component {

{t('learn.question')}

- {answers.map((option, index) => ( + {answers.map(({ answer }, index) => ( ))} @@ -338,7 +344,16 @@ class ShowOdin extends Component { }} > {this.state.isWrongAnswer && ( - {t('learn.wrong-answer')} + + {feedback ? ( + + ) : ( + t('learn.wrong-answer') + )} + )} {!this.state.allAssignmentsCompleted && assignments.length > 0 && ( @@ -420,7 +435,10 @@ export const query = graphql` } question { text - answers + answers { + answer + feedback + } solution } translationPending diff --git a/client/src/templates/Challenges/video.css b/client/src/templates/Challenges/video.css index 13ffe992c83..dcbe0cfd18c 100644 --- a/client/src/templates/Challenges/video.css +++ b/client/src/templates/Challenges/video.css @@ -114,3 +114,7 @@ input:focus-visible + .video-quiz-input-visible { /* remove default prism background */ background: none; } + +.multiple-choice-feedback p { + margin-bottom: 0; +} diff --git a/client/src/templates/Challenges/video/show.tsx b/client/src/templates/Challenges/video/show.tsx index 8348f54f84a..1a26ed9d4cb 100644 --- a/client/src/templates/Challenges/video/show.tsx +++ b/client/src/templates/Challenges/video/show.tsx @@ -208,6 +208,12 @@ class ShowVideo extends Component { const blockNameTitle = `${t( `intro:${superBlock}.blocks.${block}.title` )} - ${title}`; + + const feedback = + this.state.selectedOption !== null + ? answers[this.state.selectedOption].feedback + : undefined; + return ( { @@ -257,7 +263,7 @@ class ShowVideo extends Component {
- {answers.map((option, index) => ( + {answers.map(({ answer }, index) => ( // answers are static and have no natural id property, so // index should be fine as a key: