kandimat-user-app/src/app/euromat/components/theses.vue

294 lines
7.1 KiB
Vue

<template>
<section v-if="thesesCount > 0 && theses.length > 0" class="theses">
<div class="header-progress">
<div>
<span class="progress-current">{{ currentThesisStep }}</span>
<span>/{{ thesesCount }}</span>
</div>
<button
:disabled="currentThesisStep === 1"
class="btn-dark btn-small"
type="button"
@click="goBack"
>
{{ $t('theses.backBtn') }}
</button>
</div>
<div class="theses-content">
<header class="theses-header">
<h2>{{ thesisCategory }}</h2>
<h1>{{ thesisTitle }}</h1>
</header>
<div class="theses-controls">
<ul class="theses-btns">
<li v-for="possiblePosition in possiblePositions" :key="possiblePosition.label">
<button type="button" @click="submitAnswer(possiblePosition, $event)">
{{ possiblePosition.label }} <component :is="'feather-' + possiblePosition.icon" />
</button>
</li>
</ul>
<div class="controls-sub">
<button
class="btn-dark btn-small"
type="button"
@click="submitAnswer(optionSkip)"
>
{{ optionSkip.label }}
<feather-corner-up-right />
</button>
</div>
</div>
</div>
</section>
<section v-else>
<span>Loading...</span>
</section>
</template>
<script>
import possiblePositions from '@/app/euromat/possiblePositions'
import { getTranslatedUrl } from '@/i18n/helper'
import {
apolloThesesCountQuery,
apolloThesesCountUpdate,
apolloThesesQuery,
apolloThesesUpdate
} from '@/app/euromat/graphqlQueries'
export default {
name: 'EuroMat',
components: {
'feather-corner-up-right': () =>
import('vue-feather-icons/icons/CornerUpRightIcon' /* webpackChunkName: "icons" */),
'feather-circle': () =>
import('vue-feather-icons/icons/CircleIcon' /* webpackChunkName: "icons" */),
'feather-thumbs-up': () =>
import('vue-feather-icons/icons/ThumbsUpIcon' /* webpackChunkName: "icons" */),
'feather-thumbs-down': () =>
import('vue-feather-icons/icons/ThumbsDownIcon' /* webpackChunkName: "icons" */)
},
data () {
return {
currentThesisStep: 1,
theses: [],
thesesCount: 0,
answers: []
}
},
apollo: {
theses: {
query: apolloThesesQuery,
update: apolloThesesUpdate
},
thesesCount: {
query: apolloThesesCountQuery,
update: apolloThesesCountUpdate
}
},
computed: {
isEmbedded () {
return (
this.$route.query.embedded &&
this.$route.query.embedded === 'iframe'
)
},
thesisTitle () {
if (this.currentThesisStep > this.thesesCount) {
return
}
return this.theses[this.currentThesisStep - 1].thesis[this.$i18n.locale]
},
thesisCategory () {
if (this.currentThesisStep > this.thesesCount) {
return
}
return this.theses[this.currentThesisStep - 1].category[this.$i18n.locale]
},
possiblePositions () {
return possiblePositions.map(option =>
Object.assign({}, option, {
label: this.$t(`theses.${option.position}`),
icon: this.getIconName(option.position)
}))
.filter(option => option.position !== 'skipped')
},
optionSkip () {
const skipped = possiblePositions.find(option => option.position === 'skipped')
return Object.assign({}, skipped, {
label: this.$t('theses.skipped')
})
}
},
methods: {
getIconName (type) {
switch (type) {
case 'positive': return 'thumbs-up'
case 'neutral': return 'circle'
case 'negative': return 'thumbs-down'
case 'skipped': return 'corner-up-right'
default:
}
},
goBack () {
const thesis = this.theses[this.currentThesisStep - 1]
const index = this.answers.findIndex(a => a.thesis === thesis.id)
this.answers.splice(index, 1)
this.currentThesisStep -= 1
},
submitAnswer (option, event) {
if (!option) {
// eslint-disable-next-line
return console.warn('Invalid answer')
}
const thesis = this.theses[this.currentThesisStep - 1]
this.answers.push({ thesis: thesis.id, position: option.position })
this.currentThesisStep += 1
event && event.target.blur()
window.scrollTo(0, 0)
if (this.currentThesisStep > this.thesesCount) {
this.forwardToResults()
}
},
forwardToResults () {
const answers = JSON.stringify(this.answers)
if (this.$browser.supports('sessionStorage')) {
sessionStorage.setItem('euromat-answers', answers)
} else {
this.$root.$data.backupStorage.answers = answers
}
this.$router.push({
path: getTranslatedUrl('emphasis', getTranslatedUrl('theses', null, true)),
query: this.isEmbedded ? { embedded: 'iframe' } : {}
})
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/styles/fonts";
@import "~@/styles/colors";
@import "~@/styles/layout";
$breakpoint: 835px;
.theses {
display: flex;
align-items: flex-start;
@media (max-width: $breakpoint) {
flex-direction: column;
}
}
.header-progress {
flex: 1 0 100px;
display: flex;
flex-direction: column;
align-items: flex-end;
margin-right: $base-gap * 2;
color: $text-color-secondary;
@media (max-width: $breakpoint) {
flex: 1;
width: 100%;
flex-direction: row;
justify-content: space-between;
margin-right: 0;
margin-bottom: 0;
}
> div {
display: flex;
}
span {
font-size: $font-size-large;
font-weight: 600;
display: inline;
@media (max-width: $breakpoint) {
font-size: $font-size-large - 50%;
}
}
.progress-current {
color: $text-color-special;
}
button {
margin-top: $base-gap + 5;
@media (max-width: $breakpoint) {
margin-top: 0;
margin-left: $base-gap;
}
}
}
.theses-content {
text-align: left;
width: 100%;
}
.theses-header {
margin-bottom: $base-gap + 5;
text-align: left;
h1, h2 {
overflow-wrap: break-word;
}
h2 {
margin-bottom: $base-gap;
}
}
.theses-controls {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
}
.controls-sub {
display: flex;
margin-top: $small-gap;
button:first-of-type {
margin-right: $small-gap;
}
}
.theses-btns {
list-style: none;
display: flex;
justify-content: center;
li:not(:last-child) {
margin-right: $small-gap;
}
@media (max-width: $breakpoint) {
flex-direction: column;
margin-bottom: $base-gap;
li:not(:last-child) {
margin-right: 0;
margin-bottom: $small-gap;
}
}
}
</style>