added new login code and testing components

This commit is contained in:
2019-03-21 16:13:57 +01:00
parent 18f22fdffa
commit e04da5b273
11 changed files with 587 additions and 9 deletions

79
src/components/Login.vue Normal file
View File

@@ -0,0 +1,79 @@
<!-- components/Login.vue -->
<template>
<div>
<section class="hero is-primary">
<div class="hero-body">
<div class="container has-text-centered">
<h2 class="title">Login or Register</h2>
<p class="subtitle error-msg">{{ errorMsg }}</p>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="field">
<label class="label is-large" for="email">Email:</label>
<div class="control">
<input type="email" class="input is-large" id="email" v-model="email">
</div>
</div>
<div class="field">
<label class="label is-large" for="password">Password:</label>
<div class="control">
<input type="password" class="input is-large" id="password" v-model="password">
</div>
</div>
<div class="control">
<a class="button is-large is-primary" @click="authenticate">Login</a>
<a class="button is-large is-success" @click="register">Register</a>
</div>
</div>
</section>
</div>
</template>
<script>
import { EventBus } from '@/utils'
export default {
data () {
return {
email: '',
password: '',
errorMsg: ''
}
},
methods: {
authenticate () {
this.$store.dispatch('login', { email: this.email, password: this.password })
.then(() => this.$router.push('/'))
},
register () {
this.$store.dispatch('register', { email: this.email, password: this.password })
.then(() => this.$router.push('/'))
}
},
mounted () {
EventBus.$on('failedRegistering', (msg) => {
this.errorMsg = msg
})
EventBus.$on('failedAuthentication', (msg) => {
this.errorMsg = msg
})
},
beforeDestroy () {
EventBus.$off('failedRegistering')
EventBus.$off('failedAuthentication')
}
}
</script>
<style lang="scss">
.error-msg {
color: red;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,75 @@
<template>
<div>
<div class="field">
<label class="label is-large">Question</label>
<div class="control">
<input type="text" class="input is-large" v-model="question">
</div>
</div>
<div class="field">
<div class="control">
<a class="button is-large is-info" @click="addChoice">
<span class="icon is-small">
<i class="fa fa-plus-square-o fa-align-left" aria-hidden="true"></i>
</span>
<span>Add choice</span>
</a>
<a class="button is-large is-primary" @click="saveQuestion">
<span class="icon is-small">
<i class="fa fa-check"></i>
</span>
<span>Save</span>
</a>
</div>
</div>
<h2 class="label is-large" v-show="choices.length > 0">Question Choices</h2>
<div class="field has-addons" v-for="(choice, idx) in choices" v-bind:key="idx">
<div class="control choice">
<input type="text" class="input is-large" v-model="choices[idx]">
</div>
<div class="control">
<a class="button is-large">
<span class="icon is-small" @click.stop="removeChoice(choice)">
<i class="fa fa-times" aria-hidden="true"></i>
</span>
</a>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
question: '',
choices: []
}
},
methods: {
removeChoice (choice) {
const idx = this.choices.findIndex(c => c === choice)
this.choices.splice(idx, 1)
},
saveQuestion () {
this.$emit('questionComplete', {
question: this.question,
choices: this.choices.filter(c => !!c)
})
this.question = ''
this.choices = ['']
},
addChoice () {
this.choices.push('')
}
}
}
</script>
<style>
.choice {
width: 90%;
}
</style>

View File

