product page and cart finished
This commit is contained in:
@@ -37,13 +37,11 @@ export default {
|
||||
name: 'TheNavbar',
|
||||
data () {
|
||||
return {
|
||||
activeIndex: '1',
|
||||
activeIndex2: '1'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cardCount () {
|
||||
return this.$store.state.cart.length
|
||||
return this.$store.state.checkout.lineItems.length
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -8,21 +8,23 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addToCart (product, checkout) {
|
||||
// add to cart
|
||||
this.$store.dispatch('addItemToCart', product).then((item) => {
|
||||
addToCart (id, quantity) {
|
||||
const lineItemsToAdd = {
|
||||
variantId: item.variants[0].id,
|
||||
quantity: 1
|
||||
variantId: id,
|
||||
quantity
|
||||
}
|
||||
// Add an item to the checkout
|
||||
this.$shopify.checkout.addLineItems(checkout.id, lineItemsToAdd).then((checkout) => {
|
||||
this.$shopify.checkout.addLineItems(this.checkout.id, lineItemsToAdd).then((checkout) => {
|
||||
this.$store.commit('setCheckout', checkout)
|
||||
})
|
||||
this.$buefy.toast.open({
|
||||
message: 'Product added',
|
||||
type: 'is-success'
|
||||
})
|
||||
},
|
||||
deleteItem (id) {
|
||||
this.$shopify.checkout.removeLineItems(this.checkout.id, id).then((checkout) => {
|
||||
this.$store.commit('setCheckout', checkout)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -27,8 +27,7 @@ export default {
|
||||
/*
|
||||
** Plugins to load before mounting the App
|
||||
*/
|
||||
plugins: [
|
||||
],
|
||||
plugins: [{ src: '~/plugins/localStorage.js', ssr: false }],
|
||||
/*
|
||||
** Nuxt.js dev-modules
|
||||
*/
|
||||
|
||||
Generated
+17
-8
@@ -10045,6 +10045,11 @@
|
||||
"resolved": "https://registry.npmjs.org/shopify-buy/-/shopify-buy-2.9.1.tgz",
|
||||
"integrity": "sha512-nLAW2FAOVXKiMBQ5d8j24/OYzXrxkhUp0NDi/Wk+mdt1d9JDJ5x3Afo3TOnXDX/LmQxF6OszvPR+2W0zzJMVJQ=="
|
||||
},
|
||||
"shvl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.0.tgz",
|
||||
"integrity": "sha512-WbpzSvI5XgVGJ3A4ySGe8hBxj0JgJktfnoLhhJmvITDdK21WPVWwgG8GPlYEh4xqdti3Ff7PJ5G0QrRAjNS0Ig=="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
@@ -11399,6 +11404,15 @@
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.2.tgz",
|
||||
"integrity": "sha512-ha3jNLJqNhhrAemDXcmMJMKf1Zu4sybMPr9KxJIuOpVcsDQlTBYLLladav2U+g1AvdYDG5Gs0xBTb0M5pXXYFQ=="
|
||||
},
|
||||
"vuex-persistedstate": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-2.7.1.tgz",
|
||||
"integrity": "sha512-Ktvp6Bt6ApYj35MuxTClu+9Lpukcgl3Z/0o4PU12+Z4jU6lyOMzos0k6zGT5xrukAkGM1VV3EYNwz1TnHPhgFA==",
|
||||
"requires": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"shvl": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||
@@ -11488,13 +11502,11 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -11511,8 +11523,7 @@
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
@@ -11641,15 +11652,13 @@
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
|
||||
+2
-1
@@ -15,7 +15,8 @@
|
||||
"@nuxtjs/axios": "^5.9.5",
|
||||
"nuxt": "^2.11.0",
|
||||
"nuxt-buefy": "^0.3.23",
|
||||
"nuxt-shopify": "^1.7.1"
|
||||
"nuxt-shopify": "^1.7.1",
|
||||
"vuex-persistedstate": "^2.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config": "^2.0.2",
|
||||
|
||||
+35
-9
@@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="checkout.lineItems.length === 0">
|
||||
<div class="column">
|
||||
<h1 class="is-size-1">
|
||||
Empty Cart
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<h1 class="is-size-1">
|
||||
@@ -9,30 +17,47 @@
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<b-table :data="cart">
|
||||
<b-table :data="checkout.lineItems">
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="image" label="Image">
|
||||
<figure class="image is-96x96">
|
||||
<img class="is-rounded" :src="props.row.images[0].src" :alt="props.row.description">
|
||||
<img class="is-rounded" :src="props.row.variant.image.src" :alt="props.row.description">
|
||||
</figure>
|
||||
</b-table-column>
|
||||
<b-table-column field="title" label="Title">
|
||||
<p class="title">{{ props.row.title }}</p>
|
||||
</b-table-column>
|
||||
<b-table-column field="description" label="Description">
|
||||
<p class="subtitle">{{ props.row.description }}</p>
|
||||
<p class="title">
|
||||
{{ props.row.title }}
|
||||
</p>
|
||||
</b-table-column>
|
||||
<b-table-column field="price" label="Price">
|
||||
{{ props.row.variants[0].price }} €
|
||||
{{ props.row.variant.price }}€
|
||||
</b-table-column>
|
||||
<b-table-column field="quantity" label="Quantity">
|
||||
{{ props.row.count }}
|
||||
{{ props.row.quantity }}
|
||||
</b-table-column>
|
||||
<b-table-column field="total" label="Total">
|
||||
{{ getItemTotal(props.row) }} €
|
||||
</b-table-column>
|
||||
<b-table-column field="delete" label="Delete">
|
||||
<b-button
|
||||
class="is-danger"
|
||||
icon-left="delete"
|
||||
@click="deleteItem(props.row.id)"
|
||||
>
|
||||
Delete
|
||||
</b-button>
|
||||
</b-table-column>
|
||||
</template>
|
||||
</b-table>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
</div>
|
||||
<div class="column is-2 is-pulled-right">
|
||||
<p class="subtitle">
|
||||
Subtotal : {{ checkout.subtotalPrice }} €
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<b-button
|
||||
@@ -42,6 +67,7 @@
|
||||
Checkout
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -55,7 +81,7 @@ export default {
|
||||
window.open(this.$store.state.checkout.webUrl)
|
||||
},
|
||||
getItemTotal (item) {
|
||||
return item.variants[0].price * item.count
|
||||
return item.variant.price * item.quantity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -10,11 +10,13 @@ export default {
|
||||
const products = await $shopify.product.fetchAll()
|
||||
return { products }
|
||||
},
|
||||
created () {
|
||||
beforeUpdate () {
|
||||
if (typeof this.$store.state.checkout.id === 'undefined') {
|
||||
this.$shopify.checkout.create().then((checkout) => {
|
||||
this.$store.commit('setCheckout', checkout)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,15 +1,79 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>{{ product.title }}</h1>
|
||||
<p>{{ product.description }}</p>
|
||||
<div class="columns">
|
||||
<div class="column is-4">
|
||||
<b-carousel :indicator-inside="false">
|
||||
<b-carousel-item
|
||||
v-for="(image, index) in product.images"
|
||||
:key="index"
|
||||
>
|
||||
<span class="image">
|
||||
<img
|
||||
:src="image.src"
|
||||
style="max-width: 25rem"
|
||||
:alt="product.description"
|
||||
>
|
||||
</span>
|
||||
</b-carousel-item>
|
||||
<template slot="indicators" slot-scope="props">
|
||||
<span class="al image">
|
||||
<img
|
||||
:src="product.images[props.i].src"
|
||||
:alt="product.description"
|
||||
style="max-width: 5rem"
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</b-carousel>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<h1 class="title">
|
||||
{{ product.title }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<p class="subtitle">
|
||||
{{ product.description }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<p class="is-size-3">
|
||||
{{ product.variants[0].price }} €
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column is-1">
|
||||
<p>Quantity</p>
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<b-numberinput
|
||||
v-model.number="quantity"
|
||||
/>
|
||||
</div>
|
||||
<div class="column is-7">
|
||||
<b-button
|
||||
icon-left="cart"
|
||||
class="mx-2"
|
||||
@click="addToCart(product, checkout)"
|
||||
@click="addToCart(product.variants[0].id, quantity)"
|
||||
>
|
||||
Ajouter
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -26,12 +90,18 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
product: {}
|
||||
product: {},
|
||||
quantity: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.is-active .al img {
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
.al img {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
:to="'/products/' + product.handle"
|
||||
type="is-primary"
|
||||
>
|
||||
Voir
|
||||
See
|
||||
</b-button>
|
||||
<b-button
|
||||
type="is-primary"
|
||||
icon-left="cart"
|
||||
@click="addToCart(product, checkout)"
|
||||
@click="addToCart(product.variants[0].id, 1)"
|
||||
>
|
||||
Buy
|
||||
</b-button>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Element from 'element-ui'
|
||||
import locale from 'element-ui/lib/locale/lang/en'
|
||||
|
||||
Vue.use(Element, { locale })
|
||||
@@ -0,0 +1,7 @@
|
||||
import createPersistedState from 'vuex-persistedstate'
|
||||
|
||||
export default ({ store }) => {
|
||||
window.onNuxtReady(() => {
|
||||
createPersistedState()(store)
|
||||
})
|
||||
}
|
||||
+3
-29
@@ -1,7 +1,8 @@
|
||||
export const state = () => ({
|
||||
products: [],
|
||||
cart: [],
|
||||
checkout: {}
|
||||
checkout: {
|
||||
lineItems: []
|
||||
}
|
||||
})
|
||||
|
||||
export const mutations = {
|
||||
@@ -10,32 +11,5 @@ export const mutations = {
|
||||
},
|
||||
setCheckout (state, data) {
|
||||
state.checkout = data
|
||||
},
|
||||
incrementCart (state, index) {
|
||||
state.cart[index].count++
|
||||
},
|
||||
addCart (state, item) {
|
||||
item.count = 1
|
||||
state.cart.push(item)
|
||||
}
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
getCartItem: state => (id) => {
|
||||
return state.cart.filter(item => (item.id === id))
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
addItemToCart ({ commit, getters, state }, payload) {
|
||||
return new Promise((resolve) => {
|
||||
const element = getters.getCartItem(payload.id)
|
||||
if (element.length > 0) {
|
||||
commit('incrementCart', state.cart.indexOf(element[0]))
|
||||
} else {
|
||||
commit('addCart', payload)
|
||||
}
|
||||
resolve(getters.getCartItem(payload.id)[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user