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/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/question_mark_with_tooltip.html.haml b/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml new file mode 100644 index 0000000000..b96ce49b50 --- /dev/null +++ b/app/assets/javascripts/templates/question_mark_with_tooltip.html.haml @@ -0,0 +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 + {{ "js.shopfront.unit_price_tooltip" | t }} + %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/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..3250f032c0 --- /dev/null +++ b/app/assets/javascripts/templates/shop_variant_with_unit_price.html.haml @@ -0,0 +1,22 @@ +.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 + %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 + %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..1ca4224cee 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,9 @@ $grey-650: #666; $grey-700: #555; $grey-800: #333; +$tiny-blue: #80b2e1; +$dynamic-blue: #3d8dd1; + $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..25a4e59ca3 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/question-mark-icon.scss @@ -0,0 +1,59 @@ +.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; + display: inline-block; + color: $tiny-blue; + border: 1px solid $grey-250; + border-radius: 50%; + text-align: center; + background-color: $grey-075; + width: 20px; + height: 20px; + font-weight: bold; + font-size: 1rem; + } +} + +.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; 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 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 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 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"