]> _ Git - pmi.git/commitdiff
WIP #2738 @6
authorStephen Cameron <stephen@cubedesigners.com>
Tue, 2 Jul 2019 18:26:07 +0000 (20:26 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Tue, 2 Jul 2019 18:26:07 +0000 (20:26 +0200)
resources/js/app.js
resources/js/components/Cart.vue
resources/js/components/CartItem.vue
resources/styles/components/footer.styl
resources/views/layouts/app.blade.php
resources/views/partials/cart.blade.php
resources/views/partials/footer.blade.php
resources/views/partials/header.blade.php

index d2f8884f18a5b7d2600c5748588a0da9e09dcc98..240ac9dd791d5c9a09ba862345fc89de7fdcfbc4 100644 (file)
@@ -33,14 +33,32 @@ const app = new Vue({
     el: '#app',
 
     data: {
+      items: {}, // Populated from data attribute on root element so we can pass data from PHP
+    },
 
+    beforeMount: function () {
+      this.items = JSON.parse(this.$el.dataset.cartItems);
+    },
+
+    computed: {
+      cartItemCount() {
+        // Todo: See if this should count just number of items or make a sum of all quantities? What is more useful? The sum of quantities can be found using map/reduce functions but this needs to be adapted for the object structure using Object.keys as the source.
+        return Object.keys(this.items).length;
+      }
     },
 
     methods: {
       // Todo: find a better way to structure this with Vue
       openCart() {
         document.body.classList.add('cart-open');
+      },
+      closeCart() {
+        document.body.classList.remove('cart-open');
+      },
+      updateItemQuantity(update) {
+        this.items[update.id].quantity = update.quantity;
       }
+
     }
 
 
index c3f51510422df6cb84c6217bc899d47a2b18a96f..6e3ff2efff33fc43004a589a7239d870006a068b 100644 (file)
@@ -1,6 +1,6 @@
 <template>
     <div class="cart-wrapper">
-        <cart-item v-for="item in items" :key="item.id" :item="item"></cart-item>
+        <cart-item v-for="item in items" :key="item.id" :item="item" @update-item-quantity="updateItemQuantity"></cart-item>
     </div>
 </template>
 
 
         props: {
             items: {
-                type: Array
+                type: Object,
+                required: true,
             }
+        },
+
+        methods: {
+            // Todo: consider event bus to avoid having to pass this up through all the levels?
+            updateItemQuantity(update) {
+                this.$emit('update-item-quantity', update)
+            },
         }
     }
 </script>
index 65c50810ae913962b568b339f1e3f1c6542e0229..244258639edec69a93a61d02f00d105cefdb14f8 100644 (file)
@@ -11,9 +11,9 @@
             </div>
             <div class="bg-grey-100 py-1 pl-3 my-2 flex items-center justify-between">
                 <span class="mr-2">Quantité</span>
-                <number-input :value="item.quantity" :min="1" inline center controls></number-input>
+                <number-input :value="item.quantity" :min="1" inline center controls @change="updateQuantity"></number-input>
             </div>
-            <a href="#" class="cart-delete-item text-red">
+            <a href="#" class="cart-delete-item text-red" @click.prevent="deleteItem">
                 Supprimer
             </a>
         </div>
             item: {
                 type: Object
             }
+        },
+
+        methods: {
+            updateQuantity(newValue, oldValue) {
+                this.$emit('update-item-quantity', {
+                    id: this.item.id,
+                    quantity: newValue,
+                });
+            },
+
+            deleteItem() {
+                this.$emit('deleteItem', this.item.id);
+            }
         }
     }
 </script>
index e50103b51e44d537d2fec2ae50fe28421ee126fb..6dc3d8ef1ca8c9bd0ac5ff5b97ede58a8f820bfd 100644 (file)
@@ -113,14 +113,15 @@ $footer-logo-height = 70px // Used so we can align headings in other columns wit
     &-flag
       @apply inline-block mr-2
 
-    &-list
+    &-list-wrapper
       @apply absolute w-full -mb-1
       left: 0
       bottom: 100%
-      opacity: 0
-      transform: translateY(1.5em)
-      transition: all 0.1s ease-out
+      overflow: hidden // Child element is translated out of the visible area to give precise clipping
 
+    &-list
+      transform: translateY(100%)
+      transition: transform 0.2s ease-out
 
       li:first-child a
         @apply rounded-t
