Skip to content

Commit

Permalink
instructions multilanguage support
Browse files Browse the repository at this point in the history
  • Loading branch information
ananyajain10 committed Sep 16, 2024
1 parent f2ce09e commit 4dc78ef
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 231 deletions.
291 changes: 182 additions & 109 deletions src/components/InstructionPage.vue
Original file line number Diff line number Diff line change
@@ -1,116 +1,170 @@
<template>
<div>
<h4 class="text-lg font-bold m-6">Test Paper Overview</h4>
<!-- Table -->
<table class="table-auto mx-auto md:mx-0 m-4">
<!-- row 1 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Test Name</th>
<td class="border-black border-1 px-4 py-2" data-test="title">{{ $props.title }}</td>
</tr>
<!-- row 2 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Test Format</th>
<td class="border-black border-1 px-4 py-2" data-test="test-format">{{ testFormatMapping.get($props.testFormat || "") }} </td>
</tr>
<!-- row 3 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Duration</th>
<td class="border-black border-1 px-4 py-2" data-test="quiz-time-limit">{{ ($props.quizTimeLimit?.max || 0)/60 }} minutes</td>
</tr>
<!-- row 4 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Total Marks</th>
<td class="border-black border-1 px-4 py-2" data-test="total-marks">{{ $props.maxMarks }} Marks</td>
</tr>
<!-- row 5 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">No. of Questions</th>
<td class="border-black border-1 px-4 py-2" data-test="num-questions">{{ $props.maxQuestionsAllowedToAttempt }}</td>
</tr>
<!-- row 6 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Subjects</th>
<td class="border-black border-1 px-4 py-2" data-test="subject">{{ $props.subject }}</td>
</tr>
</table>
<!-- Test Paper Pattern(if FST) -->
<div v-if="isTestFST" data-test="test-fst">
<h4 class="text-lg font-bold m-6">Test Paper Pattern</h4>
<!-- Printing subjects extracted from questionSet.title -->
<p class="ml-6 mr-4 mb-2 text-justify">The following are the subjects in the test: <strong>
<span v-for="(part, index) in subjectNames" :key="part">
{{ index > 0 ? ', ' : '' }}{{ part }}
</span></strong>
</p>
<!-- iterating over every questionset and printing title and its description -->
<div
v-for="(questionSetState, index) in questionSetStates" :key="index">
<li class="text-base mt-2 ml-7 font-semibold leading-none mr-4" :data-test="`questionSetTitle-${index}`">{{ questionSetState.title }}</li>
<div class="text-base mx-2 mb-4 leading-tight text-slate-500 ml-12 mr-4" :data-test="`questionSetInstruction-${index}`" v-html="questionSetState.instructionText"></div>
<div>
<h4 class="text-lg font-bold m-6">Test Paper Overview</h4>
<!-- Table -->
<table class="table-auto mx-auto md:mx-0 m-4">
<!-- row 1 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Test Name</th>
<td class="border-black border-1 px-4 py-2" data-test="title">
{{ $props.title }}
</td>
</tr>
<!-- row 2 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Test Format</th>
<td class="border-black border-1 px-4 py-2" data-test="test-format">
{{ testFormatMapping.get($props.testFormat || "") }}
</td>
</tr>
<!-- row 3 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Duration</th>
<td class="border-black border-1 px-4 py-2" data-test="quiz-time-limit">
{{ ($props.quizTimeLimit?.max || 0) / 60 }} minutes
</td>
</tr>
<!-- row 4 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Total Marks</th>
<td class="border-black border-1 px-4 py-2" data-test="total-marks">
{{ $props.maxMarks }} Marks
</td>
</tr>
<!-- row 5 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">
No. of Questions
</th>
<td class="border-black border-1 px-4 py-2" data-test="num-questions">
{{ $props.maxQuestionsAllowedToAttempt }}
</td>
</tr>
<!-- row 6 -->
<tr>
<th class="border-black border-1 text-left px-4 py-2">Subjects</th>
<td class="border-black border-1 px-4 py-2" data-test="subject">
{{ $props.subject }}
</td>
</tr>
</table>
<!-- Test Paper Pattern(if FST) -->
<div v-if="isTestFST" data-test="test-fst">
<h4 class="text-lg font-bold m-6">Test Paper Pattern</h4>
<!-- Printing subjects extracted from questionSet.title -->
<p class="ml-6 mr-4 mb-2 text-justify">
The following are the subjects in the test:
<strong>
<span v-for="(part, index) in subjectNames" :key="part">
{{ index > 0 ? ", " : "" }}{{ part }}
</span></strong
>
</p>
<!-- iterating over every questionset and printing title and its description -->
<div v-for="(questionSetState, index) in questionSetStates" :key="index">
<li
class="text-base mt-2 ml-7 font-semibold leading-none mr-4"
:data-test="`questionSetTitle-${index}`"
>
{{ questionSetState.title }}
</li>
<div
class="text-base mx-2 mb-4 leading-tight text-slate-500 ml-12 mr-4"
:data-test="`questionSetInstruction-${index}`"
v-html="questionSetState.instructionText"
></div>
</div>
</div>
<!-- general Instruction -->
<!-- Locale Picker -->
<div class="flex justify-center p-4">
<LocalePicker
:options="localeOptions"
:currentLocale="currentLocale"
@update:locale="handleLocaleChange"
/>
</div>
<h4 class="text-lg font-bold m-6">{{ $t("generalInstructions.header") }}</h4>
<div class="ml-11 mr-4">
<ol class="text-justify">
<li>{{ $t("generalInstructions.timerInfo") }}</li>
<li>
{{ $t("generalInstructions.paletteInfo") }}
<span class="inline-flex items-baseline"
><BaseIcon
name="hamburger"
class="place-self-center w-4 h-4"
></BaseIcon
></span>
{{ $t("generalInstructions.expandPalette") }}
</li>
<li>
{{ $t("generalInstructions.paletteSymbols") }}
<div class="flex flex-wrap mx-2 md:mx-4 my-2">
<div class="flex items-center my-2 md:mx-4">
<Success></Success>
<span class="ml-6 mr-6">{{ $t("generalInstructions.answered") }}</span>
</div>
</div>
<!-- general Instruction -->
<h4 class="text-lg font-bold m-6">General Instructions</h4>
<div class="ml-11 mr-4">
<ol class="text-justify">
<li>The countdown timer in the top right corner of screen will display the remaining time available for you to complete the test. When the timer reaches zero, the test will end by itself. You will not be required to end or submit your test.</li>
<li>You can click on the <span class="inline-flex items-baseline"><BaseIcon name ='hamburger' class="place-self-center w-4 h-4"></BaseIcon></span> button on the top left corner of the page to expand the Question Palette.</li>
<li>The Question Palette will show the status of each question using one of the following symbols:
<div class="flex flex-wrap mx-2 md:mx-4 my-2">
<div class="flex items-center my-2 md:mx-4">
<Success></Success>
<span class="ml-6 mr-6">You have answered the question</span>
</div>
<div class="flex items-center my-2 md:mx-4">
<Error></Error>
<span class="ml-6 mr-6">You have not visited the question yet</span>
</div>
<div class="flex items-center my-2 md:mx-4">
<Neutral></Neutral>
<span class="ml-6 mr-6">You have not answered the question</span>
</div>
</div>
</li>
<li>You can click on the <span class="inline-flex items-baseline"><BaseIcon name ='hamburger' class="place-self-center w-4 h-4"></BaseIcon></span> button again to collapse the Question Palette.</li>
</ol>
</div>
<!-- Answering a question -->
<h4 class="text-lg font-bold m-6">Answering a Question:</h4>
<div class="ml-11 mr-4">
<ol class="text-justify">
<li>Procedure for answering a multiple choice type question:
<ol class="ml-7 list-[lower-alpha] text-justify">
<li>To select you answer, click on the button of one of the options.</li>
<li>To deselect your chosen answer, click on the button of the chosen option again or click on the <b>Clear</b> button.</li>
<li>To change your chosen answer, click on the button of another option.</li>
<li>To save your answer, you <b>MUST</b> click on the Save & Next button.</li>
</ol>
</li>
<li>To change your answer to a question that has already been answered, first select that question for answering and then follow the procedure for answering that type of question.</li>
<div class="flex items-center my-2 md:mx-4">
<Error></Error>
<span class="ml-6 mr-6">{{ $t("generalInstructions.notVisited") }}</span>
</div>
<div class="flex items-center my-2 md:mx-4">
<Neutral></Neutral>
<span class="ml-6 mr-6">{{ $t("generalInstructions.notAnswered") }}</span>
</div>
</div>
</li>
</ol>
</div>
<!-- Answering a question -->

