From 59c13b97ea8ba2efb4824878bee963b4b80f9cc4 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 3 Jun 2020 17:12:36 +1000 Subject: [PATCH] Replace quantity input with add-remove buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new mobile friendly design contains a nice "Add" button to add variants to your cart. Once you have the variant in you cart, it's replaced by plus and minus buttons to adjust the quantity. Other languages have longer words than "Add" which need to fit on the button. Since the add button and the +/- buttons should have the same width, I widened them a little bit so that they fit the longest words Aggiungi and Добавить. --- .../directives/shop_variant.js.coffee | 8 ++ .../shop_variant_no_group_buy.html.haml | 24 ++-- .../stylesheets/darkswarm/_shop-inputs.scss | 106 ++++++++++-------- config/locales/en.yml | 5 + .../consumer/shopping/shopping_spec.rb | 37 ++++-- spec/support/request/shop_workflow.rb | 17 +-- 6 files changed, 111 insertions(+), 86 deletions(-) diff --git a/app/assets/javascripts/darkswarm/directives/shop_variant.js.coffee b/app/assets/javascripts/darkswarm/directives/shop_variant.js.coffee index 84615e3125..55c72abfe1 100644 --- a/app/assets/javascripts/darkswarm/directives/shop_variant.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/shop_variant.js.coffee @@ -11,3 +11,11 @@ Darkswarm.directive "shopVariant", -> ], (new_value, old_value) -> return if old_value[0] == null && new_value[0] == null Cart.adjust($scope.variant.line_item) + + $scope.add = (quantity) -> + $scope.variant.line_item.quantity += quantity + + $scope.canAdd = (quantity) -> + variant = $scope.variant + wantedQuantity = variant.line_item.quantity + quantity + variant.on_demand || wantedQuantity <= variant.on_hand diff --git a/app/assets/javascripts/templates/partials/shop_variant_no_group_buy.html.haml b/app/assets/javascripts/templates/partials/shop_variant_no_group_buy.html.haml index 8ba787f20b..39b633ae24 100644 --- a/app/assets/javascripts/templates/partials/shop_variant_no_group_buy.html.haml +++ b/app/assets/javascripts/templates/partials/shop_variant_no_group_buy.html.haml @@ -1,14 +1,14 @@ .small-5.medium-3.large-3.columns.text-right{"ng-if" => "::!variant.product.group_buy"} - %input{type: :number, - integer: true, - value: nil, - min: 0, - placeholder: "0", - "ofn-disable-scroll" => true, - "ng-debounce" => "500", - onwheel: "this.blur()", - "ng-model" => "variant.line_item.quantity", - "ofn-on-hand" => "{{variant.on_demand && 9999 || variant.on_hand }}", - "ng-disabled" => "!variant.on_demand && variant.on_hand == 0", - name: "variants[{{::variant.id}}]", id: "variants_{{::variant.id}}"} + %button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}} + {{ "js.shop_variant_no_group_buy.add" | t }} + %button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(-1)"}}> + {{ "js.shop_variant_no_group_buy.decrement" | t }} + %button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}} + {{ "js.shop_variant_no_group_buy.increment" | t }} + %br + .variant-quantity-display{ng: {class: "{visible: variant.line_item.quantity}"}} + {{ "js.shop_variant_no_group_buy.in_cart" | t:{quantity: variant.line_item.quantity} }} + %input{type: :hidden, + name: "variants[{{::variant.id}}]", + ng: {model: "variant.line_item.quantity"}} diff --git a/app/assets/stylesheets/darkswarm/_shop-inputs.scss b/app/assets/stylesheets/darkswarm/_shop-inputs.scss index 59a3bd0c67..21e2267aa4 100644 --- a/app/assets/stylesheets/darkswarm/_shop-inputs.scss +++ b/app/assets/stylesheets/darkswarm/_shop-inputs.scss @@ -9,54 +9,6 @@ // ordering product { - input { - @include border-radius(0); - - @include csstrans; - - margin: 0; - width: 10rem; - display: inline; - - @include box-shadow(none); - - border-color: #b3b3b3; - text-align: right; - - @include breakpoint(desktop) { - width: 8rem; - } - - @include breakpoint(tablet) { - width: 7rem; - } - - @include breakpoint(phablet) { - float: left !important; - font-size: 0.75rem; - padding-left: 0.25rem; - padding-right: 0.25rem; - } - - @include breakpoint(mobile) { - width: 5.8rem; - } - - &:hover { - @include box-shadow(none); - - border-color: #888; - background-color: #fafafa; - } - - &:active, &:focus, &.active { - @include box-shadow(none); - - background-color: #f9f4b9; - border-color: #666; - } - } - // BULK input.bulk { @@ -96,3 +48,61 @@ } } } + +// Components to add variants to cart and change quanities +// +// They are not nested so that they can be used in modals. +button.add-variant, button.variant-quantity { + height: 2.5rem; + border-radius: 0; + background-color: $orange-500; + color: white; + // Override foundation button styles: + font-size: 1rem; + margin: 0; + padding: 0; + transition: none; + + &[disabled] { + &:hover, &:focus { + background-color: $orange-500; + } + } + &:nth-of-type(1) { + border-bottom-left-radius: 0.25em; + border-top-left-radius: 0.25em; + } + &:nth-last-of-type(1) { + border-top-right-radius: 0.25em; + border-bottom-right-radius: 0.25em; + } +} +button.add-variant { + min-width: 6rem; + padding: 0 1em; + + &[disabled] { + &:hover, &:focus { + background-color: $orange-500; + } + } +} +button.variant-quantity { + width: 3rem; + + &:nth-of-type(1) { + border-right: .1em solid $orange-400; + } +} +.variant-quantity-display { + display: inline-block; + font-size: 0.875em; + margin-top: 0.25em; + text-align: center; + width: 6rem; + visibility: hidden; + + &.visible { + visibility: visible; + } +} diff --git a/config/locales/en.yml b/config/locales/en.yml index 3c26545654..808d787b76 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2726,6 +2726,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using in your cart have reduced. Here's what's changed: now_out_of_stock: is now out of stock. only_n_remainging: "now only has %{num} remaining." + shop_variant_no_group_buy: + add: "Add" + increment: "+" # U+FF0B Fullwidth Plus Sign + decrement: "-" # U+FF0D Fullwidth Hyphen-Minus + in_cart: "%{quantity} in cart" variants: on_demand: "yes": "On demand" diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 5a821ea9fa..be28288e05 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -294,19 +294,21 @@ feature "As a consumer I want to shop with a distributor", js: true do click_add_to_cart variant, 10 - expect(page).to have_field "variants[#{variant.id}]", with: '10' + within_variant(variant) do + expect(page).to have_content "10 in cart" + end end it "alerts us when we enter a quantity greater than the stock available" do variant.update on_hand: 5 visit shop_path - - accept_alert 'Insufficient stock available, only 5 remaining' do - fill_in "variants[#{variant.id}]", with: '10' - end + click_add_to_cart variant, 5 - expect(page).to have_field "variants[#{variant.id}]", with: '5' + within_variant(variant) do + expect(page).to have_content "5 in cart" + expect(page).to have_button "+", disabled: true + end end describe "when a product goes out of stock just before it's added to the cart" do @@ -325,8 +327,13 @@ feature "As a consumer I want to shop with a distributor", js: true do # -- Page updates # Update amount in cart - expect(page).to have_field "variants[#{variant.id}]", with: '0', disabled: true - expect(page).to have_field "variants[#{variant2.id}]", with: '' + within_variant(variant) do + expect(page).to have_button "Add", disabled: true + expect(page).to have_no_content "in cart" + end + within_variant(variant2) do + expect(page).to have_button "Add", disabled: false + end # Update amount available in product list # If amount falls to zero, variant should be greyed out and input disabled @@ -352,7 +359,11 @@ feature "As a consumer I want to shop with a distributor", js: true do variant.update! on_hand: 0 # -- Messaging - click_add_bulk_max_to_cart variant + within(".reveal-modal") do + page.all("button", text: "+").last.click + end + close_modal + wait_for_cart within(".out-of-stock-modal") do expect(page).to have_content "stock levels for one or more of the products in your cart have reduced" @@ -390,6 +401,7 @@ feature "As a consumer I want to shop with a distributor", js: true do it "does not update max_quantity" do click_add_bulk_to_cart variant, 2 click_add_bulk_max_to_cart variant, 3 + close_modal variant.update! on_hand: 1 @@ -554,9 +566,10 @@ feature "As a consumer I want to shop with a distributor", js: true do end # Removes the item from the client-side cart and marks the variant as unavailable - expect(page).to have_field "variants[#{variant.id}]", with: '0', disabled: true expect(page).to have_selector "#variant-#{variant.id}.out-of-stock" - expect(page).to have_selector "#variants_#{variant.id}[ofn-on-hand='0']" - expect(page).to have_selector "#variants_#{variant.id}[disabled='disabled']" + within_variant(variant) do + expect(page).to have_button "Add", disabled: true + expect(page).to have_no_content "in cart" + end end end diff --git a/spec/support/request/shop_workflow.rb b/spec/support/request/shop_workflow.rb index fc573b6898..09e377d510 100644 --- a/spec/support/request/shop_workflow.rb +++ b/spec/support/request/shop_workflow.rb @@ -50,28 +50,17 @@ module ShopWorkflow end # Add an item to the cart - # - # At the moment, the user enters the quantity into an input field. - # But with the coming mobile-friendly UX, the user will click a button to - # add an item, hence the naming. - # - # This is temporary code. The duplication will be removed by the mobile - # product listings feature. This has been backported to avoid merge - # conflicts and to make the current build more stable. def click_add_to_cart(variant = nil, quantity = 1) within_variant(variant) do - input = page.find("input") - new_quantity = input.value.to_i + quantity - fill_in input[:name], with: new_quantity + click_button "Add" + (quantity - 1).times { click_button "+" } end wait_for_cart end def click_remove_from_cart(variant = nil, quantity = 1) within_variant(variant) do - input = page.find("input") - new_quantity = input.value.to_i - quantity - fill_in input[:name], with: new_quantity + quantity.times { click_button "-" } end wait_for_cart end