# ZeenQuiz
# Примеры:
# props
Название | Тип | Обязательный | По умолчанию | Описание |
---|---|---|---|---|
name | String | + | - | имя модального окна - используется как уникальный идентификатор |
radioValue | Function | - | - | передайте функцию принимающая в себя дату, если хотите получить массив ответов |
trueAnswers | Array | + | - | перейдайте массив правильных ответов |
quiz | Array | + | - | массив из объектов |
# Source Code - исходный код компонента
<template>
<ZeenModal :name="name" class="zeen-quiz" @closed="closed">
<div v-for="(item, i) in quiz.questions" :key="i">
<div v-show="i === count">
<div v-if="item.title" class="zeen-quiz__title">
{{ item.title }}
</div>
<div v-if="!item.title" class="zeen-quiz__number">
<div class="show-on-desktop">
<span class="zeen-quiz__number_blue">{{ num }}</span>
{{ ' / ' + length }}
</div>
<div class="show-on-phone">
<span class="zeen-quiz__number_blue">{{ mobileQuestionWord }} {{ num }}</span>
{{ mobileFromWord + ' ' + length }}
</div>
</div>
<div v-if="item.main.question" class="zeen-quiz__question">
{{ item.main.question }}
</div>
<ZeenPicture v-if="item.picture" class="zeen-quiz__picture" :src="item.picture.url" :alt="item.picture.alt" />
<div v-if="item.main.text" class="zeen-quiz__description">
<div class="zeen-quiz__description__subtitle">{{ item.main.text }}</div>
<hr v-if="quizLength" class="zeen-quiz__description__hr" />
<div v-if="quizLength" class="zeen-quiz__description__score">
<span class="zeen-quiz__description__answers">Правильных ответов:</span>
<div class="zeen-quiz__description__number">
<span class="zeen-quiz__description__number_blue">{{ right }}</span>
{{ mobileFromWord + ' ' + length }}
</div>
</div>
</div>
<ul v-if="item.main.answers" class="zeen-quiz__inputs">
<li v-for="(ans, i) in item.main.answers" :key="i" class="zeen-quiz__li">
<label
:class="[
'zeen-quiz__label',
{
'zeen-quiz__label_checked': value === ans.value && !handler,
'zeen-quiz__label_correctly': value === ans.value && !error && handler,
'zeen-quiz__label_error': value === ans.value && error && handler,
'zeen-quiz__label_disabled': disabled,
},
]"
>
<input
type="radio"
name="answer"
class="zeen-quiz__input"
:value="ans.value"
:disabled="disabled"
v-model="value"
/>
<span
v-if="value === ans.value && handler"
:class="[
'zeen-quiz__help',
{
'zeen-quiz__help_correctly': !error && handler,
'zeen-quiz__help_error': error && handler,
},
]"
>
{{ item.main.help }}
</span>
{{ ans.answer }}
</label>
</li>
</ul>
</div>
</div>
<template v-slot:footer="{close}">
<ZeenButton size="parentWidth" @click="next" v-show="buttonHandler && !closeModal">
{{ buttonTextHandler }}
</ZeenButton>
<ZeenButton size="parentWidth" @click.prevent="close" v-show="closeModal">
{{ finallyBtn }}
</ZeenButton>
</template>
</ZeenModal>
</template>
<script>
import ZeenModal from '../ZeenModal/ZeenModal'
import ZeenPicture from '../ZeenPicture/ZeenPicture'
export default {
name: 'ZeenQuiz',
components: {
ZeenModal,
ZeenPicture,
},
props: {
name: {
type: String,
required: true,
},
quiz: {
type: Object,
required: true,
},
radioValue: {
type: Function,
required: false,
},
trueAnswers: {
type: Array,
required: true,
},
startBtn: {
type: String,
default: 'Пройти тест',
},
confirmBtn: {
type: String,
default: 'Подтвердить',
},
nextBtn: {
type: String,
default: 'Дальше',
},
finallyBtn: {
type: String,
default: 'Завершить тест',
},
mobileQuestionWord: {
type: String,
default: 'Вопрос',
},
mobileFromWord: {
type: String,
default: 'из',
},
},
data() {
return {
count: 0,
handler: false,
value: '',
answers: [],
error: false,
answersIdx: 0,
right: 0,
closeModal: false,
}
},
methods: {
closed() {
if (this.quizLength) {
this.count = 0
this.handler = false
this.answersIdx = 0
this.value = ''
this.answers = []
this.right = 0
this.closeModal = false
}
},
next() {
const func = () => {
this.handler = true
this.trueAnswers[this.answersIdx++] === this.value ? ((this.error = false), this.right++) : (this.error = true)
this.answers.push(this.value)
if (this.radioValue) {
this.radioValue(this.answers)
}
}
if (this.count < 1) {
this.count++
} else if (this.count >= 1 && !this.handler && !this.quizLength) {
func()
} else if (this.count >= 1 && this.handler && !this.quizLength) {
this.handler = false
this.count++
this.value = ''
} else if (this.quizLength && !this.handler) {
func()
this.closeModal = true
}
},
},
computed: {
quizLength() {
if (this.count >= this.quiz.questions.length - 1) {
return true
}
return false
},
disabled() {
if (this.handler) {
return true
}
return false
},
buttonTextHandler() {
if (this.count < 1) {
return this.startBtn
}
if (this.count >= 1 && this.count <= this.lastQuiz && !this.handler) {
return this.confirmBtn
}
if (this.count >= 1 && this.count < this.lastQuiz && this.handler) {
return this.nextBtn
}
if (this.count === this.lastQuiz && this.handler) {
return this.finallyBtn
}
return ''
},
buttonHandler() {
if (this.count < 1) {
return true
}
if (this.count >= 1 && this.value) {
return true
}
if (this.count >= 1 && !this.value) {
return false
}
return false
},
lastQuiz() {
if (this.quiz.questions[this.quiz.questions.length - 1].title) {
return this.quiz.questions.length - 2
}
return this.quiz.questions.length - 1
},
length() {
if (this.lastQuiz <= 9) {
return '0' + this.lastQuiz
}
return this.lastQuiz
},
num() {
if (this.count <= 9) {
return '0' + this.count
}
return this.count
},
},
}
</script>
<style lang="scss">
@import '../../styles/mixins.scss';
:root {
--modal-max-width-desktop: 680px;
--modal-padding-top: 50px;
--modal-padding-horizon: 40px;
--modal-padding-bottom: 20px;
--modal-footer-margin-top: 30px;
@include phones {
--modal-padding-top: 30px;
--modal-padding-horizon: 30px;
--modal-padding-bottom: 40px;
}
}
:root {
/* Size */
--zeen-quiz-font-size: var(--main-large-size);
--zeen-quiz-line-height: 1.3;
--zeen-quiz-font-weight: 600;
--zeen-quiz-margin-title-bottom: 15px;
--zeen-quiz-picture-margin-top: 30px;
--zeen-quiz-picture-margin-bottom: 30px;
--zeen-quiz-hr-margin: 31px;
--zeen-quiz-description-answers-font-size: var(--main-small-text);
--zeen-quiz-description-answers-line-height: 1.4;
--zeen-quiz-description-number-font-size: var(--main-largest-size);
--zeen-quiz-description-number-font-weight: 600;
--zeen-quiz-description-number-line-height: 1.08;
--zeen-quiz-description-margin-top: 15px;
--zeen-quiz-subtitle-font-weight: 400;
--zeen-quiz-subtitle-font-size: var(--main-size);
--zeen-quiz-subtitle-line-height: 1.5;
--zeen-quiz-question-font-size: var(--main-size);
--zeen-quiz-question-font-weight: 400;
--zeen-quiz-question-line-height: 1.5;
--zeen-quiz-question-margin-top: 30px;
--zeen-quiz-question-margin-bottom: 15px;
--zeen-quiz-number-font-size: var(--main-large-size);
--zeen-quiz-number-font-weight: 600;
--zeen-quiz-subtitle-padding-top: 0;
/* Colors */
--zeen-quiz-title-color: var(--main-positive-color);
--zeen-quiz-subtitle-color: var(--input-placeholder-color);
--zeen-quiz-label-background: var(--input-background-color);
--zeen-quiz-label-color-checked: var(--main-color);
--zeen-quiz-label-color-correctly: var(--input-correct-color);
--zeen-quiz-label-color-error: var(--input-error-color);
--zeen-quiz-label-color-disabled: var(--input-placeholder-color);
--zeen-quiz-hr-background: var(--gray-2);
--zeen-quiz-number-color: var(--gray-4);
--zeen-quiz-number-count-color: var(--main-color);
--zeen-quiz-description-answers-color: var(--faq-description-color);
--zeen-quiz-description-number-color: var(--main-positive-color);
--zeen-quiz-description-number-right-color: var(--main-color);
}
</style>
<style lang="scss" scoped>
@import '../../styles/mixins.scss';
.zeen-quiz {
&__title {
font-size: var(--zeen-quiz-font-size);
line-height: var(--zeen-quiz-line-height);
font-weight: var(--zeen-quiz-font-weight);
color: var(--zeen-quiz-title-color);
margin-bottom: var(--zeen-quiz-title-margin-bottom);
}
&__picture {
width: 100%;
margin: var(--zeen-quiz-picture-margin-top) 0 var(--zeen-quiz-picture-margin-bottom);
}
&__description {
margin-top: var(--zeen-quiz-description-margin-top);
display: flex;
justify-content: space-between;
align-items: center;
@include phones {
flex-direction: column-reverse;
align-items: flex-start;
}
&__subtitle {
flex: 1 1 auto;
font-weight: var(--zeen-quiz-subtitle-font-weight);
font-size: var(--zeen-quiz-subtitle-font-size);
line-height: var(--zeen-quiz-subtitle-line-height);
color: var(--zeen-quiz-subtitle-color);
padding-top: var(--zeen-quiz-subtitle-padding-top);
}
&__hr {
height: 72px;
width: 1px;
background: var(--zeen-quiz-hr-background);
margin-right: var(--zeen-quiz-hr-margin);
margin-left: var(--zeen-quiz-hr-margin);
@include phones {
display: none;
}
}
&__score {
flex: 0 0 auto;
}
&__answers {
color: var(--zeen-quiz-description-answers-color);
font-size: var(--zeen-quiz-description-answers-font-size);
line-height: var(--zeen-quiz-description-answers-line-height);
@include phones {
display: none;
}
}
&__number {
font-size: var(--zeen-quiz-description-number-font-size);
font-weight: var(--zeen-quiz-description-number-font-weight);
line-height: var(--zeen-quiz-description-number-line-height);
color: var(--zeen-quiz-description-number-color);
&_blue {
color: var(--zeen-quiz-description-number-right-color);
}
}
}
&__question {
font-size: var(--zeen-quiz-question-font-size);
font-weight: var(--zeen-quiz-question-font-weight);
line-height: var(--zeen-quiz-question-line-height);
margin-top: var(--zeen-quiz-question-margin-top);
margin-bottom: var(--zeen-quiz-question-margin-bottom);
}
&__number {
height: 100%;
font-size: var(--zeen-quiz-number-font-size);
font-weight: var(--zeen-quiz-number-font-weight);
color: var(--zeen-quiz-number-color);
&_blue {
color: var(--zeen-quiz-number-count-color);
@include phones {
color: var(--zeen-quiz-number-color);
}
}
}
&__inputs {
margin: 0;
padding: 0;
list-style: none;
margin-top: 15px;
}
&__input {
position: absolute;
cursor: pointer;
opacity: 0;
margin: 0;
}
&__li {
display: flex;
width: 100%;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
&__label {
width: 100%;
padding: 15px 20px;
background: var(--zeen-quiz-label-background);
border-radius: 10px;
font-weight: 400;
font-size: 16px;
line-height: 24px;
cursor: pointer;
&_checked {
border: 1px solid var(--zeen-quiz-label-color-checked);
}
&_correctly {
border: 1px solid var(--zeen-quiz-label-color-correctly);
}
&_error {
border: 1px solid var(--zeen-quiz-label-color-error);
}
&_disabled {
color: var(--zeen-quiz-label-color-disabled);
cursor: default;
}
}
&__help {
display: block;
margin-bottom: 10px;
&_correctly {
color: var(--zeen-quiz-label-color-correctly);
}
&_error {
color: var(--zeen-quiz-label-color-error);
}
}
}
.show-on-desktop {
@include phones {
display: none;
}
}
.show-on-phone {
display: none;
@include phones {
display: block;
}
}
</style>