boussole-pluss/frontend/pages/quiz.vue

172 lines
4.8 KiB
Vue
Raw Normal View History

2022-10-07 14:15:53 +00:00
<template>
<div class="content">
<team-header/>
<hr/>
<div v-if="!loading">
<quiz-part
:key="currentAxe.identifier" :axe-number="currentAxe.identifier" :total-axes="axes.length"
:title="currentAxe.title"
:color="currentAxe.color"
:icon="'balise_' + currentAxe.identifier + '.svg'"
:questions="questions.get(currentAxe.identifier)"
@rate="onRate"
/>
<div class="button-container">
<nuxt-link
v-if="currentAxeIdentifier <= 1"
class="button gray"
to="/dashboard" aria-label="Précédent">
</nuxt-link>
<button v-if="currentAxeIdentifier > 1" class="button gray" @click="showPrevious"></button>
<button
v-if="currentAxeIdentifier < axes.length" class="button blue" :disabled="!isFilled"
@click="showNext"
>Suivant
</button>
<button
v-if="currentAxeIdentifier >= axes.length" class="button orange"
:disabled="!isFilled || saving" @click="saveResult()"
>Valider
</button>
</div>
</div>
<div v-else class="center">
<loader/>
</div>
</div>
</template>
<script lang="ts">
import {AxiosResponse} from "axios";
import {Component, Vue} from "nuxt-property-decorator";
import {RepositoryFactory} from "~/repositories/RepositoryFactory";
import {Axe} from "~/repositories/models/axe.model";
import {RestResponse} from "~/repositories/models/rest-response.model";
import {Question} from "~/repositories/models/question.model";
import {Quiz} from "~/repositories/models/quiz.model";
import {quizStore} from "~/utils/store-accessor";
@Component
export default class Login extends Vue {
readonly axeRepository = RepositoryFactory.get("axe");
readonly questionRepository = RepositoryFactory.get("question");
private axes: Axe[] = [];
private currentAxe?: Axe;
private currentAxeIdentifier = 1;
private questions: Map<number, Question[]> = new Map<number, []>();
private loading = true;
private saving = false;
private isFullRated = false;
mounted() {
this.loading = true;
this.axeRepository
.findAll()
.then((response: AxiosResponse<RestResponse<Axe>>) => {
this.axes = response.data._embedded.axes;
const promises: any[] = [];
this.axes.forEach(axe => {
promises.push(
this.questionRepository
.findAllByAxeId(axe.identifier)
.then((response: AxiosResponse<RestResponse<Question>>) => {
return {
axeId: axe.identifier,
questions: response.data._embedded.questions
};
}));
});
Promise.all(promises).then((axeQuestions) => {
axeQuestions.forEach(axeQuestion => {
this.questions.set(axeQuestion.axeId, axeQuestion.questions)
});
quizStore.initialize(this.questions);
this.initializeState();
this.loading = false;
});
});
}
showPrevious() {
if (this.currentAxeIdentifier > 1) {
this.currentAxeIdentifier--;
this.initializeState();
}
}
showNext() {
if (this.currentAxeIdentifier < this.axes.length) {
this.currentAxeIdentifier++;
this.initializeState();
setTimeout(() => {
this.scrollTop();
}, 50)
}
}
initializeState() {
this.currentAxe = this.axes.find(value => value.identifier === this.currentAxeIdentifier);
const questions = quizStore.questionsRatedPerAxe.get(this.currentAxeIdentifier);
const unratedQuestions = questions ? questions.filter(value => !value.rated) : [];
this.isFullRated = unratedQuestions.length === 0;
}
scrollTop() {
window.scrollTo({
top: 60,
behavior: "smooth",
});
}
saveResult() {
const responsesFormatted: { score: number; comment?: string; questionId: number }[] = [];
quizStore.responses.forEach((value, key) => {
responsesFormatted.push({
score: value.score ? value.score : 0,
comment: value.comment,
questionId: Number.parseInt(key.replace("http://localhost:8080/questions/", "")) // FIXME use correct url when score will be a REST ressource
})
});
this.saving = true;
RepositoryFactory.get('quiz').save(responsesFormatted).then((response: AxiosResponse<Quiz>) => {
this.saving = false;
quizStore.reset();
this.$router.push({path: "/result", query: {quiz: response.data.id + ""}});
});
}
onRate(event: { isFullRated: boolean }) {
this.isFullRated = event.isFullRated;
}
get isFilled() {
return this.isFullRated;
}
}
</script>
<style lang="scss" scoped>
.button-container {
display: flex;
flex-direction: row;
justify-content: center;
> a {
margin-right: 5px;
}
> button {
margin-left: 5px;
}
}
</style>