]> _ Git - pmi.git/commitdiff
wip #5850 @11:30
authorsoufiane <soufiane@cubedesigners.com>
Fri, 7 Apr 2023 14:45:32 +0000 (16:45 +0200)
committersoufiane <soufiane@cubedesigners.com>
Fri, 7 Apr 2023 14:45:32 +0000 (16:45 +0200)
app/Http/Controllers/AjaxController.php
app/Models/Product.php
resources/js/app.js
resources/js/components/Cart.vue
resources/js/components/CartItem.vue
resources/styles/components/cart.styl
resources/views/components/cart-add.blade.php
resources/views/pages/product-detail.blade.php
resources/views/partials/cart.blade.php
resources/views/partials/header.blade.php

index 58568f4f4c9e554cd507e8122845eeb010f7edeb..8a70f6d6e2835a8711a942f96967dcab128e64ec 100644 (file)
@@ -156,54 +156,82 @@ class AjaxController extends CubistFrontController
         $id = $request->input('id');
         $quantity = $request->input('quantity', 1);
 
-        // Cart items stored as an array with IDs as keys and quantities as values
+        $ref = $request->input('ref') ?? '';
+        $price = $request->input('price') ?? '';
+
         // Get existing session or an empty array
         $cart_items = $request->session()->get('cart_items', []);
 
+        $ga = [];
         $ga['add'] = [];
         $ga['remove'] = [];
 
         $needs_update = false;
 
+        $product = Product::find($id);
+        $currentItem = false;
+        if($product) {
+            $currentItem = array_filter($cart_items, function ($n) use ($ref) {
+                return $n['ref'] === $ref;
+            });
+            $currentIndex = key($currentItem);
+        }
+
         switch ($request->input('action')) {
             case 'add':
                 // If the item already exists in the cart, increment the quantity
-                if (isset($cart_items[$id])) {
-                    $cart_items[$id] += $quantity;
-                } else {
-                    $cart_items[$id] = $quantity;
+                if ($currentItem) {
+                    $cart_items[$currentIndex]['quantity'] += $quantity;
+                }else {
+                    $cart_items[] = [
+                        'id' => $product->id,
+                        'name' => $product->name,
+                        'reference' => $product->reference,
+                        'category' => $product->type->name,
+                        'quantity' => $quantity,
+                        'image' => $product->image,
+                        'URL' => $product->url,
+                        'price' => $price,
+                        'ref' => $ref
+                    ];
+                    $currentIndex = array_key_last($cart_items);
                 }
-                $ga['add'][$id] = $quantity;
+                $ga['add'][$currentIndex]['quantity'] = $quantity;
 
                 $needs_update = true;
                 break;
 
             case 'update':
-                if (!isset($cart_items[$id])) {
-                    $ga['add'][$id] = $quantity;
+                if (!$currentItem) {
+                    $currentIndex = array_key_last($cart_items);
+                    $ga['add'][$currentIndex]['quantity'] = $quantity;
                 } else {
-                    if ($cart_items[$id] < $quantity) {
-                        $ga['add'][$id] = $quantity - $cart_items[$id];
-                    } else if ($cart_items[$id] > $quantity) {
-                        $ga['remove'][$id] = $cart_items[$id] - $quantity;
+                    if ($cart_items[$currentIndex]['quantity'] < $quantity) {
+                        $ga['add'][$currentIndex]['quantity'] = $quantity - $cart_items[$currentIndex]['quantity'];
+                    } else if ($cart_items[$currentIndex]['quantity'] > $quantity) {
+                        $ga['remove'][$currentIndex]['quantity'] = $cart_items[$currentIndex]['quantity'] - $quantity;
                     }
                 }
+
                 if ($quantity <= 0) {
                     $needs_update = true;
                 }
-                $cart_items[$id] = $quantity;
+                $cart_items[$currentIndex]['quantity'] = $quantity;
+                //$cart_items[$currentIndex]['price'] = $price;
                 break;
 
             case 'delete':
-                if (isset($cart_items[$id])) {
-                    $ga['remove'][$id] = $cart_items[$id];
-                    unset($cart_items[$id]);
+                if ($currentItem) {
+                    $ga['remove'][$currentIndex] = $cart_items[$currentIndex];
+                    unset($cart_items[$currentIndex]);
                 }
                 $needs_update = true;
 
                 break;
         }
 
+        $cart_items = array_values($cart_items);
+
         // Save back to the session
         $request->session()->put('cart_items', $cart_items);
 
@@ -226,9 +254,9 @@ class AjaxController extends CubistFrontController
         $data['locale'] = 'fr';
         $data['products'] = [];
         $productsMessage = ['Produits : (reférence : quantité)'];
-        foreach ($cartData as $id => $quantity) {
-            $data['products'][] = ['id' => $id, 'reference' => $products[$id]['reference'], 'name' => $products[$id]['name'], 'quantity' => $quantity];
-            $productsMessage[] = $products[$id]['reference'] . ' : ' . $quantity;
+        foreach ($cartData as $id => $_data) {
+            $data['products'][] = ['id' => $id, 'reference' => $products[$id]['reference'], 'name' => $products[$id]['name'], 'quantity' => $_data['quantity']];
+            $productsMessage[] = $products[$id]['reference'] . ' : ' . $_data['quantity'];
         }
         $data['products'] = json_encode($data['products']);
         unset($data['page']);
index 8c8bf97b6297ae5e9a00f6de8c36a16c484bb094..b00d25c8cdb2dc7d6737fa9142f116790afa957a 100644 (file)
@@ -475,20 +475,22 @@ class Product extends CubistMagicPageModel
             self::$_cart_data = [];
 
             if (count($cart_items) > 0) {
+                self::$_cart_data = $cart_items;
+                //$products = self::with('media')->whereIn('id', array_keys($cart_items))->get();
 
-                $products = self::with('media')->whereIn('id', array_keys($cart_items))->get();
-
-                foreach ($products as $product) {
+                /*foreach ($cart_items as $product) {
                     self::$_cart_data[] = [
-                        'id' => $product->id,
-                        'name' => $product->name,
-                        'reference' => $product->reference,
-                        'category' => $product->type->name,
-                        'quantity' => $cart_items[$product->id],
-                        'image' => $product->image,
-                        'URL' => $product->url,
+                        'id' => $product['id'],
+                        'name' => $product['name'],
+                        'reference' => $product['reference'],
+                        'category' => $product['category'],
+                        'quantity' => $product['quantity'],
+                        'image' => $product['image'],
+                        'URL' => $product['URL'],
+                        'price' => $product['price'],
+                        'ref' => $product['ref']
                     ];
-                }
+                }*/
             }
         }
 
index ac305c0f804b094e3b565df174d267080c4037a6..6720383a74751ce160ac46180626661a9b47d1e4 100644 (file)
@@ -93,6 +93,8 @@ const app = new Vue({
     mounted() {
         eventBus.$on('add-item', data => {
             data.action = 'add';
+            data.ref = this.ref;
+            data.price = this.price;
             this.saveCart(data);
         });
 
@@ -101,13 +103,15 @@ const app = new Vue({
             this.saveCart(data);
         });
 
-        eventBus.$on('delete-item', id => {
+        eventBus.$on('delete-item', data => {
             this.saveCart({
                 action: 'delete',
-                id: id
+                id: data.id,
+                ref: data.ref
             });
         });
 
+        this.ref = this.$refs.refProduct?.dataset.ref
         this.price = this.$refs.optprice ?.dataset.default
         this.statusText = this.$refs.statusConfig ?.dataset.incomplete
     },
@@ -126,6 +130,15 @@ const app = new Vue({
 
         cartData() {
             return JSON.stringify(this.items.reduce((obj, item) => Object.assign(obj, {[item.id]: item.quantity}), {}));
+        },
+
+        cartItemHasPriceCount() {
+            return this.items.length ? this.items.filter(n => n.price !== "").length : 0
+        },
+
+        total() {
+            let prices = this.items.map(item => item.price * item.quantity)
+            return this.items.length ? prices.reduce((init, current) => init + current) : false
         }
     },
 
@@ -140,16 +153,16 @@ const app = new Vue({
 
                     // Google analytics cart events
                     var idToName = {};
-                    root.items.forEach(function (i) {
-                        idToName[i.id] = i.reference;
+                    root.items.forEach(function (i, index) {
+                        idToName[index] = i.ref;
                     });
 
-                    for (var id in response.data.ga.add) {
-                        let quantity = response.data.ga.add[id];
+                    for (var id = 0; id < response.data.ga.add.length; id++) {
+                        let quantity = response.data.ga.add[id]['quantity'];
                         cubistga.addToCart(id, idToName[id], quantity);
                     }
-                    for (var id in response.data.ga.remove) {
-                        let quantity = response.data.ga.remove[id];
+                    for (var id = 0; id < response.data.ga.add.length; id++) {
+                        let quantity = response.data.ga.remove[id].quantity;
                         cubistga.removeFromCart(id, idToName[id], quantity);
                     }
                 })
@@ -415,11 +428,17 @@ const app = new Vue({
          *
          */
         changePrice() {
-            let options = [];
+            let options = [],
+                placeholder = '';
+
             const selectOptions = document.querySelectorAll(".opt-select")
 
             selectOptions.forEach(function(e, i) {
+                let nextIndex = i+1
                 options.push(e.selectedOptions[0])
+                let r = e.selectedOptions[0].dataset.ref;
+                placeholder += r ? r : '-'
+                placeholder += selectOptions[nextIndex] ? '/' : ''
             })
 
             let prices = options.map(opt => parseFloat(opt.dataset.price)).filter(n => !isNaN(n)),
@@ -432,7 +451,7 @@ const app = new Vue({
 
             let total = prices.reduce((init, current) => init + current)
 
-            this.ref = refs
+            this.ref = this.$refs.refProduct.dataset.ref+'/'+placeholder
             this.price = total + parseFloat(this.$refs.optprice.dataset.default)
         }
     },
@@ -512,12 +531,19 @@ checkScroll();
 
 $(document).on('click', 'button.cart-add', function () {
     $(this).addClass('btn-no-hover').addClass('bg-navy');
-    $(this).find('.add').addClass('opacity-0');
-    $(this).find('.added').show();
+    $(this).find('.add').addClass('hidden');
+    $(this).find('.added').removeClass('hidden').addClass('inline-flex');
     var id = parseInt($(this).attr('data-product-id'));
     eventBus.$emit('add-item', {
         id: id,
         quantity: 1,
     });
+
+    clearTimeout(time);
+    let time = setTimeout(() => {
+        $(this).addClass('btn-no-hover').removeClass('bg-navy');
+        $(this).find('.add').removeClass('hidden');
+        $(this).find('.added').removeClass('inline-flex').addClass('hidden');
+    }, 2000)
 });
 
index 16dc90802ae56dbdaf65e39a8f87b87c596ef02b..43c59e2ba511eacd467e969f7d50a8cfe608a0fb 100644 (file)
@@ -1,6 +1,6 @@
 <template>
     <div class="cart-wrapper">
-        <cart-item v-for="item in items" :key="item.id" :item="item" :sendevents="sendevents"></cart-item>
+        <cart-item v-for="(item,key) in items" :key="key" :item="item" :sendevents="sendevents"></cart-item>
     </div>
 </template>
 
index f2d38d0fdc1e310babd198cd4555ebabe415f55f..dd56867511f99fa3d2c90cb078afd8fab4339597 100644 (file)
@@ -7,7 +7,8 @@
         <div class="cart-item-text pl-6 xs:pl-0 leading-relaxed flex-grow">
             <a :href="item.URL" class="block text-navy font-display">
 
-                <span class="text-grey-dark">{{ item.reference }}</span>
+                <span class="text-grey-dark" v-if="item.ref">{{ item.ref }}</span>
+                <span class="text-grey-dark" v-else>{{ item.reference }}</span>
                 <br>
                 {{ item.name }}
             </a>
@@ -15,6 +16,9 @@
                 <span class="mr-2">Quantité</span>
                 <number-input v-model="item.quantity" :min="1" inline center controls></number-input>
             </div>
+            <div v-if="item.price">
+                <span>{{ price }}€ HT</span>
+            </div>
             <a href="#" class="cart-delete-item text-red" @click.prevent="deleteItem">
                 Supprimer
             </a>
                 }
                 eventBus.$emit('update-item', {
                     id: this.item.id,
+                    ref: this.item.ref,
+                    price: this.price,
                     quantity: newValue,
                 });
             }
         },
 
+        computed: {
+            price() {
+                return this.item.price * this.item.quantity
+            }
+        },
+
         methods: {
             deleteItem() {
-                eventBus.$emit('delete-item', this.item.id);
+                eventBus.$emit('delete-item', {id: this.item.id, ref: this.item.ref} );
             }
         }
     }
index 242b6e478f2adb9a0347e3125d05d3eb96371926..f8cb1f6b07643c571cb316c0b6f04f27d19224ca 100644 (file)
@@ -34,7 +34,7 @@
 
     &-content
       // Fill available height if needed. Footer of popout is 139px tall
-      max-height: calc(100vh - var(--header-height) - 139px)
+      max-height: calc(100vh - var(--header-height) - 309px)
       transition: max-height var(--transition-duration)
       overflow-y: auto
 
index 61591be7b5acc52ed77e9f04f23d6e16c48f5ae0..ade4c691c08a8458ad75ea19dc8d1dc783f9ab13 100644 (file)
@@ -7,8 +7,8 @@
                     {{ __('Ajouter à ma sélection') }}
                 @endif
             </span>
-            <span class="added absolute top-0 left-0 w-full h-full flex items-center justify-ce hidden" style="top:-2px">
-                @svg('tick', 'w-4 mr-3 mt-1 inline absolute left-0') <span>{{ __('Produit ajouté') }}</span>
+            <span class="added top-0 left-0 w-full h-full inline-flex items-center justify-center hidden" style="top:-2px;">
+                @svg('tick', 'w-4 mr-3 inline left-0') <span>{{ __('Produit ajouté') }}</span>
             </span>
         </span>
 </button>
index d2d475292358a68bc2fdd7d39ea4a8320d43ab63..fe523e5c5782b8c42c4d36dcd76087449d6829d4 100644 (file)
                             </div>
                         </div>
                         <div class="opt-infos mb-8">
-                            <div class="opt-ref" v-cloak v-if="ref">{{ __('Référence') }} : <span id="opt-ref">@{{ ref }}</span></div>
+                            <div class="opt-ref" v-cloak>{{ __('Référence') }} : <span ref="refProduct" data-ref="{{ $product->reference }}">@{{ ref }}</span></div>
                             <div class="opt-price">
                                 {{ __('Prix unitaire') }} :
-                                <span id="opt-price" ref="optprice" v-cloak data-default="{{ $product->basic_selling_price }}">@{{ price }}</span>{{ "€ ".__('HT') }}
+                                <span ref="optprice" v-cloak data-default="{{ $product->basic_selling_price }}">@{{ price }}</span>{{ "€ ".__('HT') }}
                             </div>
                             <div class="opt-statut">{{ __('Statut') }} :
-                                <span id="opt-statut" v-cloak :class="{ 'text-green' : statusConfig }" ref="statusConfig" data-incomplete="{{ __('La configuration est incomplète') }}" data-completed="{{ __('La configuration est complète') }}">
+                                <span v-cloak :class="{ 'text-green' : statusConfig }" ref="statusConfig" data-incomplete="{{ __('La configuration est incomplète') }}" data-completed="{{ __('La configuration est complète') }}">
                                     @{{ statusText }}
                                 </span>
                             </div>
index 29576de31ce155b853be8b9ed8667a9ef50f7e68..8cc12c5bf328b3d1899e8c30e38c1290b103d9d5 100644 (file)
@@ -1,4 +1,4 @@
-<span class="cart-header-title">{{ __('Ma sélection') }}</span>
+<span class="cart-header-title">{{ __('Mon panier') }}</span>
 <span class="header-icon-wrapper cart-header-icon-wrapper">
     @svg('icon-cart', 'cart-header-icon header-icon')
     <span class="cart-header-count" v-html="cartItemCount">
index c5d0018764017773b7c6c39b5464d959f978941a..f7042f79e92a41bf05cf09bb649efce62a6ccad6 100644 (file)
@@ -52,7 +52,7 @@
             <div class="cart-header-popout">
                 <div class="cart-header-popout-title flex justify-between items-center px-1v">
                     <span>
-                        {{ __('Ma sélection') }}
+                        {{ __('Mon panier') }}
                     </span>
 
                     <a href="#" class="close-cart-popout text-white hover:text-primary" @click.prevent="closeCart">
                         {{ __("Vous n'avez encore rien sélectionné") }}
                     </div>
                 </div>
-                <div class="cart-header-popout-footer" v-if="cartItemCount > 0">
+                <div class="cart-header-popout-footer" v-cloak v-if="cartItemCount > 0 && cartItemCount !== cartItemHasPriceCount">
                     <link-button class="block text-center" :href="$nav->getHrefByName('cart')">
                         {{ __('Obtenir un devis') }}
                     </link-button>
                 </div>
+                <div class="cart-header-popout-footer" v-cloak v-else-if="cartItemCount > 0 && cartItemCount === cartItemHasPriceCount">
+                    <div class="cart-total text-navy text-center mb-5 text-2xl">
+                        {{__('Total'). ':' }} @{{ total }}€ HT
+                    </div>
+                    <link-button class="block text-center" :href="$nav->getHrefByName('cart')">
+                        {{ __('Valider la commande') }}
+                    </link-button>
+                    <div class="text-center">
+                        <a href="" class="animated-underline mt-5 inline-block w-100">{{ __('Obtenir un devis officiel') }}</a><br>
+                        <a href="" class="animated-underline mt-5 inline-block">{{ __('Enregistrer ce panier') }}</a>
+                    </div>
+                </div>
             </div>
         @endif