<h4 class="text-lg font-bold m-6">{{ $t("answeringQuestion.title") }}</h4>
<div class="ml-11 mr-4">
<ol class="text-justify">
<li>
{{ $t("answeringQuestion.procedureForMCQ") }}
<ol class="ml-7 list-[lower-alpha] text-justify">
<li>{{ $t("answeringQuestion.selectAnswer") }}</li>
<li>{{ $t("answeringQuestion.deselectAnswer") }}</li>
<li>{{ $t("answeringQuestion.changeAnswer") }}</li>
<li>{{ $t("answeringQuestion.saveAnswer") }}</li>
</ol>
</div>
<div class="mt-5 ml-6 mr-4 flex border-red-400 border-1 p-2">
<div class="float-left text-red-400 pr-5 pl-3 text-xl font-bold">!</div>
<div class="float-right text-justify pr-2">Note that selecting an option does NOT save your answer to the current question. Click on <b>Save & Next to save your answer</b> for the current question and then go to the next question.</div>
</div>
</li>
<li>{{ $t("answeringQuestion.changeAnsweredQuestion") }}</li>
</ol>
</div>
<div class="mt-5 ml-6 mr-4 flex border-red-400 border-1 p-2">
<div class="float-left text-red-400 pr-5 pl-3 text-xl font-bold">!</div>
<div class="float-right text-justify pr-2">
{{ $t("answeringQuestion.noteSaveAnswer") }}
</div>
</div>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from "vue";
import { computed, defineComponent, PropType, reactive } from "vue";
import BaseIcon from "./UI/Icons/BaseIcon.vue";
import Success from "./Questions/Palette/Success.vue";
import Error from "./Questions/Palette/Error.vue";
import Neutral from "./Questions/Palette/Neutral.vue";
import { quizTitleType, testFormat, questionSetPalette, TimeLimit } from "../types";
import {
quizTitleType,
testFormat,
questionSetPalette,
TimeLimit,
} from "../types";
import LocalePicker from "./LocalePicker.vue";
import { useI18n } from "vue-i18n";
export default defineComponent({
name: "InstructionPage",
components: {
BaseIcon,
Success,
Error,
Neutral
Neutral,
LocalePicker,
},
props: {
title: {
Expand All @@ -127,34 +181,40 @@ export default defineComponent({
},
maxMarks: {
type: Number,
required: true
required: true,
},
quizTimeLimit: {
type: Object as PropType<TimeLimit> || null,
default: null
type: (Object as PropType<TimeLimit>) || null,
default: null,
},
questionSetStates: {
type: Array as PropType<questionSetPalette[]>,
default: () => []
default: () => [],
},
testFormat: {
type: [null, String] as PropType<testFormat>,
default: null
default: null,
},
},
setup(props) {
const isTestFST = computed(() => props.testFormat == "full_syllabus_test")
const { t, locale } = useI18n();
const state = reactive({
currentLocale: locale.value,
});
const isTestFST = computed(() => props.testFormat == "full_syllabus_test");

// to extract the questionSetTitles from questionSets (eg. Physics - Section A)
const questionSetTitles = computed(() => {
return props.questionSetStates.map(questionSetState => questionSetState.title);
return props.questionSetStates.map(
(questionSetState) => questionSetState.title
);
});

// to split the questionSetTitles from char "-" (eg. Physics)
const subjectNames = computed(() => {
const distinctComponents = new Set();

questionSetTitles.value.forEach(title => {
questionSetTitles.value.forEach((title) => {
if (title !== null) {
const parts = title.split("-");
if (parts.length === 2) {
Expand All @@ -173,14 +233,14 @@ export default defineComponent({
["chapter_test", "Chapter Test"],
["hiring_test", "Hiring Test"],
["evaluation_test", "Evaluation Test"],
["homework", "Homework"]
["homework", "Homework"],
]);

// to split the questionSetTitles from char "-" (eg. Section A)
const sectionNames = computed(() => {
const distinctComponents = new Set();

questionSetTitles.value.forEach(title => {
questionSetTitles.value.forEach((title) => {
if (title !== null) {
const parts = title.split("-");
if (parts.length === 2) {
Expand All @@ -191,14 +251,27 @@ export default defineComponent({

return Array.from(distinctComponents);
});
const localeOptions = [
{ value: "en", label: "English" },
{ value: "hi", label: "Hindi" },
];
const handleLocaleChange = (newLocale: any) => {
state.currentLocale = newLocale;
locale.value = newLocale;
// Update vue-i18n locale here if needed
};

return {
isTestFST,
questionSetTitles,
subjectNames,
sectionNames,
testFormatMapping
}
testFormatMapping,
localeOptions,
currentLocale: computed(() => state.currentLocale),
handleLocaleChange,
t,
};
},
})
});
</script>
Loading

0 comments on commit 4dc78ef

Please sign in to comment.