浏览代码

[ADD] variants selector

Gogs 7 年之前
父节点
当前提交
2f1da163f3

+ 5 - 1
src/components/common/Cart.vue

@@ -1,5 +1,5 @@
 <template lang="pug">
-    .cart(:style='{ width, height }')
+    .cart(:style='{ width: defaultOptions.layout.width, height: defaultOptions.layout.height }')
         .cart-total
             h2.currency-cart-total {{ total | currency(...defaultOptions.currency) }}
         .cart-items-wrapper
@@ -81,6 +81,10 @@
                         thousandsSeparator: '.',
                         decimalPlaces: 2,
                         decimalSeparator: ',' 
+                    },
+                    layout: {
+                        width: '300px',
+                        height: '100%'
                     }
                 }
             }

+ 1 - 1
src/components/common/CartItem.vue

@@ -1,6 +1,6 @@
 <template lang="pug">
     li.cart-item
-        h3.item-name {{ item.name || 'Sin Nombre' }}
+        h3.item-name {{ item.displayName }}
         input.item-quantity(type='number' min='1' :value='item.quantity')
         span.item-x x
         span.item-price {{ (item.price || 1) | currency(...options) }}

+ 84 - 0
src/components/modals/VariantModal.vue

@@ -0,0 +1,84 @@
+<template lang="pug">
+    modal(name='variant-selector' transition='nice-modal-fade' height="500" @closed='handleClosed' :classes="['v--modal', 'variant-modal']")
+        searcher(:items='getItems()' :keys="['name', 'displayName']" @onSearch='filterVariants')
+        .product-variants
+            .product-variant(v-for='item in getItems()' :key='item.id' @click='selectProduct(item)')
+                img.variant-image
+                .variant-details
+                    h2.variant-name {{ item.displayName }}    
+</template>
+
+<script>
+    import { mapGetters, mapActions } from 'vuex'
+
+    import { Searcher } from '@@/common'
+    import { SELECT_PRODUCT } from '@/constants/actionTypes'
+
+    export default {
+        components: {
+            Searcher
+        },
+        computed: mapGetters([
+            'productWithVariant'
+        ]),
+        methods: {
+            getItems() {
+                return this.filteredItems.length === 0 && !!this.productWithVariant ? this.productWithVariant.variants : this.filteredItems
+            },
+            filterVariants(values) {
+                this.filteredItems = values
+            },
+            handleClosed() {
+                this.selectProduct(null)
+            },
+            ...mapActions([
+                SELECT_PRODUCT
+            ])
+        },
+        watch: {
+            productWithVariant(value) {
+                if (value) {
+                    this.$modal.show('variant-selector')
+                    return
+                }
+
+                this.$modal.hide('variant-selector')
+            }
+        },
+        data() {
+            return {
+                filteredItems: []
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    .variant-modal
+        padding: 15px !important
+        .product-variants
+            width: 100%;
+            height: calc(100% - 70px)
+            overflow-y: auto
+            .product-variant
+                width: calc(100% - 20px)
+                height: 84px
+                margin: 5px 10px
+                display: flex
+                &:hover
+                    cursor: pointer
+                    .variant-details
+                        transition-duration: 0.5s
+                        border-bottom: 2px solid #7c7bad
+                .variant-image
+                    width: 80px
+                    height: 80px
+                    margin: 0
+                    border: none
+                .variant-details
+                    flex-grow: 1
+                    border-bottom: 1px solid #d3d3d3
+                    .variant-name
+                        font-size: 10pt
+                        margin-left: 10px
+</style>

+ 4 - 1
src/components/steps/Product.vue

@@ -4,6 +4,7 @@
             searcher(:items='products' :keys="['name', 'displayName']" @onSearch='filterProducts')
             card-grid(:items='visibleProducts' :loading='loadingProducts' @onAdd='showProductForm' @onSelect='selectProduct')
             product-modal(:show='showingProductForm' @onAccept='submitProduct' @onCancel='hideProductForm')
+            variant-modal
         cart(:items='cartItems' @onTotalComputed='changeCartTotal' @onIncrementQty='addToCart' @onDecrementQty='decreaseFromCart' @onDeleteItem='removeFromCart' :options='selectedCurrency')
 </template>
 
@@ -11,6 +12,7 @@
     import { mapGetters, mapActions } from 'vuex'
     import { Searcher, CardGrid, Cart } from '@@/common'
     import ProductModal from '@@/modals/ProductModal'
+    import VariantModal from '@@/modals/VariantModal'
 
     import { FILTER_PRODUCTS, SELECT_PRODUCT, SHOW_PRODUCT_FORM, HIDE_PRODUCT_FORM, SUBMIT_PRODUCT, CHANGE_CART_TOTAL, ADD_TO_CART, DECREASE_FROM_CART, REMOVE_FROM_CART } from '@/constants/actionTypes'
 
@@ -19,7 +21,8 @@
             Searcher,
             CardGrid,
             Cart,
-            ProductModal
+            ProductModal,
+            VariantModal
         },
         computed: {
             ...mapGetters([

+ 11 - 1
src/store/modules/product.js

@@ -192,12 +192,22 @@ const actions = {
      * @param {*} payload 
      */
     [SELECT_PRODUCT] ({ commit, dispatch }, payload) {
+        if (!payload) {
+            commit(SET_PRODUCT_WITH_VARIANT, null)
+            return
+        }
+
         if (payload.variantCount > 1) {
             commit(SET_PRODUCT_WITH_VARIANT, payload)
             return
         }
 
-        dispatch(ADD_TO_CART, payload.variants[0])
+        if (!payload.variantCount) {
+            dispatch(ADD_TO_CART, payload)
+            commit(SET_PRODUCT_WITH_VARIANT, null)
+        } else {
+            dispatch(ADD_TO_CART, payload.variants[0])
+        }
     },
     /**
      *