From d97b46cd5bb47b779beb3be61ba092730a1c6323 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Fri, 12 Feb 2021 17:14:13 +0100 Subject: [PATCH 1/6] add new feature for beta testers: unit_price The aim of this "feature toggle" is to enable the unit price display for each product/variants. By default activate on both development and staging environment. --- config/initializers/feature_toggles.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/initializers/feature_toggles.rb b/config/initializers/feature_toggles.rb index 9c31940462..a0f900c44a 100644 --- a/config/initializers/feature_toggles.rb +++ b/config/initializers/feature_toggles.rb @@ -9,3 +9,7 @@ OpenFoodNetwork::FeatureToggle.enable(:customer_balance) do |user| beta_testers.include?(user.email) end end + +OpenFoodNetwork::FeatureToggle.enable(:unit_price) do + ['development', 'staging'].include?(ENV['RAILS_ENV']) +end From 8c42388af196af44d408388501e2eaefd09b8728 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Wed, 10 Feb 2021 09:39:57 +0100 Subject: [PATCH 2/6] add a randomized unit price for variant unit price is composed with : - a unit_price_price which is a number that can be localized (depending on the currency) - a unit_price_unit which can be either `item` of `kg` @andrewpbrett will do stuff to have a relevant unit price for each variant --- app/serializers/api/variant_serializer.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index 0306c95f95..5c99fc1730 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -3,7 +3,8 @@ class Api::VariantSerializer < ActiveModel::Serializer :options_text, :unit_value, :unit_description, :unit_to_display, :display_as, :display_name, :name_to_display, :price, :on_demand, :on_hand, :fees, :price_with_fees, - :tag_list, :thumb_url + :tag_list, :thumb_url, + :unit_price_price, :unit_price_unit delegate :price, to: :object @@ -38,4 +39,12 @@ class Api::VariantSerializer < ActiveModel::Serializer "/noimage/mini.png" end end + + def unit_price_price + (rand * 10).round(2) + end + + def unit_price_unit + rand > 0.5 ? "item" : "kg" + end end From 7442d06bedfe869205e47183b1413d0e2efc1453 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Fri, 12 Feb 2021 17:14:30 +0100 Subject: [PATCH 3/6] add new template to manage variant - The aim of this template is to display unit price - Duplicate the angular directive - Add a question mark icon and its own file - Add some needed colors in the branding file --- .../shop_variant_with_unit_price.js.coffee | 7 +++++++ .../shop_variant_with_unit_price.html.haml | 19 +++++++++++++++++++ .../darkswarm/_shop-product-rows.scss | 6 ++++++ .../stylesheets/darkswarm/branding.scss | 4 ++++ .../darkswarm/question-mark-icon.scss | 18 ++++++++++++++++++ app/views/shop/products/_form.html.haml | 6 ++++-- 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee create mode 100644 app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml create mode 100644 app/assets/stylesheets/darkswarm/question-mark-icon.scss diff --git a/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee b/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee new file mode 100644 index 0000000000..d23d365087 --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/shop_variant_with_unit_price.js.coffee @@ -0,0 +1,7 @@ +Darkswarm.directive "shopVariantWithUnitPrice", -> + restrict: 'E' + replace: true + templateUrl: 'shop_variant_with_unit_price.html' + scope: + variant: '=' + controller: 'ShopVariantCtrl' diff --git a/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml new file mode 100644 index 0000000000..4d261d73ed --- /dev/null +++ b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml @@ -0,0 +1,19 @@ +.variants.row + .small-4.medium-4.large-5.columns.variant-name + .inline{"ng-if" => "::variant.display_name"} {{ ::variant.display_name }} + .variant-unit {{ ::variant.unit_to_display }} + .small-3.medium-3.large-2.columns.variant-price + %price-breakdown{"price-breakdown" => "_", variant: "variant", + "price-breakdown-append-to-body" => "true", + "price-breakdown-placement" => "bottom", + "price-breakdown-animation" => true} + {{ variant.price_with_fees | localizeCurrency }} + .variant-unit-price + %span.question-mark-icon + {{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }} + + .medium-2.large-2.columns.total-price + %span{"ng-class" => "{filled: variant.line_item.total_price}"} + {{ variant.line_item.total_price | localizeCurrency }} + %ng-include{src: "'partials/shop_variant_no_group_buy.html'"} + %ng-include{src: "'partials/shop_variant_with_group_buy.html'"} diff --git a/app/assets/stylesheets/darkswarm/_shop-product-rows.scss b/app/assets/stylesheets/darkswarm/_shop-product-rows.scss index bf05fb4829..a008b916ad 100644 --- a/app/assets/stylesheets/darkswarm/_shop-product-rows.scss +++ b/app/assets/stylesheets/darkswarm/_shop-product-rows.scss @@ -65,6 +65,12 @@ } } + .variant-unit-price { + color: $grey-700; + font-size: 0.9rem; + margin-top: 15px; + } + // Total price .total-price { padding-left: 0rem; diff --git a/app/assets/stylesheets/darkswarm/branding.scss b/app/assets/stylesheets/darkswarm/branding.scss index b29e81acf9..29b52436d8 100644 --- a/app/assets/stylesheets/darkswarm/branding.scss +++ b/app/assets/stylesheets/darkswarm/branding.scss @@ -42,8 +42,10 @@ $black: #000; $white: #fff; $grey-050: #f7f7f7; +$grey-075: #f3f8fc; $grey-100: #e6e6e6; $grey-200: #ddd; +$grey-250: #cfe1f3; $grey-300: #ccc; $grey-400: #bbb; $grey-500: #999; @@ -53,6 +55,8 @@ $grey-650: #666; $grey-700: #555; $grey-800: #333; +$tiny-blue: #80b2e1; + $teal-300: #80d3df; $teal-400: #4cb5c5; $teal-500: #0096ad; diff --git a/app/assets/stylesheets/darkswarm/question-mark-icon.scss b/app/assets/stylesheets/darkswarm/question-mark-icon.scss new file mode 100644 index 0000000000..e7028a3430 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/question-mark-icon.scss @@ -0,0 +1,18 @@ +.question-mark-icon { + position: relative; + top: 1px; + &::before { + content: "?"; + padding-left: 1px; + display: inline-block; + color: $tiny-blue; + border: 1px solid $grey-250; + border-radius: 50%; + text-align: center; + background-color: $grey-075; + width: 18px; + height: 18px; + font-weight: bold; + font-size: 1rem; + } +} \ No newline at end of file diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 00255beefc..dcd261e0b2 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -13,8 +13,10 @@ %product.animate-repeat{"ng-controller" => "ProductNodeCtrl", "ng-repeat" => "product in Products.products track by product.id", "id" => "product-{{ product.id }}"} = render "shop/products/summary" .shop-variants - %shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"} - + - if feature? :unit_price, spree_current_user + %shop-variant-with-unit-price{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"} + - else + %shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"} %product{"ng-show" => "Products.loading"} .summary .small-12.columns.text-center From 4be2b42fe1d2b29116629c9104047de513820dc3 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Fri, 12 Feb 2021 17:14:00 +0100 Subject: [PATCH 4/6] create a new directive: question mark with tooltip - Display a rounded blue question mark icon - Show (hide) on click a blue tooltip on top of the question mark icon --- .../question_mark_tooltip.js.coffee | 17 +++++++++++ .../question_mark_with_tooltip.html.haml | 8 +++++ .../question_mark_with_tooltip_icon.html.haml | 1 + .../stylesheets/darkswarm/branding.scss | 1 + .../darkswarm/question-mark-icon.scss | 30 ++++++++++++++++++- .../stylesheets/darkswarm/variables.scss | 2 ++ 6 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee create mode 100644 app/assets/javascripts/templates/question_mark_with_tooltip.html.haml create mode 100644 app/assets/javascripts/templates/question_mark_with_tooltip_icon.html.haml diff --git a/app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee b/app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee new file mode 100644 index 0000000000..b1693369af --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/question_mark_tooltip.js.coffee @@ -0,0 +1,17 @@ +Darkswarm.directive "questionMarkWithTooltip", ($tooltip)-> + # We use the $tooltip service from Angular foundation to give us boilerplate + # Subsequently we patch the scope, template and restrictions + tooltip = $tooltip 'questionMarkWithTooltip', 'questionMarkWithTooltip', 'click' + tooltip.scope = + variant: "=" + tooltip.templateUrl = "question_mark_with_tooltip_icon.html" + tooltip.replace = true + tooltip.restrict = 'E' + tooltip + +# This is automatically referenced via naming convention in $tooltip +Darkswarm.directive 'questionMarkWithTooltipPopup', -> + restrict: 'EA' + replace: true + templateUrl: 'question_mark_with_tooltip.html' + scope: false diff --git a/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml b/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml new file mode 100644 index 0000000000..b3892d436b --- /dev/null +++ b/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml @@ -0,0 +1,8 @@ +.joyride-tip-guide.question-mark-tooltip{ng: {class: "{ in: tt_isOpen, fade: tt_animation }", show: "tt_isOpen"}} + .background{ng: {click: "tt_isOpen = false"}} + .joyride-content-wrapper + This is the unit price of this item. + %br/ + It allows you to compare the price of products across varying sizes and weights. + %span.joyride-nub.bottom + \ No newline at end of file diff --git a/app/assets/javascripts/templates/question_mark_with_tooltip_icon.html.haml b/app/assets/javascripts/templates/question_mark_with_tooltip_icon.html.haml new file mode 100644 index 0000000000..18ea4c771d --- /dev/null +++ b/app/assets/javascripts/templates/question_mark_with_tooltip_icon.html.haml @@ -0,0 +1 @@ +%button.question-mark-icon{"ng-class" => "{open: tt_isOpen}", type: 'button'} diff --git a/app/assets/stylesheets/darkswarm/branding.scss b/app/assets/stylesheets/darkswarm/branding.scss index 29b52436d8..1ca4224cee 100644 --- a/app/assets/stylesheets/darkswarm/branding.scss +++ b/app/assets/stylesheets/darkswarm/branding.scss @@ -56,6 +56,7 @@ $grey-700: #555; $grey-800: #333; $tiny-blue: #80b2e1; +$dynamic-blue: #3d8dd1; $teal-300: #80d3df; $teal-400: #4cb5c5; diff --git a/app/assets/stylesheets/darkswarm/question-mark-icon.scss b/app/assets/stylesheets/darkswarm/question-mark-icon.scss index e7028a3430..5a04ebbb3f 100644 --- a/app/assets/stylesheets/darkswarm/question-mark-icon.scss +++ b/app/assets/stylesheets/darkswarm/question-mark-icon.scss @@ -15,4 +15,32 @@ font-weight: bold; font-size: 1rem; } -} \ No newline at end of file +} + +.joyride-tip-guide.question-mark-tooltip { + width: 16rem; + max-width: 65%; + // JS needs to be tweaked to adjust for left alignment - this is dynamic can't rewrite in CSS + margin-left: -7.4rem; + margin-top: 0.1rem; + background-color: transparent; + + .joyride-content-wrapper { + background-color: $dynamic-blue; + padding: $padding-small; + border-radius: $radius-small; + color: $white; + width: 100%; + font-size: 0.8rem; + } + + .joyride-nub.bottom { + // Need to rewrite all with !important as it's marked as !important in the original file + border-color: $dynamic-blue !important; + border-bottom-color: transparent !important; + border-left-color: transparent !important; + border-right-color: transparent !important; + left: 7.4rem; + z-index: -1; + } +} diff --git a/app/assets/stylesheets/darkswarm/variables.scss b/app/assets/stylesheets/darkswarm/variables.scss index 08930efd76..b5039804e1 100644 --- a/app/assets/stylesheets/darkswarm/variables.scss +++ b/app/assets/stylesheets/darkswarm/variables.scss @@ -43,3 +43,5 @@ $radius-medium: 0.5em; $shop-sidebar-overlay: rgba(0, 0, 0, 0.5); $transition-sidebar: 250ms ease-in-out 0s; + +$padding-small: 0.5rem; From e50992578914872d37c08004e2fef3698434915c Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Wed, 10 Feb 2021 09:45:55 +0100 Subject: [PATCH 5/6] Use question mark with tooltip directive Needs some css customization due to the use of a button element (instead of a basic span) --- .../shop_variant_with_unit_price.html.haml | 5 ++++- .../darkswarm/question-mark-icon.scss | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml index 4d261d73ed..3250f032c0 100644 --- a/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml +++ b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml @@ -9,7 +9,10 @@ "price-breakdown-animation" => true} {{ variant.price_with_fees | localizeCurrency }} .variant-unit-price - %span.question-mark-icon + %question-mark-with-tooltip{"question-mark-with-tooltip" => "_", + "question-mark-with-tooltip-append-to-body" => "true", + "question-mark-with-tooltip-placement" => "top", + "question-mark-with-tooltip-animation" => true} {{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }} .medium-2.large-2.columns.total-price diff --git a/app/assets/stylesheets/darkswarm/question-mark-icon.scss b/app/assets/stylesheets/darkswarm/question-mark-icon.scss index 5a04ebbb3f..25a4e59ca3 100644 --- a/app/assets/stylesheets/darkswarm/question-mark-icon.scss +++ b/app/assets/stylesheets/darkswarm/question-mark-icon.scss @@ -1,6 +1,19 @@ .question-mark-icon { position: relative; top: 1px; + + // Reset button element css attributes + padding: 0; + margin: 0; + width: 20px; + height: 20px; + background-color: transparent; + + &:hover, + &:focus { + background-color: transparent; + } + &::before { content: "?"; padding-left: 1px; @@ -10,8 +23,8 @@ border-radius: 50%; text-align: center; background-color: $grey-075; - width: 18px; - height: 18px; + width: 20px; + height: 20px; font-weight: bold; font-size: 1rem; } From a8cc0d1001e13daab6e928bc98e454cee85e543a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Tue, 16 Feb 2021 15:25:46 +0100 Subject: [PATCH 6/6] add translation for question mark tooltip --- .../templates/question_mark_with_tooltip.html.haml | 4 +--- config/locales/en.yml | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml b/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml index b3892d436b..b96ce49b50 100644 --- a/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml +++ b/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml @@ -1,8 +1,6 @@ .joyride-tip-guide.question-mark-tooltip{ng: {class: "{ in: tt_isOpen, fade: tt_animation }", show: "tt_isOpen"}} .background{ng: {click: "tt_isOpen = false"}} .joyride-content-wrapper - This is the unit price of this item. - %br/ - It allows you to compare the price of products across varying sizes and weights. + {{ "js.shopfront.unit_price_tooltip" | t }} %span.joyride-nub.bottom \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 4237d739f1..20113db4d4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2775,6 +2775,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using min_quantity: "Min quantity" max_quantity: "Max quantity" price_breakdown: "Price breakdown" + unit_price_tooltip: "This is the unit price of this product. It allows you to compare the price of products independent of packaging sizes & weights." variants: on_demand: "yes": "On demand"