@@ -0,0 +1,122 @@
<template>
<div>
<section class="hero is-primary">
<div class="hero-body">
<div class="container has-text-centered">
<h2 class="title">{{ name }}</h2>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="tabs is-centered is-fullwidth is-large">
<ul>
<li :class="{'is-active': step == 'name'}" @click="step = 'name'">
<a>Name</a>
</li>
<li :class="{'is-active': step == 'questions'}" @click="step = 'questions'">
<a>Questions</a>
</li>
<li :class="{'is-active': step == 'review'}" @click="step = 'review'">
<a>Review</a>
</li>
</ul>
</div>
<div class="columns">
<div class="column is-half is-offset-one-quarter">
<div class="name" v-show="step === 'name'">
<div class="field">
<label class="label is-large" for="name">Survey name:</label>
<div class="control">
<input type="text" class="input is-large" id="name" v-model="name">
</div>
</div>
</div>
<div class="questions" v-show="step === 'questions'">
<new-question v-on:questionComplete="appendQuestion"/>
</div>
<div class="review" v-show="step === 'review'">
<ul>
<li class="question" v-for="(question, qIdx) in questions" :key="`question-${qIdx}`">
<div class="title">
{{ question.question }}
<span class="icon is-medium is-pulled-right delete-question"
@click.stop="removeQuestion(question)">
<i class="fa fa-times" aria-hidden="true"></i>
</span>
</div>
<ul>
<li v-for="(choice , cIdx) in question.choices" :key="`choice-${cIdx}`">
{{ cIdx + 1 }}. {{ choice }}
</li>
</ul>
</li>
</ul>
<div class="control">
<a class="button is-large is-primary" @click="submitSurvey">Submit</a>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
import NewQuestion from '@/components/NewQuestion'
export default {
components: { NewQuestion },
data () {
return {
step: 'name',
name: '',
questions: []
}
},
methods: {
appendQuestion (newQuestion) {
this.questions.push(newQuestion)
},
removeQuestion (question) {
const idx = this.questions.findIndex(q => q.question === question.question)
this.questions.splice(idx, 1)
},
submitSurvey () {
this.$store.dispatch('submitNewSurvey', {
name: this.name,
questions: this.questions
})
.then(() => this.$router.push('/'))
.catch((error) => {
console.log('Error creating survey', error)
this.$router.push('/')
})
}
}
}
</script>
<style>
.question {
margin: 10px 20px 25px 10px;
}
.delete-question {
cursor: pointer;
padding: 10px;
}
.delete-question:hover {
background-color: lightgray;
border-radius: 50%;
}
</style>

115
src/components/Survey.vue Normal file
View File

@@ -0,0 +1,115 @@
<template>
<div>
<section class="hero is-primary">
<div class="hero-body">
<div class="container has-text-centered">
<h2 class="title">{{ survey.name }}</h2>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-10 is-offset-1">
<div
v-for="(question, idx) in survey.questions"
v-bind:key="question.id"
v-show="currentQuestion === idx">
<div class="column is-offset-3 is-6">
<h4 class='title has-text-centered'>{{ question.text }}</h4>
</div>
<div class="column is-offset-4 is-4">
<div class="control">
<div v-for="choice in question.choices" v-bind:key="choice.id">
<label class="radio">
<input type="radio" v-model="question.choice" name="choice" :value="choice.id">
{{ choice.text }}
</label>
</div>
</div>
</div>
</div>
<div class="column is-offset-one-quarter is-half">
<nav class="pagination is-centered" role="navigation" aria-label="pagination">
<a class="pagination-previous" @click.stop="goToPreviousQuestion"><i class="fa fa-chevron-left" aria-hidden="true"></i> &nbsp;&nbsp; Back</a>
<a class="pagination-next" @click.stop="goToNextQuestion">Next &nbsp;&nbsp; <i class="fa fa-chevron-right" aria-hidden="true"></i></a>
</nav>
</div>
<div class="has-text-centered">
<a v-show="surveyComplete" class='button is-large is-focused is-primary' @click="handleSubmit">Submit</a>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
export default {
data () {
return {
currentQuestion: 0
}
},
beforeMount () {
this.$store.dispatch('loadSurvey', { id: parseInt(this.$route.params.id) })
},
methods: {
goToNextQuestion () {
if (this.currentQuestion === this.survey.questions.length - 1) {
this.currentQuestion = 0
} else {
this.currentQuestion++
}
},
goToPreviousQuestion () {
if (this.currentQuestion === 0) {
this.currentQuestion = this.survey.questions.lenth - 1
} else {
this.currentQuestion--
}
},
handleSubmit () {
this.$store.dispatch('addSurveyResponse')
.then(() => this.$router.push('/'))
}
},
computed: {
surveyComplete () {
if (this.survey.questions) {
const numQuestions = this.survey.questions.length
const numCompleted = this.survey.questions.filter(q => q.choice).length
return numQuestions === numCompleted
}
return false
},
survey () {
return this.$store.state.currentSurvey
},
selectedChoice: {
get () {
const question = this.survey.questions[this.currentQuestion]
return question.choice
},
set (value) {
const question = this.survey.questions[this.currentQuestion]
this.$store.commit('setChoice', { questionId: question.id, choice: value })
}
}
}
}
</script>
<style>
</style>