product page and cart finished

This commit is contained in:
thomas
2020-02-25 20:14:23 +01:00
parent ef8c22855f
commit bbca265dea
12 changed files with 198 additions and 115 deletions
+1 -3
View File
@@ -37,13 +37,11 @@ export default {
name: 'TheNavbar', name: 'TheNavbar',
data () { data () {
return { return {
activeIndex: '1',
activeIndex2: '1'
} }
}, },
computed: { computed: {
cardCount () { cardCount () {
return this.$store.state.cart.length return this.$store.state.checkout.lineItems.length
} }
}, },
methods: { methods: {
+17 -15
View File
@@ -8,21 +8,23 @@ export default {
} }
}, },
methods: { methods: {
addToCart (product, checkout) { addToCart (id, quantity) {
// add to cart const lineItemsToAdd = {
this.$store.dispatch('addItemToCart', product).then((item) => { variantId: id,
const lineItemsToAdd = { quantity
variantId: item.variants[0].id, }
quantity: 1 // Add an item to the checkout
} this.$shopify.checkout.addLineItems(this.checkout.id, lineItemsToAdd).then((checkout) => {
// Add an item to the checkout this.$store.commit('setCheckout', checkout)
this.$shopify.checkout.addLineItems(checkout.id, lineItemsToAdd).then((checkout) => { })
this.$store.commit('setCheckout', checkout) this.$buefy.toast.open({
}) message: 'Product added',
this.$buefy.toast.open({ type: 'is-success'
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
View File
@@ -27,8 +27,7 @@ export default {
/* /*
** Plugins to load before mounting the App ** Plugins to load before mounting the App
*/ */
plugins: [ plugins: [{ src: '~/plugins/localStorage.js', ssr: false }],
],
/* /*
** Nuxt.js dev-modules ** Nuxt.js dev-modules
*/ */
+17 -8
View File
@@ -10045,6 +10045,11 @@
"resolved": "https://registry.npmjs.org/shopify-buy/-/shopify-buy-2.9.1.tgz", "resolved": "https://registry.npmjs.org/shopify-buy/-/shopify-buy-2.9.1.tgz",
"integrity": "sha512-nLAW2FAOVXKiMBQ5d8j24/OYzXrxkhUp0NDi/Wk+mdt1d9JDJ5x3Afo3TOnXDX/LmQxF6OszvPR+2W0zzJMVJQ==" "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": { "signal-exit": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "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", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.2.tgz",
"integrity": "sha512-ha3jNLJqNhhrAemDXcmMJMKf1Zu4sybMPr9KxJIuOpVcsDQlTBYLLladav2U+g1AvdYDG5Gs0xBTb0M5pXXYFQ==" "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": { "watchpack": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
@@ -11488,13 +11502,11 @@
}, },
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@@ -11511,8 +11523,7 @@
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
@@ -11641,15 +11652,13 @@
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
}, },
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.9.0", "version": "2.9.0",
+2 -1
View File
@@ -15,7 +15,8 @@
"@nuxtjs/axios": "^5.9.5", "@nuxtjs/axios": "^5.9.5",
"nuxt": "^2.11.0", "nuxt": "^2.11.0",
"nuxt-buefy": "^0.3.23", "nuxt-buefy": "^0.3.23",
"nuxt-shopify": "^1.7.1" "nuxt-shopify": "^1.7.1",
"vuex-persistedstate": "^2.7.1"
}, },
"devDependencies": { "devDependencies": {
"@nuxtjs/eslint-config": "^2.0.2", "@nuxtjs/eslint-config": "^2.0.2",
+61 -35
View File
@@ -1,46 +1,72 @@
<template> <template>
<div> <div>
<div class="columns"> <div v-if="checkout.lineItems.length === 0">
<div class="column"> <div class="column">
<h1 class="is-size-1"> <h1 class="is-size-1">
Panier Empty Cart
</h1> </h1>
</div> </div>
</div> </div>
<div class="columns"> <div v-else>
<div class="column"> <div class="columns">
<b-table :data="cart"> <div class="column">
<template slot-scope="props"> <h1 class="is-size-1">
<b-table-column field="image" label="Image"> Panier
<figure class="image is-96x96"> </h1>
<img class="is-rounded" :src="props.row.images[0].src" :alt="props.row.description"> </div>
</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>
</b-table-column>
<b-table-column field="price" label="Price">
{{ props.row.variants[0].price }} €
</b-table-column>
<b-table-column field="quantity" label="Quantity">
{{ props.row.count }}
</b-table-column>
<b-table-column field="total" label="Total">
{{ getItemTotal(props.row) }} €
</b-table-column>
</template>
</b-table>
</div> </div>
<div class="columns">
<div class="column">
<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.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="price" label="Price">
{{ props.row.variant.price }}€
</b-table-column>
<b-table-column field="quantity" label="Quantity">
{{ 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
type="is-primary"
@click="confirmCheckout"
>
Checkout
</b-button>
</div> </div>
<b-button
type="is-primary"
@click="confirmCheckout"
>
Checkout
</b-button>
</div> </div>
</template> </template>
@@ -55,7 +81,7 @@ export default {
window.open(this.$store.state.checkout.webUrl) window.open(this.$store.state.checkout.webUrl)
}, },
getItemTotal (item) { getItemTotal (item) {
return item.variants[0].price * item.count return item.variant.price * item.quantity
} }
} }
} }
+6 -4
View File
@@ -10,10 +10,12 @@ export default {
const products = await $shopify.product.fetchAll() const products = await $shopify.product.fetchAll()
return { products } return { products }
}, },
created () { beforeUpdate () {
this.$shopify.checkout.create().then((checkout) => { if (typeof this.$store.state.checkout.id === 'undefined') {
this.$store.commit('setCheckout', checkout) this.$shopify.checkout.create().then((checkout) => {
}) this.$store.commit('setCheckout', checkout)
})
}
} }
} }
</script> </script>
+81 -11
View File
@@ -1,14 +1,78 @@
<template> <template>
<div> <div>
<h1>{{ product.title }}</h1> <div class="columns">
<p>{{ product.description }}</p> <div class="column is-4">
<b-button <b-carousel :indicator-inside="false">
icon-left="cart" <b-carousel-item
class="mx-2" v-for="(image, index) in product.images"
@click="addToCart(product, checkout)" :key="index"
> >
Ajouter <span class="image">
</b-button> <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.variants[0].id, quantity)"
>
Ajouter
</b-button>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</template> </template>
@@ -26,12 +90,18 @@ export default {
}, },
data () { data () {
return { return {
product: {} product: {},
quantity: 1
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
.is-active .al img {
filter: grayscale(0%);
}
.al img {
filter: grayscale(100%);
}
</style> </style>
+2 -2
View File
@@ -25,12 +25,12 @@
:to="'/products/' + product.handle" :to="'/products/' + product.handle"
type="is-primary" type="is-primary"
> >
Voir See
</b-button> </b-button>
<b-button <b-button
type="is-primary" type="is-primary"
icon-left="cart" icon-left="cart"
@click="addToCart(product, checkout)" @click="addToCart(product.variants[0].id, 1)"
> >
Buy Buy
</b-button> </b-button>
-5
View File
@@ -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 })
+7
View File
@@ -0,0 +1,7 @@
import createPersistedState from 'vuex-persistedstate'
export default ({ store }) => {
window.onNuxtReady(() => {
createPersistedState()(store)
})
}
+3 -29
View File
@@ -1,7 +1,8 @@
export const state = () => ({ export const state = () => ({
products: [], products: [],
cart: [], checkout: {
checkout: {} lineItems: []
}
}) })
export const mutations = { export const mutations = {
@@ -10,32 +11,5 @@ export const mutations = {
}, },
setCheckout (state, data) { setCheckout (state, data) {
state.checkout = 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])
})
} }
} }