Student result page of questionnaire

This commit is contained in:
Rotimi Best
2021-07-10 15:47:43 +00:00
parent 2aaaa7de58
commit d7968895b2
4 changed files with 100 additions and 35 deletions
@@ -1,5 +1,6 @@
<script> <script>
import { questionnaire } from "./store/index"; import { questionnaire } from "./store/index";
import { userQuestionniareAnswers } from "./store/answers";
import RadioQuestion from "../../../../Question/RadioQuestion/index.svelte"; import RadioQuestion from "../../../../Question/RadioQuestion/index.svelte";
import CheckboxQuestion from "../../../../Question/CheckboxQuestion/index.svelte"; import CheckboxQuestion from "../../../../Question/CheckboxQuestion/index.svelte";
import TextareaQuestion from "../../../../Question/TextareaQuestion/index.svelte"; import TextareaQuestion from "../../../../Question/TextareaQuestion/index.svelte";
@@ -10,51 +11,45 @@
export let preview; export let preview;
let answers = {};
let currentQuestionIndex = 0;
let currentQuestion = {}; let currentQuestion = {};
let renderProps = {}; let renderProps = {};
let progressValue = 0;
let isAnswerCorrect; let isAnswerCorrect;
let isFinished;
const { questions, title, description } = $questionnaire; const { questions, title, description } = $questionnaire;
function handleStart() { function handleStart() {
currentQuestionIndex += 1; $userQuestionniareAnswers.currentQuestionIndex += 1;
} }
function onSubmit(id, value) { function onSubmit(id, value) {
const prevAnswer = answers[id] || []; const prevAnswer = $userQuestionniareAnswers.answers[id] || [];
const formattedAnswer = const formattedAnswer =
typeof value === "string" typeof value === "string"
? value ? value
: removeDuplicate([...prevAnswer, ...(value || [])]); : removeDuplicate([...prevAnswer, ...(value || [])]);
answers = { $userQuestionniareAnswers.answers = {
...answers, ...$userQuestionniareAnswers.answers,
[id]: formattedAnswer, [id]: formattedAnswer,
}; };
if (isAnswerCorrect) { if (isAnswerCorrect) {
currentQuestionIndex += 1; $userQuestionniareAnswers.currentQuestionIndex += 1;
} }
} }
function onPrevious() { function onPrevious() {
currentQuestionIndex -= 1; $userQuestionniareAnswers.currentQuestionIndex -= 1;
} }
function wasCorrectAnswerSelected(currentQuestion) { function wasCorrectAnswerSelected(currentQuestion) {
const isOpenQuesiton = currentQuestion.type === QUESTION_TYPE.TEXTAREA; const isOpenQuesiton = currentQuestion.type === QUESTION_TYPE.TEXTAREA;
if (isOpenQuesiton) { if (isOpenQuesiton) {
isAnswerCorrect = true;
return true; return true;
} }
const answer = answers[currentQuestion.id]; const answer = $userQuestionniareAnswers.answers[currentQuestion.id];
const formattedAnswers = typeof answer === "string" ? [answer] : answer; const formattedAnswers = typeof answer === "string" ? [answer] : answer;
const options = currentQuestion.options;
isAnswerCorrect = isAnswerCorrect =
formattedAnswers && formattedAnswers &&
@@ -90,8 +85,11 @@
onPrevious, onPrevious,
disablePreviousButton: questionIndex === 1, disablePreviousButton: questionIndex === 1,
isLast, isLast,
isPreview: preview || isFinished, isPreview: preview || $userQuestionniareAnswers.isFinished,
disabled: wasCorrectAnswerSelected(question) && isFinished, disabled:
($userQuestionniareAnswers.isFinished &&
wasCorrectAnswerSelected(question)) ||
$userQuestionniareAnswers.isFinished,
nextButtonProps: isLast nextButtonProps: isLast
? { ? {
label: "Finish", label: "Finish",
@@ -115,8 +113,17 @@
}; };
} }
function getTotalScores(scoresObject) {
let total = 0;
for (const score in scoresObject) {
total += score;
}
return total;
}
function getProgressValue(currentQuestionIndex) { function getProgressValue(currentQuestionIndex) {
if (isFinished) { if ($userQuestionniareAnswers.isFinished) {
return 100; return 100;
} }
@@ -126,46 +133,64 @@
} }
$: { $: {
currentQuestion = questions[currentQuestionIndex - 1]; currentQuestion =
if (currentQuestionIndex > 0 && !currentQuestion) { questions[$userQuestionniareAnswers.currentQuestionIndex - 1];
isFinished = true; if (
$userQuestionniareAnswers.currentQuestionIndex > 0 &&
!currentQuestion
) {
$userQuestionniareAnswers.isFinished = true;
} }
if (currentQuestion) { if (currentQuestion) {
renderProps = getRenderProps( renderProps = getRenderProps(
currentQuestion, currentQuestion,
currentQuestionIndex, $userQuestionniareAnswers.currentQuestionIndex,
answers $userQuestionniareAnswers.answers
); );
} }
} }
$: progressValue = getProgressValue(currentQuestionIndex); $: $userQuestionniareAnswers.progressValue = getProgressValue(
$userQuestionniareAnswers.currentQuestionIndex
);
</script> </script>
<!-- <svelte:window on:keydown={handleKeydown} /> --> <!-- <svelte:window on:keydown={handleKeydown} /> -->
{#if !preview && currentQuestionIndex > 0} {#if !preview && !$userQuestionniareAnswers.isFinished}
<Progress value={progressValue} /> <Progress value={$userQuestionniareAnswers.progressValue} />
{/if} {/if}
{#if preview} {#if preview}
{#each questions as currentQuestion, currentQuestionIndex} {#each questions as currentQuestion, currentQuestionIndex}
{#if QUESTION_TYPE.RADIO === currentQuestion.type} {#if QUESTION_TYPE.RADIO === currentQuestion.type}
<RadioQuestion <RadioQuestion
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)} {...getRenderProps(
currentQuestion,
currentQuestionIndex + 1,
$userQuestionniareAnswers.answers
)}
/> />
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type} {:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
<CheckboxQuestion <CheckboxQuestion
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)} {...getRenderProps(
currentQuestion,
currentQuestionIndex + 1,
$userQuestionniareAnswers.answers
)}
/> />
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type} {:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type}
<TextareaQuestion <TextareaQuestion
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)} {...getRenderProps(
currentQuestion,
currentQuestionIndex + 1,
$userQuestionniareAnswers.answers
)}
/> />
{/if} {/if}
{/each} {/each}
{:else if currentQuestionIndex === 0} {:else if $userQuestionniareAnswers.currentQuestionIndex === 0}
<div> <div>
<h2 class="my-1">{title}</h2> <h2 class="my-1">{title}</h2>
<p>{description}</p> <p>{description}</p>
@@ -177,20 +202,49 @@
type="button" type="button"
/> />
</div> </div>
{:else if isFinished} {:else if $userQuestionniareAnswers.isFinished}
<h2 class="text-lg">Congratulations you have completed your task</h2> <div class="flex items-center justify-between">
<div class="flex flex-col justify-between">
<h2 class="text-xl mb-2 mt-0">{title}</h2>
<span
class="bg-green-700 text-white rounded-full py-2 px-6 text-center"
title="Status: Pending Review"
>
Pending Review
</span>
</div>
<span
class="border-2 border-gray-700 rounded-full h-24 w-24 flex items-center justify-center text-2xl"
title="Status: Pending Review"
>
{getTotalScores($userQuestionniareAnswers.scores)}/100
</span>
</div>
{#each questions as currentQuestion, currentQuestionIndex} {#each questions as currentQuestion, currentQuestionIndex}
{#if QUESTION_TYPE.RADIO === currentQuestion.type} {#if QUESTION_TYPE.RADIO === currentQuestion.type}
<RadioQuestion <RadioQuestion
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)} {...getRenderProps(
currentQuestion,
currentQuestionIndex + 1,
$userQuestionniareAnswers.answers
)}
/> />
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type} {:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
<CheckboxQuestion <CheckboxQuestion
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)} {...getRenderProps(
currentQuestion,
currentQuestionIndex + 1,
$userQuestionniareAnswers.answers
)}
/> />
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type} {:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type}
<TextareaQuestion <TextareaQuestion
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)} {...getRenderProps(
currentQuestion,
currentQuestionIndex + 1,
$userQuestionniareAnswers.answers
)}
/> />
{/if} {/if}
{/each} {/each}
@@ -0,0 +1,9 @@
import { writable } from "svelte/store";
export const userQuestionniareAnswers = writable({
answers: {},
scores: {},
currentQuestionIndex: 5,
isFinished: true,
progressValue: 100,
});
@@ -13,6 +13,7 @@
export let onPrevious = () => {}; export let onPrevious = () => {};
export let defaultValue = []; export let defaultValue = [];
export let disablePreviousButton = false; export let disablePreviousButton = false;
export let disabled = false;
export let isPreview = false; export let isPreview = false;
export let nextButtonProps = {}; export let nextButtonProps = {};
@@ -74,7 +75,7 @@
value={option.id} value={option.id}
checked={defaultValue.includes(option.id)} checked={defaultValue.includes(option.id)}
label={option.label || option.value} label={option.label || option.value}
disabled={nextButtonProps.disableOptionSelect} {disabled}
/> />
</button> </button>
{/each} {/each}
@@ -13,6 +13,7 @@
export let onPrevious = () => {}; export let onPrevious = () => {};
export let defaultValue = ""; export let defaultValue = "";
export let disablePreviousButton = false; export let disablePreviousButton = false;
export let disabled = false;
export let isPreview = false; export let isPreview = false;
export let nextButtonProps = {}; export let nextButtonProps = {};
@@ -75,7 +76,7 @@
checked={defaultValue.includes(option.id) && checked={defaultValue.includes(option.id) &&
answers.includes(option.id)} answers.includes(option.id)}
label={option.label || option.value} label={option.label || option.value}
disabled={nextButtonProps.disableOptionSelect} {disabled}
/> />
</button> </button>
{/each} {/each}