Execute Booking Mutation
May 25, 2020
In this part we will finilize the mutation.
So we will use the Apollo Mutation component to execute the mutation. Go back into your BookingIndex.vue
and make sure it looks like this:
<template>
<div>
<!-- mutation --->
<ApolloMutation
:mutation="require('../../graphql/makeABooking.gql')"
:variables="{
size: parseInt(number),
customerEmail: email,
bookingDate: date,
listingId: this.$route.params.id,
customers: customers,
}"
@done="onDone"
>
<template v-slot="{ mutate, loading, error }">
<!-- TAB ONE --->
<a-tabs v-model="activeKey">
<a-tab-pane tab="Tab 1" key="1" class="flex justify-center">
<div class="flex flex-col p-20 ">
<HeadingOne>
Booking for Listing Name
</HeadingOne>
<div class="mt-5">
<BodyOne>
Booking date
</BodyOne>
<DateInput placeholder="date" type="date" v-model="date" />
</div>
<div class="mt-5">
<BodyOne>
Number of people
</BodyOne>
<Input placeholder="3" type="number" v-model="number" />
</div>
<div class="mt-5">
<BodyOne> Email address </BodyOne>
<Input
placeholder="doku@corrisant.io"
type="email"
v-model="email"
/>
</div>
<div class="flex lg:flex-row mt-5 s:flex-col">
<RedBlockButton
@click="next(2)"
text="Proceed"
class="mr-5 s:mb-5 lg:mb-0"
/>
<RedOutlineButton @click="$router.push('/')" text="Cancel" />
</div>
</div>
</a-tab-pane>
<!-- TAB ONE END--->
<!-- TAB TWO --->
<a-tab-pane tab="Tab 2" key="2" class="flex justify-center">
<div class="flex flex-col p-20 ">
<HeadingOne>
Who are you travelling with?Who are you travelling with?
</HeadingOne>
<div
class="flex lg:flex-row s:flex-col mt-10"
v-for="(customer, i) in customers"
:key="i"
>
<hr />
<div class="flex flex-col mr-5">
<BodyOne> customer name </BodyOne>
<Input
placeholder="doku@corrisant.io"
type="email"
v-model="customer.name"
/>
<BodyOne> customer country </BodyOne>
<Input
placeholder="doku@corrisant.io"
type="email"
v-model="customer.country"
/>
<BodyOne> Physio score </BodyOne>
<Input
placeholder="doku@corrisant.io"
type="email"
v-model="customer.physioScore"
/>
</div>
<div class="flex flex-col">
<BodyOne> Customer surname </BodyOne>
<Input
placeholder="doku@corrisant.io"
type="email"
v-model="customer.Surname"
/>
<label> </label>
<input />
<BodyOne> Passport number </BodyOne>
<Input
placeholder="doku@corrisant.io"
type="email"
v-model="customer.passportNumber"
/>
<RemoveButton @click="removeCustomer(i)" />
</div>
</div>
<div class="mt-5 ">
<BlueBlockButton text="Add a customer" @click="addCustomer" />
</div>
<div class="flex lg:flex-row mt-5 s:flex-col">
<RedBlockButton
@click="next(3)"
text="Proceed"
class="mr-5 s:mb-5 lg:mb-0"
/>
<RedOutlineButton @click="next(1)" text="Back" />
</div>
</div>
</a-tab-pane>
<!-- TAB TWO END--->
<!-- TAB THREE --->
<a-tab-pane
tab="Tab 3"
key="3"
class="text-black flex justify-center"
>
<div class="flex flex-col p-20 ">
<HeadingOne>
Your trip total
</HeadingOne>
<BodyOne>
Test using this credit card: 4242 4242 4242 4242, and enter any
5 digits for the zip code</BodyOne
>
<card
class="stripe-card mt-20 w-full"
id="card"
:class="{ complete }"
stripe="pk_test_5ThYi0UvX3xwoNdgxxxTxxrG"
:options="stripeOptions"
/>
<BodyOne v-if="error"> {{ error }}</BodyOne>
<BodyOne v-if="loading"> Busy booking your trip</BodyOne>
<div class="flex flex-row mt-20">
<RedBlockButton
@click="
pay()
mutate()
"
text="Pay"
class="mr-5"
/>
<RedOutlineButton @click="next(2)" text="Back" />
</div>
</div>
</a-tab-pane>
<!-- TAB THREE END--->
<!-- TAB FOUR --->
<a-tab-pane
tab="Tab 4"
key="4"
class="text-black flex justify-center"
>
<div class="flex flex-col p-20 ">
<HeadingOne>
Thanks for booking with us
</HeadingOne>
<img src="../../assets/Vector.svg" class="mt-5" />
<BodyOne class="mt-5"
>Your link to your ticket is in the mail. Keep it safe and we
will see you soon</BodyOne
>
<div class="flex flex-row ml-32 mt-20">
<RedBlockButton
@click="$router.push('/')"
text="Book more"
class="mr-5"
/>
</div>
</div>
</a-tab-pane>
<!-- TAB FOUR END--->
</a-tabs>
</template>
</ApolloMutation>
</div>
</template>
<script>
import HeadingOne from "../../components/typography/HeadingOne"
import BodyOne from "../../components/typography/BodyOne"
import DateInput from "../../components/inputs/DateInput"
import Input from "../../components/inputs/Input"
import RedBlockButton from "../../components/buttons/RedBlockButton"
import RedOutlineButton from "../../components/buttons/RedOutlineButton"
import RemoveButton from "../../components/buttons/RemoveButton"
import BlueBlockButton from "../../components/buttons/BlueBlockButton"
import { Card, createToken } from "vue-stripe-elements-plus"
export default {
name: "Index",
components: {
HeadingOne,
BodyOne,
DateInput,
Input,
RedBlockButton,
RedOutlineButton,
RemoveButton,
BlueBlockButton,
Card,
},
data() {
return {
activeKey: "1",
email: "",
number: "",
date: "",
customers: [],
}
},
methods: {
onDone() {
this.activeKey = "4"
},
next(k) {
this.activeKey = k.toString()
},
addCustomer() {
// const o = [...this.customers];
this.customers.push({
name: null,
Surname: null,
})
// this.customers.push({ o });
// console.log(this.customers);
//Failed to persist entry: TypeError: Cannot read property 'expires_at' of null
},
removeCustomer(i) {
this.customers.splice(i, 1)
},
submitForm() {
console.log(this.date)
alert(
`${this.customers[0].customerName}, ${this.email}, ${this.number}, ${this.date}`
)
},
pay() {
createToken().then(data => console.log(data.token))
},
},
}
</script>
<style>
.ant-tabs-bar.ant-tabs-top-bar {
display: none;
}
.stripe-card {
margin-top: 10px;
border: 1px solid #ccc;
padding: 5px 10px;
box-shadow: 0px 1px 3px rgba(230, 235, 241, 0.25);
border-radius: 4px;
}
.stripe-card.complete {
border-color: green;
}
</style>
♻️ We pass in the schema document and the variables necessasry for the mutation. As well as execute an OnDone
function which will allow the user to go to the next tab post mutation.
♻️ We have a slot that as the variables that are similar to the query ones.
♻️ In the third tab we have error states and loading states.
♻️ In the red button the pay and mutate functions will hit stripe and execute the mutation.
Thats it! You have a working GraphQL FULLSTACK APP. You should be able to make bookings for different listings now.