diff --git a/app/assets/javascripts/darkswarm/controllers/hubs_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/hubs_controller.js.coffee index 769b47cbe8..98053daebf 100644 --- a/app/assets/javascripts/darkswarm/controllers/hubs_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/hubs_controller.js.coffee @@ -4,6 +4,7 @@ Darkswarm.controller "HubsCtrl", ($scope, Hubs, Search, $document, $rootScope, H $scope.totalActive = FilterSelectorsService.totalActive $scope.clearAll = FilterSelectorsService.clearAll $scope.filterText = FilterSelectorsService.filterText + $scope.FilterSelectorsService = FilterSelectorsService $scope.query = Search.search() $scope.$watch "query", (query)-> diff --git a/app/assets/javascripts/darkswarm/controllers/producers_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/producers_controller.js.coffee index 6fdb589529..d88af1e53d 100644 --- a/app/assets/javascripts/darkswarm/controllers/producers_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/producers_controller.js.coffee @@ -3,6 +3,7 @@ Darkswarm.controller "ProducersCtrl", ($scope, Producers, $filter, FilterSelecto $scope.totalActive = FilterSelectorsService.totalActive $scope.clearAll = FilterSelectorsService.clearAll $scope.filterText = FilterSelectorsService.filterText + $scope.FilterSelectorsService = FilterSelectorsService $scope.filtersActive = false $scope.activeTaxons = [] $scope.query = Search.search() diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index 73406e072b..07ddb4bc61 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -1,11 +1,6 @@ -Darkswarm.controller "ProductNodeCtrl", ($scope) -> - - $scope.price = -> - if $scope.product.variants.length > 0 - prices = (v.price for v in $scope.product.variants) - Math.min.apply(null, prices) - else - $scope.product.price - +Darkswarm.controller "ProductNodeCtrl", ($scope, $modal) -> $scope.enterprise = $scope.product.supplier # For the modal, so it's consistent - $scope.hasVariants = $scope.product.variants.length > 0 + + $scope.triggerProductModal = -> + $modal.open(templateUrl: "product_modal.html", scope: $scope) + diff --git a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee index 3860a2d56e..361c1ebca4 100644 --- a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee @@ -1,5 +1,9 @@ -Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) -> +Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle, FilterSelectorsService) -> $scope.Product = Product + $scope.totalActive = FilterSelectorsService.totalActive + $scope.clearAll = FilterSelectorsService.clearAll + $scope.filterText = FilterSelectorsService.filterText + $scope.FilterSelectorsService = FilterSelectorsService $scope.limit = 3 $scope.ordering = {order: "name"} $scope.order_cycle = OrderCycle.order_cycle diff --git a/app/assets/javascripts/darkswarm/directives/product_modal.js.coffee b/app/assets/javascripts/darkswarm/directives/product_modal.js.coffee deleted file mode 100644 index 428fde3633..0000000000 --- a/app/assets/javascripts/darkswarm/directives/product_modal.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -Darkswarm.directive "productModal", ($modal)-> - restrict: 'E' - replace: true - template: "" - transclude: true - link: (scope, elem, attrs, ctrl)-> - elem.on "click", => - scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'product_modal.html', scope: scope) - diff --git a/app/assets/javascripts/darkswarm/directives/shipping_type_selector.js.coffee b/app/assets/javascripts/darkswarm/directives/shipping_type_selector.js.coffee index 856b6dcac2..3f752f8a3d 100644 --- a/app/assets/javascripts/darkswarm/directives/shipping_type_selector.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/shipping_type_selector.js.coffee @@ -1,5 +1,6 @@ Darkswarm.directive "shippingTypeSelector", (FilterSelectorsService)-> restrict: 'E' + replace: true templateUrl: 'shipping_type_selector.html' link: (scope, elem, attr)-> scope.shippingTypes = diff --git a/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee b/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee index 88dbe919a2..a682176d77 100644 --- a/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee @@ -1,5 +1,6 @@ Darkswarm.directive "taxonSelector", (FilterSelectorsService)-> restrict: 'E' + replace: true scope: objects: "&" results: "=" @@ -19,8 +20,12 @@ Darkswarm.directive "taxonSelector", (FilterSelectorsService)-> taxons = {} selectors = [] for object in scope.objects() - for taxon in (object.taxons.concat object?.supplied_taxons) + for taxon in object.taxons taxons[taxon.id] = taxon + if object.supplied_taxons + for taxon in object.supplied_taxons + taxons[taxon.id] = taxon + for id, taxon of taxons if selector = selectors_by_id[id] selectors.push selector diff --git a/app/assets/javascripts/darkswarm/services/product.js.coffee b/app/assets/javascripts/darkswarm/services/product.js.coffee index 2c57512bff..48cdd6ae33 100644 --- a/app/assets/javascripts/darkswarm/services/product.js.coffee +++ b/app/assets/javascripts/darkswarm/services/product.js.coffee @@ -1,5 +1,5 @@ -Darkswarm.factory 'Product', ($resource, Enterprises) -> - new class Product +Darkswarm.factory 'Product', ($resource, Enterprises, Dereferencer, Taxons) -> + new class Products constructor: -> @update() @@ -10,7 +10,8 @@ Darkswarm.factory 'Product', ($resource, Enterprises) -> update: => @loading = true - @products = $resource("/shop/products").query => + @products = $resource("/shop/products").query (products)=> + @extend() @dereference() @loading = false @ @@ -18,3 +19,12 @@ Darkswarm.factory 'Product', ($resource, Enterprises) -> dereference: -> for product in @products product.supplier = Enterprises.enterprises_by_id[product.supplier.id] + Dereferencer.dereference product.taxons, Taxons.taxons_by_id + + extend: -> + for product in @products + if product.variants.length > 0 + prices = (v.price for v in product.variants) + product.price = Math.min.apply(null, prices) + + product.hasVariants = product.variants.length > 0 diff --git a/app/assets/javascripts/templates/shipping_type_selector.html.haml b/app/assets/javascripts/templates/shipping_type_selector.html.haml index cdbe702f32..8feb23e59f 100644 --- a/app/assets/javascripts/templates/shipping_type_selector.html.haml +++ b/app/assets/javascripts/templates/shipping_type_selector.html.haml @@ -1,4 +1,3 @@ -%ul.small-block-grid-2.large-block-grid-1 - %active-selector{"ng-repeat" => "(name, selector) in selectors"} - %i{"ng-class" => "selector.icon"} - {{ name | capitalize }} +%active-selector{"ng-repeat" => "(name, selector) in selectors"} + %i{"ng-class" => "selector.icon"} + {{ name | capitalize }} diff --git a/app/assets/javascripts/templates/taxon_selector.html.haml b/app/assets/javascripts/templates/taxon_selector.html.haml index dd40453e3f..02450c8d12 100644 --- a/app/assets/javascripts/templates/taxon_selector.html.haml +++ b/app/assets/javascripts/templates/taxon_selector.html.haml @@ -1,4 +1,3 @@ -%ul.small-block-grid-2.large-block-grid-5 - %active-selector{"ng-repeat" => "selector in selectors()"} - %render-svg{path: "{{selector.taxon.icon}}"} - %span {{ selector.taxon.name }} +%active-selector{"ng-repeat" => "selector in selectors()"} + %render-svg{path: "{{selector.taxon.icon}}"} + %span {{ selector.taxon.name }} diff --git a/app/assets/stylesheets/darkswarm/active_table.css.sass b/app/assets/stylesheets/darkswarm/active_table.css.sass index a386328a5a..a08f2c794b 100644 --- a/app/assets/stylesheets/darkswarm/active_table.css.sass +++ b/app/assets/stylesheets/darkswarm/active_table.css.sass @@ -2,6 +2,10 @@ @import mixins @import "compass/css3/user-interface" + +.no-results + font-size: 1.875rem + .active_table margin: 2em 0em @include user-select(none) @@ -9,9 +13,7 @@ display: block &:first-child cursor: pointer - - .no-results - font-size: 1.875rem + padding: 1rem 0 .active_table .active_table_node display: block diff --git a/app/assets/stylesheets/darkswarm/active_table_search.css.sass b/app/assets/stylesheets/darkswarm/active_table_search.css.sass index d8f253ee28..9920dc1d87 100644 --- a/app/assets/stylesheets/darkswarm/active_table_search.css.sass +++ b/app/assets/stylesheets/darkswarm/active_table_search.css.sass @@ -11,17 +11,23 @@ .row.filter-box:first-child border-top: 1px solid $clr-brick +products .filter-box + background: #f7f7f7 + .filter-box - background: rgba(255,255,255,0.65) + background: rgba(245,245,245,0.6) .tdhead padding: 0.25rem 0.5rem margin-top: 0.9rem // OVERRIDES + [class*="block-grid-"] + margin: 0 0 0.5rem 0 [class*="block-grid-"] > li padding-bottom: 0.5rem !important + li @include border-radius(12px) padding-top: 0.5rem @@ -45,6 +51,7 @@ @include csstrans display: table table-layout: fixed + text-transform: capitalize overflow: visible // width: 100% // height: 2rem diff --git a/app/assets/stylesheets/darkswarm/animations.sass b/app/assets/stylesheets/darkswarm/animations.sass index ff51d36199..d1952d1c4c 100644 --- a/app/assets/stylesheets/darkswarm/animations.sass +++ b/app/assets/stylesheets/darkswarm/animations.sass @@ -83,28 +83,35 @@ filter: alpha(opacity = 50) opacity: .5 + .animate-repeat - line-height: 40px - list-style: none - box-sizing: border-box + border-color: rgba(153, 153, 153, 1) + -webkit-transform: translateZ(0) + transform: translateZ(0) + &.ng-move, &.ng-enter, &.ng-leave + -webkit-transition: all 1s linear + transition: all 1s linear + + &.ng-leave + opacity: 1 + border-color: rgba(153, 153, 153, 1) + //max-height: 200px + &.ng-leave-active + opacity: 0 + //max-height: 0px + border-color: rgba(153, 153, 153, 0) -.animate-repeat.ng-move, -.animate-repeat.ng-enter, -.animate-repeat.ng-leave - -webkit-transition: all linear 0.2s - transition: all linear 0.2s + &.ng-enter + opacity: 0 + border-color: rgba(153, 153, 153, 0) + //max-height: 0px + &.ng-enter-active + //max-height: 200px + opacity: 1 + border-color: rgba(153, 153, 153, 1) -.animate-repeat.ng-leave.ng-leave-active, -.animate-repeat.ng-move, -.animate-repeat.ng-enter - opacity: 0 - max-height: 0 - -.animate-repeat.ng-leave, -.animate-repeat.ng-move.ng-move-active, -.animate-repeat.ng-enter.ng-enter-active - opacity: 1 - max-height: 40px + &.ng-move + &.ng-move-active .animate-show diff --git a/app/assets/stylesheets/darkswarm/big-input.sass b/app/assets/stylesheets/darkswarm/big-input.sass index 70cb3bd4f9..133097a5ac 100644 --- a/app/assets/stylesheets/darkswarm/big-input.sass +++ b/app/assets/stylesheets/darkswarm/big-input.sass @@ -17,6 +17,7 @@ box-shadow: 0 padding: 0.75rem 1rem 0.35rem 1rem height: auto + width: 100% margin-bottom: 0.5rem box-shadow: none color: $inputactv diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index 9011f99a7f..6e6001ce6e 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -6,10 +6,10 @@ .darkswarm // #search - @include placeholder(rgba(0,0,0,0.3), #999) + @include placeholder(rgba(0,0,0,0.4), #777) input#search - @include big-input(rgba(0,0,0,0.2), #999, #000) + @include big-input(rgba(0,0,0,0.3), #777, $clr-brick) @include big-input-static color: #666 @@ -115,7 +115,7 @@ .columns padding-top: 1em padding-bottom: 1em - line-height: 2.4em + line-height: 1em .row.summary, .row.variants margin-left: 0 diff --git a/app/assets/stylesheets/darkswarm/taxons.css.sass b/app/assets/stylesheets/darkswarm/taxons.css.sass index 160d2ce002..32ba3aba1b 100644 --- a/app/assets/stylesheets/darkswarm/taxons.css.sass +++ b/app/assets/stylesheets/darkswarm/taxons.css.sass @@ -6,7 +6,7 @@ line-height: 1 margin-right: 0.5rem margin-bottom: 0.35rem - text-transform: uppercase + text-transform: capitalize font-weight: 300 font-size: 0.875rem background: rgba(235,235,235,0.5) diff --git a/app/views/home/_filters.html.haml b/app/views/home/_filters.html.haml index ab98389e82..78d755f1bc 100644 --- a/app/views/home/_filters.html.haml +++ b/app/views/home/_filters.html.haml @@ -7,13 +7,15 @@ %h5.tdhead .light Filter by Type - %taxon-selector{objects: "hubs | hubs:query", - results: "activeTaxons"} + %ul.small-block-grid-2.medium-block-grid-4.large-block-grid-5 + %taxon-selector{objects: "hubs | hubs:query", + results: "activeTaxons"} .small-12.large-3.columns %h5.tdhead .light Filter by Delivery - %shipping-type-selector{results: "shippingTypes"} + %ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2 + %shipping-type-selector{results: "shippingTypes"} .row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"} .small-12.columns %a.button.secondary.small.expand{"ng-click" => "clearAll()"} diff --git a/app/views/producers/_filters.html.haml b/app/views/producers/_filters.html.haml index 2419e0478d..63ccef2f0c 100644 --- a/app/views/producers/_filters.html.haml +++ b/app/views/producers/_filters.html.haml @@ -7,8 +7,9 @@ %h5.tdhead .light Filter by Type - %taxon-selector{objects: "Producers.visible | filterProducers:query", - results: "activeTaxons"} + %ul.small-block-grid-2.medium-block-grid-4.large-block-grid-6 + %taxon-selector{objects: "Producers.visible | filterProducers:query", + results: "activeTaxons"} .row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"} .small-12.columns diff --git a/app/views/shared/components/_filter_controls.html.haml b/app/views/shared/components/_filter_controls.html.haml index 7fe95c324a..c8fccb0558 100644 --- a/app/views/shared/components/_filter_controls.html.haml +++ b/app/views/shared/components/_filter_controls.html.haml @@ -1,6 +1,10 @@ .row .small-12.columns - %a.button.primary.tiny.filterbtn{{"ng-click" => "filtersActive = !filtersActive"}} + %a.button.primary.tiny.filterbtn{"ng-click" => "filtersActive = !filtersActive", + "ng-show" => "FilterSelectorsService.selectors.length > 0"} {{ filterText(filtersActive) }} %i.ofn-i_005-caret-down{"ng-show" => "!filtersActive"} %i.ofn-i_006-caret-up{"ng-show" => "filtersActive"} + + %a.button.secondary.tiny.filterbtn.disabled{"ng-show" => "FilterSelectorsService.selectors.length == 0"} + No filters diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index b934272b9a..a337ec3b16 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -43,7 +43,7 @@ node :variants do |product| end child :taxons => :taxons do |taxon| - attributes :name + attributes :id end child :properties => :properties do |property| diff --git a/app/views/shop/products/_filters.html.haml b/app/views/shop/products/_filters.html.haml new file mode 100644 index 0000000000..7879bcc5d1 --- /dev/null +++ b/app/views/shop/products/_filters.html.haml @@ -0,0 +1,18 @@ += render partial: 'shared/components/filter_controls' + +.row.animate-show{"ng-show" => "filtersActive"} + .small-12.columns + .row.filter-box + .small-12.columns + %h5.tdhead + .light Filter by + Type + %ul.small-block-grid-2.medium-block-grid-3.large-block-grid-4 + %taxon-selector{objects: "Product.products | products:query", + results: "activeTaxons"} + + .row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"} + .small-12.columns + %a.button.secondary.small.expand{"ng-click" => "clearAll()"} + %i.ofn-i_009-close + Clear all filters diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 391ad83227..2aaf7a4f5f 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -1,30 +1,42 @@ %products.small-12.columns{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null", "infinite-scroll" => "incrementLimit()", "infinite-scroll-distance" => "1"} + = form_for :order, :url => populate_orders_path, html: {:class => "custom"} do .row - .small-6.columns + .small-12.medium-8.large-8.columns %input#search.text{"ng-model" => "query", - placeholder: "Search products", - "ng-debounce" => "150", + placeholder: "Search by product or producer", + "ng-debounce" => "100", "ofn-disable-enter" => true} - .small-6.columns + + = render partial: "shop/products/filters" + + .small-12.medium-4.large-4.columns %input.button.primary.right{type: :submit, value: "Add to Cart"} - - %div{bindonce: true} + + %div.pad-top{bindonce: true} %product.animate-repeat{"ng-controller" => "ProductNodeCtrl", - "ng-repeat" => "product in Product.products | products:query | orderBy:ordering.order"} + "ng-repeat" => "product in filteredProducts = (Product.products | products:query | taxons:activeTaxons | orderBy:ordering.order) track by product.id "} %div = render partial: "shop/products/summary" - %div{"bo-if" => "hasVariants"} + %div{"bo-if" => "product.hasVariants"} = render partial: "shop/products/variants" - .variants.row{"bo-if" => "!hasVariants"} + .variants.row{"bo-if" => "!product.hasVariants"} = render partial: "shop/products/master" %product{"ng-show" => "Product.loading"} .row.summary .small-12.columns.text-center Loading products + + %div{"ng-show" => "filteredProducts.length == 0 && !Product.loading"} + .row.summary + .small-12.columns + %p.no-results + Sorry, no results found for + %strong {{query}}. + Try another search? .row .small-12.columns %input.button.primary.right.add_to_cart{type: :submit, value: "Add to Cart"} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index b21b535315..bded87c50c 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -1,17 +1,16 @@ .row.summary .small-1.columns - %product-modal - %img{"bo-src" => "product.master.images[0].small_url"} + %img{"bo-src" => "product.master.images[0].small_url", "ng-click" => "triggerProductModal()"} .small-4.columns.summary-header %render-svg{path: "{{product.primary_taxon.icon}}"} - %product-modal {{ product.name }} + %a{"ng-click" => "triggerProductModal()"}{{ product.name }} .small-5.columns %i.ofn-i_036-producers %producer-modal {{ enterprise.name }} .small-2.columns.summary-price.text-right.price - %span{"ng-if" => "hasVariants"} + %span{"ng-if" => "product.hasVariants"} %em from - {{ price() | currency }} + {{ product.price | currency }} diff --git a/app/views/shop/products/_variants.html.haml b/app/views/shop/products/_variants.html.haml index 5d6a59535e..2d281dafe8 100644 --- a/app/views/shop/products/_variants.html.haml +++ b/app/views/shop/products/_variants.html.haml @@ -1,5 +1,5 @@ .row.variants{bindonce: true, - "ng-repeat" => "variant in product.variants"} + "ng-repeat" => "variant in product.variants track by variant.id"} .small-1.columns %i.ofn-i_056-bulk{"bo-if" => "product.group_buy"}