{{ $title }}
-{{ .Content | default "Please answer the questions below to complete the test." }}
+{{ $title }}
+{{ .Content | default "Please answer the questions below to complete the test." }}
+Preparing your test...
+ +Preparing your test...
diff --git a/assets/js/local-quiz-evaluator.js b/assets/js/local-quiz-evaluator.js new file mode 100644 index 0000000..1e2604e --- /dev/null +++ b/assets/js/local-quiz-evaluator.js @@ -0,0 +1,100 @@ +/** + * Local Quiz Evaluator — Dev Mode Only + * A simple client-side quiz evaluator for local development. + * This is NOT a replacement for the backend evaluator used in production. + */ + +window.LocalQuizEvaluator = (function () { + + /** + * Evaluates a single question against the submitted answer. + * @param {Object} question - The question object from front matter + * @param {string|string[]} submittedAnswer - The user's selected answer(s) + * @returns {{ correct: boolean, marks: number }} + */ + function evaluateQuestion(question, submittedAnswer) { + const correctAnswers = Array.isArray(question.answer) + ? question.answer.map(String) + : [String(question.answer)]; + + const submitted = Array.isArray(submittedAnswer) + ? submittedAnswer.map(String) + : [String(submittedAnswer)]; + + const isCorrect = + submitted.length === correctAnswers.length && + submitted.every((ans) => correctAnswers.includes(ans)); + + return { + correct: isCorrect, + marks: isCorrect ? (question.marks || 0) : 0, + }; + } + + /** + * Evaluates a full quiz submission. + * @param {Object[]} questions - Array of question objects + * @param {Object} answers - Map of question id → submitted answer + * @returns {{ totalMarks: number, obtainedMarks: number, passed: boolean, results: Object[] }} + */ + function evaluateQuiz(questions, answers, passPercentage) { + const threshold = passPercentage || 70; + let totalMarks = 0; + let obtainedMarks = 0; + const results = []; + + questions.forEach((question) => { + const mark = question.marks || 0; + totalMarks += mark; + + const submitted = answers[question.id]; + if (submitted === undefined || submitted === null) { + results.push({ + id: question.id, + correct: false, + marks: 0, + submittedAnswer: null, + correctAnswer: question.answer, + }); + return; + } + + const evaluation = evaluateQuestion(question, submitted); + obtainedMarks += evaluation.marks; + results.push({ + id: question.id, + correct: evaluation.correct, + marks: evaluation.marks, + submittedAnswer: submitted, + correctAnswer: question.answer, + }); + }); + + const percentage = totalMarks > 0 ? (obtainedMarks / totalMarks) * 100 : 0; + + return { + totalMarks, + obtainedMarks, + passed: percentage >= threshold, + percentage: Math.round(percentage), + results, + }; + } + + /** + * Selects a random subset of questions from the full bank. + * @param {Object[]} allQuestions + * @param {number} count + * @returns {Object[]} + */ + function selectQuestions(allQuestions, count) { + const shuffled = [...allQuestions].sort(() => Math.random() - 0.5); + return shuffled.slice(0, count); + } + + return { + evaluateQuiz, + evaluateQuestion, + selectQuestions, + }; +})(); \ No newline at end of file diff --git a/layouts/test/baseof.html b/layouts/test/baseof.html index e21b0b4..a37cda7 100644 --- a/layouts/test/baseof.html +++ b/layouts/test/baseof.html @@ -6,6 +6,20 @@
+ {{ if hugo.IsServer }} +{{ .Content | default "Please answer the questions below to complete the test." }}
+{{ .Content | default "Please answer the questions below to complete the test." }}
+Preparing your test...
+ +Preparing your test...