feat: add frontend
This commit is contained in:
171
frontend/pages/quiz.vue
Normal file
171
frontend/pages/quiz.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<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>
|
Reference in New Issue
Block a user