feat: Séparation du code spécifique aux questions

This commit is contained in:
Simon 2022-04-06 11:01:37 +02:00
parent cd149770ab
commit f9bd10b640
2 changed files with 108 additions and 92 deletions

View File

@ -0,0 +1,99 @@
<script setup>
import { ref } from "vue";
import { Splide, SplideSlide } from "@splidejs/vue-splide";
import "@splidejs/splide/dist/css/splide.min.css";
const props = defineProps({
question: {
type: Object,
required: true,
},
});
defineEmits(["answerSelected"]);
const slides = ref();
const answerWeight = ref(props.question.answers[0].weight);
function selectAnswer(answer) {
const answerIndex = props.question.answers.findIndex(
(a) => a.id === answer.id
);
slides.value.splide.go(answerIndex);
}
function slideMove(splide, newIndex) {
answerWeight.value = props.question.answers[newIndex].weight;
}
</script>
<template>
<div class="main">
<div class="top">
<legend>{{ question.title }}</legend>
<template v-if="question.answers">
<div class="choice" v-for="answer in question.answers" :key="answer.id">
<label>
<input
type="radio"
:data-answerId="answer.id"
:name="`question_${question.id}`"
:value="answer.weight"
v-model="answerWeight"
@click="selectAnswer(answer)"
/>
{{ answer.title }}
</label>
</div>
</template>
</div>
<div class="bottom">
<template v-if="question.answers">
<Splide
@splide:move="slideMove"
class="answers"
:id="`question_${question.id}`"
ref="slides"
>
<SplideSlide
v-for="answer in question.answers"
:key="answer.id"
@click="$emit('answerSelected', question, answerWeight)"
>
<img
width="200"
height="200"
:src="`/answers/${answer.image}.png`"
/>
</SplideSlide>
</Splide>
</template>
</div>
</div>
</template>
<style lang="sass" scoped>
input[type=radio]
margin-right: .5rem
.main
height: 100%
max-width: 100%
display: flex
flex-direction: column
justify-content: space-around
align-items: center
.bottom
width: 400px
max-width: 100%
min-width: 280px
.answers
text-align: center
@media only screen and (orientation : landscape)
.main
flex-direction: row
.bottom
max-width: 50%
</style>

View File

@ -6,6 +6,7 @@ import { ref, computed } from "vue";
import { useStore } from "@/stores"; import { useStore } from "@/stores";
import { Splide, SplideSlide } from "@splidejs/vue-splide"; import { Splide, SplideSlide } from "@splidejs/vue-splide";
import Question from "./Question.vue";
import "@splidejs/splide/dist/css/splide.min.css"; import "@splidejs/splide/dist/css/splide.min.css";
import ScoreHeader from "./ScoreHeader.vue"; import ScoreHeader from "./ScoreHeader.vue";
@ -60,9 +61,6 @@ function formatScore(score) {
const title = score ? score.title : ""; const title = score ? score.title : "";
const questions = ref(formatScore(score)); const questions = ref(formatScore(score));
function nextQuestion() {
setTimeout(() => slides.value.go(">"), 100);
}
const scoreSum = computed(() => { const scoreSum = computed(() => {
return questions.value return questions.value
.map((question) => question.weight) .map((question) => question.weight)
@ -97,21 +95,16 @@ const result = computed(() =>
.filter((r) => !r.max || r.max >= scoreSum.value)[0] .filter((r) => !r.max || r.max >= scoreSum.value)[0]
: null : null
); );
function selectImage(event, question, answer) { function goQuestionSlide(question) {
const input = document.querySelector( console.log(slides.value);
`input[name='question_${question.id}'][value='${answer.weight}']`
);
if (input) {
input.checked = true;
input.dispatchEvent(new Event("change"));
}
nextQuestion();
}
function geQuestionSlide(question) {
slides.value.go( slides.value.go(
questions.value.findIndex((element) => element.id === question.id) questions.value.findIndex((element) => element.id === question.id)
); );
} }
function answerSelected(question, answerWeight) {
questions.value.find((q) => q.id === question.id).weight = answerWeight;
setTimeout(() => slides.value.go(">"), 100);
}
</script> </script>
<template> <template>
@ -131,57 +124,7 @@ function geQuestionSlide(question) {
}" }"
> >
<SplideSlide v-for="question in questions" :key="question.id"> <SplideSlide v-for="question in questions" :key="question.id">
<div class="main"> <Question :question="question" @answerSelected="answerSelected" />
<div class="top">
<legend>{{ question.title }}</legend>
<template v-if="question.answers">
<div
class="choice"
v-for="answer in question.answers"
:key="answer.id"
>
<label>
<input
type="radio"
:data-answerId="answer.id"
:name="`question_${question.id}`"
:value="answer.weight"
@change="
(event) => {
question.weight = parseFloat(event.target.value);
}
"
@click="nextQuestion"
/>
{{ answer.title }}
</label>
</div>
</template>
</div>
<div class="bottom">
<template v-if="question.answers">
<Splide
class="answers"
:id="`question_${question.id}`"
ref="question.splide"
>
<SplideSlide
v-for="answer in question.answers"
:key="answer.id"
@click="
(event) => selectImage(event, { ...question }, { ...answer })
"
>
<img
width="200"
height="200"
:src="`/answers/${answer.image}.png`"
/>
</SplideSlide>
</Splide>
</template>
</div>
</div>
</SplideSlide> </SplideSlide>
<SplideSlide class="latest"> <SplideSlide class="latest">
<template v-if="displayScoreResult && result"> <template v-if="displayScoreResult && result">
@ -216,7 +159,7 @@ function geQuestionSlide(question) {
<a <a
@click=" @click="
(event) => { (event) => {
geQuestionSlide(question); goQuestionSlide(question);
return false; return false;
} }
" "
@ -254,9 +197,6 @@ function geQuestionSlide(question) {
bottom: 0 bottom: 0
background: transparent background: transparent
input[type=radio]
margin-right: .5rem
.splide__slide .splide__slide
background: transparent background: transparent
@ -313,29 +253,6 @@ label
top: 0 top: 0
line-height: .7rem line-height: .7rem
.main
height: 100%
max-width: 100%
display: flex
flex-direction: column
justify-content: space-around
align-items: center
.bottom
width: 400px
max-width: 100%
min-width: 280px
.answers
text-align: center
.splide__arrows .splide__arrows
position: inherit position: inherit
@media only screen and (orientation : landscape)
.main
flex-direction: row
.bottom
max-width: 50%
</style> </style>