index 8fd674c091efd24e2d79eab278b44b39fa575ccc..bc2e4c19e466a6a3badcf19b3e8e7eef9af59f1a 100644 (file)
 <body class="font-body text-grey-dark">
 @include('cubist::body.begin')
 
-<div id="app" class="flex flex-col min-h-screen">
+
+@php
+    //#### Generate temporary cart data
+    $cart_items = [];
+    for ($i = 1; $i <= 6; $i++) {
+        $cart_items[$i] = [
+            'id' => $i,
+            'quantity' => rand(1, 15),
+            'name' => 'Modèle '. rand(1000, 1500),
+            'category' => 'Capteur de force',
+            'image' => '/storage/products/'. rand(1,6) .'.png',
+        ];
+    }
+@endphp
+
+<div id="app" class="flex flex-col min-h-screen" data-cart-items='@json($cart_items)'>
 
     @include('partials.header')
 
     </main>
 
     @include('partials.footer')
+
+    <div class="body-overlay" @click="closeCart"></div>
 </div>
 
-<div class="body-overlay"></div>
 
 <script src="{{ mix('/js/app.js') }}"></script>
 
index 1292c2ad7a31e5f0a7ced3d51872f1fa30a35861..164e5eb7e9ba19a85094f822f7604fcadb4bd562 100644 (file)
@@ -1,2 +1,2 @@
 <span class="cart-header-title">My Selection</span>
-<span class="cart-header-icon">0</span>
+<span class="cart-header-icon" v-html="cartItemCount"></span>
index 4ceb0aa7b65d77deea11e6c068ef1476e7c53bb3..68c8e1464c1fa656bc5c64d18738aa26b7cdff6d 100644 (file)
                 <span class="footer-locales-current pr-12">
                     <img src="{{ asset('images/locale-fr.svg') }}" alt="Français" class="footer-locales-flag">Français
                 </span>
-                <ul class="footer-locales-list">
-                    <li><a href="/de"><img src="{{ asset('images/locale-de.svg') }}" alt="Deutsch" class="footer-locales-flag">Deutsche</a></li>
-                    <li><a href="/en"><img src="{{ asset('images/locale-en.svg') }}" alt="English" class="footer-locales-flag">English</a></li>
-                </ul>
+                <div class="footer-locales-list-wrapper">
+                    <ul class="footer-locales-list">
+                        <li><a href="/de"><img src="{{ asset('images/locale-de.svg') }}" alt="Deutsch" class="footer-locales-flag">Deutsche</a></li>
+                        <li><a href="/en"><img src="{{ asset('images/locale-en.svg') }}" alt="English" class="footer-locales-flag">English</a></li>
+                    </ul>
+                </div>
             </div>
 
             {{-- Footer Nav Links --}}
index e88df29d6834da8fcc62b807c108acda64014e7d..1aa9b69a1a2b1156b5b164892c1fa640ba4c2206 100644 (file)
@@ -14,8 +14,6 @@
             <portal-target name="nav-search-toggle" slim></portal-target>
         </div>
 
-        {{-- TODO: Make a Vue component for the cart + popout using portals and slots (see Search.vue) --}}
-
         <div class="cart-header text-right flex items-center cursor-pointer hover:text-blue" @click="openCart">
             @include('partials.cart')
         </div>
                     {{ __('My Selection') }}
                 </span>
 
-                <a href="#" class="close-cart-popout text-white hover:text-blue">
+                <a href="#" class="close-cart-popout text-white hover:text-blue" @click.prevent="closeCart">
                     @svg('icon-close-thin')
                 </a>
             </div>
             <div class="cart-header-popout-content text-navy font-body p-1v pb-0">
-
-                @php
-                    //#### Generate temporary data
-                    $cart_items = [];
-                    for ($i = 1; $i <= 6; $i++) {
-                        $cart_items[] = [
-                            'id' => $i,
-                            'quantity' => rand(1, 15),
-                            'name' => 'Modèle '. rand(1000, 1500),
-                            'category' => 'Capteur de force',
-                            'image' => '/storage/products/'. rand(1,6) .'.png',
-                        ];
-                    }
-                @endphp
-
-                <cart :items='@json($cart_items)'></cart>
-
+                <cart :items='items' @update-item-quantity="updateItemQuantity"></cart>
             </div>
             <div class="cart-header-popout-footer bg-grey-100 p-1v">
                 <link-button class="block text-center">Obtenir un devis</link-button>