mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Some tests passing (MultipleChoiceQuestionDisplay.test.ts)
This commit is contained in:
parent
6f270b5436
commit
39a7ecce31
15 changed files with 327 additions and 276 deletions
215
client/package-lock.json
generated
215
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -25,7 +25,7 @@
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.7",
|
||||||
"dompurify": "^3.2.3",
|
"dompurify": "^3.2.3",
|
||||||
"esbuild": "^0.23.1",
|
"esbuild": "^0.23.1",
|
||||||
"gift-pegjs": "^1.0.2",
|
"gift-pegjs": "file:../GIFT-grammar-PEG.js",
|
||||||
"jest-environment-jsdom": "^29.7.0",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"katex": "^0.16.11",
|
"katex": "^0.16.11",
|
||||||
"marked": "^14.1.2",
|
"marked": "^14.1.2",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
import { GIFTQuestion } from 'gift-pegjs';
|
|
||||||
|
|
||||||
export interface QuestionType {
|
|
||||||
question: GIFTQuestion;
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
//QuestionType.test.tsx
|
//QuestionType.test.tsx
|
||||||
import { GIFTQuestion } from 'gift-pegjs';
|
import { Question } from 'gift-pegjs';
|
||||||
import { QuestionType } from '../../Types/QuestionType';
|
|
||||||
|
|
||||||
const sampleStem = 'Sample question stem';
|
const sampleStem = 'Sample question stem';
|
||||||
const options = ['Option A', 'Option B'];
|
const options = ['Option A', 'Option B'];
|
||||||
|
|
@ -8,30 +7,28 @@ const sampleFormat = 'plain';
|
||||||
const sampleType = 'MC';
|
const sampleType = 'MC';
|
||||||
const sampleTitle = 'Sample Question';
|
const sampleTitle = 'Sample Question';
|
||||||
|
|
||||||
const mockQuestion: GIFTQuestion = {
|
const mockQuestion: Question = {
|
||||||
id: '1',
|
id: '1',
|
||||||
type: sampleType,
|
type: sampleType,
|
||||||
stem: { format: sampleFormat, text: sampleStem },
|
formattedStem: { format: sampleFormat, text: sampleStem },
|
||||||
title: sampleTitle,
|
title: sampleTitle,
|
||||||
hasEmbeddedAnswers: false,
|
hasEmbeddedAnswers: false,
|
||||||
globalFeedback: null,
|
|
||||||
choices: [
|
choices: [
|
||||||
{ text: { format: sampleFormat, text: options[0] }, isCorrect: true, weight: 1, feedback: null },
|
{ formattedText: { format: sampleFormat, text: options[0] }, isCorrect: true, weight: 1 },
|
||||||
{ text: { format: sampleFormat, text: options[1] }, isCorrect: false, weight: 0, feedback: null },
|
{ formattedText: { format: sampleFormat, text: options[1] }, isCorrect: false, weight: 0 },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockQuestionType: QuestionType = {
|
const mockQuestionType = mockQuestion;
|
||||||
question: mockQuestion,
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('QuestionType', () => {
|
// test seems useless (it's broken) now that gift-pegjs has TypeScript types (and its own tests)
|
||||||
|
describe.skip('QuestionType', () => {
|
||||||
test('has the expected structure', () => {
|
test('has the expected structure', () => {
|
||||||
expect(mockQuestionType).toEqual(expect.objectContaining({
|
expect(mockQuestionType).toEqual(expect.objectContaining({
|
||||||
question: expect.any(Object),
|
question: expect.any(Object),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
expect(mockQuestionType.question).toEqual(expect.objectContaining({
|
expect(mockQuestionType).toEqual(expect.objectContaining({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
type: expect.any(String),
|
type: expect.any(String),
|
||||||
stem: expect.objectContaining({
|
stem: expect.objectContaining({
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// TextType.test.ts
|
// TextType.test.ts
|
||||||
|
|
||||||
import { TextFormat } from "gift-pegjs";
|
|
||||||
import textType from "src/components/GiftTemplate/templates/TextType";
|
import textType from "src/components/GiftTemplate/templates/TextType";
|
||||||
|
import { TextFormat } from "gift-pegjs";
|
||||||
|
|
||||||
describe('TextType', () => {
|
describe('TextType', () => {
|
||||||
it('should format text with basic characters correctly', () => {
|
it('should format text with basic characters correctly', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,39 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, fireEvent } from '@testing-library/react';
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
import MultipleChoiceQuestion from 'src/components/Questions/MultipleChoiceQuestion/MultipleChoiceQuestion';
|
import MultipleChoiceQuestionDisplay from 'src/components/Questions/MultipleChoiceQuestionDisplay/MultipleChoiceQuestionDisplay';
|
||||||
import { act } from 'react';
|
import { act } from 'react';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { MultipleChoiceQuestion, parse } from 'gift-pegjs';
|
||||||
|
|
||||||
const questionStem = 'Question stem';
|
const questions = parse(
|
||||||
const sampleFeedback = 'Feedback';
|
`::Sample Question 1:: Question stem
|
||||||
|
{
|
||||||
|
=Choice 1
|
||||||
|
~Choice 2
|
||||||
|
}`) as MultipleChoiceQuestion[];
|
||||||
|
|
||||||
describe('MultipleChoiceQuestion', () => {
|
const question = questions[0];
|
||||||
|
|
||||||
|
describe('MultipleChoiceQuestionDisplay', () => {
|
||||||
const mockHandleOnSubmitAnswer = jest.fn();
|
const mockHandleOnSubmitAnswer = jest.fn();
|
||||||
const choices = [
|
const choices = question.choices;
|
||||||
{ feedback: null, isCorrect: true, text: { format: 'plain', text: 'Choice 1' } },
|
|
||||||
{ feedback: null, isCorrect: false, text: { format: 'plain', text: 'Choice 2' } }
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
render(
|
render(
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<MultipleChoiceQuestion
|
<MultipleChoiceQuestionDisplay
|
||||||
globalFeedback={sampleFeedback}
|
question={question}
|
||||||
choices={choices}
|
|
||||||
handleOnSubmitAnswer={mockHandleOnSubmitAnswer}
|
handleOnSubmitAnswer={mockHandleOnSubmitAnswer}
|
||||||
questionStem={{ text: questionStem, format: 'plain' }} />
|
showAnswer={false}
|
||||||
|
/>
|
||||||
</MemoryRouter>);
|
</MemoryRouter>);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders the question and choices', () => {
|
test('renders the question and choices', () => {
|
||||||
expect(screen.getByText(questionStem)).toBeInTheDocument();
|
expect(screen.getByText(question.formattedStem.text)).toBeInTheDocument();
|
||||||
choices.forEach((choice) => {
|
choices.forEach((choice) => {
|
||||||
expect(screen.getByText(choice.text.text)).toBeInTheDocument();
|
expect(screen.getByText(choice.formattedText.text)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, fireEvent } from '@testing-library/react';
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
import Questions from 'src/components/Questions/Question';
|
import Questions from 'src/components/Questions/QuestionDisplay';
|
||||||
import { GIFTQuestion } from 'gift-pegjs';
|
import { GIFTQuestion } from 'gift-pegjs';
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,20 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, fireEvent, act } from '@testing-library/react';
|
import { render, screen, fireEvent, act } from '@testing-library/react';
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
import { parse } from 'gift-pegjs';
|
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import { QuestionType } from '../../../../Types/QuestionType';
|
import { Question } from 'gift-pegjs';
|
||||||
import StudentModeQuiz from 'src/components/StudentModeQuiz/StudentModeQuiz';
|
import StudentModeQuiz from 'src/components/StudentModeQuiz/StudentModeQuiz';
|
||||||
|
import { parse } from 'gift-pegjs';
|
||||||
|
|
||||||
const mockGiftQuestions = parse(
|
const mockGiftQuestions = parse(
|
||||||
`::Sample Question 1:: Sample Question 1 {=Option A ~Option B}
|
`::Sample Question 1:: Sample Question 1 {=Option A ~Option B}
|
||||||
|
|
||||||
::Sample Question 2:: Sample Question 2 {T}`);
|
::Sample Question 2:: Sample Question 2 {T}`);
|
||||||
|
|
||||||
const mockQuestions: QuestionType[] = mockGiftQuestions.map((question, index) => {
|
const mockQuestions: Question[] = mockGiftQuestions.map((question, index) => {
|
||||||
question.id = (index + 1).toString();
|
if (question.type !== "Category")
|
||||||
const newMockQuestion: QuestionType = {
|
question.id = (index + 1).toString();
|
||||||
question: question,
|
const newMockQuestion = question;
|
||||||
};
|
|
||||||
return newMockQuestion;
|
return newMockQuestion;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export function formatLatex(text: string): string {
|
||||||
* @see marked
|
* @see marked
|
||||||
* @see katex
|
* @see katex
|
||||||
*/
|
*/
|
||||||
export default function textType({ text }: TextTypeOptions) {
|
export function textType({ text }: TextTypeOptions) {
|
||||||
const formatText = formatLatex(text.text.trim()); // latex needs pure "&", ">", etc. Must not be escaped
|
const formatText = formatLatex(text.text.trim()); // latex needs pure "&", ">", etc. Must not be escaped
|
||||||
let parsedText = '';
|
let parsedText = '';
|
||||||
switch (text.format) {
|
switch (text.format) {
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,25 @@
|
||||||
// MultipleChoiceQuestion.tsx
|
// MultipleChoiceQuestionDisplay.tsx
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import '../questionStyle.css';
|
import '../questionStyle.css';
|
||||||
import { Button } from '@mui/material';
|
import { Button } from '@mui/material';
|
||||||
import textType, { formatLatex } from '../../GiftTemplate/templates/TextType';
|
import { textType } from '../../GiftTemplate/templates/TextType';
|
||||||
import { TextFormat } from '../../GiftTemplate/templates/types';
|
import { MultipleChoiceQuestion } from 'gift-pegjs';
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
// import Latex from 'react-latex';
|
|
||||||
|
|
||||||
type Choices = {
|
|
||||||
feedback: { format: string; text: string } | null;
|
|
||||||
isCorrect: boolean;
|
|
||||||
text: { format: string; text: string };
|
|
||||||
weigth?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
questionStem: TextFormat;
|
question: MultipleChoiceQuestion;
|
||||||
choices: Choices[];
|
|
||||||
globalFeedback?: string | undefined;
|
|
||||||
handleOnSubmitAnswer?: (answer: string) => void;
|
handleOnSubmitAnswer?: (answer: string) => void;
|
||||||
showAnswer?: boolean;
|
showAnswer?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MultipleChoiceQuestion: React.FC<Props> = (props) => {
|
const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
const { questionStem: questionContent, choices, showAnswer, handleOnSubmitAnswer, globalFeedback } = props;
|
const { question, showAnswer, handleOnSubmitAnswer } = props;
|
||||||
const [answer, setAnswer] = useState<string>();
|
const [answer, setAnswer] = useState<string>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAnswer(undefined);
|
setAnswer(undefined);
|
||||||
}, [questionContent]);
|
}, [question]);
|
||||||
|
|
||||||
const handleOnClickAnswer = (choice: string) => {
|
const handleOnClickAnswer = (choice: string) => {
|
||||||
setAnswer(choice);
|
setAnswer(choice);
|
||||||
|
|
@ -41,38 +31,40 @@ const MultipleChoiceQuestion: React.FC<Props> = (props) => {
|
||||||
return (
|
return (
|
||||||
<div className="question-container">
|
<div className="question-container">
|
||||||
<div className="question content">
|
<div className="question content">
|
||||||
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(textType({text: questionContent})) }} />
|
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(textType({text: question.formattedStem})) }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="choices-wrapper mb-1">
|
<div className="choices-wrapper mb-1">
|
||||||
{choices.map((choice, i) => {
|
{question.choices.map((choice, i) => {
|
||||||
const selected = answer === choice.text.text ? 'selected' : '';
|
const selected = answer === choice.formattedText.text ? 'selected' : '';
|
||||||
return (
|
return (
|
||||||
<div key={choice.text.text + i} className="choice-container">
|
<div key={choice.formattedText.text + i} className="choice-container">
|
||||||
<Button
|
<Button
|
||||||
variant="text"
|
variant="text"
|
||||||
className="button-wrapper"
|
className="button-wrapper"
|
||||||
onClick={() => !showAnswer && handleOnClickAnswer(choice.text.text)}
|
onClick={() => !showAnswer && handleOnClickAnswer(choice.formattedText.text)}
|
||||||
>
|
>
|
||||||
{choice.feedback === null &&
|
{choice.formattedFeedback === null &&
|
||||||
showAnswer &&
|
showAnswer &&
|
||||||
(choice.isCorrect ? '✅' : '❌')}
|
(choice.isCorrect ? '✅' : '❌')}
|
||||||
<div className={`circle ${selected}`}>{alphabet[i]}</div>
|
<div className={`circle ${selected}`}>{alphabet[i]}</div>
|
||||||
<div className={`answer-text ${selected}`}>
|
<div className={`answer-text ${selected}`}>
|
||||||
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(formatLatex(choice.text.text)) }} />
|
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(textType({ text: choice.formattedText })) }} />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
{choice.feedback && showAnswer && (
|
{choice.formattedFeedback && showAnswer && (
|
||||||
<div className="feedback-container mb-1 mt-1/2">
|
<div className="feedback-container mb-1 mt-1/2">
|
||||||
{choice.isCorrect ? '✅' : '❌'}
|
{choice.isCorrect ? '✅' : '❌'}
|
||||||
{choice.feedback?.text}
|
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(textType({ text: choice.formattedFeedback })) }} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
{globalFeedback && showAnswer && (
|
{question.formattedGlobalFeedback && showAnswer && (
|
||||||
<div className="global-feedback mb-2">{globalFeedback}</div>
|
<div className="global-feedback mb-2">
|
||||||
|
<p>${textType({ text: question.formattedGlobalFeedback })}</p>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!showAnswer && handleOnSubmitAnswer && (
|
{!showAnswer && handleOnSubmitAnswer && (
|
||||||
|
|
@ -92,4 +84,4 @@ const MultipleChoiceQuestion: React.FC<Props> = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MultipleChoiceQuestion;
|
export default MultipleChoiceQuestionDisplay;
|
||||||
|
|
@ -3,19 +3,19 @@ import React, { useState } from 'react';
|
||||||
import '../questionStyle.css';
|
import '../questionStyle.css';
|
||||||
import { Button, TextField } from '@mui/material';
|
import { Button, TextField } from '@mui/material';
|
||||||
import textType from '../../GiftTemplate/templates/TextType';
|
import textType from '../../GiftTemplate/templates/TextType';
|
||||||
import { TextFormat } from '../../GiftTemplate/templates/types';
|
import { TextFormat, NumericalAnswer, isHighLowNumericalAnswer, isMultipleNumericalAnswer, isRangeNumericalAnswer, isSimpleNumericalAnswer, SimpleNumericalAnswer, RangeNumericalAnswer, HighLowNumericalAnswer } from 'gift-pegjs';
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
type CorrectAnswer = {
|
// type CorrectAnswer = {
|
||||||
numberHigh?: number;
|
// numberHigh?: number;
|
||||||
numberLow?: number;
|
// numberLow?: number;
|
||||||
number?: number;
|
// number?: number;
|
||||||
type: string;
|
// type: string;
|
||||||
};
|
// };
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
questionContent: TextFormat;
|
questionContent: TextFormat;
|
||||||
correctAnswers: CorrectAnswer;
|
correctAnswers: NumericalAnswer;
|
||||||
globalFeedback?: string | undefined;
|
globalFeedback?: string | undefined;
|
||||||
handleOnSubmitAnswer?: (answer: number) => void;
|
handleOnSubmitAnswer?: (answer: number) => void;
|
||||||
showAnswer?: boolean;
|
showAnswer?: boolean;
|
||||||
|
|
@ -27,10 +27,21 @@ const NumericalQuestion: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
const [answer, setAnswer] = useState<number>();
|
const [answer, setAnswer] = useState<number>();
|
||||||
|
|
||||||
const correctAnswer =
|
let correctAnswer= '';
|
||||||
correctAnswers.type === 'high-low'
|
|
||||||
? `Entre ${correctAnswers.numberLow} et ${correctAnswers.numberHigh}`
|
if (isSimpleNumericalAnswer(correctAnswers)) {
|
||||||
: correctAnswers.number;
|
correctAnswer = `${(correctAnswers as SimpleNumericalAnswer).number}`;
|
||||||
|
} else if (isRangeNumericalAnswer(correctAnswers)) {
|
||||||
|
const choice = correctAnswers as RangeNumericalAnswer;
|
||||||
|
correctAnswer = `Entre ${choice.number - choice.range} et ${choice.number + choice.range}`;
|
||||||
|
} else if (isHighLowNumericalAnswer(correctAnswers)) {
|
||||||
|
const choice = correctAnswers as HighLowNumericalAnswer;
|
||||||
|
correctAnswer = `Entre ${choice.numberLow} et ${choice.numberHigh}`;
|
||||||
|
} else if (isMultipleNumericalAnswer(correctAnswers)) {
|
||||||
|
correctAnswer = `MultipleNumericalAnswer is not supported yet`;
|
||||||
|
} else {
|
||||||
|
throw new Error('Unknown numerical answer type');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="question-wrapper">
|
<div className="question-wrapper">
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,22 @@
|
||||||
// Question;tsx
|
// Question;tsx
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { GIFTQuestion } from 'gift-pegjs';
|
import { Question } from 'gift-pegjs';
|
||||||
|
|
||||||
import TrueFalseQuestion from './TrueFalseQuestion/TrueFalseQuestion';
|
import TrueFalseQuestion from './TrueFalseQuestion/TrueFalseQuestion';
|
||||||
import MultipleChoiceQuestion from './MultipleChoiceQuestion/MultipleChoiceQuestion';
|
import MultipleChoiceQuestionDisplay from './MultipleChoiceQuestionDisplay/MultipleChoiceQuestionDisplay';
|
||||||
import NumericalQuestion from './NumericalQuestion/NumericalQuestion';
|
import NumericalQuestion from './NumericalQuestion/NumericalQuestion';
|
||||||
import ShortAnswerQuestion from './ShortAnswerQuestion/ShortAnswerQuestion';
|
import ShortAnswerQuestion from './ShortAnswerQuestion/ShortAnswerQuestion';
|
||||||
import useCheckMobileScreen from '../../services/useCheckMobileScreen';
|
import useCheckMobileScreen from '../../services/useCheckMobileScreen';
|
||||||
|
|
||||||
interface QuestionProps {
|
interface QuestionProps {
|
||||||
question: GIFTQuestion | undefined;
|
question: Question;
|
||||||
handleOnSubmitAnswer?: (answer: string | number | boolean) => void;
|
handleOnSubmitAnswer?: (answer: string | number | boolean) => void;
|
||||||
showAnswer?: boolean;
|
showAnswer?: boolean;
|
||||||
imageUrl?: string;
|
|
||||||
}
|
}
|
||||||
const Question: React.FC<QuestionProps> = ({
|
const QuestionDisplay: React.FC<QuestionProps> = ({
|
||||||
question,
|
question,
|
||||||
handleOnSubmitAnswer,
|
handleOnSubmitAnswer,
|
||||||
showAnswer,
|
showAnswer,
|
||||||
imageUrl
|
|
||||||
}) => {
|
}) => {
|
||||||
const isMobile = useCheckMobileScreen();
|
const isMobile = useCheckMobileScreen();
|
||||||
const imgWidth = useMemo(() => {
|
const imgWidth = useMemo(() => {
|
||||||
|
|
@ -30,22 +28,20 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
case 'TF':
|
case 'TF':
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<TrueFalseQuestion
|
<TrueFalseQuestion
|
||||||
questionContent={question.stem}
|
questionContent={question.formattedStem}
|
||||||
correctAnswer={question.isTrue}
|
correctAnswer={question.isTrue}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
globalFeedback={question.globalFeedback?.text}
|
globalFeedback={question.formattedGlobalFeedback?.text}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'MC':
|
case 'MC':
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<MultipleChoiceQuestion
|
<MultipleChoiceQuestionDisplay
|
||||||
questionStem={question.stem}
|
question={question}
|
||||||
choices={question.choices.map((choice, index) => ({ ...choice, id: index.toString() }))}
|
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
globalFeedback={question.globalFeedback?.text}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
@ -54,21 +50,21 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
if (!Array.isArray(question.choices)) {
|
if (!Array.isArray(question.choices)) {
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<NumericalQuestion
|
<NumericalQuestion
|
||||||
questionContent={question.stem}
|
questionContent={question.formattedStem}
|
||||||
correctAnswers={question.choices}
|
correctAnswers={question.choices}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
globalFeedback={question.globalFeedback?.text}
|
globalFeedback={question.formattedGlobalFeedback?.text}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
questionTypeComponent = (
|
questionTypeComponent = ( // TODO fix NumericalQuestion (correctAnswers is borked)
|
||||||
<NumericalQuestion
|
<NumericalQuestion
|
||||||
questionContent={question.stem}
|
questionContent={question.formattedStem}
|
||||||
correctAnswers={question.choices[0].text}
|
correctAnswers={question.choices}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
globalFeedback={question.globalFeedback?.text}
|
globalFeedback={question.formattedGlobalFeedback?.text}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -77,11 +73,11 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
case 'Short':
|
case 'Short':
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<ShortAnswerQuestion
|
<ShortAnswerQuestion
|
||||||
questionContent={question.stem}
|
questionContent={question.formattedStem}
|
||||||
choices={question.choices.map((choice, index) => ({ ...choice, id: index.toString() }))}
|
choices={question.choices.map((choice, index) => ({ ...choice, id: index.toString() }))}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
globalFeedback={question.globalFeedback?.text}
|
globalFeedback={question.formattedGlobalFeedback?.text}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
@ -106,4 +102,4 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Question;
|
export default QuestionDisplay;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// StudentModeQuiz.tsx
|
// StudentModeQuiz.tsx
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import QuestionComponent from '../Questions/Question';
|
import QuestionComponent from '../Questions/QuestionDisplay';
|
||||||
import '../../pages/Student/JoinRoom/joinRoom.css';
|
import '../../pages/Student/JoinRoom/joinRoom.css';
|
||||||
import { QuestionType } from '../../Types/QuestionType';
|
import { QuestionType } from '../../Types/QuestionType';
|
||||||
// import { QuestionService } from '../../services/QuestionService';
|
// import { QuestionService } from '../../services/QuestionService';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// TeacherModeQuiz.tsx
|
// TeacherModeQuiz.tsx
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import QuestionComponent from '../Questions/Question';
|
import QuestionComponent from '../Questions/QuestionDisplay';
|
||||||
|
|
||||||
import '../../pages/Student/JoinRoom/joinRoom.css';
|
import '../../pages/Student/JoinRoom/joinRoom.css';
|
||||||
import { QuestionType } from '../../Types/QuestionType';
|
import { QuestionType } from '../../Types/QuestionType';
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { Refresh, Error } from '@mui/icons-material';
|
||||||
import StudentWaitPage from 'src/components/StudentWaitPage/StudentWaitPage';
|
import StudentWaitPage from 'src/components/StudentWaitPage/StudentWaitPage';
|
||||||
import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton';
|
import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton';
|
||||||
//import QuestionNavigation from 'src/components/QuestionNavigation/QuestionNavigation';
|
//import QuestionNavigation from 'src/components/QuestionNavigation/QuestionNavigation';
|
||||||
import Question from 'src/components/Questions/Question';
|
import QuestionDisplay from 'src/components/Questions/QuestionDisplay';
|
||||||
import ApiService from '../../../services/ApiService';
|
import ApiService from '../../../services/ApiService';
|
||||||
|
|
||||||
const ManageRoom: React.FC = () => {
|
const ManageRoom: React.FC = () => {
|
||||||
|
|
@ -474,7 +474,7 @@ const ManageRoom: React.FC = () => {
|
||||||
<div className="preview-and-result-container">
|
<div className="preview-and-result-container">
|
||||||
|
|
||||||
{currentQuestion && (
|
{currentQuestion && (
|
||||||
<Question
|
<QuestionDisplay
|
||||||
showAnswer={false}
|
showAnswer={false}
|
||||||
question={currentQuestion?.question}
|
question={currentQuestion?.question}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue