Changed approach to display level for Level Testing

This commit is contained in:
Joao Ramos
2023-12-13 00:11:48 +00:00
parent 21b612eaa4
commit 7b3c3d15db
4 changed files with 153 additions and 114 deletions

View File

@@ -1,5 +1,4 @@
import {infoButtonStyle} from "@/constants/buttonStyles"; import {infoButtonStyle} from "@/constants/buttonStyles";
import {BAND_SCORES} from "@/constants/ielts";
import {Module} from "@/interfaces"; import {Module} from "@/interfaces";
import {User} from "@/interfaces/user"; import {User} from "@/interfaces/user";
import useExamStore from "@/stores/examStore"; import useExamStore from "@/stores/examStore";

View File

@@ -2,96 +2,119 @@ import {Module} from "@/interfaces";
export const MODULES: Module[] = ["reading", "listening", "writing", "speaking"]; export const MODULES: Module[] = ["reading", "listening", "writing", "speaking"];
export const BAND_SCORES: {[key in Module]: number[]} = { // BAND SCORES is not in use anymore and level scoring is made based on thresholds
reading: [0, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9], // export const BAND_SCORES: {[key in Module]: number[]} = {
listening: [0, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9], // reading: [0, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9],
writing: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // listening: [0, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9],
speaking: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // writing: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
level: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // speaking: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
}; // level: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
// };
export const moduleResultText = (level: number) => { export type LevelScore = "Advanced" | "Upper-Intermediate" | "Intermediate" | "Pre-Intermediate" | "Elementary" | "Beginner";
if (level === 9) {
return (
<>
Congratulations on your exam performance! You achieved an impressive <span className="font-bold">level {level}</span>, demonstrating
excellent mastery of the assessed knowledge.
<br />
<br />
If you disagree with the result, you can request a review by a qualified teacher. We are committed to the accuracy and transparency of
the results.
<br />
<br />
Please contact us for further information. Congratulations again on your outstanding achievement! We are here to support you on your
academic journey.
</>
);
}
if (level >= 6) {
return (
<>
Congratulations on your exam performance! You achieved a commendable <span className="font-bold">level {level}</span>, demonstrating a
good understanding of the assessed knowledge.
<br />
<br />
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and
transparency of the results.
<br />
<br />
Please contact us for further information. Congratulations again on your achievement! We are here to support you on your academic
journey.
</>
);
}
if (level >= 3) { const generateHighestScoreText = () : React.ReactNode => (
return ( <>
<> <br />
Congratulations on your exam performance! You achieved a <span className="font-bold">level of {level}</span>, demonstrating a <br />
satisfactory understanding of the assessed knowledge. If you disagree with the result, you can request a review by a qualified teacher. We are committed to the accuracy and transparency of
<br /> the results.
<br /> <br />
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and <br />
transparency of the results. Please contact us for further information. Congratulations again on your outstanding achievement! We are here to support you on your
<br /> academic journey.
<br /> </>
Please contact us for further information. Congratulations again on your achievement! We are here to support you on your academic );
journey.
</>
);
}
return ( const generateAverageScoreText = () : React.ReactNode => (
<> <>
Thank you for taking the exam. You achieved a <span className="font-bold">level {level}</span>, but unfortunately, it did not meet the <br />
required standards. <br />
<br /> If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and
<br /> transparency of the results.
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and <br />
transparency of the results. <br />
<br /> Please contact us for further information. Congratulations again on your achievement! We are here to support you on your academic
<br /> journey.
Please contact us for further information. We encourage you to continue your studies and wish you the best of luck in your future </>
endeavors. );
</>
); const generateLowestScoreText = () : React.ReactNode => (
}; <>
<br />
<br />
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and
transparency of the results.
<br />
<br />
Please contact us for further information. We encourage you to continue your studies and wish you the best of luck in your future
endeavors.
</>
)
export const levelResultText = (level: number) => { export const levelResultText = (level: number) => {
if(level === 9) {
return (
<>
{"Outstanding! Your command of English is excellent. Focus on fine-tuning subtle language nuances and exploring sophisticated vocabulary. Keep up the excellent work!"}
{generateHighestScoreText()}
</>
);
}
if(level >= 8) {
return (
<>
{"Impressive! You're approaching fluency. Continue refining nuances in grammar and expanding your vocabulary to express ideas more precisely."}
{generateAverageScoreText()}
</>
);
}
if(level >= 6) {
return (
<>
{"Great job! You're navigating the complexities of English. Keep honing your grammar skills and exploring more advanced vocabulary."}
{generateAverageScoreText()}
</>
);
}
if(level >= 4) {
return (
<>
{"Well done! You're moving beyond the basics. Work on expanding your vocabulary and refining your understanding of grammar structures."}
{generateAverageScoreText()}
</>
);
}
if(level >= 2) {
return (
<>
{"Good effort! You're making progress. Continue studying and pay attention to common vocabulary and fundamental grammar rules."}
{generateAverageScoreText()}
</>
);
}
if(level >= 0) {
return (
<>
{"Keep practicing! You're just starting, and improvement takes time. Focus on building your vocabulary and basic grammar skills."}
{generateLowestScoreText()}
</>
);
}
return null;
};
export const moduleResultText = (module: Module, level: number) => {
if(module === 'level') return levelResultText(level);
if (level === 9) { if (level === 9) {
return ( return (
<> <>
Congratulations on your exam performance! You achieved an impressive <span className="font-bold">level {level}</span>, demonstrating Congratulations on your exam performance! You achieved an impressive <span className="font-bold">level {level}</span>, demonstrating
excellent mastery of the assessed knowledge. excellent mastery of the assessed knowledge.
<br /> {generateHighestScoreText()}
<br />
If you disagree with the result, you can request a review by a qualified teacher. We are committed to the accuracy and transparency of
the results.
<br />
<br />
Please contact us for further information. Congratulations again on your outstanding achievement! We are here to support you on your
academic journey.
</> </>
); );
} }
@@ -101,14 +124,7 @@ export const levelResultText = (level: number) => {
<> <>
Congratulations on your exam performance! You achieved a commendable <span className="font-bold">level {level}</span>, demonstrating a Congratulations on your exam performance! You achieved a commendable <span className="font-bold">level {level}</span>, demonstrating a
good understanding of the assessed knowledge. good understanding of the assessed knowledge.
<br /> {generateAverageScoreText()}
<br />
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and
transparency of the results.
<br />
<br />
Please contact us for further information. Congratulations again on your achievement! We are here to support you on your academic
journey.
</> </>
); );
} }
@@ -118,14 +134,7 @@ export const levelResultText = (level: number) => {
<> <>
Congratulations on your exam performance! You achieved a <span className="font-bold">level of {level}</span>, demonstrating a Congratulations on your exam performance! You achieved a <span className="font-bold">level of {level}</span>, demonstrating a
satisfactory understanding of the assessed knowledge. satisfactory understanding of the assessed knowledge.
<br /> {generateAverageScoreText()}
<br />
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and
transparency of the results.
<br />
<br />
Please contact us for further information. Congratulations again on your achievement! We are here to support you on your academic
journey.
</> </>
); );
} }
@@ -134,14 +143,7 @@ export const levelResultText = (level: number) => {
<> <>
Thank you for taking the exam. You achieved a <span className="font-bold">level {level}</span>, but unfortunately, it did not meet the Thank you for taking the exam. You achieved a <span className="font-bold">level {level}</span>, but unfortunately, it did not meet the
required standards. required standards.
<br /> {generateLowestScoreText()}
<br />
If you have any concerns about the result, you can request a review by a qualified teacher. We are committed to the accuracy and
transparency of the results.
<br />
<br />
Please contact us for further information. We encourage you to continue your studies and wish you the best of luck in your future
endeavors.
</> </>
); );
}; };

View File

@@ -10,6 +10,8 @@ import Link from "next/link";
import {useRouter} from "next/router"; import {useRouter} from "next/router";
import {Fragment, useEffect, useState} from "react"; import {Fragment, useEffect, useState} from "react";
import {BsArrowCounterclockwise, BsBook, BsClipboard, BsEyeFill, BsHeadphones, BsMegaphone, BsPen, BsShareFill} from "react-icons/bs"; import {BsArrowCounterclockwise, BsBook, BsClipboard, BsEyeFill, BsHeadphones, BsMegaphone, BsPen, BsShareFill} from "react-icons/bs";
import { LevelScore } from "@/constants/ielts";
import { getLevelScore } from "@/utils/score";
interface Score { interface Score {
module: Module; module: Module;
@@ -66,6 +68,24 @@ export default function Finish({user, scores, modules, isLoading, onViewResults}
return exam.exercises.length; return exam.exercises.length;
}; };
const bandScore: number = calculateBandScore(selectedScore.correct, selectedScore.total, selectedModule, user.focus);
const showLevel = (level: number) => {
if(selectedModule === "level") {
const [levelStr, grade] = getLevelScore(level);
return (
<div className="flex flex-col items-center justify-center gap-1">
<span className="text-xl font-bold">{levelStr}</span>
<span className="text-xl">{grade}</span>
</div>
)
}
return <span className="text-3xl font-bold">{level}</span>;
}
return ( return (
<> <>
<div className="w-full min-h-full h-fit flex flex-col items-center justify-between gap-8"> <div className="w-full min-h-full h-fit flex flex-col items-center justify-between gap-8">
@@ -142,7 +162,7 @@ export default function Finish({user, scores, modules, isLoading, onViewResults}
{!isLoading && ( {!isLoading && (
<div className="w-full flex gap-9 mt-32 items-center justify-between mb-20"> <div className="w-full flex gap-9 mt-32 items-center justify-between mb-20">
<span className="max-w-3xl"> <span className="max-w-3xl">
{moduleResultText(calculateBandScore(selectedScore.correct, selectedScore.total, selectedModule, user.focus))} {moduleResultText(selectedModule, bandScore)}
</span> </span>
<div className="flex gap-9 px-16"> <div className="flex gap-9 px-16">
<div <div
@@ -156,9 +176,7 @@ export default function Finish({user, scores, modules, isLoading, onViewResults}
moduleColors[selectedModule].inner, moduleColors[selectedModule].inner,
)}> )}>
<span className="text-xl">Level</span> <span className="text-xl">Level</span>
<span className="text-3xl font-bold"> {showLevel(bandScore)}
{calculateBandScore(selectedScore.correct, selectedScore.total, selectedModule, user.focus)}
</span>
</div> </div>
</div> </div>
<div className="flex flex-col gap-5"> <div className="flex flex-col gap-5">

View File

@@ -1,4 +1,5 @@
import {Module} from "@/interfaces"; import {Module} from "@/interfaces";
import { LevelScore } from "@/constants/ielts";
type Type = "academic" | "general"; type Type = "academic" | "general";
@@ -94,11 +95,12 @@ const academicMarking: {[key: number]: number} = {
}; };
const levelMarking: {[key: number]: number} = { const levelMarking: {[key: number]: number} = {
88: 9, 88: 9, // Advanced
64: 8, 64: 8 , // Upper-Intermediate
52: 6, 52: 6, // Intermediate
32: 4, 32: 4, // Pre-Intermediate
16: 2, 16: 2, // Elementary
0: 0, // Beginner
}; };
const moduleMarkings: {[key in Module]: {[key in Type]: {[key: number]: number}}} = { const moduleMarkings: {[key in Module]: {[key in Type]: {[key: number]: number}}} = {
@@ -142,3 +144,21 @@ export const calculateBandScore = (correct: number, total: number, module: Modul
export const calculateAverageLevel = (levels: {[key in Module]: number}) => { export const calculateAverageLevel = (levels: {[key in Module]: number}) => {
return Object.keys(levels).reduce((accumulator, current) => levels[current as Module] + accumulator, 0) / 4; return Object.keys(levels).reduce((accumulator, current) => levels[current as Module] + accumulator, 0) / 4;
}; };
export const getLevelScore = (level: number) => {
switch(level) {
case 0:
return ['Beginner', 'Low A1'];
case 2:
return ['Elementary', 'High A1/Low A2'];
case 4:
return ['Pre-Intermediate', 'High A2/Low B1'];
case 6:
return ['Intermediate', 'High B1/Low B2'];
case 8:
return ['Upper-Intermediate', 'High B2/Low C1'];
case 9:
return ['Advanced', 'C1'];
default: return [];
}
}