mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Minor fixes
This commit is contained in:
parent
8db658e7a0
commit
490f4dab76
4 changed files with 116 additions and 104 deletions
|
|
@ -19,7 +19,7 @@ interface Props {
|
||||||
const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
|
const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
const { question, showAnswer, handleOnSubmitAnswer, students, isDisplayOnly, passedAnswer } = props;
|
const { question, showAnswer, handleOnSubmitAnswer, students, isDisplayOnly, passedAnswer } = props;
|
||||||
const [answer, setAnswer] = useState<AnswerType>(passedAnswer || '');
|
const [answer, setAnswer] = useState<AnswerType>(passedAnswer || '');
|
||||||
const [pickRates, setPickRates] = useState<number[]>([]);
|
const [pickRates, setPickRates] = useState<{ percentages: number[], counts: number[], totalCount: number }>({ percentages: [], counts: [], totalCount: 0 });
|
||||||
const [showCorrectAnswers, setShowCorrectAnswers] = useState(false);
|
const [showCorrectAnswers, setShowCorrectAnswers] = useState(false);
|
||||||
|
|
||||||
let disableButton = false;
|
let disableButton = false;
|
||||||
|
|
@ -37,20 +37,26 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
const calculatePickRates = () => {
|
const calculatePickRates = () => {
|
||||||
if (!students || students.length === 0) {
|
if (!students || students.length === 0) {
|
||||||
setPickRates(new Array(question.choices.length).fill(0)); // Fill with 0 for each choice
|
setPickRates({ percentages: new Array(question.choices.length).fill(0), counts: new Array(question.choices.length).fill(0), totalCount: 0 });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rates = question.choices.map(choice => {
|
const rates: number[] = [];
|
||||||
const choiceAnswers = students.filter(student =>
|
const counts: number[] = [];
|
||||||
|
let totalResponses = 0;
|
||||||
|
|
||||||
|
question.choices.forEach(choice => {
|
||||||
|
const choiceCount = students.filter(student =>
|
||||||
student.answers.some(ans =>
|
student.answers.some(ans =>
|
||||||
ans.idQuestion === Number(question.id) && ans.answer === choice.formattedText.text
|
ans.idQuestion === Number(question.id) && ans.answer === choice.formattedText.text
|
||||||
)
|
)
|
||||||
).length;
|
).length;
|
||||||
return (choiceAnswers / students.length) * 100;
|
totalResponses += choiceCount;
|
||||||
|
rates.push((choiceCount / students.length) * 100);
|
||||||
|
counts.push(choiceCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
setPickRates(rates);
|
setPickRates({ percentages: rates, counts: counts, totalCount: totalResponses });
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -76,7 +82,7 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
{question.choices.map((choice, i) => {
|
{question.choices.map((choice, i) => {
|
||||||
const selected = answer === choice.formattedText.text ? 'selected' : '';
|
const selected = answer === choice.formattedText.text ? 'selected' : '';
|
||||||
const rateStyle = showCorrectAnswers ? {
|
const rateStyle = showCorrectAnswers ? {
|
||||||
backgroundImage: `linear-gradient(to right, ${choice.isCorrect ? 'royalblue' : 'orange'} ${pickRates[i]}%, transparent ${pickRates[i]}%)`,
|
backgroundImage: `linear-gradient(to right, ${choice.isCorrect ? 'lightgreen' : 'lightcoral'} ${pickRates.percentages[i]}%, transparent ${pickRates.percentages[i]}%)`,
|
||||||
color: 'black'
|
color: 'black'
|
||||||
} : {};
|
} : {};
|
||||||
return (
|
return (
|
||||||
|
|
@ -114,7 +120,7 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedFeedback) }} />
|
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedFeedback) }} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showCorrectAnswers && <div className="pick-rate">{choice.isCorrect ? '✅' : '❌'} {pickRates[i].toFixed(1)}%</div>}
|
{showCorrectAnswers && <div className="pick-rate">{choice.isCorrect ? '✅' : '❌'} {`${pickRates.counts[i]}/${pickRates.totalCount} (${pickRates.percentages[i].toFixed(1)}%)`}</div>}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,9 @@ const ShortAnswerQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="question-wrapper">
|
<><div className="container question-wrapper">
|
||||||
|
<div className="row justify-content-center">
|
||||||
|
<div className="col-auto">
|
||||||
<div>
|
<div>
|
||||||
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedStem) }} />
|
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(question.formattedStem) }} />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -98,39 +100,37 @@ const ShortAnswerQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
setAnswer(e.target.value);
|
setAnswer(e.target.value);
|
||||||
} }
|
} }
|
||||||
disabled={showAnswer}
|
disabled={showAnswer}
|
||||||
aria-label="short-answer-input"
|
aria-label="short-answer-input" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{handleOnSubmitAnswer && (
|
{handleOnSubmitAnswer && (
|
||||||
|
<div className="col-auto d-flex flex-column align-items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={() =>
|
onClick={() => answer !== undefined &&
|
||||||
answer !== undefined &&
|
|
||||||
handleOnSubmitAnswer &&
|
handleOnSubmitAnswer &&
|
||||||
handleOnSubmitAnswer(answer)
|
handleOnSubmitAnswer(answer)}
|
||||||
}
|
|
||||||
disabled={answer === null || answer === ''}
|
disabled={answer === null || answer === ''}
|
||||||
>
|
>
|
||||||
Répondre
|
Répondre
|
||||||
</Button>
|
</Button>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
{isDisplayOnly && (
|
{isDisplayOnly && (
|
||||||
<>
|
<>
|
||||||
<div style={{ marginTop: '10px' }}>
|
<div className="col-auto d-flex flex-column align-items-center">
|
||||||
<Button
|
<Button
|
||||||
|
style={{ marginTop: '10px' }}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={toggleShowCorrectAnswers}
|
onClick={toggleShowCorrectAnswers}
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
{showCorrectAnswers ? "Masquer les résultats" : "Afficher les résultats"}
|
{showCorrectAnswers ? "Masquer les résultats" : "Afficher les résultats"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
{showCorrectAnswers && (
|
||||||
<div style={{
|
<div>
|
||||||
visibility: showCorrectAnswers ? 'visible' : 'hidden'
|
|
||||||
}}>
|
|
||||||
<div>
|
<div>
|
||||||
Taux de réponse correcte: {submissionCounts.correctSubmissions}/{submissionCounts.totalSubmissions}
|
Taux de réponse correcte: {submissionCounts.correctSubmissions}/{submissionCounts.totalSubmissions}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -141,9 +141,12 @@ const ShortAnswerQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div></>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,13 @@ interface Props {
|
||||||
const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
|
const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
const { question, showAnswer, handleOnSubmitAnswer, students, passedAnswer, isDisplayOnly } = props;
|
const { question, showAnswer, handleOnSubmitAnswer, students, passedAnswer, isDisplayOnly } = props;
|
||||||
const [answer, setAnswer] = useState<boolean | undefined>(undefined);
|
const [answer, setAnswer] = useState<boolean | undefined>(undefined);
|
||||||
const [pickRates, setPickRates] = useState<{ trueRate: number, falseRate: number }>({ trueRate: 0, falseRate: 0 });
|
const [pickRates, setPickRates] = useState<{ trueRate: number, falseRate: number, trueCount: number, falseCount: number, totalCount: number }>({
|
||||||
|
trueRate: 0,
|
||||||
|
falseRate: 0,
|
||||||
|
trueCount: 0,
|
||||||
|
falseCount: 0,
|
||||||
|
totalCount: 0
|
||||||
|
});
|
||||||
const [showCorrectAnswers, setShowCorrectAnswers] = useState(false);
|
const [showCorrectAnswers, setShowCorrectAnswers] = useState(false);
|
||||||
|
|
||||||
let disableButton = false;
|
let disableButton = false;
|
||||||
|
|
@ -54,30 +60,27 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
// Calcul le pick rate de chaque réponse
|
// Calcul le pick rate de chaque réponse
|
||||||
const calculatePickRates = () => {
|
const calculatePickRates = () => {
|
||||||
if (!students) {
|
if (!students) {
|
||||||
setPickRates({ trueRate: 0, falseRate: 0 });
|
setPickRates({ trueRate: 0, falseRate: 0, trueCount: 0, falseCount: 0, totalCount: 0 });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalAnswers = students.length;
|
const totalAnswers = students.length;
|
||||||
|
|
||||||
const trueAnswers = students.filter(student =>
|
const trueAnswers = students.filter(student =>
|
||||||
student.answers.some(ans =>
|
student.answers.some(ans =>
|
||||||
ans.idQuestion === Number(question.id) && ans.answer === true
|
ans.idQuestion === Number(question.id) && ans.answer === true
|
||||||
)).length;
|
)).length;
|
||||||
|
|
||||||
const falseAnswers = students.filter(student =>
|
const falseAnswers = students.filter(student =>
|
||||||
student.answers.some(ans =>
|
student.answers.some(ans =>
|
||||||
ans.idQuestion === Number(question.id) && ans.answer === false
|
ans.idQuestion === Number(question.id) && ans.answer === false
|
||||||
)).length;
|
)).length;
|
||||||
|
|
||||||
if (totalAnswers > 0) {
|
|
||||||
setPickRates({
|
setPickRates({
|
||||||
trueRate: (trueAnswers / totalAnswers) * 100,
|
trueRate: (trueAnswers / totalAnswers) * 100,
|
||||||
falseRate: (falseAnswers / totalAnswers) * 100
|
falseRate: (falseAnswers / totalAnswers) * 100,
|
||||||
|
trueCount: trueAnswers,
|
||||||
|
falseCount: falseAnswers,
|
||||||
|
totalCount: totalAnswers
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
setPickRates({ trueRate: 0, falseRate: 0 });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -102,7 +105,7 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
</div>
|
</div>
|
||||||
{showCorrectAnswers && (
|
{showCorrectAnswers && (
|
||||||
<>
|
<>
|
||||||
<div className="pick-rate">{question.isTrue ? '✅' : '❌'} {pickRates.trueRate.toFixed(1)}%</div>
|
<div className="pick-rate">{question.isTrue ? '✅' : '❌'} {pickRates.trueRate}/{pickRates.totalCount} ({pickRates.trueRate.toFixed(1)}%)</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -131,7 +134,7 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
{showCorrectAnswers && (
|
{showCorrectAnswers && (
|
||||||
<>
|
<>
|
||||||
<div className="pick-rate">{!question.isTrue ? '✅' : '❌'} {pickRates.falseRate.toFixed(1)}%</div>
|
<div className="pick-rate">{!question.isTrue ? '✅' : '❌'} {pickRates.falseCount}/{pickRates.totalCount} ({pickRates.falseRate.toFixed(1)}%)</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,6 @@
|
||||||
|
|
||||||
.pick-rate{
|
.pick-rate{
|
||||||
color: rgba(0,0,0,1);
|
color: rgba(0,0,0,1);
|
||||||
min-width: 70px;
|
min-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue