From 668371ec9eeab8f59eb661febe0f7d75963cb69d Mon Sep 17 00:00:00 2001 From: soufiane Date: Fri, 7 Apr 2023 16:45:32 +0200 Subject: [PATCH] wip #5850 @11:30 --- app/Http/Controllers/AjaxController.php | 66 +++++++++++++------ app/Models/Product.php | 24 +++---- resources/js/app.js | 50 ++++++++++---- resources/js/components/Cart.vue | 2 +- resources/js/components/CartItem.vue | 16 ++++- resources/styles/components/cart.styl | 2 +- resources/views/components/cart-add.blade.php | 4 +- .../views/pages/product-detail.blade.php | 6 +- resources/views/partials/cart.blade.php | 2 +- resources/views/partials/header.blade.php | 16 ++++- 10 files changed, 134 insertions(+), 54 deletions(-) diff --git a/app/Http/Controllers/AjaxController.php b/app/Http/Controllers/AjaxController.php index 58568f4..8a70f6d 100644 --- a/app/Http/Controllers/AjaxController.php +++ b/app/Http/Controllers/AjaxController.php @@ -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']); diff --git a/app/Models/Product.php b/app/Models/Product.php index 8c8bf97..b00d25c 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -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'] ]; - } + }*/ } } diff --git a/resources/js/app.js b/resources/js/app.js index ac305c0..6720383 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -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) }); diff --git a/resources/js/components/Cart.vue b/resources/js/components/Cart.vue index 16dc908..43c59e2 100644 --- a/resources/js/components/Cart.vue +++ b/resources/js/components/Cart.vue @@ -1,6 +1,6 @@ diff --git a/resources/js/components/CartItem.vue b/resources/js/components/CartItem.vue index f2d38d0..dd56867 100644 --- a/resources/js/components/CartItem.vue +++ b/resources/js/components/CartItem.vue @@ -7,7 +7,8 @@
- {{ item.reference }} + {{ item.ref }} + {{ item.reference }}
{{ item.name }}
@@ -15,6 +16,9 @@ Quantité
+
+ {{ price }}€ HT +
Supprimer @@ -52,14 +56,22 @@ } 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} ); } } } diff --git a/resources/styles/components/cart.styl b/resources/styles/components/cart.styl index 242b6e4..f8cb1f6 100644 --- a/resources/styles/components/cart.styl +++ b/resources/styles/components/cart.styl @@ -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 diff --git a/resources/views/components/cart-add.blade.php b/resources/views/components/cart-add.blade.php index 61591be..ade4c69 100644 --- a/resources/views/components/cart-add.blade.php +++ b/resources/views/components/cart-add.blade.php @@ -7,8 +7,8 @@ {{ __('Ajouter à ma sélection') }} @endif - diff --git a/resources/views/pages/product-detail.blade.php b/resources/views/pages/product-detail.blade.php index d2d4752..fe523e5 100644 --- a/resources/views/pages/product-detail.blade.php +++ b/resources/views/pages/product-detail.blade.php @@ -73,13 +73,13 @@
-
{{ __('Référence') }} : @{{ ref }}
+
{{ __('Référence') }} : @{{ ref }}
{{ __('Prix unitaire') }} : - @{{ price }}{{ "€ ".__('HT') }} + @{{ price }}{{ "€ ".__('HT') }}
{{ __('Statut') }} : - + @{{ statusText }}
diff --git a/resources/views/partials/cart.blade.php b/resources/views/partials/cart.blade.php index 29576de..8cc12c5 100644 --- a/resources/views/partials/cart.blade.php +++ b/resources/views/partials/cart.blade.php @@ -1,4 +1,4 @@ -{{ __('Ma sélection') }} +{{ __('Mon panier') }} @svg('icon-cart', 'cart-header-icon header-icon') diff --git a/resources/views/partials/header.blade.php b/resources/views/partials/header.blade.php index c5d0018..f7042f7 100644 --- a/resources/views/partials/header.blade.php +++ b/resources/views/partials/header.blade.php @@ -52,7 +52,7 @@
- {{ __('Ma sélection') }} + {{ __('Mon panier') }} @@ -65,11 +65,23 @@ {{ __("Vous n'avez encore rien sélectionné") }}
- @endif -- 2.39.5