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