Skip to content
46 changes: 46 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "form-wizard",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"vue": "^2.5.17",
"vuelidate": "^0.7.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.0.0",
"@vue/cli-plugin-eslint": "^3.0.0",
"@vue/cli-service": "^3.0.0",
"vue-template-compiler": "^2.5.17"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
"no-console": 0
},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
26 changes: 25 additions & 1 deletion src/components/FormAddress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@
<script>
import {required} from 'vuelidate/lib/validators'
export default {
props: {
wizardData: {
type: Object,
required: true
}
},
data () {
return {
form: {
address: null,
recipient: null
recipient: this.wizardData.name
}
}
},
activated () {
this.form.recipient = this.wizardData.name
},
validations: {
form: {
address: {
Expand All @@ -42,6 +51,21 @@
required
}
}
},
methods: {
submit () {
this.$v.$touch()
return new Promise((resolve, reject) => {
if (!this.$v.$invalid) {
resolve({
recipient: this.form.recipient,
address: this.form.address
})
} else {
reject('invalid address')
}
})
}
}
}
</script>
Expand Down
12 changes: 12 additions & 0 deletions src/components/FormPlanPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@
methods: {
pickPlan (plan) {
this.selectedPlan = plan
},
submit () {
this.$v.$touch()
return new Promise((resolve, reject) => {
if (!this.$v.$invalid) {
resolve({
plan: this.selectedPlan
})
} else {
reject('plan not selected')
}
})
}
}
}
Expand Down
34 changes: 28 additions & 6 deletions src/components/FormReviewOrder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
<div class="plans">
<div class="plan active-plan">
<div class="weight">
PLAN WEIGHT
{{wizardData.plan.weight}}
</div>

<div class="description">
<span class="title">
PLAN NAME
{{wizardData.plan.name}}
</span>
<span class="description">
PLAN DESC
{{wizardData.plan.description}}
</span>
</div>

Expand Down Expand Up @@ -64,9 +64,9 @@
</div>

<div class="w-1/3">
<h3>RECIPIENT</h3>
<h3>{{wizardData.recipient}}</h3>
<p class="leading-normal">
ADDRESS
{{wizardData.address}}
</p>
</div>
</div>
Expand All @@ -76,6 +76,12 @@

<script>
export default {
props: {
wizardData: {
type: Object,
required: true
}
},
data () {
return {
form: {
Expand All @@ -86,7 +92,23 @@
},
computed: {
totalPrice () {
return 0
let total = this.wizardData.plan.price
if (this.form.chocolate) {
total += 4
}
if (this.form.otherTreat) {
total += 2
}
return total
}
},
validations: {},
methods: {
submit () {
return Promise.resolve({
chocolate: this.form.chocolate,
otherTreat: this.form.otherTreat
})
}
}
}
Expand Down
122 changes: 115 additions & 7 deletions src/components/FormUserDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,39 @@
Create an account or log in to order your liquid gold subscription
</h2>

<form class="form">
<form v-if="!loggedIn" class="form">
<div class="form-group">
<label class="form-label" for="email">Email</label>
<input type="text" v-model="$v.form.email.$model" placeholder="[email protected]" class="form-control" id="email">
<input type="text" v-model="$v.form.email.$model" :disabled="emailCheckedInDB" placeholder="[email protected]" class="form-control" id="email">
<div v-if="emailCheckedInDB" class="error info">
<a href="#" @click="reset">Not you?</a>
</div>
<div v-if="$v.form.email.$error && !$v.form.email.required" class="error">email is required</div>
<div v-if="$v.form.email.$error && !$v.form.email.email" class="error">email is invalid</div>
</div>


<div class="form-group">
<div v-if="emailCheckedInDB" class="form-group">
<label class="form-label" for="password">Password</label>
<input v-model="$v.form.password.$model" type="password" placeholder="Super Secret Password" class="form-control" id="password">
<div v-if="$v.form.password.$error && !$v.form.password.required" class="error">password is required</div>
<div v-if="$v.form.password.$error && !$v.form.password.correct" class="error">password is invalid - try again</div>
</div>


<div class="form-group">
<div v-if="emailCheckedInDB && !existingUser" class="form-group">
<label class="form-label" for="name">Name</label>
<input v-model="$v.form.name.$model" type="text" placeholder="What should we call you?" class="form-control" id="name">
<div v-if="$v.form.name.$error" class="error">name is required</div>
</div>
</form>
<div v-else class="text-center">
Successfully logged in! <a href="#" @click="reset">Not {{form.name}}?</a>
</div>
</div>
</template>

<script>
import {authenticateUser, checkIfUserExistsInDB} from "../api";
import {required, email} from 'vuelidate/lib/validators'
export default {
data () {
Expand All @@ -40,7 +47,15 @@
email: null,
password: null,
name: null,
}
},
emailCheckedInDB: false,
existingUser: false,
wrongPassword: false
}
},
computed: {
loggedIn () {
return this.existingUser && this.form.name
}
},
validations: {
Expand All @@ -50,12 +65,105 @@
email
},
password: {
required
required,
correct () {
return !this.wrongPassword
}
},
name: {
required
}
}
},
methods: {
checkIfUserExists () {
if (!this.$v.form.email.$invalid) {
this.$emit('updateAsyncState', 'pending')
return checkIfUserExistsInDB(this.form.email)
.then(() => {
// USER EXISTS
this.existingUser = true
this.emailCheckedInDB = true
this.$emit('updateAsyncState', 'success')
})
.catch(() => {
// USER DOESN'T EXIST
this.existingUser = false
this.emailCheckedInDB = true
this.$emit('updateAsyncState', 'success')
})
} else {
return Promise.reject('email is invalid')
}
},
login () {
this.wrongPassword = false
if (!this.$v.form.password.$invalid) {
this.$emit('updateAsyncState', 'pending')
return authenticateUser(this.form.email, this.form.password)
.then(user => {
// LOGGED IN
this.form.name = user.name
this.$emit('updateAsyncState', 'success')
})
.catch(() => {
// WRONG PASSWORD?
this.wrongPassword = true
this.$emit('updateAsyncState', 'success')
})
} else {
return Promise.reject('password is invalid')
}
},
reset () {
this.form.email = null
this.form.password = null
this.form.name = null
this.emailCheckedInDB = false
this.wrongPassword = false
this.existingUser = false
this.$v.$reset()
},
submit () {
let job
if (!this.emailCheckedInDB) {
this.$v.form.email.$touch()
job = this.checkIfUserExists()
} else {
if (this.existingUser && !this.loggedIn) {
this.$v.form.password.$touch()
job = this.login()
} else {
// new user is typing info manually
this.$v.$touch()
job = Promise.resolve()
}
}

return new Promise((resolve, reject) => {
job.then(() => {
if (!this.$v.$invalid) {
resolve({
email: this.form.email,
password: this.form.password,
name: this.form.name
})
} else {
reject('data is not valid yet')
}
})
.catch(error => reject(error))
})

// this.$emit('update', {
// data: {
// email: this.form.email,
// password: this.form.password,
// name: this.form.name
// },
// valid: !this.$v.$invalid
// })
}
}
}
</script>
Expand Down
Loading