diff --git a/Gemfile b/Gemfile
index f28e8a8baa..f8407decdc 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,7 +9,7 @@ gem 'i18n', '~> 0.6.11'
gem 'nokogiri', '>= 1.6.7.1'
gem 'pg'
-gem 'spree', github: 'openfoodfoundation/spree', branch: '1-3-stable'
+gem 'spree', github: 'openfoodfoundation/spree', branch: 'spree-upgrade-step1c'
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '1-3-stable'
@@ -50,7 +50,7 @@ gem 'gmaps4rails'
gem 'spinjs-rails'
gem 'rack-ssl', :require => 'rack/ssl'
gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg'
-gem 'angularjs-file-upload-rails', '~> 1.1.0'
+gem 'angularjs-file-upload-rails', '~> 1.1.6'
gem 'roadie-rails', '~> 1.0.3'
gem 'figaro'
gem 'blockenspiel'
@@ -87,6 +87,7 @@ gem "foundation-rails"
gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: "rails3"
gem 'jquery-rails'
+gem 'jquery-migrate-rails'
gem 'css_splitter'
diff --git a/Gemfile.lock b/Gemfile.lock
index a645196fc5..824f8a0c04 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -23,45 +23,48 @@ GIT
GIT
remote: git://github.com/openfoodfoundation/spree.git
- revision: 6e3edfe40a5de8eba0095b2c5f3db9ea54c3afda
- branch: 1-3-stable
+ revision: a4c439570b77afa50f9e36299811f293232bd281
+ branch: spree-upgrade-step1c
specs:
- spree (1.3.6.beta)
- spree_api (= 1.3.6.beta)
- spree_cmd (= 1.3.6.beta)
- spree_core (= 1.3.6.beta)
- spree_promo (= 1.3.6.beta)
- spree_sample (= 1.3.6.beta)
- spree_api (1.3.6.beta)
- spree_core (= 1.3.6.beta)
+ spree (1.3.99)
+ spree_api (= 1.3.99)
+ spree_cmd (= 1.3.99)
+ spree_core (= 1.3.99)
+ spree_dash (= 1.3.99)
+ spree_promo (= 1.3.99)
+ spree_sample (= 1.3.99)
+ spree_api (1.3.99)
+ spree_core (= 1.3.99)
versioncake (= 0.4.0)
- spree_cmd (1.3.6.beta)
+ spree_cmd (1.3.99)
thor (>= 0.14.6)
- spree_core (1.3.6.beta)
- activemerchant (~> 1.34)
+ spree_core (1.3.99)
+ activemerchant (~> 1.50.0)
acts_as_list (= 0.1.4)
awesome_nested_set (= 2.1.5)
aws-sdk (~> 1.11.1)
cancan (= 1.6.8)
deface (>= 0.9.0)
ffaker (~> 1.15.0)
- highline (= 1.6.18)
- jquery-rails (~> 2.2.0)
+ highline (= 1.6.11)
+ jquery-rails (~> 2.0)
json (>= 1.5.5)
- kaminari (= 0.14.1)
- money (= 5.1.1)
+ kaminari (= 0.13.0)
+ money (= 5.0.0)
paperclip (~> 3.0)
rabl (= 0.7.2)
- rails (~> 3.2.16)
+ rails (~> 3.2.13)
ransack (= 0.7.2)
- select2-rails (= 3.5.9.3)
- state_machine (= 1.1.2)
+ select2-rails (~> 3.2)
+ state_machine (= 1.2.0)
stringex (~> 1.3.2)
- truncate_html (~> 0.5.5)
- spree_promo (1.3.6.beta)
- spree_core (= 1.3.6.beta)
- spree_sample (1.3.6.beta)
- spree_core (= 1.3.6.beta)
+ spree_dash (1.3.99)
+ httparty (~> 0.8.1)
+ spree_core (= 1.3.99)
+ spree_promo (1.3.99)
+ spree_core (= 1.3.99)
+ spree_sample (1.3.99)
+ spree_core (= 1.3.99)
GIT
remote: git://github.com/spree/deface.git
@@ -123,8 +126,8 @@ GEM
sprockets (~> 2.2.1)
active_model_serializers (0.8.3)
activemodel (>= 3.0)
- activemerchant (1.57.0)
- activesupport (>= 3.2.14, < 5.1)
+ activemerchant (1.50.0)
+ activesupport (>= 3.2.14, < 5.0.0)
builder (>= 2.1.2, < 4.0.0)
i18n (>= 0.6.9)
nokogiri (~> 1.4)
@@ -151,7 +154,7 @@ GEM
railties (>= 3.1)
sprockets (~> 2)
tilt
- angularjs-file-upload-rails (1.1.0)
+ angularjs-file-upload-rails (1.1.6)
angularjs-rails (1.5.5)
ansi (1.4.2)
arel (3.0.3)
@@ -167,9 +170,7 @@ GEM
bcrypt-ruby (3.1.5)
bcrypt (>= 3.1.3)
blockenspiel (0.4.5)
- bugsnag (1.5.2)
- httparty (>= 0.6, < 1.0)
- multi_json (~> 1.0)
+ bugsnag (4.1.0)
builder (3.0.4)
byebug (2.7.0)
columnize (~> 0.3)
@@ -189,7 +190,7 @@ GEM
climate_control (0.0.3)
activesupport (>= 3.0)
cliver (0.3.2)
- cocaine (0.5.7)
+ cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
coderay (1.0.9)
coffee-rails (3.2.2)
@@ -404,12 +405,12 @@ GEM
zeus
haml (4.0.4)
tilt
- highline (1.6.18)
+ highline (1.6.11)
hike (1.2.3)
http_parser.rb (0.5.3)
- httparty (0.13.1)
- json (~> 1.8)
- multi_xml (>= 0.5.2)
+ httparty (0.8.3)
+ multi_json (~> 1.0)
+ multi_xml
i18n (0.6.11)
immigrant (0.1.6)
activerecord (>= 3.0)
@@ -417,16 +418,18 @@ GEM
inflecto (0.0.2)
ipaddress (0.8.0)
journey (1.0.4)
- jquery-rails (2.2.2)
+ jquery-migrate-rails (1.2.1)
+ jquery-rails (2.3.0)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.3)
json_spec (1.1.1)
multi_json (~> 1.0)
rspec (~> 2.0)
- kaminari (0.14.1)
+ kaminari (0.13.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
+ railties (>= 3.0.0)
kgio (2.9.3)
knapsack (1.5.1)
rake
@@ -449,8 +452,9 @@ GEM
mini_portile2 (2.0.0)
momentjs-rails (2.5.1)
railties (>= 3.1)
- money (5.1.1)
- i18n (~> 0.6.0)
+ money (5.0.0)
+ i18n (~> 0.4)
+ json
multi_json (1.12.1)
multi_xml (0.5.5)
newrelic_rpm (3.12.0.288)
@@ -494,7 +498,7 @@ GEM
activesupport (>= 2.3.14)
multi_json (~> 1.0)
rack (1.4.7)
- rack-cache (1.2)
+ rack-cache (1.6.1)
rack (>= 0.4)
rack-livereload (0.3.15)
rack
@@ -521,7 +525,7 @@ GEM
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
raindrops (0.13.0)
- rake (10.4.2)
+ rake (11.1.2)
ransack (0.7.2)
actionpack (~> 3.0)
activerecord (~> 3.0)
@@ -571,7 +575,7 @@ GEM
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
- select2-rails (3.5.9.3)
+ select2-rails (3.5.10)
thor (~> 0.14)
shoulda-matchers (1.1.0)
activesupport (>= 3.0.0)
@@ -583,14 +587,14 @@ GEM
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
- state_machine (1.1.2)
+ state_machine (1.2.0)
stringex (1.3.3)
therubyracer (0.12.0)
libv8 (~> 3.16.14.0)
ref
thor (0.19.1)
tilt (1.4.1)
- timecop (0.6.2.2)
+ timecop (0.8.1)
timers (1.1.0)
treetop (1.4.15)
polyglot
@@ -601,7 +605,7 @@ GEM
sprockets (>= 2.0.0)
turn (0.8.3)
ansi
- tzinfo (0.3.44)
+ tzinfo (0.3.49)
uglifier (2.7.1)
execjs (>= 0.3.0)
json (>= 1.8.0)
@@ -645,7 +649,7 @@ DEPENDENCIES
acts-as-taggable-on (~> 3.4)
andand
angular-rails-templates (~> 0.2.0)
- angularjs-file-upload-rails (~> 1.1.0)
+ angularjs-file-upload-rails (~> 1.1.6)
angularjs-rails (= 1.5.5)
atomic
awesome_print
@@ -682,6 +686,7 @@ DEPENDENCIES
haml
i18n (~> 0.6.11)
immigrant
+ jquery-migrate-rails
jquery-rails
json_spec
knapsack
@@ -728,5 +733,8 @@ DEPENDENCIES
wicked_pdf
wkhtmltopdf-binary
+RUBY VERSION
+ ruby 2.1.5p273
+
BUNDLED WITH
- 1.12.5
+ 1.13.6
diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js
index 0923e5721c..e71405ae46 100644
--- a/app/assets/javascripts/admin/all.js
+++ b/app/assets/javascripts/admin/all.js
@@ -6,6 +6,7 @@
//
//= require jquery
+//= require jquery-migrate-min
//= require jquery_ujs
//= require jquery-ui
//= require shared/jquery-ui-timepicker-addon
@@ -36,6 +37,7 @@
//= require ./order_cycles/order_cycles
//= require ./payment_methods/payment_methods
//= require ./products/products
+//= require ./resources/resources
//= require ./shipping_methods/shipping_methods
//= require ./side_menu/side_menu
//= require ./tag_rules/tag_rules
diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee
index 7a9d2677b9..d464a49bf4 100644
--- a/app/assets/javascripts/admin/bulk_product_update.js.coffee
+++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee
@@ -22,7 +22,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
$scope.producers = producers
- $scope.taxons = Taxons.taxons
+ $scope.taxons = Taxons.all
$scope.tax_categories = tax_categories
$scope.filterProducers = [{id: "0", name: ""}].concat $scope.producers
$scope.filterTaxons = [{id: "0", name: ""}].concat $scope.taxons
diff --git a/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee b/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee
index 9e956a1977..2506e994ac 100644
--- a/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee
+++ b/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee
@@ -3,8 +3,8 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt
$scope.availableCountries = availableCountries
$scope.RequestMonitor = RequestMonitor
$scope.submitAll = pendingChanges.submitAll
- $scope.add = Customers.add
$scope.customerLimit = 20
+ $scope.customers = Customers.all
$scope.columns = Columns.columns
$scope.confirmRefresh = (event) ->
@@ -16,7 +16,6 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt
Customers.index({enterprise_id: $scope.shop_id}).then (data) ->
pendingChanges.removeAll()
$scope.customers_form.$setPristine()
- $scope.customers = data
$scope.shop_id = shops[0].id if shops.length == 1
diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee
index f21c96a27e..0a68ce9d94 100644
--- a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee
+++ b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee
@@ -27,7 +27,7 @@ angular.module("admin.enterprises")
# Provide a callback for generating warning messages displayed before leaving the page. This is passed in
# from a directive "nav-check" in the page - if we pass it here it will be called in the test suite,
- # and on all new uses of this contoller, and we might not want that .
+ # and on all new uses of this contoller, and we might not want that.
enterpriseNavCallback = ->
if $scope.Enterprise.$dirty
"Your changes to the enterprise are not saved yet."
diff --git a/app/assets/javascripts/admin/enterprises/controllers/side_menu_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/side_menu_controller.js.coffee
index 913ff59d3e..fa346e100f 100644
--- a/app/assets/javascripts/admin/enterprises/controllers/side_menu_controller.js.coffee
+++ b/app/assets/javascripts/admin/enterprises/controllers/side_menu_controller.js.coffee
@@ -6,7 +6,6 @@ angular.module("admin.enterprises")
$scope.menu.setItems [
{ name: 'primary_details', label: t('primary_details'), icon_class: "icon-home" }
- { name: 'users', label: t('users'), icon_class: "icon-user" }
{ name: 'address', label: t('address'), icon_class: "icon-map-marker" }
{ name: 'contact', label: t('contact'), icon_class: "icon-phone" }
{ name: 'social', label: t('social'), icon_class: "icon-twitter" }
@@ -20,11 +19,11 @@ angular.module("admin.enterprises")
{ name: 'inventory_settings', label: t('inventory_settings'), icon_class: "icon-list-ol", show: "enterpriseIsShop()" }
{ name: 'tag_rules', label: t('tag_rules'), icon_class: "icon-random", show: "enterpriseIsShop()" }
{ name: 'shop_preferences', label: t('shop_preferences'), icon_class: "icon-shopping-cart", show: "enterpriseIsShop()" }
+ { name: 'users', label: t('users'), icon_class: "icon-user" }
]
$scope.select(0)
-
$scope.showItem = (item) ->
if item.show?
$parse(item.show)($scope)
diff --git a/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee b/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee
index d65341e6fe..6890589b9d 100644
--- a/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee
+++ b/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee
@@ -3,19 +3,42 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
restrict: 'C'
scope:
data: "="
- minSearch: "@?"
- text: "@?"
+ minSearch: "@"
+ text: "@"
blank: "=?"
filter: "=?"
onSelecting: "=?"
+ multiple: '@'
link: (scope, element, attrs, ngModel) ->
$timeout ->
- scope.text ||= 'name'
- scope.filter ||= -> true
+ scope.text ?= 'name'
+ scope.multiple ?= false
+ scope.filter ?= -> true
+
+ if scope.data.$promise
+ scope.data.$promise.then -> init()
+ else
+ init()
+
+ element.on "select2-opening", scope.onSelecting || angular.noop
+
+ attrs.$observe 'disabled', (value) ->
+ element.select2('enable', !value)
+
+ ngModel.$formatters.push (value) ->
+ element.select2('val', value)
+ value
+
+ ngModel.$parsers.push (value) ->
+ return value.split(",") if scope.multiple
+ value
+
+ init = ->
scope.data.unshift(scope.blank) if scope.blank? && typeof scope.blank is "object"
item.name = $sanitize(item.name) for item in scope.data
element.select2
+ multiple: scope.multiple
minimumResultsForSearch: scope.minSearch || 0
data: ->
filtered = $filter('filter')(scope.data,scope.filter)
@@ -24,12 +47,3 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
item[scope.text]
formatResult: (item) ->
item[scope.text]
-
- element.on "select2-opening", scope.onSelecting || angular.noop
-
- attrs.$observe 'disabled', (value) ->
- element.select2('enable', !value)
-
- ngModel.$formatters.push (value) ->
- element.select2('val', value)
- value
diff --git a/app/assets/javascripts/admin/index_utils/index_utils.js.coffee b/app/assets/javascripts/admin/index_utils/index_utils.js.coffee
index 1ea74e614b..a956fd955c 100644
--- a/app/assets/javascripts/admin/index_utils/index_utils.js.coffee
+++ b/app/assets/javascripts/admin/index_utils/index_utils.js.coffee
@@ -1 +1 @@
-angular.module("admin.indexUtils", ['ngResource', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content");
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*";
\ No newline at end of file
+angular.module("admin.indexUtils", ['admin.resources', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content");
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*";
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/index_utils/services/dereferencer.js.coffee b/app/assets/javascripts/admin/index_utils/services/dereferencer.js.coffee
index 4793c63034..fba6ef7908 100644
--- a/app/assets/javascripts/admin/index_utils/services/dereferencer.js.coffee
+++ b/app/assets/javascripts/admin/index_utils/services/dereferencer.js.coffee
@@ -3,7 +3,8 @@ angular.module("admin.indexUtils").factory 'Dereferencer', ->
dereference: (array, data)->
if array
for object, i in array
- array[i] = data[object.id]
+ match = data[object.id]
+ array[i] = match if match?
dereferenceAttr: (array, attr, data)->
if array
diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee
index f105ebb0e5..72e17d0931 100644
--- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee
+++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee
@@ -1,4 +1,4 @@
-angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, blankOption, VariantUnitManager, RequestMonitor) ->
+angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) ->
$scope.initialized = false
$scope.RequestMonitor = RequestMonitor
$scope.filteredLineItems = []
@@ -15,31 +15,31 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
$scope.resetSelectFilters = ->
- $scope.distributorFilter = blankOption().id
- $scope.supplierFilter = blankOption().id
- $scope.orderCycleFilter = blankOption().id
+ $scope.distributorFilter = 0
+ $scope.supplierFilter = 0
+ $scope.orderCycleFilter = 0
$scope.quickSearch = ""
$scope.refreshData = ->
- unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == "0"
- $scope.startDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].first_order
- $scope.endDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].last_order
+ unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == 0
+ $scope.startDate = OrderCycles.byID[$scope.orderCycleFilter].first_order
+ $scope.endDate = OrderCycles.byID[$scope.orderCycleFilter].last_order
RequestMonitor.load $scope.orders = Orders.index("q[state_not_eq]": "canceled", "q[completed_at_not_null]": "true", "q[completed_at_gt]": "#{parseDate($scope.startDate)}", "q[completed_at_lt]": "#{parseDate($scope.endDate)}")
RequestMonitor.load $scope.lineItems = LineItems.index("q[order][state_not_eq]": "canceled", "q[order][completed_at_not_null]": "true", "q[order][completed_at_gt]": "#{parseDate($scope.startDate)}", "q[order][completed_at_lt]": "#{parseDate($scope.endDate)}")
unless $scope.initialized
- RequestMonitor.load $scope.distributors = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
- RequestMonitor.load $scope.orderCycles = OrderCycles.index(includeBlank: true, ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
- RequestMonitor.load $scope.suppliers = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
+ RequestMonitor.load $scope.distributors = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
+ RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
+ RequestMonitor.load $scope.suppliers = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise]).then ->
- Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.enterprisesByID
- Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.orderCyclesByID
+ Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID
+ Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.suppliers.$promise, $scope.lineItems.$promise]).then ->
- Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.enterprisesByID
- Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.ordersByID
+ Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.byID
+ Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.byID
$scope.bulk_order_form.$setPristine()
StatusMessage.clear()
unless $scope.initialized
diff --git a/app/assets/javascripts/admin/line_items/filters/select_filter.js.coffee b/app/assets/javascripts/admin/line_items/filters/select_filter.js.coffee
index 5195057663..fb91acdeb3 100644
--- a/app/assets/javascripts/admin/line_items/filters/select_filter.js.coffee
+++ b/app/assets/javascripts/admin/line_items/filters/select_filter.js.coffee
@@ -1,8 +1,8 @@
-angular.module("admin.lineItems").filter "selectFilter", (blankOption, RequestMonitor) ->
+angular.module("admin.lineItems").filter "selectFilter", (RequestMonitor) ->
return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) ->
filtered = []
unless RequestMonitor.loading
- filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) &&
- (angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) &&
- (angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle)
+ filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,0) || lineItem.supplier.id == selectedSupplier) &&
+ (angular.equals(selectedDistributor,0) || lineItem.order.distributor.id == selectedDistributor) &&
+ (angular.equals(selectedOrderCycle,0) || lineItem.order.order_cycle.id == selectedOrderCycle)
filtered
diff --git a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee
index c0818acafa..0e1a0ab45c 100644
--- a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee
@@ -68,6 +68,7 @@ angular.module('admin.orderCycles')
$scope.removeCoordinatorFee = ($event, index) ->
$event.preventDefault()
OrderCycle.removeCoordinatorFee(index)
+ $scope.order_cycle_form.$dirty = true
$scope.addExchangeFee = ($event, exchange) ->
$event.preventDefault()
@@ -76,6 +77,7 @@ angular.module('admin.orderCycles')
$scope.removeExchangeFee = ($event, exchange, index) ->
$event.preventDefault()
OrderCycle.removeExchangeFee(exchange, index)
+ $scope.order_cycle_form.$dirty = true
$scope.removeDistributionOfVariant = (variant_id) ->
OrderCycle.removeDistributionOfVariant(variant_id)
diff --git a/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee b/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee
index 6ea3f76984..99dcbfe4b7 100644
--- a/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee
@@ -1,4 +1,4 @@
-angular.module('admin.orderCycles', ['ngResource', 'admin.utils', 'admin.indexUtils', 'ngTagsInput'])
+angular.module('admin.orderCycles', ['admin.utils', 'admin.indexUtils', 'ngTagsInput'])
.config ($httpProvider) ->
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
diff --git a/app/assets/javascripts/admin/payment_methods/controllers/payment_methods_controller.js.coffee b/app/assets/javascripts/admin/payment_methods/controllers/payment_methods_controller.js.coffee
index ddad6cd259..2def86a25a 100644
--- a/app/assets/javascripts/admin/payment_methods/controllers/payment_methods_controller.js.coffee
+++ b/app/assets/javascripts/admin/payment_methods/controllers/payment_methods_controller.js.coffee
@@ -1,3 +1,3 @@
angular.module("admin.paymentMethods").controller "paymentMethodsCtrl", ($scope, PaymentMethods) ->
$scope.findPaymentMethodByID = (id) ->
- $scope.PaymentMethod = PaymentMethods.findByID(id)
+ $scope.PaymentMethod = PaymentMethods.byID[id]
diff --git a/app/assets/javascripts/admin/payment_methods/services/payment_methods.js.coffee b/app/assets/javascripts/admin/payment_methods/services/payment_methods.js.coffee
deleted file mode 100644
index c31a20d96f..0000000000
--- a/app/assets/javascripts/admin/payment_methods/services/payment_methods.js.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-angular.module("admin.paymentMethods")
- .factory "PaymentMethods", (paymentMethods) ->
- new class PaymentMethods
- paymentMethods: paymentMethods
-
- findByID: (id) ->
- for paymentMethod in @paymentMethods
- return paymentMethod if paymentMethod.id is id
diff --git a/app/assets/javascripts/admin/resources/resources.js.coffee b/app/assets/javascripts/admin/resources/resources.js.coffee
new file mode 100644
index 0000000000..9e89237732
--- /dev/null
+++ b/app/assets/javascripts/admin/resources/resources.js.coffee
@@ -0,0 +1 @@
+angular.module("admin.resources", ['ngResource'])
diff --git a/app/assets/javascripts/admin/customers/services/customer_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/customer_resource.js.coffee
similarity index 86%
rename from app/assets/javascripts/admin/customers/services/customer_resource.js.coffee
rename to app/assets/javascripts/admin/resources/resources/customer_resource.js.coffee
index 3904d0333d..0a67586374 100644
--- a/app/assets/javascripts/admin/customers/services/customer_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/customer_resource.js.coffee
@@ -1,4 +1,4 @@
-angular.module("admin.customers").factory 'CustomerResource', ($resource) ->
+angular.module("admin.resources").factory 'CustomerResource', ($resource) ->
$resource('/admin/customers/:id.json', {}, {
'index':
method: 'GET'
diff --git a/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee
similarity index 75%
rename from app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee
rename to app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee
index b522f5be3b..7cdd5b7bce 100644
--- a/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee
@@ -1,4 +1,4 @@
-angular.module("admin.enterprises").factory 'EnterpriseResource', ($resource) ->
+angular.module("admin.resources").factory 'EnterpriseResource', ($resource) ->
ignoredAttrs = ->
["$$hashKey", "producer", "package", "producerError", "packageError", "status"]
diff --git a/app/assets/javascripts/admin/line_items/services/line_item_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee
similarity index 85%
rename from app/assets/javascripts/admin/line_items/services/line_item_resource.js.coffee
rename to app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee
index 60ca925753..4301f8df82 100644
--- a/app/assets/javascripts/admin/line_items/services/line_item_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee
@@ -1,4 +1,4 @@
-angular.module("admin.lineItems").factory 'LineItemResource', ($resource) ->
+angular.module("admin.resources").factory 'LineItemResource', ($resource) ->
$resource('/admin/:orders/:order_number/line_items/:id.json', {}, {
'index':
method: 'GET'
diff --git a/app/assets/javascripts/admin/order_cycles/services/order_cycle_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/order_cycle_resource.js.coffee
similarity index 64%
rename from app/assets/javascripts/admin/order_cycles/services/order_cycle_resource.js.coffee
rename to app/assets/javascripts/admin/resources/resources/order_cycle_resource.js.coffee
index 4a5df3c44a..cd5be31acd 100644
--- a/app/assets/javascripts/admin/order_cycles/services/order_cycle_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/order_cycle_resource.js.coffee
@@ -1,4 +1,4 @@
-angular.module("admin.orderCycles").factory 'OrderCycleResource', ($resource) ->
+angular.module("admin.resources").factory 'OrderCycleResource', ($resource) ->
$resource('/admin/order_cycles/:id/:action.json', {}, {
'index':
method: 'GET'
diff --git a/app/assets/javascripts/admin/orders/services/order_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee
similarity index 66%
rename from app/assets/javascripts/admin/orders/services/order_resource.js.coffee
rename to app/assets/javascripts/admin/resources/resources/order_resource.js.coffee
index ab360a2fc9..317b384485 100644
--- a/app/assets/javascripts/admin/orders/services/order_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee
@@ -1,4 +1,4 @@
-angular.module("admin.orders").factory 'OrderResource', ($resource) ->
+angular.module("admin.resources").factory 'OrderResource', ($resource) ->
$resource('/admin/orders/:id/:action.json', {}, {
'index':
method: 'GET'
diff --git a/app/assets/javascripts/admin/customers/services/customers.js.coffee b/app/assets/javascripts/admin/resources/services/customers.js.coffee
similarity index 56%
rename from app/assets/javascripts/admin/customers/services/customers.js.coffee
rename to app/assets/javascripts/admin/resources/services/customers.js.coffee
index f4c6f6f3cd..3783097f56 100644
--- a/app/assets/javascripts/admin/customers/services/customers.js.coffee
+++ b/app/assets/javascripts/admin/resources/services/customers.js.coffee
@@ -1,19 +1,24 @@
-angular.module("admin.customers").factory "Customers", ($q, InfoDialog, RequestMonitor, CustomerResource, CurrentShop) ->
+angular.module("admin.resources").factory "Customers", ($q, InfoDialog, RequestMonitor, CustomerResource, CurrentShop) ->
new class Customers
- customers: []
+ all: []
+ byID: {}
+ pristineByID: {}
add: (email) ->
params =
enterprise_id: CurrentShop.shop.id
email: email
CustomerResource.create params, (customer) =>
- @customers.unshift customer if customer.id
+ if customer.id
+ @all.unshift customer
+ @byID[customer.id] = customer
+ @pristineByID[customer.id] = angular.copy(customer)
remove: (customer) ->
params = id: customer.id
CustomerResource.destroy params, =>
- i = @customers.indexOf customer
- @customers.splice i, 1 unless i < 0
+ i = @all.indexOf customer
+ @all.splice i, 1 unless i < 0
, (response) =>
errors = response.data.errors
if errors?
@@ -22,10 +27,17 @@ angular.module("admin.customers").factory "Customers", ($q, InfoDialog, RequestM
InfoDialog.open 'error', "Could not delete customer: #{customer.email}"
index: (params) ->
- request = CustomerResource.index(params, (data) => @customers = data)
+ @clear()
+ request = CustomerResource.index(params, (data) => @load(data))
RequestMonitor.load(request.$promise)
request.$promise
+ load: (customers) ->
+ for customer in customers
+ @all.push customer
+ @byID[customer.id] = customer
+ @pristineByID[customer.id] = angular.copy(customer)
+
update: (address, customer, addressType) ->
params =
id: customer.id
@@ -33,3 +45,5 @@ angular.module("admin.customers").factory "Customers", ($q, InfoDialog, RequestM
"#{addressType}_attributes": address
CustomerResource.update params
+ clear: ->
+ @all.length = 0
diff --git a/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee b/app/assets/javascripts/admin/resources/services/enterprises.js.coffee
similarity index 67%
rename from app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee
rename to app/assets/javascripts/admin/resources/services/enterprises.js.coffee
index 80db943689..0b7fa6e870 100644
--- a/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee
+++ b/app/assets/javascripts/admin/resources/services/enterprises.js.coffee
@@ -1,21 +1,18 @@
-angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResource, blankOption) ->
+angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource) ->
new class Enterprises
- enterprisesByID: {}
+ byID: {}
pristineByID: {}
index: (params={}, callback=null) ->
- includeBlank = !!params['includeBlank']
- delete params['includeBlank']
- EnterpriseResource.index(params, (data) =>
- for enterprise in data
- @enterprisesByID[enterprise.id] = enterprise
- @pristineByID[enterprise.id] = angular.copy(enterprise)
-
+ EnterpriseResource.index params, (data) =>
+ @load(data)
(callback || angular.noop)(data)
-
- data.unshift(blankOption()) if includeBlank
data
- )
+
+ load: (enterprises) ->
+ for enterprise in enterprises
+ @byID[enterprise.id] = enterprise
+ @pristineByID[enterprise.id] = angular.copy(enterprise)
save: (enterprise) ->
deferred = $q.defer()
diff --git a/app/assets/javascripts/admin/line_items/services/line_items.js.coffee b/app/assets/javascripts/admin/resources/services/line_items.js.coffee
similarity index 81%
rename from app/assets/javascripts/admin/line_items/services/line_items.js.coffee
rename to app/assets/javascripts/admin/resources/services/line_items.js.coffee
index e78389c559..182ef81e6a 100644
--- a/app/assets/javascripts/admin/line_items/services/line_items.js.coffee
+++ b/app/assets/javascripts/admin/resources/services/line_items.js.coffee
@@ -1,23 +1,25 @@
-angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
+angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
new class LineItems
- lineItemsByID: {}
+ byID: {}
pristineByID: {}
index: (params={}, callback=null) ->
LineItemResource.index params, (data) =>
- @resetData()
- for lineItem in data
- @lineItemsByID[lineItem.id] = lineItem
- @pristineByID[lineItem.id] = angular.copy(lineItem)
-
+ @load(data)
(callback || angular.noop)(data)
resetData: ->
- @lineItemsByID = {}
+ @byID = {}
@pristineByID = {}
+ load: (lineItems) ->
+ @resetData()
+ for lineItem in lineItems
+ @byID[lineItem.id] = lineItem
+ @pristineByID[lineItem.id] = angular.copy(lineItem)
+
saveAll: ->
- for id, lineItem of @lineItemsByID
+ for id, lineItem of @byID
lineItem.errors = {} # removes errors when line_item has been returned to original state
@save(lineItem) if !@isSaved(lineItem)
@@ -34,7 +36,7 @@ angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
deferred.promise
allSaved: ->
- for id, lineItem of @lineItemsByID
+ for id, lineItem of @byID
return false unless @isSaved(lineItem)
true
@@ -54,7 +56,7 @@ angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
deferred = $q.defer()
lineItem.$delete({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
.then( (data) =>
- delete @lineItemsByID[lineItem.id]
+ delete @byID[lineItem.id]
delete @pristineByID[lineItem.id]
(callback || angular.noop)(data)
deferred.resolve(data)
diff --git a/app/assets/javascripts/admin/order_cycles/services/order_cycles.js.coffee b/app/assets/javascripts/admin/resources/services/order_cycles.js.coffee
similarity index 63%
rename from app/assets/javascripts/admin/order_cycles/services/order_cycles.js.coffee
rename to app/assets/javascripts/admin/resources/services/order_cycles.js.coffee
index a182f19f12..728b173e35 100644
--- a/app/assets/javascripts/admin/order_cycles/services/order_cycles.js.coffee
+++ b/app/assets/javascripts/admin/resources/services/order_cycles.js.coffee
@@ -1,21 +1,24 @@
-angular.module("admin.orderCycles").factory 'OrderCycles', ($q, OrderCycleResource, blankOption) ->
+angular.module("admin.resources").factory 'OrderCycles', ($q, $injector, OrderCycleResource) ->
new class OrderCycles
- orderCyclesByID: {}
+ all: []
+ byID: {}
pristineByID: {}
+ constructor: ->
+ if $injector.has('orderCycles')
+ @load($injector.get('orderCycles'))
+
index: (params={}, callback=null) ->
- includeBlank = !!params['includeBlank']
- delete params['includeBlank']
- OrderCycleResource.index(params, (data) =>
- for orderCycle in data
- @orderCyclesByID[orderCycle.id] = orderCycle
- @pristineByID[orderCycle.id] = angular.copy(orderCycle)
-
+ OrderCycleResource.index params, (data) =>
+ @load(data)
(callback || angular.noop)(data)
-
- data.unshift(blankOption()) if includeBlank
data
- )
+
+ load: (orderCycles) ->
+ for orderCycle in orderCycles
+ @all.push orderCycle
+ @byID[orderCycle.id] = orderCycle
+ @pristineByID[orderCycle.id] = angular.copy(orderCycle)
save: (order_cycle) ->
deferred = $q.defer()
diff --git a/app/assets/javascripts/admin/orders/services/orders.js.coffee b/app/assets/javascripts/admin/resources/services/orders.js.coffee
similarity index 76%
rename from app/assets/javascripts/admin/orders/services/orders.js.coffee
rename to app/assets/javascripts/admin/resources/services/orders.js.coffee
index a7b5bc1b68..da3f409149 100644
--- a/app/assets/javascripts/admin/orders/services/orders.js.coffee
+++ b/app/assets/javascripts/admin/resources/services/orders.js.coffee
@@ -1,16 +1,18 @@
-angular.module("admin.orders").factory 'Orders', ($q, OrderResource) ->
+angular.module("admin.resources").factory 'Orders', ($q, OrderResource) ->
new class Orders
- ordersByID: {}
+ byID: {}
pristineByID: {}
index: (params={}, callback=null) ->
OrderResource.index params, (data) =>
- for order in data
- @ordersByID[order.id] = order
- @pristineByID[order.id] = angular.copy(order)
-
+ @load(data)
(callback || angular.noop)(data)
+ load: (orders) ->
+ for order in orders
+ @byID[order.id] = order
+ @pristineByID[order.id] = angular.copy(order)
+
save: (order) ->
deferred = $q.defer()
order.$update({id: order.number})
diff --git a/app/assets/javascripts/admin/resources/services/payment_methods.js.coffee b/app/assets/javascripts/admin/resources/services/payment_methods.js.coffee
new file mode 100644
index 0000000000..f84f3a165d
--- /dev/null
+++ b/app/assets/javascripts/admin/resources/services/payment_methods.js.coffee
@@ -0,0 +1,16 @@
+angular.module("admin.resources")
+ .factory "PaymentMethods", ($injector) ->
+ new class PaymentMethods
+ paymentMethods: []
+ byID: {}
+ pristineByID: {}
+
+ constructor: ->
+ if $injector.has('paymentMethods')
+ @load($injector.get('paymentMethods'))
+
+ load: (paymentMethods) ->
+ for paymentMethod in paymentMethods
+ @paymentMethods.push paymentMethod
+ @byID[paymentMethod.id] = paymentMethod
+ @pristineByID[paymentMethod.id] = angular.copy(paymentMethod)
diff --git a/app/assets/javascripts/admin/resources/services/shipping_methods.js.coffee b/app/assets/javascripts/admin/resources/services/shipping_methods.js.coffee
new file mode 100644
index 0000000000..9fde8c9d06
--- /dev/null
+++ b/app/assets/javascripts/admin/resources/services/shipping_methods.js.coffee
@@ -0,0 +1,16 @@
+angular.module("admin.resources")
+ .factory "ShippingMethods", ($injector) ->
+ new class ShippingMethods
+ shippingMethods: []
+ byID: {}
+ pristineByID: {}
+
+ constructor: ->
+ if $injector.has('shippingMethods')
+ @load($injector.get('shippingMethods'))
+
+ load: (shippingMethods) ->
+ for shippingMethod in shippingMethods
+ @shippingMethods.push shippingMethod
+ @byID[shippingMethod.id] = shippingMethod
+ @pristineByID[shippingMethod.id] = angular.copy(shippingMethod)
diff --git a/app/assets/javascripts/admin/shipping_methods/controllers/shipping_methods_controller.js.coffee b/app/assets/javascripts/admin/shipping_methods/controllers/shipping_methods_controller.js.coffee
index 9efd2a5fea..c9b85ea76e 100644
--- a/app/assets/javascripts/admin/shipping_methods/controllers/shipping_methods_controller.js.coffee
+++ b/app/assets/javascripts/admin/shipping_methods/controllers/shipping_methods_controller.js.coffee
@@ -1,3 +1,3 @@
angular.module("admin.shippingMethods").controller "shippingMethodsCtrl", ($scope, ShippingMethods) ->
$scope.findShippingMethodByID = (id) ->
- $scope.ShippingMethod = ShippingMethods.findByID(id)
+ $scope.ShippingMethod = ShippingMethods.byID[id]
diff --git a/app/assets/javascripts/admin/shipping_methods/services/shipping_methods.js.coffee b/app/assets/javascripts/admin/shipping_methods/services/shipping_methods.js.coffee
deleted file mode 100644
index c691f5dae5..0000000000
--- a/app/assets/javascripts/admin/shipping_methods/services/shipping_methods.js.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-angular.module("admin.shippingMethods")
- .factory "ShippingMethods", (shippingMethods) ->
- new class ShippingMethods
- shippingMethods: shippingMethods
-
- findByID: (id) ->
- for shippingMethod in @shippingMethods
- return shippingMethod if shippingMethod.id is id
diff --git a/app/assets/javascripts/admin/taxons/services/taxons.js.coffee b/app/assets/javascripts/admin/taxons/services/taxons.js.coffee
index 62daf77901..48fd503980 100644
--- a/app/assets/javascripts/admin/taxons/services/taxons.js.coffee
+++ b/app/assets/javascripts/admin/taxons/services/taxons.js.coffee
@@ -1,19 +1,20 @@
angular.module("admin.taxons").factory "Taxons", (taxons, $filter) ->
new class Taxons
- taxons: taxons
- taxonsByID: {}
+ all: []
+ byID: {}
constructor: ->
- for taxon in @taxons
- @taxonsByID[taxon.id] = taxon
+ for taxon in taxons
+ @all.push taxon
+ @byID[taxon.id] = taxon
# For finding a single Taxon
findByID: (id) ->
- @taxonsByID[id]
+ @byID[id]
# For finding multiple Taxons represented by comma delimited string
findByIDs: (ids) ->
- @taxonsByID[taxon_id] for taxon_id in ids.split(",") when @taxonsByID[taxon_id]
+ @byID[taxon_id] for taxon_id in ids.split(",") when @byID[taxon_id]
findByTerm: (term) ->
- $filter('filter')(@taxons, term)
+ $filter('filter')(@all, term)
diff --git a/app/assets/javascripts/admin/util.js.erb b/app/assets/javascripts/admin/util.js.erb
index bc963d4612..4a8c526414 100644
--- a/app/assets/javascripts/admin/util.js.erb
+++ b/app/assets/javascripts/admin/util.js.erb
@@ -30,8 +30,16 @@ show_flash_error = function(message) {
}
$(document).ready(function(){
- $('a.close').click(function(event){
- event.preventDefault();
- $(this).parent().slideUp(250);
- });
+ $('a.close').click(function(event){
+ event.preventDefault();
+ $(this).parent().slideUp(250);
+ });
+
+ // Spree locates hidden with prev(), which with our current version of jQuery
+ // does not locate the hidden field, resulting in the delete failing. This
+ // handler updates the hidden field, fixing the problem.
+ $('body').on('click', 'a.remove_fields', function() {
+ $(this).next("input[type=hidden]").val("1");
+ return false;
+ });
});
diff --git a/app/assets/javascripts/admin/utils/services/blank_option.js.coffee b/app/assets/javascripts/admin/utils/services/blank_option.js.coffee
deleted file mode 100644
index f4089aa20d..0000000000
--- a/app/assets/javascripts/admin/utils/services/blank_option.js.coffee
+++ /dev/null
@@ -1,2 +0,0 @@
-angular.module("admin.utils").value "blankOption", ->
- { id: "0", name: "All" }
diff --git a/app/assets/javascripts/darkswarm/controllers/shopping_tabs_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/shopping_tabs_controller.js.coffee
index 8daac0212c..b99d169c5b 100644
--- a/app/assets/javascripts/darkswarm/controllers/shopping_tabs_controller.js.coffee
+++ b/app/assets/javascripts/darkswarm/controllers/shopping_tabs_controller.js.coffee
@@ -1,4 +1,4 @@
-Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation) ->
+Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation, $location) ->
angular.extend this, $controller('TabsCtrl', {$scope: $scope})
$scope.tabs =
@@ -6,3 +6,7 @@ Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation) ->
producers: { active: Navigation.isActive('/producers') }
contact: { active: Navigation.isActive('/contact') }
groups: { active: Navigation.isActive('/groups') }
+
+ $scope.$on '$locationChangeStart', (event, url) ->
+ tab = $location.path().replace(/^\//, '')
+ $scope.tabs[tab]?.active = true
diff --git a/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee b/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee
index 0dcda8f59a..deb7186d95 100644
--- a/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee
+++ b/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee
@@ -15,7 +15,7 @@ Darkswarm.directive 'mapOsmTiles', ($timeout) ->
if x < 0
x = tilesPerGlobe + x
# Wrap y (latitude) in a like manner if you want to enable vertical infinite scroll
- 'http://tile.openstreetmap.org/' + zoom + '/' + x + '/' + coord.y + '.png'
+ 'https://a.tile.openstreetmap.org/' + zoom + '/' + x + '/' + coord.y + '.png'
tileSize: new google.maps.Size(256, 256)
name: 'OpenStreetMap'
maxZoom: 18
diff --git a/app/assets/javascripts/darkswarm/filters/filter_products.js.coffee b/app/assets/javascripts/darkswarm/filters/filter_products.js.coffee
index 4cc325e483..18402edc02 100644
--- a/app/assets/javascripts/darkswarm/filters/filter_products.js.coffee
+++ b/app/assets/javascripts/darkswarm/filters/filter_products.js.coffee
@@ -4,5 +4,5 @@ Darkswarm.filter 'products', (Matcher) ->
text ?= ""
return products if text == ""
products.filter (product) =>
- propertiesToMatch = [product.name, product.supplier.name, product.primary_taxon.name]
+ propertiesToMatch = [product.name, product.variant_names, product.supplier.name, product.primary_taxon.name]
Matcher.match propertiesToMatch, text
diff --git a/app/assets/javascripts/darkswarm/filters/properties.js.coffee b/app/assets/javascripts/darkswarm/filters/properties.js.coffee
index 1453cac053..fe7ed71fa3 100644
--- a/app/assets/javascripts/darkswarm/filters/properties.js.coffee
+++ b/app/assets/javascripts/darkswarm/filters/properties.js.coffee
@@ -1,13 +1,17 @@
Darkswarm.filter 'properties', ->
# Filter anything that responds to object.supplied_properties
- (objects, ids) ->
+ (objects, ids, source) ->
objects ||= []
ids ?= []
+
+ source ||= 'properties'
+ return [] unless source in ['properties', 'supplied_properties', 'distributed_properties']
+
if ids.length == 0
# No properties selected, pass all objects through.
objects
else
objects.filter (obj) ->
- properties = obj.supplied_properties || obj.properties
+ properties = obj[source]
properties.some (property) ->
property.id in ids
diff --git a/app/assets/javascripts/darkswarm/filters/properties_of.js.coffee b/app/assets/javascripts/darkswarm/filters/properties_of.js.coffee
index 7eac12bf1e..f3f4f51b5e 100644
--- a/app/assets/javascripts/darkswarm/filters/properties_of.js.coffee
+++ b/app/assets/javascripts/darkswarm/filters/properties_of.js.coffee
@@ -1,12 +1,12 @@
Darkswarm.filter 'propertiesOf', ->
- (objects) ->
+ (objects, source) ->
+ source ||= 'properties'
+ return {} unless source in ['properties', 'supplied_properties', 'distributed_properties']
+
properties = {}
for object in objects
- if object.supplied_properties?
- for property in object.supplied_properties
- properties[property.id] = property
- else
- for property in object.properties
+ if object[source]?
+ for property in object[source]
properties[property.id] = property
properties
diff --git a/app/assets/javascripts/darkswarm/services/products.js.coffee b/app/assets/javascripts/darkswarm/services/products.js.coffee
index b120cab737..63e015e5ba 100644
--- a/app/assets/javascripts/darkswarm/services/products.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/products.js.coffee
@@ -25,7 +25,6 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
prices = (v.price for v in product.variants)
product.price = Math.min.apply(null, prices)
product.hasVariants = product.variants?.length > 0
-
product.primaryImage = product.images[0]?.small_url if product.images
product.primaryImageOrMissing = product.primaryImage || "/assets/noimage/small.png"
product.largeImage = product.images[0]?.large_url if product.images
@@ -45,5 +44,7 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
if product.variants
product.variants = for variant in product.variants
variant = Variants.register variant
+ if product.name != variant.name_to_display
+ product.variant_names += variant.name_to_display
variant.product = product
variant
diff --git a/app/assets/javascripts/templates/admin/panels/exchange_distributed_products.html.haml b/app/assets/javascripts/templates/admin/panels/exchange_distributed_products.html.haml
index 4c6a86e926..44080e3fe0 100644
--- a/app/assets/javascripts/templates/admin/panels/exchange_distributed_products.html.haml
+++ b/app/assets/javascripts/templates/admin/panels/exchange_distributed_products.html.haml
@@ -14,9 +14,6 @@
.exchange-product{'ng-repeat' => 'product in supplied_products | filter:productSuppliedToOrderCycle | visibleProducts:exchange:order_cycle.visible_variants_for_outgoing_exchanges | orderBy:"name"' }
.exchange-product-details
%label
- -# MASTER_VARIANTS: No longer required
- -# = check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}',
- -# 'ng-disabled' => 'product.variants.length > 0 || !order_cycle.editable_variants_for_outgoing_exchanges.hasOwnProperty(exchange.enterprise_id) || order_cycle.editable_variants_for_outgoing_exchanges[exchange.enterprise_id].indexOf(product.master_id) < 0'
%img{'ng-src' => '{{ product.image_url }}'}
.name {{ product.name }}
.supplier {{ product.supplier_name }}
diff --git a/app/assets/stylesheets/admin/alert.css.sass b/app/assets/stylesheets/admin/alert.css.sass
deleted file mode 100644
index d86cb38f55..0000000000
--- a/app/assets/stylesheets/admin/alert.css.sass
+++ /dev/null
@@ -1,15 +0,0 @@
-.alert
- border: 3px solid #919191
- border-radius: 6px
- margin-bottom: 20px
- color: #919191
- padding: 5px 10px
- h6
- color: #919191
- .message
- font-weight: bold
- &:hover
- border-color: #DA5354
- color: #DA5354
- h6
- color: #DA5354
diff --git a/app/assets/stylesheets/admin/alert.css.scss b/app/assets/stylesheets/admin/alert.css.scss
new file mode 100644
index 0000000000..b516867a96
--- /dev/null
+++ b/app/assets/stylesheets/admin/alert.css.scss
@@ -0,0 +1,24 @@
+.alert {
+ border: 3px solid #919191;
+ border-radius: 6px;
+ margin-bottom: 20px;
+ color: #919191;
+ padding: 5px 10px;
+
+ h6 {
+ color: #919191;
+ }
+
+ .message {
+ font-weight: bold;
+ }
+
+ &:hover {
+ border-color: #DA5354;
+ color: #DA5354;
+
+ h6 {
+ color: #DA5354;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/admin/animations.css.sass b/app/assets/stylesheets/admin/animations.css.scss
similarity index 56%
rename from app/assets/stylesheets/admin/animations.css.sass
rename to app/assets/stylesheets/admin/animations.css.scss
index 88284c7487..bbc766ecfd 100644
--- a/app/assets/stylesheets/admin/animations.css.sass
+++ b/app/assets/stylesheets/admin/animations.css.scss
@@ -1,10 +1,14 @@
-@-webkit-keyframes slideInUp
- 0%
- -webkit-transform: translateY(20px)
- transform: translateY(20px)
- 100%
- -webkit-transform: translateY(0)
- transform: translateY(0)
+@-webkit-keyframes slideInUp {
+ 0% {
+ -webkit-transform: translateY(20px);
+ transform: translateY(20px);
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
// @-webkit-keyframes slideOutDown
// 0%
@@ -14,13 +18,14 @@
// -webkit-transform: translateY(20px)
// transform: translateY(20px)
-.animate-show
- -webkit-animation-name: slideInUp
- animation-name: slideInUp
- -webkit-animation-duration: 0.3s
- animation-duration: 0.3s
- -webkit-animation-fill-mode: both
- animation-fill-mode: both
+.animate-show {
+ -webkit-animation-name: slideInUp;
+ animation-name: slideInUp;
+ -webkit-animation-duration: 0.3s;
+ animation-duration: 0.3s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+
// line-height: 20px
// opacity: 1
@@ -33,3 +38,4 @@
// animation-fill-mode: both
// // line-height: 20px
// // opacity: 1
+}
diff --git a/app/assets/stylesheets/admin/change_type_form.css.sass b/app/assets/stylesheets/admin/change_type_form.css.sass
deleted file mode 100644
index bf67f89696..0000000000
--- a/app/assets/stylesheets/admin/change_type_form.css.sass
+++ /dev/null
@@ -1,72 +0,0 @@
-@import ../darkswarm/branding
-@import ../darkswarm/mixins
-
-#change_type
- section
- margin: 2em 0 0 0
- &, & *
- color: #5498da
-
- .description
- background-color: #eff5fc
- margin-top: -2em
- padding: 4em 2em 2em 1em
- @media all and (max-width: 786px)
- margin-bottom: 2em
-
- .admin-cta
- border: 1px solid #5498da
- @include border-radius(3px)
- text-align: center
- padding: 1em
-
- .error
- display: block
- color: #f57e80
- border: 1px solid #f57e80
- background-color: #fde6e7
- @include border-radius(3px)
- margin-bottom: 1em
- padding: 0.5em
-
- a.selector
- position: relative
- border: 2px solid black
- text-align: center
- width: 100%
- cursor: pointer
- &, & *
- color: white
- &:after, &:before
- top: 100%
- left: 50%
- border: solid transparent
- content: " "
- height: 0
- width: 0
- position: absolute
- pointer-events: none
- &:after
- border-color: rgba(136, 183, 213, 0)
- border-top-color: #5498da
- border-width: 12px
- margin-left: -12px
- &:hover
- &:after
- border-top-color: #9fc820
- &:before
- border-color: rgba(84, 152, 218, 0)
- border-top-color: black
- border-width: 15px
- margin-left: -15px
- .bottom
- background: repeating-linear-gradient(60deg, rgba(84, 152, 218, 0), rgba(84, 152, 218, 0) 5px, rgba(255, 255, 255, 0.25) 5px, rgba(255, 255, 255, 0.25) 10px)
- margin-top: 1em
- margin-left: -15px
- margin-right: -15px
- padding: 5px
- text-transform: uppercase
- &.selected
- background-color: black
- &:after, &:hover &:after
- border-top-color: black
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/change_type_form.css.scss b/app/assets/stylesheets/admin/change_type_form.css.scss
new file mode 100644
index 0000000000..0153d701e8
--- /dev/null
+++ b/app/assets/stylesheets/admin/change_type_form.css.scss
@@ -0,0 +1,103 @@
+@import "../darkswarm/branding";
+@import "../darkswarm/mixins";
+
+#change_type {
+ section {
+ margin: 2em 0 0 0;
+
+ &, & * {
+ color: #5498da;
+ }
+ }
+
+ .description {
+ background-color: #eff5fc;
+ margin-top: -2em;
+ padding: 4em 2em 2em 1em;
+
+ @media all and (max-width: 786px) {
+ margin-bottom: 2em;
+ }
+ }
+
+ .admin-cta {
+ border: 1px solid #5498da;
+
+ @include border-radius(3px);
+
+ text-align: center;
+ padding: 1em;
+ }
+
+ .error {
+ display: block;
+ color: #f57e80;
+ border: 1px solid #f57e80;
+ background-color: #fde6e7;
+
+ @include border-radius(3px);
+
+ margin-bottom: 1em;
+ padding: 0.5em;
+ }
+
+ a.selector {
+ position: relative;
+ border: 2px solid black;
+ text-align: center;
+ width: 100%;
+ cursor: pointer;
+
+ &, & * {
+ color: white;
+ }
+
+ &:after, &:before {
+ top: 100%;
+ left: 50%;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ }
+
+ &:after {
+ border-color: rgba(136, 183, 213, 0);
+ border-top-color: #5498da;
+ border-width: 12px;
+ margin-left: -12px;
+ }
+
+ &:hover {
+ &:after {
+ border-top-color: #9fc820;
+ }
+ }
+
+ &:before {
+ border-color: rgba(84, 152, 218, 0);
+ border-top-color: black;
+ border-width: 15px;
+ margin-left: -15px;
+ }
+
+ .bottom {
+ background: repeating-linear-gradient(60deg, rgba(84, 152, 218, 0), rgba(84, 152, 218, 0) 5px, rgba(255, 255, 255, 0.25) 5px, rgba(255, 255, 255, 0.25) 10px);
+ margin-top: 1em;
+ margin-left: -15px;
+ margin-right: -15px;
+ padding: 5px;
+ text-transform: uppercase;
+ }
+
+ &.selected {
+ background-color: black;
+
+ &:after, &:hover &:after {
+ border-top-color: black;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/admin/components/save_bar.sass b/app/assets/stylesheets/admin/components/save_bar.sass
deleted file mode 100644
index f453c5ddfc..0000000000
--- a/app/assets/stylesheets/admin/components/save_bar.sass
+++ /dev/null
@@ -1,14 +0,0 @@
-#save-bar
- position: fixed
- width: 100%
- z-index: 100
- bottom: 0px
- left: 0
- padding: 8px 8px
- font-weight: bold
- background-color: #eff5fc
- color: #5498da
- h5
- color: #5498da
- input
- margin-right: 5px
diff --git a/app/assets/stylesheets/admin/components/save_bar.scss b/app/assets/stylesheets/admin/components/save_bar.scss
new file mode 100644
index 0000000000..4b63a50bc8
--- /dev/null
+++ b/app/assets/stylesheets/admin/components/save_bar.scss
@@ -0,0 +1,19 @@
+#save-bar {
+ position: fixed;
+ width: 100%;
+ z-index: 100;
+ bottom: 0px;
+ left: 0;
+ padding: 8px 8px;
+ font-weight: bold;
+ background-color: #eff5fc;
+ color: #5498da;
+
+ h5 {
+ color: #5498da;
+ }
+
+ input {
+ margin-right: 5px;
+ }
+}
diff --git a/app/assets/stylesheets/admin/components/trial_progess_bar.sass b/app/assets/stylesheets/admin/components/trial_progess_bar.sass
deleted file mode 100644
index cb6a648273..0000000000
--- a/app/assets/stylesheets/admin/components/trial_progess_bar.sass
+++ /dev/null
@@ -1,9 +0,0 @@
-#trial_progress_bar
- position: fixed
- left: 0px
- bottom: 0px
- width: 100vw
- padding: 8px 10px
- font-weight: bold
- background-color: #5498da
- color: white
diff --git a/app/assets/stylesheets/admin/components/trial_progess_bar.scss b/app/assets/stylesheets/admin/components/trial_progess_bar.scss
new file mode 100644
index 0000000000..049c1f1f3d
--- /dev/null
+++ b/app/assets/stylesheets/admin/components/trial_progess_bar.scss
@@ -0,0 +1,10 @@
+#trial_progress_bar {
+ position: fixed;
+ left: 0px;
+ bottom: 0px;
+ width: 100vw;
+ padding: 8px 10px;
+ font-weight: bold;
+ background-color: #5498da;
+ color: white;
+}
diff --git a/app/assets/stylesheets/admin/dashboard-single-ent.css.sass b/app/assets/stylesheets/admin/dashboard-single-ent.css.sass
deleted file mode 100644
index 567999b43d..0000000000
--- a/app/assets/stylesheets/admin/dashboard-single-ent.css.sass
+++ /dev/null
@@ -1,33 +0,0 @@
-@import ../darkswarm/mixins
-
-.alert-box
- position: relative
- display: block
- background-color: #eff5dc
- border: 1px solid #9fc820
- color: #666
- margin-top: 1em
- margin-bottom: 1em
- @include border-radius(3px)
- transition: opacity 300ms ease-out
- padding: 0.77778em 1.33333em 0.77778em 0.77778em
- a.close
- position: absolute
- right: 5px
- top: 0px
- font-size: 1.5em
-
-
-.dashboard_item.single-ent
- .header
- padding: 0.77778em 1.33333em 0.77778em 0.77778em
- height: auto !important
- .list
- .button.bottom
- width: 100%
-
-.button.big
- width: 100%
- font-size: 1rem
- @include border-radius(25px)
- padding: 15px
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/dashboard-single-ent.css.scss b/app/assets/stylesheets/admin/dashboard-single-ent.css.scss
new file mode 100644
index 0000000000..b9aca09481
--- /dev/null
+++ b/app/assets/stylesheets/admin/dashboard-single-ent.css.scss
@@ -0,0 +1,45 @@
+@import "../darkswarm/mixins";
+
+.alert-box {
+ position: relative;
+ display: block;
+ background-color: #eff5dc;
+ border: 1px solid #9fc820;
+ color: #666;
+ margin-top: 1em;
+ margin-bottom: 1em;
+
+ @include border-radius(3px);
+
+ transition: opacity 300ms ease-out;
+ padding: 0.77778em 1.33333em 0.77778em 0.77778em;
+
+ a.close {
+ position: absolute;
+ right: 5px;
+ top: 0px;
+ font-size: 1.5em;
+ }
+}
+
+.dashboard_item.single-ent {
+ .header {
+ padding: 0.77778em 1.33333em 0.77778em 0.77778em;
+ height: auto !important;
+ }
+
+ .list {
+ .button.bottom {
+ width: 100%;
+ }
+ }
+}
+
+.button.big {
+ width: 100%;
+ font-size: 1rem;
+
+ @include border-radius(25px);
+
+ padding: 15px;
+}
diff --git a/app/assets/stylesheets/admin/dashboard_item.css.sass b/app/assets/stylesheets/admin/dashboard_item.css.sass
deleted file mode 100644
index 4bb4855660..0000000000
--- a/app/assets/stylesheets/admin/dashboard_item.css.sass
+++ /dev/null
@@ -1,159 +0,0 @@
-div.dashboard_item
- margin-bottom: 30px
-
- .centered
- text-align: center
-
- .text-icon
- margin-top: 8px
- display: block
- font-size: 16px
- font-weight: bold
- color: #fff
- padding: 0px 6px
- border-radius: 10px
- &.green
- background-color: #9fc820
- &.red
- background-color: #DA5354
- &.orange
- background-color: #DA7F52
-
- div.header
- height: 50px
- border-radius: 6px 6px 0px 0px
- border: 1px solid #5498da
- position: relative
-
- a[ofn-with-tip]
- position: absolute
- right: 5px
- bottom: 5px
-
- &.red
- border-color: #DA5354
- border-width: 3px
- h3
- color: #DA5354
-
- &.orange
- border-color: #DA7F52
- border-width: 3px
- h3
- color: #DA7F52
-
- h3.alpha
- height: 100%
- padding: 10px 5px 0px 3%
-
- a
- border-radius: 0px 4px 0px 0px
- margin-left: 8px
- height: 100%
- padding: 15px 2px 0px 2px
-
- .tabs
- height: 30px
- border: solid #5498da
- border-width: 0px 0px 1px 0px
- margin-top: 3px
- div.dashboard_tab
- cursor: pointer
- height: 30px
- color: #fff
- background-color: #5498da
- padding: 5px 5px 0px 5px
- text-align: center
- font-weight: bold
- border: solid #5498da
- border-width: 1px 1px 0px 1px
- &:hover
- background-color: #9fc820
- &.selected
- color: #5498da
- background-color: #fff
-
- .list
- max-height: 250px
- overflow-y: auto
- overflow-x: hidden
-
- .list-title
- border: solid #5498da
- border-width: 0px 1px 0px 1px
- span
- font-size: 105%
- padding: 10px 0px
- font-weight: bold
- span.alpha
- padding: 10px 2px 10px 5%
-
- .list-item
- border: solid #5498da
- border-width: 0px 1px 0px 1px
- height: 38px
- span.alpha
- font-weight: bold
- margin-left: -3px
- padding: 10px 2px 0px 5%
- span.omega
- padding-right: 13px
- margin-right: -3px
- text-align: right
- .icon-arrow-right
- padding-top: 6px
- font-size: 20px
- .icon-warning-sign
- color: #DA7F52
- font-size: 30px
- .icon-remove-sign
- color: #DA5354
- font-size: 30px
- .icon-ok-sign
- color: #9fc820
- font-size: 30px
- &.orange
- color: #DA7F52
- border: solid #DA7F52
- &.red
- color: #DA5354
- border: solid #DA5354
- &.orange, &.red
- border-width: 0px 3px 0px 3px
- &.even
- background-color: #fff
- &.odd
- background-color: #eff5fc
- &.even, &.odd
- &:hover
- color: #ffffff
- background-color: #9fc820
- .icon-arrow-right
- color: #fff
- .icon-remove-sign
- color: #fff
- .icon-warning-sign
- color: #fff
- .icon-ok-sign
- color: #fff
- .text-icon
- &.green
- color: #9fc820
- background-color: #fff
-
- a.button
- color: #fff
- font-size: 110%
- font-weight: bold
- text-align: center
- &.orange
- background-color: #DA7F52
- &.blue
- background-color: #5498da
- &.red
- background-color: #DA5354
- &:hover
- background-color: #9fc820
- &.bottom
- border-radius: 0px 0px 6px 6px
- padding: 15px 15px
diff --git a/app/assets/stylesheets/admin/dashboard_item.css.scss b/app/assets/stylesheets/admin/dashboard_item.css.scss
new file mode 100644
index 0000000000..f314500031
--- /dev/null
+++ b/app/assets/stylesheets/admin/dashboard_item.css.scss
@@ -0,0 +1,239 @@
+div.dashboard_item {
+ margin-bottom: 30px;
+
+ .centered {
+ text-align: center;
+ }
+
+ .text-icon {
+ margin-top: 8px;
+ display: block;
+ font-size: 16px;
+ font-weight: bold;
+ color: #fff;
+ padding: 0px 6px;
+ border-radius: 10px;
+
+ &.green {
+ background-color: #9fc820;
+ }
+
+ &.red {
+ background-color: #DA5354;
+ }
+
+ &.orange {
+ background-color: #DA7F52;
+ }
+ }
+
+ div.header {
+ height: 50px;
+ border-radius: 6px 6px 0px 0px;
+ border: 1px solid #5498da;
+ position: relative;
+
+ a[ofn-with-tip] {
+ position: absolute;
+ right: 5px;
+ bottom: 5px;
+ }
+
+ &.red {
+ border-color: #DA5354;
+ border-width: 3px;
+
+ h3 {
+ color: #DA5354;
+ }
+ }
+
+ &.orange {
+ border-color: #DA7F52;
+ border-width: 3px;
+
+ h3 {
+ color: #DA7F52;
+ }
+ }
+
+ h3.alpha {
+ height: 100%;
+ padding: 10px 5px 0px 3%;
+ }
+
+ a {
+ border-radius: 0px 4px 0px 0px;
+ margin-left: 8px;
+ height: 100%;
+ padding: 15px 2px 0px 2px;
+ }
+ }
+
+ .tabs {
+ height: 30px;
+ border: solid #5498da;
+ border-width: 0px 0px 1px 0px;
+ margin-top: 3px;
+
+ div.dashboard_tab {
+ cursor: pointer;
+ height: 30px;
+ color: #fff;
+ background-color: #5498da;
+ padding: 5px 5px 0px 5px;
+ text-align: center;
+ font-weight: bold;
+ border: solid #5498da;
+ border-width: 1px 1px 0px 1px;
+
+ &:hover {
+ background-color: #9fc820;
+ }
+
+ &.selected {
+ color: #5498da;
+ background-color: #fff;
+ }
+ }
+ }
+
+ .list {
+ max-height: 250px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ }
+
+ .list-title {
+ border: solid #5498da;
+ border-width: 0px 1px 0px 1px;
+
+ span {
+ font-size: 105%;
+ padding: 10px 0px;
+ font-weight: bold;
+ }
+
+ span.alpha {
+ padding: 10px 2px 10px 5%;
+ }
+ }
+
+ .list-item {
+ border: solid #5498da;
+ border-width: 0px 1px 0px 1px;
+ height: 38px;
+
+ span.alpha {
+ font-weight: bold;
+ margin-left: -3px;
+ padding: 10px 2px 0px 5%;
+ }
+
+ span.omega {
+ padding-right: 13px;
+ margin-right: -3px;
+ text-align: right;
+ }
+
+ .icon-arrow-right {
+ padding-top: 6px;
+ font-size: 20px;
+ }
+
+ .icon-warning-sign {
+ color: #DA7F52;
+ font-size: 30px;
+ }
+
+ .icon-remove-sign {
+ color: #DA5354;
+ font-size: 30px;
+ }
+
+ .icon-ok-sign {
+ color: #9fc820;
+ font-size: 30px;
+ }
+
+ &.orange {
+ color: #DA7F52;
+ border: solid #DA7F52;
+ }
+
+ &.red {
+ color: #DA5354;
+ border: solid #DA5354;
+ }
+
+ &.orange, &.red {
+ border-width: 0px 3px 0px 3px;
+ }
+
+ &.even {
+ background-color: #fff;
+ }
+
+ &.odd {
+ background-color: #eff5fc;
+ }
+
+ &.even, &.odd {
+ &:hover {
+ color: #ffffff;
+ background-color: #9fc820;
+
+ .icon-arrow-right {
+ color: #fff;
+ }
+
+ .icon-remove-sign {
+ color: #fff;
+ }
+
+ .icon-warning-sign {
+ color: #fff;
+ }
+
+ .icon-ok-sign {
+ color: #fff;
+ }
+
+ .text-icon {
+ &.green {
+ color: #9fc820;
+ background-color: #fff;
+ }
+ }
+ }
+ }
+ }
+
+ a.button {
+ color: #fff;
+ font-size: 110%;
+ font-weight: bold;
+ text-align: center;
+
+ &.orange {
+ background-color: #DA7F52;
+ }
+
+ &.blue {
+ background-color: #5498da;
+ }
+
+ &.red {
+ background-color: #DA5354;
+ }
+
+ &:hover {
+ background-color: #9fc820;
+ }
+
+ &.bottom {
+ border-radius: 0px 0px 6px 6px;
+ padding: 15px 15px;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/admin/openfoodnetwork.css.scss b/app/assets/stylesheets/admin/openfoodnetwork.css.scss
index 1532ea8520..4b5703d317 100644
--- a/app/assets/stylesheets/admin/openfoodnetwork.css.scss
+++ b/app/assets/stylesheets/admin/openfoodnetwork.css.scss
@@ -203,6 +203,10 @@ text-angular {
.ta-scroll-window > .ta-bind {
max-height: 400px;
min-height: 100px;
+ outline: none;
+ p {
+ margin-bottom: 1.5rem;
+ }
}
.ta-scroll-window.form-control {
min-height: 100px;
diff --git a/app/assets/stylesheets/admin/relationships.css.sass b/app/assets/stylesheets/admin/relationships.css.sass
deleted file mode 100644
index a5b8879125..0000000000
--- a/app/assets/stylesheets/admin/relationships.css.sass
+++ /dev/null
@@ -1,23 +0,0 @@
-// TODO: Provide -moz- and -o- directives
-@-webkit-keyframes alert-flash
- 0%
- background-color: #f9f1ae
-
- 100%
- background-color: #fff
-
-
-table#enterprise-relationships, table#enterprise-roles
- ul
- list-style-type: none
-
- th.actions, td.actions
- width: 16%
- .errors
- color: #f00
-
- tr.ng-enter
- -webkit-animation-name: alert-flash
- -webkit-animation-duration: 1200ms
- -webkit-animation-iteration-count: 1
- -webkit-animation-timing-function: ease-in-out
diff --git a/app/assets/stylesheets/admin/relationships.css.scss b/app/assets/stylesheets/admin/relationships.css.scss
new file mode 100644
index 0000000000..103da85e47
--- /dev/null
+++ b/app/assets/stylesheets/admin/relationships.css.scss
@@ -0,0 +1,31 @@
+// TODO: Provide -moz- and -o- directives
+@-webkit-keyframes alert-flash {
+ 0% {
+ background-color: #f9f1ae;
+ }
+
+ 100% {
+ background-color: #fff;
+ }
+}
+
+table#enterprise-relationships, table#enterprise-roles {
+ ul {
+ list-style-type: none;
+ }
+
+ th.actions, td.actions {
+ width: 16%;
+
+ .errors {
+ color: #f00;
+ }
+ }
+
+ tr.ng-enter {
+ -webkit-animation-name: alert-flash;
+ -webkit-animation-duration: 1200ms;
+ -webkit-animation-iteration-count: 1;
+ -webkit-animation-timing-function: ease-in-out;
+ }
+}
diff --git a/app/assets/stylesheets/admin/side_menu.css.sass b/app/assets/stylesheets/admin/side_menu.css.sass
deleted file mode 100644
index c218cfbcf0..0000000000
--- a/app/assets/stylesheets/admin/side_menu.css.sass
+++ /dev/null
@@ -1,18 +0,0 @@
-.side_menu
- border-right: 2px solid #f6f6f6
- border-top: 2px solid #f6f6f6
- .menu_item
- display: block
- padding: 8px 15px
- font-size: 120%
- cursor: pointer
- text-transform: uppercase
- &:nth-child(odd)
- background-color: #ebf3fb
- &:nth-child(even)
- background-color: #ffffff
- &:hover
- background-color: #eaf0f5
- &.selected
- background-color: #5498da
- color: #ffffff
diff --git a/app/assets/stylesheets/admin/side_menu.css.scss b/app/assets/stylesheets/admin/side_menu.css.scss
new file mode 100644
index 0000000000..921b9dee52
--- /dev/null
+++ b/app/assets/stylesheets/admin/side_menu.css.scss
@@ -0,0 +1,29 @@
+.side_menu {
+ border-right: 2px solid #f6f6f6;
+ border-top: 2px solid #f6f6f6;
+
+ .menu_item {
+ display: block;
+ padding: 8px 15px;
+ font-size: 120%;
+ cursor: pointer;
+ text-transform: uppercase;
+
+ &:nth-child(odd) {
+ background-color: #ebf3fb;
+ }
+
+ &:nth-child(even) {
+ background-color: #ffffff;
+ }
+
+ &:hover {
+ background-color: #eaf0f5;
+ }
+
+ &.selected {
+ background-color: #5498da;
+ color: #ffffff;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/admin/sidebar-item.css.sass b/app/assets/stylesheets/admin/sidebar-item.css.sass
deleted file mode 100644
index d25d43ab29..0000000000
--- a/app/assets/stylesheets/admin/sidebar-item.css.sass
+++ /dev/null
@@ -1,77 +0,0 @@
-div.sidebar_item
- margin-bottom: 30px
-
- .centered
- text-align: center
-
- div.header
- font-size: 105%
- color: #fff
- padding: 10px 0px
- position: relative
- &.blue
- background-color: #5498da
- &.red
- background-color: #DA5354
-
- .list
- max-height: 400px
- overflow-y: auto
- overflow-x: hidden
- &.red
- color: #DA5354
- .list-item
- border: solid #DA5354
- border-width: 0px 3px 0px 3px
- a.alpha, span.alpha
- margin-left: -3px
- &.odd
- background-color: #fcf6ef
- &:hover
- background-color: #9fc820
- a
- color: #DA5354
-
- .list-item
- .icon-arrow-right
- padding-top: 6px
- font-size: 20px
- border: solid #5498da
- border-width: 0px 1px 0px 1px
- a.alpha, span.alpha
- font-weight: bold
- margin-left: -1px
- padding: 10px 2px 10px 5%
- overflow: hidden
- text-overflow: ellipsis
- span.omega
- padding: 8px 18px 8px 0px
- margin-right: -3px
- text-align: right
- .icon-remove-sign
- color: #DA5354
- font-size: 18px
- &.even
- background-color: #fff
- &.odd
- background-color: #eff5fc
- &.even, &.odd
- &:hover
- color: #ffffff
- background-color: #9fc820
- a
- color: #ffffff
-
- a.button
- color: #fff
- padding: 15px 15px
- font-weight: bold
- text-align: center
- border-radius: 0px
- &.blue
- background-color: #5498da
- &.red
- background-color: #DA5354
- &:hover
- background-color: #9fc820
-
diff --git a/app/assets/stylesheets/admin/sidebar-item.css.scss b/app/assets/stylesheets/admin/sidebar-item.css.scss
new file mode 100644
index 0000000000..a3baa7b6e0
--- /dev/null
+++ b/app/assets/stylesheets/admin/sidebar-item.css.scss
@@ -0,0 +1,121 @@
+div.sidebar_item {
+ margin-bottom: 30px;
+
+ .centered {
+ text-align: center;
+ }
+
+ div.header {
+ font-size: 105%;
+ color: #fff;
+ padding: 10px 0px;
+ position: relative;
+
+ &.blue {
+ background-color: #5498da;
+ }
+
+ &.red {
+ background-color: #DA5354;
+ }
+ }
+
+ .list {
+ max-height: 400px;
+ overflow-y: auto;
+ overflow-x: hidden;
+
+ &.red {
+ color: #DA5354;
+
+ .list-item {
+ border: solid #DA5354;
+ border-width: 0px 3px 0px 3px;
+
+ a.alpha, span.alpha {
+ margin-left: -3px;
+ }
+
+ &.odd {
+ background-color: #fcf6ef;
+
+ &:hover {
+ background-color: #9fc820;
+ }
+ }
+ }
+
+ a {
+ color: #DA5354;
+ }
+ }
+ }
+
+ .list-item {
+ .icon-arrow-right {
+ padding-top: 6px;
+ font-size: 20px;
+ }
+
+ border: solid #5498da;
+ border-width: 0px 1px 0px 1px;
+
+ a.alpha, span.alpha {
+ font-weight: bold;
+ margin-left: -1px;
+ padding: 10px 2px 10px 5%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ span.omega {
+ padding: 8px 18px 8px 0px;
+ margin-right: -3px;
+ text-align: right;
+ }
+
+ .icon-remove-sign {
+ color: #DA5354;
+ font-size: 18px;
+ }
+
+ &.even {
+ background-color: #fff;
+ }
+
+ &.odd {
+ background-color: #eff5fc;
+ }
+
+ &.even, &.odd {
+ &:hover {
+ color: #ffffff;
+ background-color: #9fc820;
+
+ a {
+ color: #ffffff;
+ }
+ }
+ }
+ }
+
+ a.button {
+ color: #fff;
+ padding: 15px 15px;
+ font-weight: bold;
+ text-align: center;
+ border-radius: 0px;
+
+ &.blue {
+ background-color: #5498da;
+ }
+
+ &.red {
+ background-color: #DA5354;
+ }
+
+ &:hover {
+ background-color: #9fc820;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/admin/variant_overrides.css.sass b/app/assets/stylesheets/admin/variant_overrides.css.sass
deleted file mode 100644
index 0488c1d56b..0000000000
--- a/app/assets/stylesheets/admin/variant_overrides.css.sass
+++ /dev/null
@@ -1,6 +0,0 @@
-.variant-override-unit
- float: right
- font-style: italic
-
-button.hide:hover
- background-color: #DA5354
diff --git a/app/assets/stylesheets/admin/variant_overrides.css.scss b/app/assets/stylesheets/admin/variant_overrides.css.scss
new file mode 100644
index 0000000000..d4e3e4aaac
--- /dev/null
+++ b/app/assets/stylesheets/admin/variant_overrides.css.scss
@@ -0,0 +1,8 @@
+.variant-override-unit {
+ float: right;
+ font-style: italic;
+}
+
+button.hide:hover {
+ background-color: #DA5354;
+}
diff --git a/app/assets/stylesheets/admin/welcome.css.sass b/app/assets/stylesheets/admin/welcome.css.sass
deleted file mode 100644
index 5d14fc1436..0000000000
--- a/app/assets/stylesheets/admin/welcome.css.sass
+++ /dev/null
@@ -1,16 +0,0 @@
-@import ../darkswarm/mixins
-
-#welcome_page
- header
- text-align: center
- padding: 4em 2em
- @include fullbg
- background-image: url('/assets/home/tagline-bg.jpg')
- background-repeat: no-repeat
- background-position: center center
- margin-bottom: 2em
- p
- text-transform: uppercase
- font-weight: 300
- &, & *
- color: white
diff --git a/app/assets/stylesheets/admin/welcome.css.scss b/app/assets/stylesheets/admin/welcome.css.scss
new file mode 100644
index 0000000000..fe31a07396
--- /dev/null
+++ b/app/assets/stylesheets/admin/welcome.css.scss
@@ -0,0 +1,24 @@
+@import "../darkswarm/mixins";
+
+#welcome_page {
+ header {
+ text-align: center;
+ padding: 4em 2em;
+
+ @include fullbg;
+
+ background-image: url("/assets/home/tagline-bg.jpg");
+ background-repeat: no-repeat;
+ background-position: center center;
+ margin-bottom: 2em;
+
+ p {
+ text-transform: uppercase;
+ font-weight: 300;
+ }
+
+ &, & * {
+ color: white;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-filters.css.sass b/app/assets/stylesheets/darkswarm/_shop-filters.css.sass
deleted file mode 100644
index 3c4f9a514d..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-filters.css.sass
+++ /dev/null
@@ -1,125 +0,0 @@
-@import mixins
-@import branding
-@import big-input
-@import animations
-
-@mixin filter-selector($base-clr, $border-clr, $hover-clr)
- &.inline-block, ul.inline-block
- display: inline-block
-
- li
- display: inline-block
- @include border-radius(0)
- padding: 0
- margin: 0 0 0.25rem 0.25rem
- &:hover, &:focus
- background: transparent
- &.active
- box-shadow: none
-
- a, a.button
- display: block
- padding-top: 0.5rem
- @include border-radius(0.5em)
- border: 1px solid $border-clr
- padding: 0.5em 0.625em
- font-size: 0.875em
- color: $base-clr
- font-size: 0.75em
- background: white
- margin: 0
- i
- padding-left: 0.25rem
-
- render-svg
- &, & svg
- width: 1rem
- height: 1rem
- float: left
- padding-right: 0.25rem
- path
- @include csstrans
- fill: $base-clr
-
- &:hover, &:focus
- border-color: $hover-clr
- color: $hover-clr
- render-svg
- svg
- path
- fill: $hover-clr
-
- &.disabled
- opacity: 0.6
-
- &:hover, &:focus
- border-color: $border-clr
- color: $base-clr
- render-svg
- svg
- path
- fill: $base-clr
-
-
- &.active, &.active:hover, &.active:focus
- border: 1px solid $base-clr
- background: $base-clr
- color: white
- render-svg
- svg
- path
- fill: white
-
-
-// Alert when search, taxon, filter is triggered
-
-.alert-box.search-alert
- background-color: $clr-yellow-light
- border-color: $clr-yellow-light
- color: #777
- font-size: 0.75rem
- padding: 0.5rem 0.75rem
-
- span.applied-properties
- color: #333
-
- span.applied-taxons
- color: $clr-blue
-
- span.applied-search
- color: $clr-brick
-
- span.filter-label
- opacity: 0.75
-
-// singleLineSelectors directive provides a drop-down that can overlap
-// content. Ensure that the dropdown appears above the content.
-.filter-row
- position: relative
- z-index: 100
-
-.filter-shopfront
- &.taxon-selectors, &.property-selectors
- background: transparent
-
- single-line-selectors
- overflow-x: hidden
- white-space: nowrap
-
- .f-dropdown
- overflow-x: auto
- white-space: normal
-
- ul
- margin: 0
- display: inline-block
- ul, ul li
- list-style: none
-
- // Shopfront taxons
- &.taxon-selectors
- @include filter-selector($clr-blue, $clr-blue-light, $clr-blue-bright)
-
- // Shopfront properties
- &.property-selectors
- @include filter-selector(#666, #ccc, #777)
diff --git a/app/assets/stylesheets/darkswarm/_shop-filters.css.scss b/app/assets/stylesheets/darkswarm/_shop-filters.css.scss
new file mode 100644
index 0000000000..16bca77cbc
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-filters.css.scss
@@ -0,0 +1,173 @@
+@import "mixins";
+@import "branding";
+@import "big-input";
+@import "animations";
+
+@mixin filter-selector($base-clr, $border-clr, $hover-clr) {
+ &.inline-block, ul.inline-block {
+ display: inline-block;
+ }
+
+ li {
+ display: inline-block;
+
+ @include border-radius(0);
+
+ padding: 0;
+ margin: 0 0 0.25rem 0.25rem;
+
+ &:hover, &:focus {
+ background: transparent;
+ }
+
+ &.active {
+ box-shadow: none;
+ }
+
+ a, a.button {
+ display: block;
+ padding-top: 0.5rem;
+
+ @include border-radius(0.5em);
+
+ border: 1px solid $border-clr;
+ padding: 0.5em 0.625em;
+ font-size: 0.875em;
+ color: $base-clr;
+ font-size: 0.75em;
+ background: white;
+ margin: 0;
+
+ i {
+ padding-left: 0.25rem;
+ }
+
+ render-svg {
+ &, & svg {
+ width: 1rem;
+ height: 1rem;
+ float: left;
+ padding-right: 0.25rem;
+
+ path {
+ @include csstrans;
+
+ fill: $base-clr;
+ }
+ }
+ }
+
+ &:hover, &:focus {
+ border-color: $hover-clr;
+ color: $hover-clr;
+
+ render-svg {
+ svg {
+ path {
+ fill: $hover-clr;
+ }
+ }
+ }
+ }
+
+ &.disabled {
+ opacity: 0.6;
+
+ &:hover, &:focus {
+ border-color: $border-clr;
+ color: $base-clr;
+
+ render-svg {
+ svg {
+ path {
+ fill: $base-clr;
+ }
+ }
+ }
+ }
+ }
+
+ &.active, &.active:hover, &.active:focus {
+ border: 1px solid $base-clr;
+ background: $base-clr;
+ color: white;
+
+ render-svg {
+ svg {
+ path {
+ fill: white;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Alert when search, taxon, filter is triggered
+
+.alert-box.search-alert {
+ background-color: $clr-yellow-light;
+ border-color: $clr-yellow-light;
+ color: #777;
+ font-size: 0.75rem;
+ padding: 0.5rem 0.75rem;
+
+ span.applied-properties {
+ color: #333;
+ }
+
+ span.applied-taxons {
+ color: $clr-blue;
+ }
+
+ span.applied-search {
+ color: $clr-brick;
+ }
+
+ span.filter-label {
+ opacity: 0.75;
+ }
+}
+
+// singleLineSelectors directive provides a drop-down that can overlap
+// content. Ensure that the dropdown appears above the content.
+.filter-row {
+ position: relative;
+ z-index: 90;
+}
+
+.filter-shopfront {
+ &.taxon-selectors, &.property-selectors {
+ background: transparent;
+
+ single-line-selectors {
+ overflow-x: hidden;
+ white-space: nowrap;
+
+ .f-dropdown {
+ overflow-x: auto;
+ white-space: normal;
+ }
+ }
+
+ ul {
+ margin: 0;
+ display: inline-block;
+ }
+
+ ul, ul li {
+ list-style: none;
+ }
+ }
+
+ // Shopfront taxons
+ &.taxon-selectors {
+ @include filter-selector($clr-blue, $clr-blue-light, $clr-blue-bright);
+ }
+
+ // Shopfront properties
+ &.property-selectors {
+ @include filter-selector(#666, #ccc, #777);
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-inputs.css.sass b/app/assets/stylesheets/darkswarm/_shop-inputs.css.sass
deleted file mode 100644
index b191913020..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-inputs.css.sass
+++ /dev/null
@@ -1,85 +0,0 @@
-@import mixins
-@import variables
-@import branding
-@import big-input
-
-
-.darkswarm
- // #search
- @include placeholder(rgba(0,0,0,0.4), #777)
-
- input#search
- @include medium-input(rgba(0,0,0,0.3), #777, $clr-brick)
-
- // 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
-
- @media all and (max-width: 1024px)
- width: 8rem
-
- @media all and (max-width: 768px)
- width: 7rem
-
- @media all and (max-width: 640px)
- float: left !important
- font-size: 0.75rem
- padding-left: 0.25rem
- padding-right: 0.25rem
-
- @media all and (max-width: 480px)
- 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
- width: 5rem
-
- @media all and (max-width: 1024px)
- width: 4rem
-
- @media all and (max-width: 768px)
- width: 3.5rem
-
- @media all and (max-width: 480px)
- width: 2.8rem
-
- input.bulk.first
- border-right: 0
-
- input.bulk.second
- border-left: 0
-
- .bulk-input-container
- float: right
-
- @media all and (max-width: 640px)
- float: left !important
-
- .bulk-input
- float: left
-
-
-
-
-
diff --git a/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss b/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss
new file mode 100644
index 0000000000..55f3309477
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss
@@ -0,0 +1,102 @@
+@import "mixins";
+@import "variables";
+@import "branding";
+@import "big-input";
+
+.darkswarm {
+ // #search
+ @include placeholder(rgba(0, 0, 0, 0.4), #777);
+
+ input#search {
+ @include medium-input(rgba(0, 0, 0, 0.3), #777, $clr-brick);
+ }
+
+ // 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;
+
+ @media all and (max-width: 1024px) {
+ width: 8rem;
+ }
+
+ @media all and (max-width: 768px) {
+ width: 7rem;
+ }
+
+ @media all and (max-width: 640px) {
+ float: left !important;
+ font-size: 0.75rem;
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+ }
+
+ @media all and (max-width: 480px) {
+ 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 {
+ width: 5rem;
+
+ @media all and (max-width: 1024px) {
+ width: 4rem;
+ }
+
+ @media all and (max-width: 768px) {
+ width: 3.5rem;
+ }
+
+ @media all and (max-width: 480px) {
+ width: 2.8rem;
+ }
+ }
+
+ input.bulk.first {
+ border-right: 0;
+ }
+
+ input.bulk.second {
+ border-left: 0;
+ }
+
+ .bulk-input-container {
+ float: right;
+
+ @media all and (max-width: 640px) {
+ float: left !important;
+ }
+
+ .bulk-input {
+ float: left;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.sass b/app/assets/stylesheets/darkswarm/_shop-modals.css.sass
deleted file mode 100644
index 405c1bc701..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-modals.css.sass
+++ /dev/null
@@ -1,6 +0,0 @@
-
-.product-header
- h1, h2, h3, h4, h5, h6
- margin: 0
- hr
- margin: 0.5em 0
\ No newline at end of file
diff --git a/app/assets/stylesheets/darkswarm/_shop-modals.css.scss b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss
new file mode 100644
index 0000000000..6215e22c9f
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-modals.css.scss
@@ -0,0 +1,9 @@
+.product-header {
+ h1, h2, h3, h4, h5, h6 {
+ margin: 0;
+ }
+
+ hr {
+ margin: 0.5em 0;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-popovers.css.sass b/app/assets/stylesheets/darkswarm/_shop-popovers.css.sass
deleted file mode 100644
index 38b77dd756..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-popovers.css.sass
+++ /dev/null
@@ -1,112 +0,0 @@
-@import mixins
-@import branding
-
-// .darkswarm
-// product
-
-ordercycle
- .joyride-tip-guide
- background-color: $clr-brick
- .joyride-nub.right
- border-color: $clr-brick !important
- border-top-color: transparent !important
- border-right-color: transparent !important
- border-bottom-color: transparent !important
- p
- margin: 0
- font-weight: 700
-
-// Pop over
-// Foundation overrides
-.joyride-tip-guide.price_breakdown
- // JS needs to be tweaked to adjust for left alignment - this is dynamic can't rewrite in CSS
- background-color: #999
- color: #1f1f1f
- margin-left: -8px
- @include box-shadow(0 1px 2px 0 rgba(0,0,0,0.7))
-
- .joyride-content-wrapper
- padding: 1.125rem 1.25rem 1.5rem
- padding: 1rem
- margin: 1%
- width: 98%
- background-color: white
-
- h1, h2, h3, h4, h5, h6
- color: #1f1f1f
-
- .joyride-nub.right
- top: 38px
- border-color: #999 !important
- border-top-color: transparent !important
- border-right-color: transparent !important
- border-bottom-color: transparent !important
-
- .progress
- background-color: #13bf85
- padding: 0
- border: none
- color: white
- font-size: 0.75rem
- font-style: oblique
- line-height: 1
- height: auto
- .right
- padding: 0.5rem 0.25rem 0 0
- .meter
- background-color: #0b8c61
- padding: 0.5rem 0.25rem
- border-right: 1px solid #539f92
-
- .expanded
- ul, li
- list-style: none
- margin: 0
- font-size: 0.875rem
- li
- background-color: #13bf85
- padding: 0 0.25rem
- margin-bottom: 2px
- color: white
- li.cost
- background-color: #0b8c61
- li:last-child
- margin-bottom: 0.75rem
-
-
-button.graph-button
- // z-index: 9999999
- border: 1px solid transparent
- padding: 0
- margin: 0
- display: inline
- background-color: rgba(255,255,255,0.5)
- padding: 4px
- @include box-shadow(none)
- @include border-radius(999rem)
- &:before
- @include icon-font
- content: '\e639'
- color: #999
- &:focus
- border: 1px solid #e0e0e0
- background-color: rgba(255,255,255,1)
- &:before
- color: #666
- &:hover, &:active
- background-color: rgba(255,255,255,1)
- border: 1px solid transparent
- &:before
- color: $clr-brick-bright
- @media all and (max-width: 768px)
- // Hide for small
- display: none
-
-button.graph-button.open
- border: 1px solid transparent
- background-color: $clr-brick-bright
- &:before
- content: '\e608'
- color: white
-
-
diff --git a/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss b/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss
new file mode 100644
index 0000000000..92bfa84a30
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss
@@ -0,0 +1,152 @@
+@import "mixins";
+@import "branding";
+
+// .darkswarm
+// product
+
+ordercycle {
+ .joyride-tip-guide {
+ background-color: $clr-brick;
+
+ .joyride-nub.right {
+ border-color: $clr-brick !important;
+ border-top-color: transparent !important;
+ border-right-color: transparent !important;
+ border-bottom-color: transparent !important;
+ }
+
+ p {
+ margin: 0;
+ font-weight: 700;
+ }
+ }
+}
+
+// Pop over
+// Foundation overrides
+.joyride-tip-guide.price_breakdown {
+ // JS needs to be tweaked to adjust for left alignment - this is dynamic can't rewrite in CSS
+ background-color: #999;
+ color: #1f1f1f;
+ margin-left: -8px;
+
+ @include box-shadow(0 1px 2px 0 rgba(0, 0, 0, 0.7));
+
+ .joyride-content-wrapper {
+ padding: 1.125rem 1.25rem 1.5rem;
+ padding: 1rem;
+ margin: 1%;
+ width: 98%;
+ background-color: white;
+ }
+
+ h1, h2, h3, h4, h5, h6 {
+ color: #1f1f1f;
+ }
+
+ .joyride-nub.right {
+ top: 38px;
+ border-color: #999 !important;
+ border-top-color: transparent !important;
+ border-right-color: transparent !important;
+ border-bottom-color: transparent !important;
+ }
+
+ .progress {
+ background-color: #13bf85;
+ padding: 0;
+ border: none;
+ color: white;
+ font-size: 0.75rem;
+ font-style: oblique;
+ line-height: 1;
+ height: auto;
+
+ .right {
+ padding: 0.5rem 0.25rem 0 0;
+ }
+
+ .meter {
+ background-color: #0b8c61;
+ padding: 0.5rem 0.25rem;
+ border-right: 1px solid #539f92;
+ }
+ }
+
+ .expanded {
+ ul, li {
+ list-style: none;
+ margin: 0;
+ font-size: 0.875rem;
+ }
+
+ li {
+ background-color: #13bf85;
+ padding: 0 0.25rem;
+ margin-bottom: 2px;
+ color: white;
+ }
+
+ li.cost {
+ background-color: #0b8c61;
+ }
+
+ li:last-child {
+ margin-bottom: 0.75rem;
+ }
+ }
+}
+
+button.graph-button {
+ // z-index: 9999999
+ border: 1px solid transparent;
+ padding: 0;
+ margin: 0;
+ display: inline;
+ background-color: rgba(255, 255, 255, 0.5);
+ padding: 4px;
+
+ @include box-shadow(none);
+
+ @include border-radius(999rem);
+
+ &:before {
+ @include icon-font;
+
+ content: "";
+ color: #999;
+ }
+
+ &:focus {
+ border: 1px solid #e0e0e0;
+ background-color: rgba(255, 255, 255, 1);
+
+ &:before {
+ color: #666;
+ }
+ }
+
+ &:hover, &:active {
+ background-color: rgba(255, 255, 255, 1);
+ border: 1px solid transparent;
+
+ &:before {
+ color: $clr-brick-bright;
+ }
+ }
+
+ @media all and (max-width: 768px) {
+ // Hide for small
+ display: none;
+ }
+}
+
+button.graph-button.open {
+ border: 1px solid transparent;
+ background-color: $clr-brick-bright;
+
+ &:before {
+ content: "";
+ color: white;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-product-rows.css.sass b/app/assets/stylesheets/darkswarm/_shop-product-rows.css.sass
deleted file mode 100644
index c0e4fb27aa..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-product-rows.css.sass
+++ /dev/null
@@ -1,123 +0,0 @@
-@import branding.css.sass
-@import animations.sass
-
-.darkswarm
- products
- product
- // GENERAL LAYOUT
- .row
- .columns
- padding-top: 0em
- padding-bottom: 0em
- display: table
- line-height: 1.1
- // outline: 1px solid red
-
- @media all and (max-width: 768px)
- font-size: 0.875rem
-
- @media all and (max-width: 640px)
- font-size: 0.75rem
-
- .table-cell
- display: table-cell
- vertical-align: middle
- height: 37px
-
- // ROW VARIANTS
- .row.variants
- margin-left: 0
- margin-right: 0
- background-color: #ECECEC
- &:hover, &:focus, &:active
- background-color: $clr-brick-light
- &:nth-of-type(even)
- background-color: #f9f9f9
- &:hover, &:focus, &:active
- background-color: $clr-brick-ultra-light
-
- &.out-of-stock
- opacity: 0.2
-
- // Variant name
- .variant-name
- padding-left: 7.9375rem
- @media all and (max-width: 768px)
- padding-left: 4.9375rem
-
- .variant-name
- @media all and (max-width: 640px)
- background: #333
- color: white
- padding-left: 0.9375rem
- font-weight: bold
- .table-cell
- height: 27px
-
- // Variant unit
- .variant-unit
- padding-left: 0rem
- padding-right: 0rem
- color: #888
- font-size: 0.875rem
- overflow: hidden
-
- @media all and (max-width: 768px)
- font-size: 0.75rem
-
- // Variant price
- .variant-price
- padding-left: 0.25rem
- padding-right: 0.25rem
- @media all and (max-width: 640px)
- text-align: right
-
- // Total price
- .total-price
- padding-left: 0rem
- color: $disabled-med
- .filled
- color: $med-drk-grey
- @media all and (max-width: 640px)
- background: #777
- color: $disabled-med
- .filled
- color: white
- .table-cell
- height: 27px
-
- // ROW SUMMARY
- .row.summary
- margin-left: 0
- margin-right: 0
- background: #fff
-
- .columns
- padding-top: 1em
- padding-bottom: 1em
- line-height: 1
-
- @media all and (max-width: 768px)
- padding-top: 0.65rem
- padding-bottom: 0.65rem
-
- .summary-header
- padding-left: 7.9375rem
- @media all and (max-width: 768px)
- padding-left: 4.9375rem
- @media all and (max-width: 640px)
- padding-left: 0.9375rem
- small
- font-size: 80%
- h3
- font-size: 1.5rem
- margin: 0
- h3 a
- color: #222
- i
- @include csstrans
- font-size: 0.6em
- &:hover, &:focus, &:active
- color: $clr-brick
- i
- font-size: 0.8em
diff --git a/app/assets/stylesheets/darkswarm/_shop-product-rows.css.scss b/app/assets/stylesheets/darkswarm/_shop-product-rows.css.scss
new file mode 100644
index 0000000000..d98457cd73
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-product-rows.css.scss
@@ -0,0 +1,182 @@
+@import "branding";
+@import "animations";
+
+.darkswarm {
+ products {
+ product {
+ // GENERAL LAYOUT
+ .row {
+ .columns {
+ padding-top: 0em;
+ padding-bottom: 0em;
+ display: table;
+ line-height: 1.1;
+
+ // outline: 1px solid red
+
+ @media all and (max-width: 768px) {
+ font-size: 0.875rem;
+ }
+
+ @media all and (max-width: 640px) {
+ font-size: 0.75rem;
+ }
+ }
+
+ .table-cell {
+ display: table-cell;
+ vertical-align: middle;
+ height: 37px;
+ }
+ }
+
+ // ROW VARIANTS
+ .row.variants {
+ margin-left: 0;
+ margin-right: 0;
+ background-color: #ECECEC;
+
+ &:hover, &:focus, &:active {
+ background-color: $clr-brick-light;
+ }
+
+ &:nth-of-type(even) {
+ background-color: #f9f9f9;
+
+ &:hover, &:focus, &:active {
+ background-color: $clr-brick-ultra-light;
+ }
+ }
+
+ &.out-of-stock {
+ opacity: 0.2;
+ }
+
+ // Variant name
+ .variant-name {
+ padding-left: 7.9375rem;
+
+ @media all and (max-width: 768px) {
+ padding-left: 4.9375rem;
+ }
+ }
+
+ .variant-name {
+ @media all and (max-width: 640px) {
+ background: #333;
+ color: white;
+ padding-left: 0.9375rem;
+ font-weight: bold;
+
+ .table-cell {
+ height: 27px;
+ }
+ }
+ }
+
+ // Variant unit
+ .variant-unit {
+ padding-left: 0rem;
+ padding-right: 0rem;
+ color: #888;
+ font-size: 0.875rem;
+ overflow: hidden;
+
+ @media all and (max-width: 768px) {
+ font-size: 0.75rem;
+ }
+ }
+
+ // Variant price
+ .variant-price {
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+
+ @media all and (max-width: 640px) {
+ text-align: right;
+ }
+ }
+
+ // Total price
+ .total-price {
+ padding-left: 0rem;
+ color: $disabled-med;
+
+ .filled {
+ color: $med-drk-grey;
+ }
+
+ @media all and (max-width: 640px) {
+ background: #777;
+ color: $disabled-med;
+
+ .filled {
+ color: white;
+ }
+
+ .table-cell {
+ height: 27px;
+ }
+ }
+ }
+ }
+
+ // ROW SUMMARY
+ .row.summary {
+ margin-left: 0;
+ margin-right: 0;
+ background: #fff;
+
+ .columns {
+ padding-top: 1em;
+ padding-bottom: 1em;
+ line-height: 1;
+
+ @media all and (max-width: 768px) {
+ padding-top: 0.65rem;
+ padding-bottom: 0.65rem;
+ }
+ }
+
+ .summary-header {
+ padding-left: 7.9375rem;
+
+ @media all and (max-width: 768px) {
+ padding-left: 4.9375rem;
+ }
+
+ @media all and (max-width: 640px) {
+ padding-left: 0.9375rem;
+ }
+
+ small {
+ font-size: 80%;
+ }
+
+ h3 {
+ font-size: 1.5rem;
+ margin: 0;
+ }
+
+ h3 a {
+ color: #222;
+
+ i {
+ @include csstrans;
+
+ font-size: 0.6em;
+ }
+
+ &:hover, &:focus, &:active {
+ color: $clr-brick;
+
+ i {
+ font-size: 0.8em;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-product-thumb.css.sass b/app/assets/stylesheets/darkswarm/_shop-product-thumb.css.sass
deleted file mode 100644
index 701e8005b0..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-product-thumb.css.sass
+++ /dev/null
@@ -1,59 +0,0 @@
-@import branding
-@import animations.sass
-
-.darkswarm
- products
- product
- .product-thumb
- @include csstrans
- position: absolute
- top: 2px
- left: 0px
- width: 7rem
- height: 7rem
- float: left
- display: block
- z-index: 1
- background-color: white
- overflow: hidden
- i
- @include csstrans
- transition-delay: 150ms
- position: absolute
- left: 45%
- top: 45%
- z-index: 99999
- color: white
- font-size: 1rem
- opacity: 0
- img
- @include csstrans
- opacity: 1
- @include transform-scale(scale(1))
-
- &:hover, &:focus, &:active
- background-color: $clr-brick
- i
- left: 32%
- top: 30%
- font-size: 3rem
- opacity: 1
- img
- opacity: 0.5
- @include transform-scale(scale(1.1))
-
- @media all and (max-width: 768px)
- top: 2px
- width: 4rem
- height: 4rem
- &:hover, &:focus, &:active
- i
- left: 30%
- top: 30%
- font-size: 2rem
- @media all and (max-width: 640px)
- display: none
- width: 0rem
- height: 0rem
-
-
diff --git a/app/assets/stylesheets/darkswarm/_shop-product-thumb.css.scss b/app/assets/stylesheets/darkswarm/_shop-product-thumb.css.scss
new file mode 100644
index 0000000000..8a75467c9c
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-product-thumb.css.scss
@@ -0,0 +1,81 @@
+@import "branding";
+@import "animations";
+
+.darkswarm {
+ products {
+ product {
+ .product-thumb {
+ @include csstrans;
+
+ position: absolute;
+ top: 2px;
+ left: 0px;
+ width: 7rem;
+ height: 7rem;
+ float: left;
+ display: block;
+ z-index: 1;
+ background-color: white;
+ overflow: hidden;
+
+ i {
+ @include csstrans;
+
+ transition-delay: 150ms;
+ position: absolute;
+ left: 45%;
+ top: 45%;
+ z-index: 99999;
+ color: white;
+ font-size: 1rem;
+ opacity: 0;
+ }
+
+ img {
+ @include csstrans;
+
+ opacity: 1;
+
+ @include transform-scale(scale(1));
+ }
+
+ &:hover, &:focus, &:active {
+ background-color: $clr-brick;
+
+ i {
+ left: 32%;
+ top: 30%;
+ font-size: 3rem;
+ opacity: 1;
+ }
+
+ img {
+ opacity: 0.5;
+
+ @include transform-scale(scale(1.1));
+ }
+ }
+
+ @media all and (max-width: 768px) {
+ top: 2px;
+ width: 4rem;
+ height: 4rem;
+
+ &:hover, &:focus, &:active {
+ i {
+ left: 30%;
+ top: 30%;
+ font-size: 2rem;
+ }
+ }
+ }
+
+ @media all and (max-width: 640px) {
+ display: none;
+ width: 0rem;
+ height: 0rem;
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.sass b/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.sass
deleted file mode 100644
index 7a6b04cbc2..0000000000
--- a/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.sass
+++ /dev/null
@@ -1,31 +0,0 @@
-.darkswarm
- products
- product
- .taxon-flag
- background: transparent url("/assets/flag.svg") top center no-repeat
- background-size: 34px 39px
- min-height: 40px
- width: 34px
- margin-top: -1.1rem
- padding-top: 0.25rem
- z-index: 999999
- @media all and (max-width: 480px)
- background-size: 28px 32px
- min-height: 32px
- width: 28px
-
- render-svg
- svg
- width: 24px
- height: 24px
- path
- fill: #999
-
- @media all and (max-width: 768px)
- margin-top: -0.85rem
-
- @media all and (max-width: 480px)
- render-svg
- svg
- width: 18px
- height: 18px
diff --git a/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss b/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss
new file mode 100644
index 0000000000..6a2c993600
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/_shop-taxon-flag.css.scss
@@ -0,0 +1,45 @@
+.darkswarm {
+ products {
+ product {
+ .taxon-flag {
+ background: transparent url("/assets/flag.svg") top center no-repeat;
+ background-size: 34px 39px;
+ min-height: 40px;
+ width: 34px;
+ margin-top: -1.1rem;
+ padding-top: 0.25rem;
+ z-index: 999999;
+
+ @media all and (max-width: 480px) {
+ background-size: 28px 32px;
+ min-height: 32px;
+ width: 28px;
+ }
+
+ render-svg {
+ svg {
+ width: 24px;
+ height: 24px;
+
+ path {
+ fill: #999;
+ }
+ }
+ }
+
+ @media all and (max-width: 768px) {
+ margin-top: -0.85rem;
+ }
+
+ @media all and (max-width: 480px) {
+ render-svg {
+ svg {
+ width: 18px;
+ height: 18px;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/account.css.sass b/app/assets/stylesheets/darkswarm/account.css.sass
deleted file mode 100644
index 0f3de5af57..0000000000
--- a/app/assets/stylesheets/darkswarm/account.css.sass
+++ /dev/null
@@ -1,70 +0,0 @@
-@import branding
-@import mixins
-
-.orders
- @include sidepaddingSm
- @include panepadding
- padding-top: 10px
-
- h3
- padding-top: 2em
-
- a
- color: $clr-brick
- &:hover, &:active, &:focus
- color: $clr-brick-med-bright
-
- img
- display: block
- width: 80px
- height: auto
-
- i.ofn-i_059-producer, i.ofn-i_060-producer-reversed
- font-size: 3rem
- display: inline-block
- margin-right: 0.25rem
- float: left
- color: $clr-turquoise
-
- .credit
- color: green
-
- .debit
- color: $clr-brick
-
- .invalid
- color: $ofn-grey
- .credit
- color: $ofn-grey
- .debit
- color: $ofn-grey
-
- .distributor-balance.paid
- visibility: hidden
-
- .transaction-group
-
-
- table
- border-radius: 0.5em 0.5em 0 0
- tr:nth-of-type(even)
- background: transparent // clear previous
- tbody.odd
- tr
- background-color: #f9f9f9
- border: none
- // Column widths for order table
- .order1
- width: 20%
- .order2
- width: 20%
- .order3
- width: 20%
- .order4
- width: 10%
- .order5
- width: 10%
- .order6
- width: 10%
- .order7
- width: 10%
diff --git a/app/assets/stylesheets/darkswarm/account.css.scss b/app/assets/stylesheets/darkswarm/account.css.scss
new file mode 100644
index 0000000000..0d44ea1eaa
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/account.css.scss
@@ -0,0 +1,106 @@
+@import "branding";
+@import "mixins";
+
+.orders {
+ @include sidepaddingSm;
+
+ @include panepadding;
+
+ padding-top: 10px;
+
+ h3 {
+ padding-top: 2em;
+ }
+
+ a {
+ color: $clr-brick;
+
+ &:hover, &:active, &:focus {
+ color: $clr-brick-med-bright;
+ }
+ }
+
+ img {
+ display: block;
+ width: 80px;
+ height: auto;
+ }
+
+ i.ofn-i_059-producer, i.ofn-i_060-producer-reversed {
+ font-size: 3rem;
+ display: inline-block;
+ margin-right: 0.25rem;
+ float: left;
+ color: $clr-turquoise;
+ }
+
+ .credit {
+ color: green;
+ }
+
+ .debit {
+ color: $clr-brick;
+ }
+
+ .invalid {
+ color: $ofn-grey;
+
+ .credit {
+ color: $ofn-grey;
+ }
+
+ .debit {
+ color: $ofn-grey;
+ }
+ }
+
+ .distributor-balance.paid {
+ visibility: hidden;
+ }
+
+ .transaction-group {}
+
+ table {
+ border-radius: 0.5em 0.5em 0 0;
+
+ tr:nth-of-type(even) {
+ background: transparent;
+ }
+
+ tbody.odd {
+ tr {
+ background-color: #f9f9f9;
+ border: none;
+ }
+ }
+ }
+
+ // Column widths for order table
+ .order1 {
+ width: 20%;
+ }
+
+ .order2 {
+ width: 20%;
+ }
+
+ .order3 {
+ width: 20%;
+ }
+
+ .order4 {
+ width: 10%;
+ }
+
+ .order5 {
+ width: 10%;
+ }
+
+ .order6 {
+ width: 10%;
+ }
+
+ .order7 {
+ width: 10%;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/active_table.css.sass b/app/assets/stylesheets/darkswarm/active_table.css.sass
deleted file mode 100644
index b8280d22ca..0000000000
--- a/app/assets/stylesheets/darkswarm/active_table.css.sass
+++ /dev/null
@@ -1,114 +0,0 @@
-@import branding
-@import mixins
-@import "compass/css3/user-interface"
-
-
-.no-results
- font-size: 1.875rem
-
-.active_table
- margin: 2em 0em
- @include user-select(none)
- .active_table_row
- display: block
- cursor: pointer
- &:first-child
- padding: 1rem 0
-
-.active_table .active_table_node
- margin-top: 0.25rem
- display: block
- border: 0
-
- @media all and (max-width: 640px)
- margin-bottom: 1rem
-
- //Generic text link style
- a:hover, a:active, a:focus
- color: $dark-grey
- span
- text-decoration: underline
-
- span.margin-top
- margin-top: 0.5rem
- display: inline-block
-
- // Generic text resize
- @media all and (max-width: 640px)
- &, & *
- font-size: 0.875rem
- fat > div label
- &, & *
- font-size: 0.75rem
-
- // Inherits from active_table
- .active_table_row
- border: 1px solid transparent
- @include border-radius(0.5em)
-
- // Foundation overrides
- margin-left: 0
- margin-right: 0
-
- &, & > a.row
- display: block
-
- .active_table_row.link
- border: 0
-
- &.open
- // .active_table_row:nth-child(2)
-
- .active_table_row
- border-left: 1px solid $disabled-bright
- border-right: 1px solid $disabled-bright
- border-top: 0
- border-bottom: 0
- @include border-radius(0)
-
- .active_table_row:first-child
- border-top: 1px solid $disabled-bright
- color: $dark-grey
- @include border-radius-mixed(0.5em, 0.5em, 0, 0)
- &:hover, &:active, &:focus
- // color: $dark-grey
-
- .active_table_row:last-child
- border-bottom: 1px solid $disabled-bright
- @include border-radius-mixed(0, 0, 0.5em, 0.5em)
-
-
- //Open row sections
- .fat > div
- border-top: 1px solid #aaa
- @media all and (max-width: 640px)
- margin-top: 1em
-
- ul, ol
- font-size: 0.875rem
-
- [class*="block-grid-"] > li
- padding-bottom: 0.25rem !important
-
- label
- text-transform: uppercase
- font-size: 0.75rem
- margin-top: 0.25rem
- margin-bottom: 0.25rem
- color: #777
-
- p.trans-sentence
- text-transform: capitalize
-
- &.closed
- &:hover, &:active, &:focus
- .active_table_row.closed
- border: 1px solid $disabled-bright
-
- &.current
- &.closed
- &, & *
- color: $dark-grey
- &.open
- .active_table_row:first-child
- color: $dark-grey
diff --git a/app/assets/stylesheets/darkswarm/active_table.css.scss b/app/assets/stylesheets/darkswarm/active_table.css.scss
new file mode 100644
index 0000000000..e343eb07d9
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/active_table.css.scss
@@ -0,0 +1,160 @@
+@import "branding";
+@import "mixins";
+@import "compass/css3/user-interface";
+
+.no-results {
+ font-size: 1.875rem;
+}
+
+.active_table {
+ margin: 2em 0em;
+
+ @include user-select(none);
+
+ .active_table_row {
+ display: block;
+ cursor: pointer;
+
+ &:first-child {
+ padding: 1rem 0;
+ }
+ }
+}
+
+.active_table .active_table_node {
+ margin-top: 0.25rem;
+ display: block;
+ border: 0;
+
+ @media all and (max-width: 640px) {
+ margin-bottom: 1rem;
+ }
+
+ //Generic text link style
+ a:hover, a:active, a:focus {
+ color: $dark-grey;
+
+ span {
+ text-decoration: underline;
+ }
+ }
+
+ span.margin-top {
+ margin-top: 0.5rem;
+ display: inline-block;
+ }
+
+ // Generic text resize
+ @media all and (max-width: 640px) {
+ &, & * {
+ font-size: 0.875rem;
+ }
+
+ fat > div label {
+ &, & * {
+ font-size: 0.75rem;
+ }
+ }
+ }
+
+ // Inherits from active_table
+ .active_table_row {
+ border: 1px solid transparent;
+
+ @include border-radius(0.5em);
+
+ // Foundation overrides
+ margin-left: 0;
+ margin-right: 0;
+
+ &, & > a.row {
+ display: block;
+ }
+ }
+
+ .active_table_row.link {
+ border: 0;
+ }
+
+ &.open {
+ // .active_table_row:nth-child(2)
+
+ .active_table_row {
+ border-left: 1px solid $disabled-bright;
+ border-right: 1px solid $disabled-bright;
+ border-top: 0;
+ border-bottom: 0;
+
+ @include border-radius(0);
+ }
+
+ .active_table_row:first-child {
+ border-top: 1px solid $disabled-bright;
+ color: $dark-grey;
+
+ @include border-radius-mixed(0.5em, 0.5em, 0, 0);
+
+ &:hover, &:active, &:focus {
+ // color: $dark-grey
+
+ }
+ }
+
+ .active_table_row:last-child {
+ border-bottom: 1px solid $disabled-bright;
+
+ @include border-radius-mixed(0, 0, 0.5em, 0.5em);
+ }
+
+ //Open row sections
+ .fat > div {
+ border-top: 1px solid #aaa;
+
+ @media all and (max-width: 640px) {
+ margin-top: 1em;
+ }
+
+ ul, ol {
+ font-size: 0.875rem;
+ }
+
+ [class*="block-grid-"] > li {
+ padding-bottom: 0.25rem !important;
+ }
+
+ label {
+ text-transform: uppercase;
+ font-size: 0.75rem;
+ margin-top: 0.25rem;
+ margin-bottom: 0.25rem;
+ color: #777;
+ }
+ }
+
+ p.trans-sentence {
+ text-transform: capitalize;
+ }
+ }
+
+ &.closed {
+ &:hover, &:active, &:focus {
+ .active_table_row.closed {
+ border: 1px solid $disabled-bright;
+ }
+ }
+ }
+
+ &.current {
+ &.closed {
+ &, & * {
+ color: $dark-grey;
+ }
+ }
+
+ &.open {
+ .active_table_row:first-child {
+ color: $dark-grey;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/active_table_search.css.sass b/app/assets/stylesheets/darkswarm/active_table_search.css.sass
deleted file mode 100644
index 49981895d0..0000000000
--- a/app/assets/stylesheets/darkswarm/active_table_search.css.sass
+++ /dev/null
@@ -1,117 +0,0 @@
-@import mixins
-@import branding
-@import big-input
-@import animations
-
-// Filter-box
-.row .row.filter-box
- margin-left: 0
- margin-right: 0
-
-.row.filter-box:first-child
- border: 1px solid $clr-blue-light
- @include border-radius(0.25em)
- margin-top: 2px
- @media all and (max-width: 640px)
- margin-bottom: 1em
-
-.row.filter-box.clear-filters
- background: transparent
- margin-top: 1em
-
-products .filter-box
- background: #f7f7f7
-
-.filter-box
- background: rgba(245,245,245,0.6)
- .tdhead
- padding: 0.25rem 0.5rem
- margin-top: 0.9rem
- color: $clr-blue
- border-bottom: 1px solid $clr-blue-light
-
- // 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
- margin-bottom: 0.25rem
- &:hover, &:focus
- background: rgba(255,255,255,0.25)
- li.active
- background: white
- @include box-shadow(inset 0 1px 3px 0 rgba(143,48,29,0.5))
-
- li.active a
- color: $clr-brick
- render-svg
- svg
- path
- fill: $clr-brick
- &:hover, &:focus
- border-color: $clr-brick-bright
-
- li a
- @include csstrans
- display: table
- table-layout: fixed
- text-transform: capitalize
- overflow: visible
- line-height: 1
- color: $med-drk-grey
- font-size: 0.875rem
- span
- display: table-cell
- vertical-align: middle
- text-align: left
- i
- display: block
- font-size: 1.5rem
- margin: 0 0.2rem 0 0
-
- &:hover, &:focus
- color: $clr-brick-bright
-
- render-svg
- svg
- path
- fill: $clr-brick-bright
-
- &:active, &.active
- color: $clr-brick
- render-svg
- svg
- path
- fill: $clr-brick
-
- render-svg
- display: block
- width: 1.5rem
- height: 1.5rem
- margin: 0 0.2rem 0 0
- padding: 0
- svg
- width: 1.5rem
- height: 1.5rem
- path
- fill: #666
-
-.button.filterbtn
- margin-bottom: 0 !important
- min-width: 160px
-
-#active-table-search
- position: relative
- @include placeholder(rgba(0,0,0,0.4), #777)
- input[type="text"]
- @include big-input(rgba(0,0,0,0.3), #777, $clr-brick)
-
-
-
-
-
-
diff --git a/app/assets/stylesheets/darkswarm/active_table_search.css.scss b/app/assets/stylesheets/darkswarm/active_table_search.css.scss
new file mode 100644
index 0000000000..4159126538
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/active_table_search.css.scss
@@ -0,0 +1,164 @@
+@import "mixins";
+@import "branding";
+@import "big-input";
+@import "animations";
+
+// Filter-box
+.row .row.filter-box {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+.row.filter-box:first-child {
+ border: 1px solid $clr-blue-light;
+
+ @include border-radius(0.25em);
+
+ margin-top: 2px;
+
+ @media all and (max-width: 640px) {
+ margin-bottom: 1em;
+ }
+}
+
+.row.filter-box.clear-filters {
+ background: transparent;
+ margin-top: 1em;
+}
+
+products .filter-box {
+ background: #f7f7f7;
+}
+
+.filter-box {
+ background: rgba(245, 245, 245, 0.6);
+
+ .tdhead {
+ padding: 0.25rem 0.5rem;
+ margin-top: 0.9rem;
+ color: $clr-blue;
+ border-bottom: 1px solid $clr-blue-light;
+ }
+
+ // 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;
+ margin-bottom: 0.25rem;
+
+ &:hover, &:focus {
+ background: rgba(255, 255, 255, 0.25);
+ }
+ }
+
+ li.active {
+ background: white;
+
+ @include box-shadow(inset 0 1px 3px 0 rgba(143, 48, 29, 0.5));
+ }
+
+ li.active a {
+ color: $clr-brick;
+
+ render-svg {
+ svg {
+ path {
+ fill: $clr-brick;
+ }
+ }
+ }
+
+ &:hover, &:focus {
+ border-color: $clr-brick-bright;
+ }
+ }
+
+ li a {
+ @include csstrans;
+
+ display: table;
+ table-layout: fixed;
+ text-transform: capitalize;
+ overflow: visible;
+ line-height: 1;
+ color: $med-drk-grey;
+ font-size: 0.875rem;
+
+ span {
+ display: table-cell;
+ vertical-align: middle;
+ text-align: left;
+ }
+
+ i {
+ display: block;
+ font-size: 1.5rem;
+ margin: 0 0.2rem 0 0;
+ }
+
+ &:hover, &:focus {
+ color: $clr-brick-bright;
+
+ render-svg {
+ svg {
+ path {
+ fill: $clr-brick-bright;
+ }
+ }
+ }
+ }
+
+ &:active, &.active {
+ color: $clr-brick;
+
+ render-svg {
+ svg {
+ path {
+ fill: $clr-brick;
+ }
+ }
+ }
+ }
+
+ render-svg {
+ display: block;
+ width: 1.5rem;
+ height: 1.5rem;
+ margin: 0 0.2rem 0 0;
+ padding: 0;
+
+ svg {
+ width: 1.5rem;
+ height: 1.5rem;
+
+ path {
+ fill: #666;
+ }
+ }
+ }
+ }
+}
+
+.button.filterbtn {
+ margin-bottom: 0 !important;
+ min-width: 160px;
+}
+
+#active-table-search {
+ position: relative;
+
+ @include placeholder(rgba(0, 0, 0, 0.4), #777);
+
+ input[type="text"] {
+ @include big-input(rgba(0, 0, 0, 0.3), #777, $clr-brick);
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/angular.css.sass b/app/assets/stylesheets/darkswarm/angular.css.scss
similarity index 71%
rename from app/assets/stylesheets/darkswarm/angular.css.sass
rename to app/assets/stylesheets/darkswarm/angular.css.scss
index 0430dd1390..bbb1d61c40 100644
--- a/app/assets/stylesheets/darkswarm/angular.css.sass
+++ b/app/assets/stylesheets/darkswarm/angular.css.scss
@@ -1,3 +1,4 @@
// https://docs.angularjs.org/api/ng/directive/ngCloak
-[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak
- display: none !important
+[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
+ display: none !important;
+}
diff --git a/app/assets/stylesheets/darkswarm/animations.sass b/app/assets/stylesheets/darkswarm/animations.sass
deleted file mode 100644
index d452b69d39..0000000000
--- a/app/assets/stylesheets/darkswarm/animations.sass
+++ /dev/null
@@ -1,217 +0,0 @@
-@import mixins
-
-// ANIMATION FUNCTIONS
-
-
-//
-@-webkit-keyframes slideInDown
- 0%
- opacity: 0
- -webkit-transform: translateY(-20px)
- transform: translateY(-20px)
- 100%
- -webkit-transform: translateY(0)
- transform: translateY(0)
-
-@keyframes slideInDown
- 0%
- opacity: 0
- -webkit-transform: translateY(-20px)
- -ms-transform: translateY(-20px)
- transform: translateY(-20px)
- 100%
- -webkit-transform: translateY(0)
- -ms-transform: translateY(0)
- transform: translateY(0)
-
-
-
-@-webkit-keyframes slideOutUp
- 0%
- -webkit-transform: translateY(0)
- transform: translateY(0)
- 100%
- opacity: 0
- -webkit-transform: translateY(-20px)
- transform: translateY(-20px)
-
-
-@keyframes slideOutUp
- 0%
- -webkit-transform: translateY(0)
- -ms-transform: translateY(0)
- transform: translateY(0)
-
-@-webkit-keyframes fadeIn
- 0%
- opacity: 0
- 100%
- opacity: 1
-
-
-@keyframes fadeIn
- 0%
- opacity: 0
- 100%
- opacity: 1
-
-@-webkit-keyframes spin
- 0%
- -webkit-transform: rotate(0deg)
- transform: rotate(0deg)
- 100%
- -webkit-transform: rotate(359deg)
- transform: rotate(359deg)
-@keyframes spin
- 0%
- -webkit-transform: rotate(0deg)
- transform: rotate(0deg)
- 100%
- -webkit-transform: rotate(359deg)
- transform: rotate(359deg)
-
-// ANIMATION CLASSES
-
-.fade
- opacity: 0
- -webkit-transition: opacity .15s linear
- transition: opacity .15s linear
-
-.fade.in
- opacity: 1
-
-.reveal-modal.fade
- -webkit-transition: -webkit-transform .2s ease-out
- -moz-transition: -moz-transform .2s ease-out
- -o-transition: -o-transform .2s ease-out
- transition: transform .2s ease-out
- -webkit-transform: translate(0, -25%)
- -ms-transform: translate(0, -25%)
- transform: translate(0, -25%)
-
-.reveal-modal.in
- -webkit-transform: translate(0, 0)
- -ms-transform: translate(0, 0)
- transform: translate(0, 0)
-
-.reveal-modal-bg.fade
- filter: alpha(opacity = 0)
- opacity: 0
-
-.reveal-modal-bg.in
- filter: alpha(opacity = 50)
- opacity: .5
-
-
-.animate-repeat
- &.ng-move, &.ng-enter, &.ng-leave
- -webkit-transition: all 300ms linear
- transition: all 300ms linear
-
- &.ng-leave
- opacity: 1
- &.ng-leave-active
- opacity: 0
-
- &.ng-enter
- opacity: 0
- &.ng-enter-active
- opacity: 1
-
-product.animate-repeat
- &.ng-leave
- border-color: rgba(153, 153, 153, 1)
- &.ng-leave-active
- border-color: rgba(153, 153, 153, 0)
-
- &.ng-enter
- border-color: rgba(153, 153, 153, 0)
- &.ng-enter-active
- border-color: rgba(153, 153, 153, 1)
-
-.animate-show
- -webkit-animation-name: slideInDown
- animation-name: slideInDown
- -webkit-animation-duration: 0.5s
- animation-duration: 0.5s
- -webkit-animation-fill-mode: both
- animation-fill-mode: both
- // line-height: 20px
- // opacity: 1
-
-.animate-show.ng-hide-add,
-.animate-show.ng-hide-remove
- // display: block !important
-
-.animate-show.ng-hide
- -webkit-animation-name: slideOutUp
- animation-name: slideOutUp
- -webkit-animation-duration: 0.15s
- animation-duration: 0.15s
- -webkit-animation-fill-mode: both
- animation-fill-mode: both
- // line-height: 0
- // opacity: 0
- // padding: 0 10px
-
-.row.animate-show ~ .row
- -webkit-animation-name: fadeIn
- animation-name: fadeIn
- -webkit-animation-duration: 0.5s
- animation-duration: 0.5s
- -webkit-animation-fill-mode: both
- animation-fill-mode: both
-
-//
-
-.animate-slide
- max-height: 500px
- opacity: 1 !important
- -webkit-transition: all 300ms ease-in-out
- -moz-transition: all 300ms ease-in-out
- -o-transition: all 300ms ease-in-out
- transition: all 300ms ease-in-out
-
- &.ng-hide
- overflow: hidden
- max-height: 0
- opacity: 0 !important
-
- // &.ng-hide-add-active, &.ng-hide-remove-active
-
- &.ng-hide-add, &.ng-hide-remove
- /* IMPORTANT: this needs to be here to make it visible during the animation
- since the .ng-hide class is already on the element rendering
- it as hidden. */
- display: block !important
-
-
-.animate-show
- opacity: 1 !important
- -webkit-transition: all 300ms ease-in-out
- -moz-transition: all 300ms ease-in-out
- -o-transition: all 300ms ease-in-out
- transition: all 300ms ease-in-out
-
- &.ng-hide
- opacity: 0 !important
-
- // &.ng-hide-add-active, &.ng-hide-remove-active
-
- &.ng-hide-add, &.ng-hide-remove
- /* IMPORTANT: this needs to be here to make it visible during the animation
- since the .ng-hide class is already on the element rendering
- it as hidden. */
- display: block !important
-
-
-
-
-
-@mixin csstrans
- -webkit-transition: all 300ms ease
- -moz-transition: all 300ms ease
- -ms-transition: all 300ms ease
- -o-transition: all 300ms ease
- transition: all 300ms ease
- -webkit-transform-style: preserve-3d
diff --git a/app/assets/stylesheets/darkswarm/animations.scss b/app/assets/stylesheets/darkswarm/animations.scss
new file mode 100644
index 0000000000..f9c7c1967f
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/animations.scss
@@ -0,0 +1,271 @@
+@import "mixins";
+
+// ANIMATION FUNCTIONS
+
+//
+@-webkit-keyframes slideInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translateY(-20px);
+ transform: translateY(-20px);
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+@keyframes slideInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translateY(-20px);
+ -ms-transform: translateY(-20px);
+ transform: translateY(-20px);
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ -ms-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+@-webkit-keyframes slideOutUp {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translateY(-20px);
+ transform: translateY(-20px);
+ }
+}
+
+@keyframes slideOutUp {
+ 0% {
+ -webkit-transform: translateY(0);
+ -ms-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+@-webkit-keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+@keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+@-webkit-keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+
+@keyframes spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+
+// ANIMATION CLASSES
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+
+.fade.in {
+ opacity: 1;
+}
+
+.reveal-modal.fade {
+ -webkit-transition: -webkit-transform 0.2s ease-out;
+ -moz-transition: -moz-transform 0.2s ease-out;
+ -o-transition: -o-transform 0.2s ease-out;
+ transition: transform 0.2s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+
+.reveal-modal.in {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+
+.reveal-modal-bg.fade {
+ filter: alpha(opacity = 0);
+ opacity: 0;
+}
+
+.reveal-modal-bg.in {
+ filter: alpha(opacity = 50);
+ opacity: 0.5;
+}
+
+.animate-repeat {
+ &.ng-move, &.ng-enter, &.ng-leave {
+ -webkit-transition: all 300ms linear;
+ transition: all 300ms linear;
+ }
+
+ &.ng-leave {
+ opacity: 1;
+
+ &.ng-leave-active {
+ opacity: 0;
+ }
+ }
+
+ &.ng-enter {
+ opacity: 0;
+
+ &.ng-enter-active {
+ opacity: 1;
+ }
+ }
+}
+
+product.animate-repeat {
+ &.ng-leave {
+ border-color: rgba(153, 153, 153, 1);
+
+ &.ng-leave-active {
+ border-color: rgba(153, 153, 153, 0);
+ }
+ }
+
+ &.ng-enter {
+ border-color: rgba(153, 153, 153, 0);
+
+ &.ng-enter-active {
+ border-color: rgba(153, 153, 153, 1);
+ }
+ }
+}
+
+.animate-show {
+ -webkit-animation-name: slideInDown;
+ animation-name: slideInDown;
+ -webkit-animation-duration: 0.5s;
+ animation-duration: 0.5s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+
+ // line-height: 20px
+ // opacity: 1
+}
+
+.animate-show.ng-hide-add,
+.animate-show.ng-hide-remove {
+ // display: block !important
+}
+
+.animate-show.ng-hide {
+ -webkit-animation-name: slideOutUp;
+ animation-name: slideOutUp;
+ -webkit-animation-duration: 0.15s;
+ animation-duration: 0.15s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+
+ // line-height: 0
+ // opacity: 0
+ // padding: 0 10px
+}
+
+.row.animate-show ~ .row {
+ -webkit-animation-name: fadeIn;
+ animation-name: fadeIn;
+ -webkit-animation-duration: 0.5s;
+ animation-duration: 0.5s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+}
+
+//
+
+.animate-slide {
+ max-height: 500px;
+ opacity: 1 !important;
+ -webkit-transition: all 300ms ease-in-out;
+ -moz-transition: all 300ms ease-in-out;
+ -o-transition: all 300ms ease-in-out;
+ transition: all 300ms ease-in-out;
+
+ &.ng-hide {
+ overflow: hidden;
+ max-height: 0;
+ opacity: 0 !important;
+ }
+
+ // &.ng-hide-add-active, &.ng-hide-remove-active
+
+ &.ng-hide-add, &.ng-hide-remove {
+ /* IMPORTANT: this needs to be here to make it visible during the animation
+ * since the .ng-hide class is already on the element rendering
+ * it as hidden. */
+ display: block !important;
+ }
+}
+
+.animate-show {
+ opacity: 1 !important;
+ -webkit-transition: all 300ms ease-in-out;
+ -moz-transition: all 300ms ease-in-out;
+ -o-transition: all 300ms ease-in-out;
+ transition: all 300ms ease-in-out;
+
+ &.ng-hide {
+ opacity: 0 !important;
+ }
+
+ // &.ng-hide-add-active, &.ng-hide-remove-active
+
+ &.ng-hide-add, &.ng-hide-remove {
+ /* IMPORTANT: this needs to be here to make it visible during the animation
+ * since the .ng-hide class is already on the element rendering
+ * it as hidden. */
+ display: block !important;
+ }
+}
+
+@mixin csstrans {
+ -webkit-transition: all 300ms ease;
+ -moz-transition: all 300ms ease;
+ -ms-transition: all 300ms ease;
+ -o-transition: all 300ms ease;
+ transition: all 300ms ease;
+ -webkit-transform-style: preserve-3d;
+}
diff --git a/app/assets/stylesheets/darkswarm/big-input.sass b/app/assets/stylesheets/darkswarm/big-input.sass
deleted file mode 100644
index 0660fda460..0000000000
--- a/app/assets/stylesheets/darkswarm/big-input.sass
+++ /dev/null
@@ -1,93 +0,0 @@
-@import typography
-@import branding
-@import animations
-@import mixins
-
-//Big search used in active table search \\
-
-@mixin big-input($input, $inputhvr, $inputactv)
- @include headingFont
- @include csstrans
- @include border-radius(0.5rem)
- background: rgba(255,255,255,0.1)
- border: 2px solid $input
- font-size: 2rem
- box-shadow: 0
- padding: 0.5rem 1rem
- height: auto
- width: 100%
- margin-bottom: 0.5rem
- box-shadow: none
- color: $inputactv
- @media all and (max-width: 640px)
- font-size: 1.25rem
-
- &:hover
- @include box-shadow(0 1px 1px 0 rgba(255,255,255,0.25))
- border: 2px solid $inputhvr
- color: $inputactv
-
- &:active, &:focus, &.active
- border: 2px solid $inputactv
- color: $inputactv
- background: white
- background: rgba(255,255,255,0.5)
- text-shadow: 0 0 10px #ffffff
- padding: 1rem
- letter-spacing: 0.02rem
- outline: none
-
-@mixin big-input-static
- outline: 0
- &:active, &:focus, &.active
- padding: 0.75rem 1rem 0.35rem 1rem
- letter-spacing: 0
-
-@mixin medium-input($input, $inputhvr, $inputactv)
- @include headingFont
- @include csstrans
- @include border-radius(0.5rem)
- background: rgba(255,255,255,0.1)
- border: 2px solid $input
- font-size: 0.875rem
- box-shadow: 0
- padding: 0.5rem 0.625rem 0.375rem
- height: auto
- width: 100%
- margin-bottom: 0.5rem
- box-shadow: none
- color: $inputactv
-
- &:hover
- @include box-shadow(0 1px 1px 0 rgba(255,255,255,0.25))
- border: 2px solid $inputhvr
- color: $inputactv
-
- &:active, &:focus, &.active
- border: 2px solid $inputactv
- color: $inputactv
- background: white
- background: rgba(255,255,255,0.5)
- text-shadow: 0 0 10px #ffffff
- outline: none
-
-@mixin placeholder($placeholder, $placeholderhvr)
- ::-webkit-input-placeholder
- color: $placeholder
- :-moz-placeholder
- color: $placeholder
- ::-moz-placeholder
- color: $placeholder
- :-ms-input-placeholder
- color: $placeholder
-
- &:hover
- ::-webkit-input-placeholder
- color: $placeholderhvr
- :-moz-placeholder
- color: $placeholderhvr
- ::-moz-placeholder
- color: $placeholderhvr
- :-ms-input-placeholder
- color: $placeholderhvr
-
diff --git a/app/assets/stylesheets/darkswarm/big-input.scss b/app/assets/stylesheets/darkswarm/big-input.scss
new file mode 100644
index 0000000000..7b9ecdac8d
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/big-input.scss
@@ -0,0 +1,127 @@
+@import "typography";
+@import "branding";
+@import "animations";
+@import "mixins";
+
+//Big search used in active table search \\
+
+@mixin big-input($input, $inputhvr, $inputactv) {
+ @include headingFont;
+
+ @include csstrans;
+
+ @include border-radius(0.5rem);
+
+ background: rgba(255, 255, 255, 0.1);
+ border: 2px solid $input;
+ font-size: 2rem;
+ box-shadow: 0;
+ padding: 0.5rem 1rem;
+ height: auto;
+ width: 100%;
+ margin-bottom: 0.5rem;
+ box-shadow: none;
+ color: $inputactv;
+
+ @media all and (max-width: 640px) {
+ font-size: 1.25rem;
+ }
+
+ &:hover {
+ @include box-shadow(0 1px 1px 0 rgba(255, 255, 255, 0.25));
+
+ border: 2px solid $inputhvr;
+ color: $inputactv;
+ }
+
+ &:active, &:focus, &.active {
+ border: 2px solid $inputactv;
+ color: $inputactv;
+ background: white;
+ background: rgba(255, 255, 255, 0.5);
+ text-shadow: 0 0 10px #ffffff;
+ padding: 1rem;
+ letter-spacing: 0.02rem;
+ outline: none;
+ }
+}
+
+@mixin big-input-static {
+ outline: 0;
+
+ &:active, &:focus, &.active {
+ padding: 0.75rem 1rem 0.35rem 1rem;
+ letter-spacing: 0;
+ }
+}
+
+@mixin medium-input($input, $inputhvr, $inputactv) {
+ @include headingFont;
+
+ @include csstrans;
+
+ @include border-radius(0.5rem);
+
+ background: rgba(255, 255, 255, 0.1);
+ border: 2px solid $input;
+ font-size: 0.875rem;
+ box-shadow: 0;
+ padding: 0.5rem 0.625rem 0.375rem;
+ height: auto;
+ width: 100%;
+ margin-bottom: 0.5rem;
+ box-shadow: none;
+ color: $inputactv;
+
+ &:hover {
+ @include box-shadow(0 1px 1px 0 rgba(255, 255, 255, 0.25));
+
+ border: 2px solid $inputhvr;
+ color: $inputactv;
+ }
+
+ &:active, &:focus, &.active {
+ border: 2px solid $inputactv;
+ color: $inputactv;
+ background: white;
+ background: rgba(255, 255, 255, 0.5);
+ text-shadow: 0 0 10px #ffffff;
+ outline: none;
+ }
+}
+
+@mixin placeholder($placeholder, $placeholderhvr) {
+ ::-webkit-input-placeholder {
+ color: $placeholder;
+ }
+
+ -moz-placeholder: {
+ color: $placeholder;
+ };
+
+ ::-moz-placeholder {
+ color: $placeholder;
+ }
+
+ -ms-input-placeholder: {
+ color: $placeholder;
+ };
+
+ &:hover {
+ ::-webkit-input-placeholder {
+ color: $placeholderhvr;
+ }
+
+ -moz-placeholder: {
+ color: $placeholderhvr;
+ };
+
+ ::-moz-placeholder {
+ color: $placeholderhvr;
+ }
+
+ -ms-input-placeholder: {
+ color: $placeholderhvr;
+ };
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/branding.css.sass b/app/assets/stylesheets/darkswarm/branding.css.sass
deleted file mode 100644
index 76614599cf..0000000000
--- a/app/assets/stylesheets/darkswarm/branding.css.sass
+++ /dev/null
@@ -1,38 +0,0 @@
-$ofn-brand: #f27052
-// e.g. australia, uk, norway specific color
-
-$ofn-grey: #808184
-
-
-// old colors:
-
-$clr-brick: #c1122b
-$clr-brick-light: #f5e6e7
-$clr-brick-light-trans: rgba(245, 230, 231, 0.9)
-$clr-brick-ultra-light: #faf5f6
-$clr-brick-bright: #eb4c46
-$clr-brick-med-bright: #e5a2a0
-$clr-brick-light-bright: #f5c4c9
-
-$clr-turquoise: #0b8c61
-$clr-turquoise-light: #ceefe4
-$clr-turquoise-ultra-light: #e8f9f4
-$clr-turquoise-bright: #23a877
-
-$clr-blue: #0096ad
-$clr-blue-light: #85d9e5
-$clr-blue-bright: #14b6cc
-
-$clr-yellow-light: #faf6c7
-
-$disabled-light: #e5e5e5
-$disabled-bright: #ccc
-$disabled-med: #b3b3b3
-$disabled-dark: #999
-$disabled-v-dark: #808080
-$med-grey: #666
-$med-drk-grey: #444
-$dark-grey: #333
-$light-grey: #ddd
-$black: #000
-
diff --git a/app/assets/stylesheets/darkswarm/branding.css.scss b/app/assets/stylesheets/darkswarm/branding.css.scss
new file mode 100644
index 0000000000..c9a68b513b
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/branding.css.scss
@@ -0,0 +1,37 @@
+$ofn-brand: #f27052;
+
+// e.g. australia, uk, norway specific color
+
+$ofn-grey: #808184;
+
+// old colors:
+
+$clr-brick: #c1122b;
+$clr-brick-light: #f5e6e7;
+$clr-brick-light-trans: rgba(245, 230, 231, 0.9);
+$clr-brick-ultra-light: #faf5f6;
+$clr-brick-bright: #eb4c46;
+$clr-brick-med-bright: #e5a2a0;
+$clr-brick-light-bright: #f5c4c9;
+
+$clr-turquoise: #0b8c61;
+$clr-turquoise-light: #ceefe4;
+$clr-turquoise-ultra-light: #e8f9f4;
+$clr-turquoise-bright: #23a877;
+
+$clr-blue: #0096ad;
+$clr-blue-light: #85d9e5;
+$clr-blue-bright: #14b6cc;
+
+$clr-yellow-light: #faf6c7;
+
+$disabled-light: #e5e5e5;
+$disabled-bright: #ccc;
+$disabled-med: #b3b3b3;
+$disabled-dark: #999;
+$disabled-v-dark: #808080;
+$med-grey: #666;
+$med-drk-grey: #444;
+$dark-grey: #333;
+$light-grey: #ddd;
+$black: #000;
diff --git a/app/assets/stylesheets/darkswarm/footer.sass b/app/assets/stylesheets/darkswarm/footer.sass
deleted file mode 100644
index 80681cedfb..0000000000
--- a/app/assets/stylesheets/darkswarm/footer.sass
+++ /dev/null
@@ -1,78 +0,0 @@
-@import branding
-@import mixins
-@import animations
-
-footer
- .row
- p a
- font-size: 0.875rem
- a, a *
- @include csstrans
- color: white
- &:hover, &:active, &:focus
- color: rgba(white, 1)
- text-decoration: underline
-
- .footer-global
- background-color: $ofn-grey
- padding-top: 60px
- padding-bottom: 40px
- .logo
- width: 200px
- height: 200px
- background: $ofn-grey
- @include border-radius(120px)
- margin: -140px auto 0 auto
- img
- margin-top: 36px
-
- .alert-box
- background-color: transparent
- border: none
- padding: 0
- .alert-cta
- @include csstrans
- width: 100%
- border: 1px solid rgba($dark-grey, 0.35)
- background-image: url("/assets/tile-wide.png")
- background-position: center center
- background-color: #bbb
- padding: 12px 0 8px 0
- display: block
- &, & *
- @include csstrans
- color: #333
- strong
- letter-spacing: 0.5px
- a:hover, a:active, a:focus
- text-decoration: none
- border-color: white
- &, & *
- color: rgba(white, 1)
- .row
- &, p, h1, h2, h3, h4, h5, h6
- color: $disabled-bright
-
- .footer-local
- background: lighten($dark-grey, 3%)
- @include panepadding
- .row
- &, p, h1, h2, h3, h4, h5, h6
- color: $disabled-med
- p.secure-icon i
- font-size: 10rem
- color: rgba(white, 0.1)
- p.secure-text
- color: rgba($disabled-med, 0.35)
- .social-icons
- margin-bottom: 0.25rem
- margin-top: 0.75rem
- a
- i
- font-size: 1.5rem
- color: white
- &:hover, &:active, &:focus
- text-decoration: none
- i
- color: lighten($dark-grey, 60%)
- text-shadow: 2px 2px 0 black
diff --git a/app/assets/stylesheets/darkswarm/footer.scss b/app/assets/stylesheets/darkswarm/footer.scss
new file mode 100644
index 0000000000..56176a1b4d
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/footer.scss
@@ -0,0 +1,127 @@
+@import "branding";
+@import "mixins";
+@import "animations";
+
+footer {
+ .row {
+ p a {
+ font-size: 0.875rem;
+ }
+
+ a, a * {
+ @include csstrans;
+
+ color: white;
+
+ &:hover, &:active, &:focus {
+ color: rgba(white, 1);
+ text-decoration: underline;
+ }
+ }
+ }
+
+ .footer-global {
+ background-color: $ofn-grey;
+ padding-top: 60px;
+ padding-bottom: 40px;
+
+ .logo {
+ width: 200px;
+ height: 200px;
+ background: $ofn-grey;
+
+ @include border-radius(120px);
+
+ margin: (-140px) auto 0 auto;
+
+ img {
+ margin-top: 36px;
+ }
+ }
+
+ .alert-box {
+ background-color: transparent;
+ border: none;
+ padding: 0;
+
+ .alert-cta {
+ @include csstrans;
+
+ width: 100%;
+ border: 1px solid rgba($dark-grey, 0.35);
+ background-image: url("/assets/tile-wide.png");
+ background-position: center center;
+ background-color: #bbb;
+ padding: 12px 0 8px 0;
+ display: block;
+
+ &, & * {
+ @include csstrans;
+
+ color: #333;
+ }
+
+ strong {
+ letter-spacing: 0.5px;
+ }
+
+ a:hover, a:active, a:focus {
+ text-decoration: none;
+ border-color: white;
+
+ &, & * {
+ color: rgba(white, 1);
+ }
+ }
+ }
+ }
+
+ .row {
+ &, p, h1, h2, h3, h4, h5, h6 {
+ color: $disabled-bright;
+ }
+ }
+ }
+
+ .footer-local {
+ background: lighten($dark-grey, 3%);
+
+ @include panepadding;
+
+ .row {
+ &, p, h1, h2, h3, h4, h5, h6 {
+ color: $disabled-med;
+ }
+
+ p.secure-icon i {
+ font-size: 10rem;
+ color: rgba(white, 0.1);
+ }
+
+ p.secure-text {
+ color: rgba($disabled-med, 0.35);
+ }
+
+ .social-icons {
+ margin-bottom: 0.25rem;
+ margin-top: 0.75rem;
+
+ a {
+ i {
+ font-size: 1.5rem;
+ color: white;
+ }
+
+ &:hover, &:active, &:focus {
+ text-decoration: none;
+
+ i {
+ color: lighten($dark-grey, 60%);
+ text-shadow: 2px 2px 0 black;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/forms.css.sass b/app/assets/stylesheets/darkswarm/forms.css.sass
deleted file mode 100644
index 7047159601..0000000000
--- a/app/assets/stylesheets/darkswarm/forms.css.sass
+++ /dev/null
@@ -1,5 +0,0 @@
-@import mixins
-@import branding
-
-fieldset
- border: 0
\ No newline at end of file
diff --git a/app/assets/stylesheets/darkswarm/forms.css.scss b/app/assets/stylesheets/darkswarm/forms.css.scss
new file mode 100644
index 0000000000..9ca7f6f391
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/forms.css.scss
@@ -0,0 +1,6 @@
+@import "mixins";
+@import "branding";
+
+fieldset {
+ border: 0;
+}
diff --git a/app/assets/stylesheets/darkswarm/groups.css.sass b/app/assets/stylesheets/darkswarm/groups.css.sass
deleted file mode 100644
index 7243112b67..0000000000
--- a/app/assets/stylesheets/darkswarm/groups.css.sass
+++ /dev/null
@@ -1,108 +0,0 @@
-@import branding
-@import mixins
-@import typography
-
-// Search page
-#groups
- @include groupsbg
- @include sidepaddingSm
- @include panepadding
- h1, p.text
- font-weight: 300
- h1
- font-size: 350%
- a > .group-name
- &:hover, &:focus, &:active
- text-decoration: underline
-
- .groups-icons
- text-align: right
- a
- font-size: 1.5em
-
- .groups-header
- border: 2px solid $clr-brick-light-bright
- @include border-radius-mixed(0.5em, 0.5em, 0, 0)
- margin: -1rem 0 1rem
- padding: 1rem 0.9375rem
- @media screen and (min-width: 640px)
- border: 0 none
- @include border-radius(0)
- margin: 0
- padding: 0
-
-.group
- padding-bottom: 0.5em
- .row div
- font-size: 110%
- .row a
- vertical-align: middle
- .ofn-i_035-groups
- font-size: 120%
- vertical-align: middle
-
-// Individual Page
-#group-page
- .group-logo, .group-header
- text-align: center
- .group-logo
- padding-bottom: 1em
- max-height: 200px
- .group-name
- border-bottom: 1px solid #ccc
- @media screen and (min-width: 768px)
- .group-logo, .group-header
- text-align: left
- .group-logo
- max-height: 120px
- float: left
- padding-right: 1em
- background-color: white
-
- // Tabs
- .tabs dd a // Mobile first
- padding: 0.25rem 0.45rem 0rem
- font-size: 0.75rem
- border: none
- margin-bottom: -2px
- margin-right: 2px
- text-transform: capitalize
- @include headingFont
- @include border-radius(1em 0.25em 0 0)
- @include gradient($disabled-light, $disabled-bright)
- @media screen and (min-width: 768px)
- .tabs dd a
- padding: 0.5rem 1rem 0.25em
- font-size: 0.875rem
- @include border-radius(1.5em 0.25em 0 0)
- @media screen and (min-width: 1024px)
- .tabs dd a
- padding: 0.75rem 1.5rem 0.5em
- font-size: 1rem
- @include border-radius(2em 0.25em 0 0)
- .tabs dd.active a
- @include gradient(white, white)
- margin-bottom: -1px
- border-top: 1px solid $light-grey
- border-left: 1px solid $light-grey
- border-right: 1px solid $light-grey
- border-bottom: 0
- .tabs-content
- border-top: 1px solid $light-grey
- border-left: 1px solid $light-grey
- border-right: 1px solid $light-grey
- border-bottom: 1px solid $light-grey
- padding: 1.5em
-
- // Producers tab
- .producers
- background-image: none
- background-color: initial
- .active_table .active_table_node a.is_distributor, .active_table .active_table_node a.is_distributor i.ofn-i_059-producer
- color: $clr-turquoise
- padding: 0
- // Hubs tab
- .hubs
- background-image: none
- padding-top: 0
- padding-bottom: 0
diff --git a/app/assets/stylesheets/darkswarm/groups.css.scss b/app/assets/stylesheets/darkswarm/groups.css.scss
new file mode 100644
index 0000000000..b6ba8087c7
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/groups.css.scss
@@ -0,0 +1,169 @@
+@import "branding";
+@import "mixins";
+@import "typography";
+
+// Search page
+#groups {
+ @include groupsbg;
+
+ @include sidepaddingSm;
+
+ @include panepadding;
+
+ h1, p.text {
+ font-weight: 300;
+ }
+
+ h1 {
+ font-size: 350%;
+ }
+
+ a > .group-name {
+ &:hover, &:focus, &:active {
+ text-decoration: underline;
+ }
+ }
+
+ .groups-icons {
+ text-align: right;
+
+ a {
+ font-size: 1.5em;
+ }
+ }
+
+ .groups-header {
+ border: 2px solid $clr-brick-light-bright;
+
+ @include border-radius-mixed(0.5em, 0.5em, 0, 0);
+
+ margin: (-1rem) 0 1rem;
+ padding: 1rem 0.9375rem;
+
+ @media screen and (min-width: 640px) {
+ border: 0 none;
+
+ @include border-radius(0);
+
+ margin: 0;
+ padding: 0;
+ }
+ }
+}
+
+.group {
+ padding-bottom: 0.5em;
+
+ .row div {
+ font-size: 110%;
+ }
+
+ .row a {
+ vertical-align: middle;
+ }
+
+ .ofn-i_035-groups {
+ font-size: 120%;
+ vertical-align: middle;
+ }
+}
+
+// Individual Page
+#group-page {
+ .group-logo, .group-header {
+ text-align: center;
+ }
+
+ .group-logo {
+ padding-bottom: 1em;
+ max-height: 200px;
+ }
+
+ .group-name {
+ border-bottom: 1px solid #ccc;
+ }
+
+ @media screen and (min-width: 768px) {
+ .group-logo, .group-header {
+ text-align: left;
+ }
+
+ .group-logo {
+ max-height: 120px;
+ float: left;
+ padding-right: 1em;
+ background-color: white;
+ }
+ }
+
+ // Tabs
+ .tabs dd a {
+ padding: 0.25rem 0.45rem 0rem;
+ font-size: 0.75rem;
+ border: none;
+ margin-bottom: -2px;
+ margin-right: 2px;
+ text-transform: capitalize;
+
+ @include headingFont;
+
+ @include border-radius(1em 0.25em 0 0);
+
+ @include gradient($disabled-light, $disabled-bright);
+ }
+
+ @media screen and (min-width: 768px) {
+ .tabs dd a {
+ padding: 0.5rem 1rem 0.25em;
+ font-size: 0.875rem;
+
+ @include border-radius(1.5em 0.25em 0 0);
+ }
+ }
+
+ @media screen and (min-width: 1024px) {
+ .tabs dd a {
+ padding: 0.75rem 1.5rem 0.5em;
+ font-size: 1rem;
+
+ @include border-radius(2em 0.25em 0 0);
+ }
+ }
+
+ .tabs dd.active a {
+ @include gradient(white, white);
+
+ margin-bottom: -1px;
+ border-top: 1px solid $light-grey;
+ border-left: 1px solid $light-grey;
+ border-right: 1px solid $light-grey;
+ border-bottom: 0;
+ }
+
+ .tabs-content {
+ border-top: 1px solid $light-grey;
+ border-left: 1px solid $light-grey;
+ border-right: 1px solid $light-grey;
+ border-bottom: 1px solid $light-grey;
+ padding: 1.5em;
+ }
+
+ // Producers tab
+ .producers {
+ background-image: none;
+ background-color: initial;
+
+ .active_table .active_table_node a.is_distributor, .active_table .active_table_node a.is_distributor i.ofn-i_059-producer {
+ color: $clr-turquoise;
+ }
+
+ padding: 0;
+ }
+
+ // Hubs tab
+ .hubs {
+ background-image: none;
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/header.css.sass b/app/assets/stylesheets/darkswarm/header.css.sass
deleted file mode 100644
index 523afca824..0000000000
--- a/app/assets/stylesheets/darkswarm/header.css.sass
+++ /dev/null
@@ -1,21 +0,0 @@
-@import variables
-
-nav.top-bar
- margin-bottom: 0px
- a.icon
- &:hover
- text-decoration: none
- height: $topbar-height
- color: white
- i
- font-size: 29px
- line-height: $topbar-height
- span
- font-size: 13px
- display: inline-block
- line-height: $topbar-height
- height: $topbar-height
- vertical-align: top
-
-body > section[role='main']
- padding: 0px
diff --git a/app/assets/stylesheets/darkswarm/header.css.scss b/app/assets/stylesheets/darkswarm/header.css.scss
new file mode 100644
index 0000000000..6d04b31f0f
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/header.css.scss
@@ -0,0 +1,31 @@
+@import "variables";
+
+nav.top-bar {
+ margin-bottom: 0px;
+
+ a.icon {
+ &:hover {
+ text-decoration: none;
+ }
+
+ height: $topbar-height;
+ color: white;
+
+ i {
+ font-size: 29px;
+ line-height: $topbar-height;
+ }
+
+ span {
+ font-size: 13px;
+ display: inline-block;
+ line-height: $topbar-height;
+ height: $topbar-height;
+ vertical-align: top;
+ }
+ }
+}
+
+body > section[role='main'] {
+ padding: 0px;
+}
diff --git a/app/assets/stylesheets/darkswarm/home_panes.css.sass b/app/assets/stylesheets/darkswarm/home_panes.css.sass
deleted file mode 100644
index 4bb9c19aa6..0000000000
--- a/app/assets/stylesheets/darkswarm/home_panes.css.sass
+++ /dev/null
@@ -1,156 +0,0 @@
-@import branding
-@import mixins
-@import typography
-@import animations
-@import variables
-
-// Styling for big panes on homepage \\
-#panes
- .pane
- .row
- @include panepadding
- padding-top: 75px
- padding-bottom: 75px
- &.header
- padding-bottom: 0
- &.content
- padding-top: 0
-
-
-// Background styles \\
-#system.pane
- background-color: white
-
-#brand-story.pane, #cta.pane, #shops.pane, #sell.pane
- @include tiledPane
-
-#connect.pane
- @include groupsbg
-
-#learn.pane
- @include hubsbg
-
-#stats.pane
- background-image: url("/assets/home/background-blurred-oranges.jpg")
- background-position: center center
- background-color: $ofn-grey
- @include fullbg
- @include paneWhiteText
-
-
-// Content styles \\
-#brand-story.pane
- .row
- h2
- font-weight: 300
- font-size: 88px
- p
- @include bodyFont
- font-size: 1.5rem
- font-weight: 300
- @media all and (max-width: 768px)
- h2
- font-size: 52px
- p
- font-size: 1.3rem
-
- a.text-vbig i
- font-size: 75px
-
-#system.pane
- .row .row
- padding-bottom: 0
- @media all and (max-width: 640px)
- .row .row
- padding: 0
-
- .home-icon-box
- background-image: url("/assets/ofn-o.png")
- background-position: center center
- background-repeat: no-repeat
- background-size: auto 100%
- padding: 3rem 0
- text-align: center
- margin-top: 2rem
- @media all and (min-width: 642px)
- margin-top: 0
- i
- font-size: 4rem
- a
- display: block
- width: 64px
- height: 64px
- margin: 0 auto
- background-color: $brand-colour
- background-position: center center
- background-repeat: no-repeat
- background-size: auto 100%
- &.search
- background-image: url("/assets/icon-mask-magnifier.png")
- &.shop
- background-image: url("/assets/icon-mask-apple.png")
- &.pick-up-delivery
- background-image: url("/assets/icon-mask-truck.png")
-
- h2
- font-size: 70px
- font-weight: 300
- color: $brand-colour
- @media all and (max-width: 640px)
- font-size: 45px
-
- .home-icon-box-bottom
- margin-top: 1rem
- width: 100%
- padding-left: 1rem
- padding-right: 1rem
- @media all and (min-width: 480px)
- padding-left: 3rem
- padding-right: 3rem
- @media all and (min-width: 642px)
- padding-left: 1rem
- padding-right: 1rem
- h4
- color: $brand-colour
- border-bottom: 2px solid lighten($brand-colour, 20%)
- text-align: center
- padding: 1rem 0
- margin: 1.5rem 0
-
-#cta.pane, #stats.pane
- h2
- font-weight: 300
- font-size: 45px
- margin-bottom: 2rem
- @media all and (max-width: 830px)
- font-size: 35px
-
-#stats.pane
- .row.header
- padding-bottom: 2rem
-
- h4
- font-weight: 300
- text-transform: uppercase
- margin: 1.5rem 0
- display: inline-block
- strong
- display: block
- font-weight: normal
- font-size: 75px
-
-#shops.pane
- @include paneWhiteText
- h2
- margin-bottom: 2rem
- font-size: 4.4rem
- font-weight: 300
-
-#shops-signup.pane
- background-color: $brand-colour
-
-#sell-detail.pane
- margin: 50px 0
- .row
- padding-top: 25px
- padding-bottom: 25px
diff --git a/app/assets/stylesheets/darkswarm/home_panes.css.scss b/app/assets/stylesheets/darkswarm/home_panes.css.scss
new file mode 100644
index 0000000000..92053189e2
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/home_panes.css.scss
@@ -0,0 +1,225 @@
+@import "branding";
+@import "mixins";
+@import "typography";
+@import "animations";
+@import "variables";
+
+// Styling for big panes on homepage \\
+#panes {
+ .pane {
+ .row {
+ @include panepadding;
+
+ padding-top: 75px;
+ padding-bottom: 75px;
+
+ &.header {
+ padding-bottom: 0;
+ }
+
+ &.content {
+ padding-top: 0;
+ }
+ }
+ }
+}
+
+// Background styles \\
+#system.pane {
+ background-color: white;
+}
+
+#brand-story.pane, #cta.pane, #shops.pane, #sell.pane {
+ @include tiledPane;
+}
+
+#connect.pane {
+ @include groupsbg;
+}
+
+#learn.pane {
+ @include hubsbg;
+}
+
+#stats.pane {
+ background-image: url("/assets/home/background-blurred-oranges.jpg");
+ background-position: center center;
+ background-color: $ofn-grey;
+
+ @include fullbg;
+
+ @include paneWhiteText;
+}
+
+// Content styles \\
+#brand-story.pane {
+ .row {
+ h2 {
+ font-weight: 300;
+ font-size: 88px;
+ }
+
+ p {
+ @include bodyFont;
+
+ font-size: 1.5rem;
+ font-weight: 300;
+ }
+
+ @media all and (max-width: 768px) {
+ h2 {
+ font-size: 52px;
+ }
+
+ p {
+ font-size: 1.3rem;
+ }
+ }
+ }
+
+ a.text-vbig i {
+ font-size: 75px;
+ }
+}
+
+#system.pane {
+ .row .row {
+ padding-bottom: 0;
+ }
+
+ @media all and (max-width: 640px) {
+ .row .row {
+ padding: 0;
+ }
+ }
+
+ .home-icon-box {
+ background-image: url("/assets/ofn-o.png");
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: auto 100%;
+ padding: 3rem 0;
+ text-align: center;
+ margin-top: 2rem;
+
+ @media all and (min-width: 642px) {
+ margin-top: 0;
+ }
+
+ i {
+ font-size: 4rem;
+ }
+
+ a {
+ display: block;
+ width: 64px;
+ height: 64px;
+ margin: 0 auto;
+ background-color: $brand-colour;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: auto 100%;
+
+ &.search {
+ background-image: url("/assets/icon-mask-magnifier.png");
+ }
+
+ &.shop {
+ background-image: url("/assets/icon-mask-apple.png");
+ }
+
+ &.pick-up-delivery {
+ background-image: url("/assets/icon-mask-truck.png");
+ }
+ }
+ }
+
+ h2 {
+ font-size: 70px;
+ font-weight: 300;
+ color: $brand-colour;
+
+ @media all and (max-width: 640px) {
+ font-size: 45px;
+ }
+ }
+
+ .home-icon-box-bottom {
+ margin-top: 1rem;
+ width: 100%;
+ padding-left: 1rem;
+ padding-right: 1rem;
+
+ @media all and (min-width: 480px) {
+ padding-left: 3rem;
+ padding-right: 3rem;
+ }
+
+ @media all and (min-width: 642px) {
+ padding-left: 1rem;
+ padding-right: 1rem;
+ }
+
+ h4 {
+ color: $brand-colour;
+ border-bottom: 2px solid lighten($brand-colour, 20%);
+ text-align: center;
+ padding: 1rem 0;
+ margin: 1.5rem 0;
+ }
+ }
+}
+
+#cta.pane, #stats.pane {
+ h2 {
+ font-weight: 300;
+ font-size: 45px;
+ margin-bottom: 2rem;
+
+ @media all and (max-width: 830px) {
+ font-size: 35px;
+ }
+ }
+}
+
+#stats.pane {
+ .row.header {
+ padding-bottom: 2rem;
+ }
+
+ h4 {
+ font-weight: 300;
+ text-transform: uppercase;
+ margin: 1.5rem 0;
+ display: inline-block;
+
+ strong {
+ display: block;
+ font-weight: normal;
+ font-size: 75px;
+ }
+ }
+}
+
+#shops.pane {
+ @include paneWhiteText;
+
+ h2 {
+ margin-bottom: 2rem;
+ font-size: 4.4rem;
+ font-weight: 300;
+ }
+}
+
+#shops-signup.pane {
+ background-color: $brand-colour;
+}
+
+#sell-detail.pane {
+ margin: 50px 0;
+
+ .row {
+ padding-top: 25px;
+ padding-bottom: 25px;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/home_tagline.css.sass b/app/assets/stylesheets/darkswarm/home_tagline.css.sass
deleted file mode 100644
index fadaae70b0..0000000000
--- a/app/assets/stylesheets/darkswarm/home_tagline.css.sass
+++ /dev/null
@@ -1,33 +0,0 @@
-@import branding
-@import mixins
-@import variables
-
-// Styling for brand intro / tagline on homepage
-
-#tagline
- width: 100%
- &:before
- content: ""
- @include fullbg
- background-color: $ofn-grey
- background-image: url("/assets/home/home.jpg")
- position: fixed
- left: 0
- right: 0
- bottom: 0
- z-index: -1
- width: 100%
- height: 100%
-
- h1
- margin-top: 2rem
- @media all and (min-width: 768px)
- margin-top: 10rem
- img
- max-width: 45%
- @media all and (min-height: 500px)
- max-width: 80%
-
- margin-bottom: 2rem
- @media all and (min-width: 768px)
- margin-bottom: 5rem
diff --git a/app/assets/stylesheets/darkswarm/home_tagline.css.scss b/app/assets/stylesheets/darkswarm/home_tagline.css.scss
new file mode 100644
index 0000000000..b278f79e25
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/home_tagline.css.scss
@@ -0,0 +1,47 @@
+@import "branding";
+@import "mixins";
+@import "variables";
+
+// Styling for brand intro / tagline on homepage
+
+#tagline {
+ width: 100%;
+
+ &:before {
+ content: "";
+
+ @include fullbg;
+
+ background-color: $ofn-grey;
+ background-image: url("/assets/home/home.jpg");
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: -1;
+ width: 100%;
+ height: 100%;
+ }
+
+ h1 {
+ margin-top: 2rem;
+
+ @media all and (min-width: 768px) {
+ margin-top: 10rem;
+ }
+
+ img {
+ max-width: 45%;
+
+ @media all and (min-height: 500px) {
+ max-width: 80%;
+ }
+
+ margin-bottom: 2rem;
+
+ @media all and (min-width: 768px) {
+ margin-bottom: 5rem;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/hub_node.css.sass b/app/assets/stylesheets/darkswarm/hub_node.css.sass
deleted file mode 100644
index 4d175681f2..0000000000
--- a/app/assets/stylesheets/darkswarm/hub_node.css.sass
+++ /dev/null
@@ -1,168 +0,0 @@
-@import branding
-@import mixins
-
-.hubs
- .active_table .active_table_node
-
- //Prevents ugly overflows on hub title
- .columns.skinny-head
- white-space: nowrap
- overflow-x: hidden
- overflow-y: visible
-
- //Generic text link style
- a, a *
- color: $clr-brick
- &:hover, &:active, &:focus
- color: $clr-brick-bright
-
- //Hub and Producer icons
- i.ofn-i_063-hub, i.ofn-i_064-hub-reversed, i.ofn-i_059-producer, i.ofn-i_060-producer-reversed
- font-size: 2rem
- display: inline-block
- margin-right: 0.25rem
- float: left
-
- //Closed & Open column
- .open_closed
- i
- font-size: 2rem
- float: right
- margin-left: 0.5rem
-
- //Hub Link
- @media all and (max-width: 640px)
- a.hub
- display: block
-
- //Hub Name
- span.hub-name-listing
- font-weight: 700
- &:after
- content: ">>"
- display: inline-block
- margin-left: 5px
-
- //CLOSED row
- &.closed
- .active_table_row
- border: 1px solid transparent
- @media all and (max-width: 640px)
- border-color: $clr-brick-light
- &:hover, &:active, &:focus
- border-color: $clr-brick-light-bright
-
- //OPEN row
- &.open
- .active_table_row, .active_table_row:first-child, .active_table_row:last-child
- border-color: $clr-brick-light-bright
-
- &.open, &.closed
- @media all and (max-width: 640px)
- .active_table_row:first-child .skinny-head
- background-color: $clr-brick-light
- @include border-radius-mixed(0.5em, 0.5em, 0, 0)
- margin-top: -1rem
- margin-bottom: 1rem
- padding-top: 1rem
- padding-bottom: 1rem
- label
- margin-top: 1rem
-
- //Padding second row
- &.open
- .active_table_row:nth-child(2)
- padding-bottom: 0.75rem
-
-
- .producers-list
- li.more-producers-link
- .less
- display: none
- a:hover
- text-decoration: underline
- li.additional-producer
- display: none
- &.show-more-producers
- li.additional-producer
- display: block
- li.more-producers-link
- .more
- display: none
- .less
- display: block
-
- //CURRENT hub (shows selected hub)
- &.current
- //overwrites active_table
- &.closed, &.open
- a, a *
- color: $clr-brick
- .active_table_row
- border-color: $clr-brick
- .active_table_row:first-child, .active_table_row:last-child
- background-color: $clr-brick-light-trans
- opacity: 1
- &:hover, &:focus, &:active
- opacity: 0.9
- border-color: $clr-brick-bright
- @media all and (max-width: 640px)
- .active_table_row:first-child .skinny-head
- background-color: rgba(255,255,255,0.85)
-
-
- //INACTIVE - closed hub
- &.inactive
- &.closed, &.open
- &, & *
- color: $disabled-med
- a, a *
- color: $disabled-dark
- &.closed
- .active_table_row, .active_table_row:first-child, .active_table_row:last-child
- &:hover, &:active, &:focus
- border-color: $disabled-bright
- &.open
- .active_table_row, .active_table_row:first-child, .active_table_row:last-child
- // border-color: $disabled-bright
- &, &:hover, &:active, &:focus
- border-color: $disabled-bright
-
- &.closed, &.open
-
- // & Current hub
- &.current
- .active_table_row, .active_table_row:first-child, .active_table_row:last-child
- a, a *
- color: $med-grey
- border-color: $disabled-dark
- background-color: rgba(220,220,220,0.5)
- &:hover, &:focus, &:active
- border-color: $disabled-dark
-
- // Small devices
- @media all and (max-width: 640px)
- .active_table_row:first-child .skinny-head
- background-color: $disabled-bright
-
- // Small devices
- @media all and (max-width: 640px)
- .active_table_row, .active_table_row:first-child, .active_table_row:last-child
- border-color: $disabled-bright
- background-color: transparent
- &:hover, &:focus, &:active
- border-color: $disabled-bright
- opacity: 0.85
- .active_table_row:first-child .skinny-head
- background-color: $disabled-light
-
- //Is Profile - profile node
- &.inactive.is_profile
- &.closed, &.open
- .active_table_row
- &:hover, &:active, &:focus
- border-color: transparent
- cursor: auto
- @media all and (max-width: 640px)
- border-color: transparent
-
diff --git a/app/assets/stylesheets/darkswarm/hub_node.css.scss b/app/assets/stylesheets/darkswarm/hub_node.css.scss
new file mode 100644
index 0000000000..5df4f68b01
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/hub_node.css.scss
@@ -0,0 +1,255 @@
+@import "branding";
+@import "mixins";
+
+.hubs {
+ .active_table .active_table_node {
+ //Prevents ugly overflows on hub title
+ .columns.skinny-head {
+ white-space: nowrap;
+ overflow-x: hidden;
+ overflow-y: visible;
+ }
+
+ //Generic text link style
+ a, a * {
+ color: $clr-brick;
+
+ &:hover, &:active, &:focus {
+ color: $clr-brick-bright;
+ }
+ }
+
+ //Hub and Producer icons
+ i.ofn-i_063-hub, i.ofn-i_064-hub-reversed, i.ofn-i_059-producer, i.ofn-i_060-producer-reversed {
+ font-size: 2rem;
+ display: inline-block;
+ margin-right: 0.25rem;
+ float: left;
+ }
+
+ //Closed & Open column
+ .open_closed {
+ i {
+ font-size: 2rem;
+ float: right;
+ margin-left: 0.5rem;
+ }
+ }
+
+ //Hub Link
+ @media all and (max-width: 640px) {
+ a.hub {
+ display: block;
+ }
+ }
+
+ //Hub Name
+ span.hub-name-listing {
+ font-weight: 700;
+
+ &:after {
+ content: ">>";
+ display: inline-block;
+ margin-left: 5px;
+ }
+ }
+
+ //CLOSED row
+ &.closed {
+ .active_table_row {
+ border: 1px solid transparent;
+
+ @media all and (max-width: 640px) {
+ border-color: $clr-brick-light;
+ }
+
+ &:hover, &:active, &:focus {
+ border-color: $clr-brick-light-bright;
+ }
+ }
+ }
+
+ //OPEN row
+ &.open {
+ .active_table_row, .active_table_row:first-child, .active_table_row:last-child {
+ border-color: $clr-brick-light-bright;
+ }
+ }
+
+ &.open, &.closed {
+ @media all and (max-width: 640px) {
+ .active_table_row:first-child .skinny-head {
+ background-color: $clr-brick-light;
+
+ @include border-radius-mixed(0.5em, 0.5em, 0, 0);
+
+ margin-top: -1rem;
+ margin-bottom: 1rem;
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ }
+
+ label {
+ margin-top: 1rem;
+ }
+ }
+ }
+
+ //Padding second row
+ &.open {
+ .active_table_row:nth-child(2) {
+ padding-bottom: 0.75rem;
+ }
+ }
+
+ .producers-list {
+ li.more-producers-link {
+ .less {
+ display: none;
+ }
+
+ a:hover {
+ text-decoration: underline;
+ }
+ }
+
+ li.additional-producer {
+ display: none;
+ }
+
+ &.show-more-producers {
+ li.additional-producer {
+ display: block;
+ }
+
+ li.more-producers-link {
+ .more {
+ display: none;
+ }
+
+ .less {
+ display: block;
+ }
+ }
+ }
+ }
+
+ //CURRENT hub (shows selected hub)
+ &.current {
+ //overwrites active_table
+ &.closed, &.open {
+ a, a * {
+ color: $clr-brick;
+ }
+
+ .active_table_row {
+ border-color: $clr-brick;
+ }
+
+ .active_table_row:first-child, .active_table_row:last-child {
+ background-color: $clr-brick-light-trans;
+ opacity: 1;
+
+ &:hover, &:focus, &:active {
+ opacity: 0.9;
+ border-color: $clr-brick-bright;
+ }
+ }
+
+ @media all and (max-width: 640px) {
+ .active_table_row:first-child .skinny-head {
+ background-color: rgba(255, 255, 255, 0.85);
+ }
+ }
+ }
+ }
+
+ //INACTIVE - closed hub
+ &.inactive {
+ &.closed, &.open {
+ &, & * {
+ color: $disabled-med;
+ }
+
+ a, a * {
+ color: $disabled-dark;
+ }
+ }
+
+ &.closed {
+ .active_table_row, .active_table_row:first-child, .active_table_row:last-child {
+ &:hover, &:active, &:focus {
+ border-color: $disabled-bright;
+ }
+ }
+ }
+
+ &.open {
+ .active_table_row, .active_table_row:first-child, .active_table_row:last-child {
+ // border-color: $disabled-bright
+ &, &:hover, &:active, &:focus {
+ border-color: $disabled-bright;
+ }
+ }
+ }
+
+ &.closed, &.open {
+ // & Current hub
+ &.current {
+ .active_table_row, .active_table_row:first-child, .active_table_row:last-child {
+ a, a * {
+ color: $med-grey;
+ }
+
+ border-color: $disabled-dark;
+ background-color: rgba(220, 220, 220, 0.5);
+
+ &:hover, &:focus, &:active {
+ border-color: $disabled-dark;
+ }
+ }
+
+ // Small devices
+ @media all and (max-width: 640px) {
+ .active_table_row:first-child .skinny-head {
+ background-color: $disabled-bright;
+ }
+ }
+ }
+
+ // Small devices
+ @media all and (max-width: 640px) {
+ .active_table_row, .active_table_row:first-child, .active_table_row:last-child {
+ border-color: $disabled-bright;
+ background-color: transparent;
+
+ &:hover, &:focus, &:active {
+ border-color: $disabled-bright;
+ opacity: 0.85;
+ }
+ }
+
+ .active_table_row:first-child .skinny-head {
+ background-color: $disabled-light;
+ }
+ }
+ }
+ }
+
+ //Is Profile - profile node
+ &.inactive.is_profile {
+ &.closed, &.open {
+ .active_table_row {
+ &:hover, &:active, &:focus {
+ border-color: transparent;
+ cursor: auto;
+ }
+
+ @media all and (max-width: 640px) {
+ border-color: transparent;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/hubs.css.sass b/app/assets/stylesheets/darkswarm/hubs.css.sass
deleted file mode 100644
index 5946d6ee77..0000000000
--- a/app/assets/stylesheets/darkswarm/hubs.css.sass
+++ /dev/null
@@ -1,13 +0,0 @@
-@import branding
-@import mixins
-
-#hubs
- background-color: lighten($ofn-grey, 43%)
- @include panepadding
- @include sidepaddingSm
-
- .name-matches, .distance-matches
- margin-top: 4em
-
- .more-controls
- text-align: center
diff --git a/app/assets/stylesheets/darkswarm/hubs.css.scss b/app/assets/stylesheets/darkswarm/hubs.css.scss
new file mode 100644
index 0000000000..9845ce9ad8
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/hubs.css.scss
@@ -0,0 +1,18 @@
+@import "branding";
+@import "mixins";
+
+#hubs {
+ background-color: lighten($ofn-grey, 43%);
+
+ @include panepadding;
+
+ @include sidepaddingSm;
+
+ .name-matches, .distance-matches {
+ margin-top: 4em;
+ }
+
+ .more-controls {
+ text-align: center;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/ie_warning.sass b/app/assets/stylesheets/darkswarm/ie_warning.sass
deleted file mode 100644
index ede86a3083..0000000000
--- a/app/assets/stylesheets/darkswarm/ie_warning.sass
+++ /dev/null
@@ -1,32 +0,0 @@
-#ie-warning
- margin-bottom: 0
- padding-bottom: 2rem
- .ie-msg
- background: rgba(255,255,255,0.15)
- padding: 0.5rem
- margin-bottom: 1rem
- margin-top: 1rem
- .browserbtn
- text-align: center
- margin-bottom: 1rem
- a
- color: white
- font-size: 1rem
- filter: alpha(opacity=70)
- opacity: 0.7
- &:hover, &:active, &:focus
- filter: alpha(opacity=100)
- opacity: 1
-
- a.browserlogo
- display: block
- width: 100%
- i
- font-size: 5rem
- color: white
- text-align: center
- display: block
-
-
-
-
diff --git a/app/assets/stylesheets/darkswarm/ie_warning.scss b/app/assets/stylesheets/darkswarm/ie_warning.scss
new file mode 100644
index 0000000000..0ed3940734
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/ie_warning.scss
@@ -0,0 +1,40 @@
+#ie-warning {
+ margin-bottom: 0;
+ padding-bottom: 2rem;
+
+ .ie-msg {
+ background: rgba(255, 255, 255, 0.15);
+ padding: 0.5rem;
+ margin-bottom: 1rem;
+ margin-top: 1rem;
+ }
+
+ .browserbtn {
+ text-align: center;
+ margin-bottom: 1rem;
+
+ a {
+ color: white;
+ font-size: 1rem;
+ filter: alpha(opacity = 70);
+ opacity: 0.7;
+
+ &:hover, &:active, &:focus {
+ filter: alpha(opacity = 100);
+ opacity: 1;
+ }
+ }
+
+ a.browserlogo {
+ display: block;
+ width: 100%;
+ }
+ }
+
+ i {
+ font-size: 5rem;
+ color: white;
+ text-align: center;
+ display: block;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/images.css.sass b/app/assets/stylesheets/darkswarm/images.css.sass
deleted file mode 100644
index b89cbb21fc..0000000000
--- a/app/assets/stylesheets/darkswarm/images.css.sass
+++ /dev/null
@@ -1,47 +0,0 @@
-@import mixins
-@import variables
-@import branding
-
-.product-img
- padding: 5px
- margin-bottom: 10px
- outline: 1px solid #ccc
- @include box-shadow(0 1px 2px 1px rgba(0,0,0,0.15))
- // placeholder for when no product images
- &.placeholder
- opacity: 0.35
- @media all and (max-width: 1024px)
- display: none
-
-.hero-img
- outline: 1px solid $disabled-bright
- border-color: transparent
- @include box-shadow(none)
- width: 100%
- min-height: 80px
- height: inherit
- max-height: 260px
- overflow: hidden
- @media all and (max-width: 640px)
- min-height: 68px
-
-.hero-img-small
- background-color: #333
- width: 100%
- // min-height: 60px
- height: inherit
- overflow: hidden
- margin: 0 0 1rem 0 !important
-
-.producer-logo
- max-width: 220px
-
-@media only screen and (max-width: 1024px)
- .product-img
- margin-top: 2em
- margin-bottom: 1em
-
-
-
-
-
diff --git a/app/assets/stylesheets/darkswarm/images.css.scss b/app/assets/stylesheets/darkswarm/images.css.scss
new file mode 100644
index 0000000000..2a9f931f6e
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/images.css.scss
@@ -0,0 +1,58 @@
+@import "mixins";
+@import "variables";
+@import "branding";
+
+.product-img {
+ padding: 5px;
+ margin-bottom: 10px;
+ outline: 1px solid #ccc;
+
+ @include box-shadow(0 1px 2px 1px rgba(0, 0, 0, 0.15));
+
+ // placeholder for when no product images
+ &.placeholder {
+ opacity: 0.35;
+
+ @media all and (max-width: 1024px) {
+ display: none;
+ }
+ }
+}
+
+.hero-img {
+ outline: 1px solid $disabled-bright;
+ border-color: transparent;
+
+ @include box-shadow(none);
+
+ width: 100%;
+ min-height: 80px;
+ height: inherit;
+ max-height: 260px;
+ overflow: hidden;
+
+ @media all and (max-width: 640px) {
+ min-height: 68px;
+ }
+}
+
+.hero-img-small {
+ background-color: #333;
+ width: 100%;
+
+ // min-height: 60px
+ height: inherit;
+ overflow: hidden;
+ margin: 0 0 1rem 0 !important;
+}
+
+.producer-logo {
+ max-width: 220px;
+}
+
+@media only screen and (max-width: 1024px) {
+ .product-img {
+ margin-top: 2em;
+ margin-bottom: 1em;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/lists.css.sass b/app/assets/stylesheets/darkswarm/lists.css.sass
deleted file mode 100644
index 244d0dd862..0000000000
--- a/app/assets/stylesheets/darkswarm/lists.css.sass
+++ /dev/null
@@ -1,7 +0,0 @@
-
-body ol
- list-style-type: none
- margin-left: 0em
- padding-top: 1em
- li
- margin-left: 0
diff --git a/app/assets/stylesheets/darkswarm/lists.css.scss b/app/assets/stylesheets/darkswarm/lists.css.scss
new file mode 100644
index 0000000000..51d54744ca
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/lists.css.scss
@@ -0,0 +1,9 @@
+body ol {
+ list-style-type: none;
+ margin-left: 0em;
+ padding-top: 1em;
+
+ li {
+ margin-left: 0;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/loading.sass b/app/assets/stylesheets/darkswarm/loading.sass
deleted file mode 100644
index d2950f07fd..0000000000
--- a/app/assets/stylesheets/darkswarm/loading.sass
+++ /dev/null
@@ -1,83 +0,0 @@
-@import "compass/css3/user-interface"
-
-#loading
- .reveal-modal-bg
- z-index: 101
- background: rgba(0, 0, 0, 0.85)
- #message
- width: 100%
- text-align: center
- position: absolute
- z-index: 102
- margin: auto
- top: 0
- left: 0
- bottom: 0
- right: 0
- @include user-select(none)
- h1
- -webkit-animation: blurFadeIn 0.8s ease-in-out 0s
- color: white
- font-size: 1.15rem
- position: fixed
- text-align: center
- left: 0
- right: 0
- margin: 0 auto
- top: 55%
- width: 100%
- overflow: visible
-
- .loader
- position: fixed
- margin: 0 auto
- left: 0
- right: 0
- top: 50%
- margin-top: -30px
- width: 60px
- height: 60px
- list-style: none
-
- li
- background-color: #FFFFFF
- width: 10px
- height: 10px
- float: right
- margin-right: 5px
- box-shadow: 0px 100px 20px rgba(0, 0, 0, 0.2)
-
- li:first-child
- -webkit-animation: loadbars 0.6s cubic-bezier(0.645, 0.045, 0.355, 1) infinite 0s
-
- li:nth-child(2)
- -webkit-animation: loadbars 0.6s ease-in-out infinite -0.2s
-
- li:nth-child(3)
- -webkit-animation: loadbars 0.6s ease-in-out infinite -0.4s
-
-@-webkit-keyframes blurFadeIn
- 0%
- opacity: 0
- text-shadow: 0px 0px 10px #fff
- -webkit-transform: scale(1.3)
- 50%
- opacity: 0.5
- text-shadow: 0px 0px 5px #fff
- -webkit-transform: scale(1.1)
- 100%
- opacity: 1
- text-shadow: 0px 0px 0px #fff
- -webkit-transform: scale(1)
-
-@-webkit-keyframes 'loadbars'
- 0%
- height: 10px
- margin-top: 25px
- 50%
- height: 50px
- margin-top: 0px
- 100%
- height: 10px
- margin-top: 25px
-
diff --git a/app/assets/stylesheets/darkswarm/loading.scss b/app/assets/stylesheets/darkswarm/loading.scss
new file mode 100644
index 0000000000..32a3d6b9b4
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/loading.scss
@@ -0,0 +1,106 @@
+@import "compass/css3/user-interface";
+
+#loading {
+ .reveal-modal-bg {
+ z-index: 101;
+ background: rgba(0, 0, 0, 0.85);
+ }
+
+ #message {
+ width: 100%;
+ text-align: center;
+ position: absolute;
+ z-index: 102;
+ margin: auto;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+
+ @include user-select(none);
+
+ h1 {
+ -webkit-animation: blurFadeIn 0.8s ease-in-out 0s;
+ color: white;
+ font-size: 1.15rem;
+ position: fixed;
+ text-align: center;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ top: 55%;
+ width: 100%;
+ overflow: visible;
+ }
+ }
+
+ .loader {
+ position: fixed;
+ margin: 0 auto;
+ left: 0;
+ right: 0;
+ top: 50%;
+ margin-top: -30px;
+ width: 60px;
+ height: 60px;
+ list-style: none;
+
+ li {
+ background-color: #FFFFFF;
+ width: 10px;
+ height: 10px;
+ float: right;
+ margin-right: 5px;
+ box-shadow: 0px 100px 20px rgba(0, 0, 0, 0.2);
+ }
+
+ li:first-child {
+ -webkit-animation: loadbars 0.6s cubic-bezier(0.645, 0.045, 0.355, 1) infinite 0s;
+ }
+
+ li:nth-child(2) {
+ -webkit-animation: loadbars 0.6s ease-in-out infinite -0.2s;
+ }
+
+ li:nth-child(3) {
+ -webkit-animation: loadbars 0.6s ease-in-out infinite -0.4s;
+ }
+ }
+}
+
+@-webkit-keyframes blurFadeIn {
+ 0% {
+ opacity: 0;
+ text-shadow: 0px 0px 10px #fff;
+ -webkit-transform: scale(1.3);
+ }
+
+ 50% {
+ opacity: 0.5;
+ text-shadow: 0px 0px 5px #fff;
+ -webkit-transform: scale(1.1);
+ }
+
+ 100% {
+ opacity: 1;
+ text-shadow: 0px 0px 0px #fff;
+ -webkit-transform: scale(1);
+ }
+}
+
+@-webkit-keyframes 'loadbars' {
+ 0% {
+ height: 10px;
+ margin-top: 25px;
+ }
+
+ 50% {
+ height: 50px;
+ margin-top: 0px;
+ }
+
+ 100% {
+ height: 10px;
+ margin-top: 25px;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/map.css.sass b/app/assets/stylesheets/darkswarm/map.css.sass
deleted file mode 100644
index e2a25d61c9..0000000000
--- a/app/assets/stylesheets/darkswarm/map.css.sass
+++ /dev/null
@@ -1,50 +0,0 @@
-// Place all the styles related to the map controller here.
-// They will automatically be included in application.css.
-// You can use Sass (SCSS) here: http://sass-lang.com/
-@import big-input
-
-.map-container
- width: 100%
- map, .angular-google-map-container, google-map, .angular-google-map
- display: block
- height: 100%
- width: 100%
-
- // https://github.com/zurb/foundation/issues/112
- img
- max-width: none
- height: auto
-
- #pac-input
- @include big-input(#888, #333, $clr-brick)
- @include big-input-static
- font-size: 1.5rem
- background: rgba(255,255,255,0.85)
- width: 50%
- margin-top: 1.2rem
- margin-left: 1rem
- @media all and (max-width: 768px)
- width: 80%
- &:active, &:focus, &.active
- background: rgba(255,255,255, 1)
-
-.map-footer
- position: fixed
- z-index: 2
- width: 100%
- height: 23px
- left: 80px
- right: 0
- bottom: 6px
- margin: 0
- padding: 6px
- font-size: 14px
- font-weight: bold
- text-shadow: 2px 2px #aaa
- color: #fff
-
- a, a:hover, a:active, a:focus
- color: #fff
-
- @media all and (max-width: 1025px)
- left: 0px
\ No newline at end of file
diff --git a/app/assets/stylesheets/darkswarm/map.css.scss b/app/assets/stylesheets/darkswarm/map.css.scss
new file mode 100644
index 0000000000..d880b3025b
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/map.css.scss
@@ -0,0 +1,64 @@
+// Place all the styles related to the map controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
+@import "big-input";
+
+.map-container {
+ width: 100%;
+
+ map, .angular-google-map-container, google-map, .angular-google-map {
+ display: block;
+ height: 100%;
+ width: 100%;
+ }
+
+ // https://github.com/zurb/foundation/issues/112
+ img {
+ max-width: none;
+ height: auto;
+ }
+
+ #pac-input {
+ @include big-input(#888, #333, $clr-brick);
+
+ @include big-input-static;
+
+ font-size: 1.5rem;
+ background: rgba(255, 255, 255, 0.85);
+ width: 50%;
+ margin-top: 1.2rem;
+ margin-left: 1rem;
+
+ @media all and (max-width: 768px) {
+ width: 80%;
+ }
+
+ &:active, &:focus, &.active {
+ background: rgba(255, 255, 255, 1);
+ }
+ }
+}
+
+.map-footer {
+ position: fixed;
+ z-index: 2;
+ width: 100%;
+ height: 23px;
+ left: 80px;
+ right: 0;
+ bottom: 6px;
+ margin: 0;
+ padding: 6px;
+ font-size: 14px;
+ font-weight: bold;
+ text-shadow: 2px 2px #aaa;
+ color: #fff;
+
+ a, a:hover, a:active, a:focus {
+ color: #fff;
+ }
+
+ @media all and (max-width: 1025px) {
+ left: 0px;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/menu.css.sass b/app/assets/stylesheets/darkswarm/menu.css.sass
deleted file mode 100644
index 41b86f72ff..0000000000
--- a/app/assets/stylesheets/darkswarm/menu.css.sass
+++ /dev/null
@@ -1,137 +0,0 @@
-@import compass
-@import branding
-@import mixins
-@import typography
-@import variables
-
-
-nav
- @include textpress
- text-shadow: none
-
- // Create center style for nav ul (foundation provides left and right)
- text-align: center
- .top-bar-section
- // Avoid menu items blocking logo
- li:not(.has-form), li:not(.has-form) a:not(.button), li:not(.has-form) a:not(.button):hover
- background-color: transparent
-
- ul.center
- display: inline-block
- // By default, we center between the left and right uls, but we want to be centered
- // relative to the whole page. The difference in width between the other uls is 74px,
- // so we offset by that amount here.
- margin-left: -74px
-
- .joyride-tip-guide .button
- text-shadow: none
-
- // Default overrides - big menu
- .top-bar-section .has-dropdown > a
- padding-right: $topbar-height / 3 !important
-
- i.ofn-i_022-cog
- font-size: 24px
- line-height: $topbar-height
-
- .top-bar-section .has-dropdown > a:after
- display: none
-
- .top-bar-section ul li > a
- font-size: 0.75rem
- height: $topbar-height
- opacity: 0.8
- &:hover, &:focus, &:active
- opacity: 1
- @include transition(all 0.3s ease-in-out)
-
- .top-bar-section ul li.ofn-logo > a
- display: table-cell
- vertical-align: middle
- opacity: 1
-
- .nav-branded
- color: $brand-colour
- span
- font-size: 13px
- .nav-primary
- @include headingFont
- font-size: 0.875rem
- font-weight: 300
- ul .nav-primary
- text-transform: uppercase
- ul.dropdown
- border: 1px solid $smoke
- border-top: none
-
-
-// Mobile Menu
-
-.tab-bar
- background-color: white
-
-.off-canvas-wrap.move-right .tab-bar .menu-icon
- @include box-shadow(inset 0 0 6px 2px rgba(0,0,0,0.5))
-
-.off-canvas-wrap .tab-bar .menu-icon
- @include box-shadow(none)
-
-.off-canvas-wrap.move-right .tab-bar .menu-icon span
- -moz-box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666
- -webkit-box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666
- box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666
-
-.tab-bar .menu-icon span::after
- box-shadow: 0 0 0 1px black, 0 7px 0 1px black, 0 14px 0 1px black
-
-.tab-bar .ofn-logo
- padding: 9px 0 0 9px
-
-.left-off-canvas-menu
- background-color: white
-
-.off-canvas-wrap.move-right ul.off-canvas-list
- font-size: 0.875rem
-
- .li-menu
- @include headingFont
- font-size: 1rem
- a
- color: rgba(0, 0, 0, 0.9)
- li a
- color: rgba(0, 0, 0, 0.9)
- &:hover
- background-color: transparent
- color: $brand-colour
- @include transition(all 0.3s ease-in-out)
-
-.off-canvas-wrap.move-right ul.off-canvas-list i
- font-size: 1.5rem
- margin-right: 0.25rem
-
-
-
-// Responsive
-
-@media screen and (max-width: 1450px)
- nav .top-bar-section
- ul li a, .has-dropdown > a
- padding: 0 $topbar-height / 8 !important
-
- ul.center
- margin-left: -24px
-
-
-@media screen and (min-width: 1025px)
- body.off-canvas
- // padding required to placehold for fixed menu bar
- padding-top: $topbar-height
-
-
-@media screen and (max-width: 1025px)
- body.off-canvas
- // padding required to placehold for fixed menu bar
- padding-top: 0
- section.right
- .nav-branded
- padding: 0 1em
diff --git a/app/assets/stylesheets/darkswarm/menu.css.scss b/app/assets/stylesheets/darkswarm/menu.css.scss
new file mode 100644
index 0000000000..801ccb57a4
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/menu.css.scss
@@ -0,0 +1,186 @@
+@import "compass";
+@import "branding";
+@import "mixins";
+@import "typography";
+@import "variables";
+
+nav {
+ @include textpress;
+
+ text-shadow: none;
+
+ // Create center style for nav ul (foundation provides left and right)
+ text-align: center;
+
+ .top-bar-section {
+ // Avoid menu items blocking logo
+ li:not(.has-form), li:not(.has-form) a:not(.button), li:not(.has-form) a:not(.button):hover {
+ background-color: transparent;
+ }
+
+ ul.center {
+ display: inline-block;
+
+ // By default, we center between the left and right uls, but we want to be centered
+ // relative to the whole page. The difference in width between the other uls is 74px,
+ // so we offset by that amount here.
+ margin-left: -74px;
+ }
+ }
+
+ .joyride-tip-guide .button {
+ text-shadow: none;
+ }
+
+ // Default overrides - big menu
+ .top-bar-section .has-dropdown > a {
+ padding-right: ($topbar-height / 3) !important;
+
+ i.ofn-i_022-cog {
+ font-size: 24px;
+ line-height: $topbar-height;
+ }
+ }
+
+ .top-bar-section .has-dropdown > a:after {
+ display: none;
+ }
+
+ .top-bar-section ul li > a {
+ font-size: 0.75rem;
+ height: $topbar-height;
+ opacity: 0.8;
+
+ &:hover, &:focus, &:active {
+ opacity: 1;
+ }
+
+ @include transition(all 0.3s ease-in-out);
+ }
+
+ .top-bar-section ul li.ofn-logo > a {
+ display: table-cell;
+ vertical-align: middle;
+ opacity: 1;
+ }
+
+ .nav-branded {
+ color: $brand-colour;
+
+ span {
+ font-size: 13px;
+ }
+ }
+
+ .nav-primary {
+ @include headingFont;
+
+ font-size: 0.875rem;
+ font-weight: 300;
+ }
+
+ ul .nav-primary {
+ text-transform: uppercase;
+ }
+
+ ul.dropdown {
+ border: 1px solid $smoke;
+ border-top: none;
+ }
+}
+
+// Mobile Menu
+
+.tab-bar {
+ background-color: white;
+}
+
+.off-canvas-wrap.move-right .tab-bar .menu-icon {
+ @include box-shadow(inset 0 0 6px 2px rgba(0, 0, 0, 0.5));
+}
+
+.off-canvas-wrap .tab-bar .menu-icon {
+ @include box-shadow(none);
+}
+
+.off-canvas-wrap.move-right .tab-bar .menu-icon span {
+ -moz-box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666;
+ -webkit-box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666;
+ box-shadow: 0 0px 0 1px #666, 0 7px 0 1px #666, 0 14px 0 1px #666;
+}
+
+.tab-bar .menu-icon span::after {
+ box-shadow: 0 0 0 1px black, 0 7px 0 1px black, 0 14px 0 1px black;
+}
+
+.tab-bar .ofn-logo {
+ padding: 9px 0 0 9px;
+}
+
+.left-off-canvas-menu {
+ background-color: white;
+}
+
+.off-canvas-wrap.move-right ul.off-canvas-list {
+ font-size: 0.875rem;
+
+ .li-menu {
+ @include headingFont;
+
+ font-size: 1rem;
+
+ a {
+ color: rgba(0, 0, 0, 0.9);
+ }
+ }
+
+ li a {
+ color: rgba(0, 0, 0, 0.9);
+
+ &:hover {
+ background-color: transparent;
+ color: $brand-colour;
+ }
+
+ @include transition(all 0.3s ease-in-out);
+ }
+}
+
+.off-canvas-wrap.move-right ul.off-canvas-list i {
+ font-size: 1.5rem;
+ margin-right: 0.25rem;
+}
+
+// Responsive
+
+@media screen and (max-width: 1450px) {
+ nav .top-bar-section {
+ ul li a, .has-dropdown > a {
+ padding: 0 ($topbar-height / 8) !important;
+ }
+
+ ul.center {
+ margin-left: -24px;
+ }
+ }
+}
+
+@media screen and (min-width: 1025px) {
+ body.off-canvas {
+ // padding required to placehold for fixed menu bar
+ padding-top: $topbar-height;
+ }
+}
+
+@media screen and (max-width: 1025px) {
+ body.off-canvas {
+ // padding required to placehold for fixed menu bar
+ padding-top: 0;
+ }
+
+ section.right {
+ .nav-branded {
+ padding: 0 1em;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/mixins.sass b/app/assets/stylesheets/darkswarm/mixins.sass
deleted file mode 100644
index d35c5aa1a7..0000000000
--- a/app/assets/stylesheets/darkswarm/mixins.sass
+++ /dev/null
@@ -1,192 +0,0 @@
-// Note this mixin file is used in ADMIN and FRONTEND
-
-@import branding
-
-
-// Generic \\
-
-@mixin tiledPane
- background-image: url("/assets/tile-wide.png")
- background-color: $brand-colour
- background-position: center center
- @include paneWhiteText
-
-@mixin panepadding
- padding-top: 100px
- padding-bottom: 100px
-
-@mixin paneWhiteText
- &, & *
- color: white
-
-@mixin sidepaddingSm
- padding-left: 10px
- padding-right: 10px
- @media all and (min-width: 768px)
- padding-left: 20px
- padding-right: 20px
- @media all and (min-width: 1024px)
- padding-left: 50px
- padding-right: 50px
- @media all and (min-width: 1200px)
- padding-left: 100px
- padding-right: 100px
-
-@mixin sidepaddingBg
- padding-left: 20px
- padding-right: 20px
- @media all and (min-width: 768px)
- padding-left: 40px
- padding-right: 40px
- @media all and (min-width: 1024px)
- padding-left: 100px
- padding-right: 100px
- @media all and (min-width: 1200px)
- padding-left: 200px
- padding-right: 200px
-
-@mixin disabled
- color: $disabled-bright
-
-@mixin box-shadow($box-shadow)
- -moz-box-shadow: $box-shadow
- -webkit-box-shadow: $box-shadow
- box-shadow: $box-shadow
-
-@mixin elipse-shadow($elipse-shadow)
- content: ""
- position: absolute
- z-index: -1
- -webkit-box-shadow: $elipse-shadow
- box-shadow: $elipse-shadow
- bottom: -12%
- left: 10%
- right: 10%
- width: 80%
- height: 10%
- -moz-border-radius: 100%
- border-radius: 100%
-
-@mixin border-radius($border-radius)
- -webkit-border-radius: $border-radius
- border-radius: $border-radius
-
-@mixin border-radius-mixed($border-radius-TL, $border-radius-TR, $border-radius-BR, $border-radius-BL)
- -webkit-border-radius: $border-radius-TL $border-radius-TR $border-radius-BR $border-radius-BL
- border-radius: $border-radius-TL $border-radius-TR $border-radius-BR $border-radius-BL
-
-@mixin transform-translate($translate)
- -ms-transform: $translate
- -webkit-transform: $translate
- transform: $translate
-
-@mixin transform-scale($scale)
- -moz-transform: $scale
- -webkit-transform: $scale
- -o-transform: $scale
- -ms-transform: $scale
- transform: $scale
-
-// Typography \\
-
-@mixin textpress
- text-shadow: 0 -1px 1px #111111, 0 1px 2px #222222
-
-@mixin textsoftpress
- text-shadow: 0 0 3px rgba(0,0,0,0.35)
-
-// TO USE icon-font
-// Assign to :before or :after element
-// Assign content: "string"
-
-@mixin icon-font
- font-family: "OFN"
- display: inline-block
- font-weight: normal
- font-style: normal
- font-variant: normal
- text-transform: none
-
-
-// Background options \\
-
-@mixin darkbg
- background-color: $clr-brick
- &, & *
- color: white
- a
- color: $clr-brick-ultra-light
- &:hover
- text-decoration: none
- color: $clr-brick-light
-
-@mixin lightbg
- background-color: $clr-brick-light
- &, & *
- color: black
- a
- color: $clr-brick
- &:hover
- text-decoration: none
- color: $clr-brick-bright
-
-@mixin turqbg
- background-color: $clr-turquoise-light
- &, & *
- color: $clr-turquoise
- a
- color: $clr-turquoise
- &:hover
- text-decoration: none
- color: $clr-turquoise-bright
-
-@mixin fullbg
- background-position: center center
- background-repeat: no-repeat
- -webkit-background-size: cover
- -moz-background-size: cover
- -o-background-size: cover
- background-size: cover
-
-@mixin fullwidthbg
- background-position: center top
- background-repeat: no-repeat
- background-size: 100% auto
-
-@mixin gradient($gradient-clr1, $gradient-clr2)
- background: $gradient-clr1
- // Old browsers
- background: -moz-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
- // FF3.6+
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, $gradient-clr1), color-stop(100%, $gradient-clr2))
- // Chrome,Safari4+
- background: -webkit-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
- // Chrome10+,Safari5.1+
- background: -o-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
- // Opera 11.10+
- background: -ms-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%)
- // IE10+
- background: linear-gradient(to bottom, $gradient-clr1 0%, $gradient-clr2 100%)
- // W3C
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$gradient-clr1', endColorstr='$gradient-clr2',GradientType=0 )
- // IE6-8
-
-
-@mixin producersbg
- background-color: lighten($clr-turquoise, 68%)
- background-image: url("/assets/producers.svg")
- background-position: center 50px
- background-repeat: no-repeat
- background-size: 922px 763px
-
-@mixin hubsbg
- background-color: $brand-colour
- background-image: url("/assets/hubs-bg.jpg")
- background-position: center center
-
-@mixin groupsbg
- background-color: lighten($clr-brick, 56%)
- background-image: url("/assets/groups.svg")
- background-position: center 50px
- background-repeat: no-repeat
- background-size: 922px 922px
diff --git a/app/assets/stylesheets/darkswarm/mixins.scss b/app/assets/stylesheets/darkswarm/mixins.scss
new file mode 100644
index 0000000000..a473a014bf
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/mixins.scss
@@ -0,0 +1,253 @@
+// Note this mixin file is used in ADMIN and FRONTEND
+
+@import "branding";
+
+// Generic \\
+
+@mixin tiledPane {
+ background-image: url("/assets/tile-wide.png");
+ background-color: $brand-colour;
+ background-position: center center;
+
+ @include paneWhiteText;
+}
+
+@mixin panepadding {
+ padding-top: 100px;
+ padding-bottom: 100px;
+}
+
+@mixin paneWhiteText {
+ &, & * {
+ color: white;
+ }
+}
+
+@mixin sidepaddingSm {
+ padding-left: 10px;
+ padding-right: 10px;
+
+ @media all and (min-width: 768px) {
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+
+ @media all and (min-width: 1024px) {
+ padding-left: 50px;
+ padding-right: 50px;
+ }
+
+ @media all and (min-width: 1200px) {
+ padding-left: 100px;
+ padding-right: 100px;
+ }
+}
+
+@mixin sidepaddingBg {
+ padding-left: 20px;
+ padding-right: 20px;
+
+ @media all and (min-width: 768px) {
+ padding-left: 40px;
+ padding-right: 40px;
+ }
+
+ @media all and (min-width: 1024px) {
+ padding-left: 100px;
+ padding-right: 100px;
+ }
+
+ @media all and (min-width: 1200px) {
+ padding-left: 200px;
+ padding-right: 200px;
+ }
+}
+
+@mixin disabled {
+ color: $disabled-bright;
+}
+
+@mixin box-shadow($box-shadow) {
+ -moz-box-shadow: $box-shadow;
+ -webkit-box-shadow: $box-shadow;
+ box-shadow: $box-shadow;
+}
+
+@mixin elipse-shadow($elipse-shadow) {
+ content: "";
+ position: absolute;
+ z-index: -1;
+ -webkit-box-shadow: $elipse-shadow;
+ box-shadow: $elipse-shadow;
+ bottom: -12%;
+ left: 10%;
+ right: 10%;
+ width: 80%;
+ height: 10%;
+ -moz-border-radius: 100%;
+ border-radius: 100%;
+}
+
+@mixin border-radius($border-radius) {
+ -webkit-border-radius: $border-radius;
+ border-radius: $border-radius;
+}
+
+@mixin border-radius-mixed($border-radius-TL, $border-radius-TR, $border-radius-BR, $border-radius-BL) {
+ -webkit-border-radius: $border-radius-TL $border-radius-TR $border-radius-BR $border-radius-BL;
+ border-radius: $border-radius-TL $border-radius-TR $border-radius-BR $border-radius-BL;
+}
+
+@mixin transform-translate($translate) {
+ -ms-transform: $translate;
+ -webkit-transform: $translate;
+ transform: $translate;
+}
+
+@mixin transform-scale($scale) {
+ -moz-transform: $scale;
+ -webkit-transform: $scale;
+ -o-transform: $scale;
+ -ms-transform: $scale;
+ transform: $scale;
+}
+
+// Typography \\
+
+@mixin textpress {
+ text-shadow: 0 -1px 1px #111111, 0 1px 2px #222222;
+}
+
+@mixin textsoftpress {
+ text-shadow: 0 0 3px rgba(0, 0, 0, 0.35);
+}
+
+// TO USE icon-font
+// Assign to :before or :after element
+// Assign content: "string"
+
+@mixin icon-font {
+ font-family: "OFN";
+ display: inline-block;
+ font-weight: normal;
+ font-style: normal;
+ font-variant: normal;
+ text-transform: none;
+}
+
+// Background options \\
+
+@mixin darkbg {
+ background-color: $clr-brick;
+
+ &, & * {
+ color: white;
+ }
+
+ a {
+ color: $clr-brick-ultra-light;
+
+ &:hover {
+ text-decoration: none;
+ color: $clr-brick-light;
+ }
+ }
+}
+
+@mixin lightbg {
+ background-color: $clr-brick-light;
+
+ &, & * {
+ color: black;
+ }
+
+ a {
+ color: $clr-brick;
+
+ &:hover {
+ text-decoration: none;
+ color: $clr-brick-bright;
+ }
+ }
+}
+
+@mixin turqbg {
+ background-color: $clr-turquoise-light;
+
+ &, & * {
+ color: $clr-turquoise;
+ }
+
+ a {
+ color: $clr-turquoise;
+
+ &:hover {
+ text-decoration: none;
+ color: $clr-turquoise-bright;
+ }
+ }
+}
+
+@mixin fullbg {
+ background-position: center center;
+ background-repeat: no-repeat;
+ -webkit-background-size: cover;
+ -moz-background-size: cover;
+ -o-background-size: cover;
+ background-size: cover;
+}
+
+@mixin fullwidthbg {
+ background-position: center top;
+ background-repeat: no-repeat;
+ background-size: 100% auto;
+}
+
+@mixin gradient($gradient-clr1, $gradient-clr2) {
+ background: $gradient-clr1;
+
+ // Old browsers
+ background: -moz-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%);
+
+ // FF3.6+
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, $gradient-clr1), color-stop(100%, $gradient-clr2));
+
+ // Chrome,Safari4+
+ background: -webkit-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%);
+
+ // Chrome10+,Safari5.1+
+ background: -o-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%);
+
+ // Opera 11.10+
+ background: -ms-linear-gradient(top, $gradient-clr1 0%, $gradient-clr2 100%);
+
+ // IE10+
+ background: linear-gradient(to bottom, $gradient-clr1 0%, $gradient-clr2 100%);
+
+ // W3C
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$gradient-clr1', endColorstr='$gradient-clr2',GradientType=0 );
+
+ // IE6-8
+}
+
+@mixin producersbg {
+ background-color: lighten($clr-turquoise, 68%);
+ background-image: url("/assets/producers.svg");
+ background-position: center 50px;
+ background-repeat: no-repeat;
+ background-size: 922px 763px;
+}
+
+@mixin hubsbg {
+ background-color: $brand-colour;
+ background-image: url("/assets/hubs-bg.jpg");
+ background-position: center center;
+}
+
+@mixin groupsbg {
+ background-color: lighten($clr-brick, 56%);
+ background-image: url("/assets/groups.svg");
+ background-position: center 50px;
+ background-repeat: no-repeat;
+ background-size: 922px 922px;
+}
diff --git a/app/assets/stylesheets/darkswarm/modal-enterprises.css.sass b/app/assets/stylesheets/darkswarm/modal-enterprises.css.sass
deleted file mode 100644
index e4724a13f5..0000000000
--- a/app/assets/stylesheets/darkswarm/modal-enterprises.css.sass
+++ /dev/null
@@ -1,165 +0,0 @@
-@import branding
-@import mixins
-
-
-// Generic styles for use
-
-.modal-centered
- text-align: center
- p
- margin-bottom: 0
-
-.modal-header, p.modal-header
- text-align: center
- text-transform: uppercase
- font-size: 1rem
- font-weight: 400
- color: $disabled-dark
- border-bottom: 1px solid $light-grey
- margin-top: 0.75rem
- margin-bottom: 0.5rem
-
-// Enterprise promo image and text
-
-.highlight
- position: relative
-
-.highlight-top
- padding-top: 0.75rem
- padding-bottom: 0.75rem
- background-color: rgba(255,255,255,0.65)
- position: absolute
- bottom: 0
- width: 100%
- border: 0
- outline: 0
- @media only screen and (max-width: 640px)
- padding-top: 0.5rem
- padding-bottom: 0.35rem
-
- h3, p
- margin-top: 0
- margin-bottom: 0
- padding-bottom: 0
- line-height: 1
-
- h3 > i
- color: $clr-brick
-
- p
- line-height: 2.4
- @media all and (max-width: 640px)
- line-height: 1.4
-
- h3 a:hover span
- border-bottom: 1px solid $clr-brick-bright
-
- .is_producer
- &, & *
- color: $clr-turquoise
-
-
-// ABOUT Enterprise
-
-.about-container
- min-height: 20px
- margin-bottom: 0.5rem
- overflow-x: hidden
- border-bottom: 1px solid $light-grey
- @include box-shadow(0 2px 2px -2px $light-grey)
-
- .enterprise-logo, img
- float: left
- margin-right: 2rem
- margin-bottom: 0.5rem
- max-width: 180px
- max-height: 180px
-
-// CONTACT Enterprise
-
-.contact-container
- a:hover
- text-decoration: underline
-
-// FOLLOW Enterprise
-
-.follow-icons
- // text-align: center
- span
- display: inline-block
- margin: 0 0.25rem 0.75rem 0.25rem
- i
- font-size: 2rem
- a
- color: #999
- &:hover, &:active, &:focus
- color: #666
-
-
-// CALL TO ACTION - hub click throughs
-
-.cta-container
- background-color: #ececec
- padding-top: 0.75rem
-
- label
- text-transform: uppercase
- font-size: 0.875rem
- margin-bottom: 0.75rem
- 5rem
- color: $dark-grey
-
- label.right
- color: $disabled-dark
- span
- text-transform: capitalize
-
- .cta-hub
- margin-right: 2rem
- margin-top: 0rem
- margin-bottom: 0.75rem
- display: inline-block
-
- &.secondary
- color: $disabled-dark
-
- &.primary
- color: $clr-brick
-
- i.ofn-i_033-open-sign, i.ofn-i_032-closed-sign
- margin-right: 0.1rem
- font-size: 2rem
- padding: 0.15rem 0.25rem 0.35rem 0.25rem
- float: left
-
- .hub-name
- margin-top: 0.75rem
- margin-bottom: 0.2rem
- font-weight: 400
- display: inline-block
- border-bottom: 1px solid transparent
- .button-address
- margin-top: 0.5rem
- margin-bottom: 0.2rem
- margin-left: 0.1rem
- text-transform: uppercase
- font-weight: 300
- font-style: italic
- font-size: 0.75rem
- display: inline-block
- border-bottom: 1px solid transparent
- @media all and (max-width: 640px)
- display: none
-
- &:hover, &:focus, &:active
- &.secondary
- color: #666
- .hub-name, .button-address
- border-bottom: 1px solid #999
- &.primary
- color: $clr-brick-bright
- .hub-name, .button-address
- border-bottom: 1px solid $clr-brick-bright
-
-
-
diff --git a/app/assets/stylesheets/darkswarm/modal-enterprises.css.scss b/app/assets/stylesheets/darkswarm/modal-enterprises.css.scss
new file mode 100644
index 0000000000..7b37c46955
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/modal-enterprises.css.scss
@@ -0,0 +1,212 @@
+@import "branding";
+@import "mixins";
+
+// Generic styles for use
+
+.modal-centered {
+ text-align: center;
+
+ p {
+ margin-bottom: 0;
+ }
+}
+
+.modal-header, p.modal-header {
+ text-align: center;
+ text-transform: uppercase;
+ font-size: 1rem;
+ font-weight: 400;
+ color: $disabled-dark;
+ border-bottom: 1px solid $light-grey;
+ margin-top: 0.75rem;
+ margin-bottom: 0.5rem;
+}
+
+// Enterprise promo image and text
+
+.highlight {
+ position: relative;
+}
+
+.highlight-top {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+ background-color: rgba(255, 255, 255, 0.65);
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ border: 0;
+ outline: 0;
+
+ @media only screen and (max-width: 640px) {
+ padding-top: 0.5rem;
+ padding-bottom: 0.35rem;
+ }
+
+ h3, p {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ line-height: 1;
+ }
+
+ h3 > i {
+ color: $clr-brick;
+ }
+
+ p {
+ line-height: 2.4;
+
+ @media all and (max-width: 640px) {
+ line-height: 1.4;
+ }
+ }
+
+ h3 a:hover span {
+ border-bottom: 1px solid $clr-brick-bright;
+ }
+
+ .is_producer {
+ &, & * {
+ color: $clr-turquoise;
+ }
+ }
+}
+
+// ABOUT Enterprise
+
+.about-container {
+ min-height: 20px;
+ margin-bottom: 0.5rem;
+ overflow-x: hidden;
+ border-bottom: 1px solid $light-grey;
+
+ @include box-shadow(0 2px 2px -2px $light-grey);
+
+ .enterprise-logo, img {
+ float: left;
+ margin-right: 2rem;
+ margin-bottom: 0.5rem;
+ max-width: 180px;
+ max-height: 180px;
+ }
+}
+
+// CONTACT Enterprise
+
+.contact-container {
+ a:hover {
+ text-decoration: underline;
+ }
+}
+
+// FOLLOW Enterprise
+
+.follow-icons {
+ // text-align: center
+ span {
+ display: inline-block;
+ margin: 0 0.25rem 0.75rem 0.25rem;
+ }
+
+ i {
+ font-size: 2rem;
+ }
+
+ a {
+ color: #999;
+
+ &:hover, &:active, &:focus {
+ color: #666;
+ }
+ }
+}
+
+// CALL TO ACTION - hub click throughs
+
+.cta-container {
+ background-color: #ececec;
+ padding-top: 0.75rem;
+
+ label {
+ text-transform: uppercase;
+ font-size: 0.875rem;
+ margin-bottom: 0.75rem;
+
+ 5rem {}
+
+ color: $dark-grey;
+ }
+
+ label.right {
+ color: $disabled-dark;
+
+ span {
+ text-transform: capitalize;
+ }
+ }
+
+ .cta-hub {
+ margin-right: 2rem;
+ margin-top: 0rem;
+ margin-bottom: 0.75rem;
+ display: inline-block;
+
+ &.secondary {
+ color: $disabled-dark;
+ }
+
+ &.primary {
+ color: $clr-brick;
+ }
+
+ i.ofn-i_033-open-sign, i.ofn-i_032-closed-sign {
+ margin-right: 0.1rem;
+ font-size: 2rem;
+ padding: 0.15rem 0.25rem 0.35rem 0.25rem;
+ float: left;
+ }
+
+ .hub-name {
+ margin-top: 0.75rem;
+ margin-bottom: 0.2rem;
+ font-weight: 400;
+ display: inline-block;
+ border-bottom: 1px solid transparent;
+ }
+
+ .button-address {
+ margin-top: 0.5rem;
+ margin-bottom: 0.2rem;
+ margin-left: 0.1rem;
+ text-transform: uppercase;
+ font-weight: 300;
+ font-style: italic;
+ font-size: 0.75rem;
+ display: inline-block;
+ border-bottom: 1px solid transparent;
+
+ @media all and (max-width: 640px) {
+ display: none;
+ }
+ }
+
+ &:hover, &:focus, &:active {
+ &.secondary {
+ color: #666;
+
+ .hub-name, .button-address {
+ border-bottom: 1px solid #999;
+ }
+ }
+
+ &.primary {
+ color: $clr-brick-bright;
+
+ .hub-name, .button-address {
+ border-bottom: 1px solid $clr-brick-bright;
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/modal-login.css.sass b/app/assets/stylesheets/darkswarm/modal-login.css.sass
deleted file mode 100644
index 61108145bb..0000000000
--- a/app/assets/stylesheets/darkswarm/modal-login.css.sass
+++ /dev/null
@@ -1,13 +0,0 @@
-
-// Styling for login modal to style tabs
-.reveal-modal.login-modal
- border-bottom-color: #efefef
-
-.login-modal
- background: #efefef
- .tabs-content
- background: #fff
- padding-top: 10px
-
-
-
\ No newline at end of file
diff --git a/app/assets/stylesheets/darkswarm/modal-login.css.scss b/app/assets/stylesheets/darkswarm/modal-login.css.scss
new file mode 100644
index 0000000000..4b87a7d1d9
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/modal-login.css.scss
@@ -0,0 +1,13 @@
+// Styling for login modal to style tabs
+.reveal-modal.login-modal {
+ border-bottom-color: #efefef;
+}
+
+.login-modal {
+ background: #efefef;
+
+ .tabs-content {
+ background: #fff;
+ padding-top: 10px;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/modals.css.sass b/app/assets/stylesheets/darkswarm/modals.css.sass
deleted file mode 100644
index 5844a8b600..0000000000
--- a/app/assets/stylesheets/darkswarm/modals.css.sass
+++ /dev/null
@@ -1,54 +0,0 @@
-@import branding
-@import mixins
-
-dialog, .reveal-modal
- border: none
- outline: none
- padding: 30px 20px 0 20px
- border-bottom: 30px solid white
- overflow-y: scroll
- overflow-x: hidden
- min-height: 260px
- // Not working yet - want a nice gradient shadow when there is overflow - needs JS too
- // &:after
- // @include elipse-shadow(0 0 40px rgba(0, 0, 0, 0.8))
-
-
- // Reveal.js break point:
- // @media only screen and (max-width: 40.063em)
-
- // Small - when modal IS full screen
- @media only screen and (max-width: 640px)
- max-height: initial
- // This is needed to make the height not the height of whole content page
- min-height: 100%
- position: absolute !important
- top: 0
- left: 0
-
- // Medium and up - when modal IS NOT full screen
- @media only screen and (min-width: 641px)
- top: 10%
- max-height: 80%
-
-.reveal-modal-bg
- background-color: rgba(0,0,0,0.85)
- position: fixed
-
-dialog .close-reveal-modal, .reveal-modal .close-reveal-modal
- right: 0.25rem
- top: 0.25rem
- background-color: rgba(205,205,205,0.65)
- text-shadow: none
- font-size: 2rem
- padding: 0.45rem
- color: #666
- z-index: 9999999
- @include border-radius(999999rem)
- &:hover, &:active, &:focus
- background-color: rgba(205,205,205,1)
- color: #333
-
-// Prevent body from scrolling when a modal is open
-body.modal-open
- overflow: hidden
diff --git a/app/assets/stylesheets/darkswarm/modals.css.scss b/app/assets/stylesheets/darkswarm/modals.css.scss
new file mode 100644
index 0000000000..122d840f2a
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/modals.css.scss
@@ -0,0 +1,64 @@
+@import "branding";
+@import "mixins";
+
+dialog, .reveal-modal {
+ border: none;
+ outline: none;
+ padding: 30px 20px 0 20px;
+ border-bottom: 30px solid white;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ min-height: 260px;
+
+ // Not working yet - want a nice gradient shadow when there is overflow - needs JS too
+ // &:after
+ // @include elipse-shadow(0 0 40px rgba(0, 0, 0, 0.8))
+
+ // Reveal.js break point:
+ // @media only screen and (max-width: 40.063em)
+
+ // Small - when modal IS full screen
+ @media only screen and (max-width: 640px) {
+ max-height: initial;
+
+ // This is needed to make the height not the height of whole content page
+ min-height: 100%;
+ position: absolute !important;
+ top: 0;
+ left: 0;
+ }
+
+ // Medium and up - when modal IS NOT full screen
+ @media only screen and (min-width: 641px) {
+ top: 10%;
+ max-height: 80%;
+ }
+}
+
+.reveal-modal-bg {
+ background-color: rgba(0, 0, 0, 0.85);
+ position: fixed;
+}
+
+dialog .close-reveal-modal, .reveal-modal .close-reveal-modal {
+ right: 0.25rem;
+ top: 0.25rem;
+ background-color: rgba(205, 205, 205, 0.65);
+ text-shadow: none;
+ font-size: 2rem;
+ padding: 0.45rem;
+ color: #666;
+ z-index: 9999999;
+
+ @include border-radius(999999rem);
+
+ &:hover, &:active, &:focus {
+ background-color: rgba(205, 205, 205, 1);
+ color: #333;
+ }
+}
+
+// Prevent body from scrolling when a modal is open
+body.modal-open {
+ overflow: hidden;
+}
diff --git a/app/assets/stylesheets/darkswarm/overrides.css.sass b/app/assets/stylesheets/darkswarm/overrides.css.sass
deleted file mode 100644
index fcec6b455d..0000000000
--- a/app/assets/stylesheets/darkswarm/overrides.css.sass
+++ /dev/null
@@ -1,2 +0,0 @@
-.row
- max-width: 74em
diff --git a/app/assets/stylesheets/darkswarm/overrides.css.scss b/app/assets/stylesheets/darkswarm/overrides.css.scss
new file mode 100644
index 0000000000..ccad1b5d35
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/overrides.css.scss
@@ -0,0 +1,3 @@
+.row {
+ max-width: 74em;
+}
diff --git a/app/assets/stylesheets/darkswarm/page_alert.css.sass b/app/assets/stylesheets/darkswarm/page_alert.css.sass
deleted file mode 100644
index 7e66d35518..0000000000
--- a/app/assets/stylesheets/darkswarm/page_alert.css.sass
+++ /dev/null
@@ -1,58 +0,0 @@
-@import branding
-@import animations
-@import "compass/css3/transition"
-
-// Basic style \\
-.page-alert
- .alert-box
- height: 55px
- overflow: hidden
- border: 1px solid rgba($dark-grey, 0.35)
- border-left: none
- border-right: none
- background-color: #bbb
- background-image: url("/assets/tile-wide.png")
- background-position: center center
- padding: 12px 0 8px 0
- margin: 0
-
- h6
- @media all and (max-width: 480px)
- font-size: 10px
- line-height: 24px
-
- .alert-cta
- &, & *
- @include csstrans
- color: #333
- strong
- letter-spacing: 0.5px
- a:hover, a:active, a:focus
- &, & *
- text-decoration: none
- color: white
-
-
-// Show-hide animation \\
-.off-canvas-wrap .inner-wrap, .off-canvas-wrap .inner-wrap .fixed, nav.tab-bar
- @include transition(all, 1000ms, ease-in-out)
-
- &.move-down
- margin-top: 55px
- @include transition(all, 1000ms, ease-in-out)
-
-
-.off-canvas-wrap .inner-wrap .page-alert.fixed
- top: -55px
- z-index: 1
- // TODO: Compass to disable transition
- -moz-transition: none
- -webkit-transition: none
- -o-transition: color 0 ease-in
- transition: none
-
-.off-canvas-wrap.move-right .inner-wrap.move-down
- .page-alert
- top: -55px * 2
- .left-off-canvas-menu
- top: -55px
diff --git a/app/assets/stylesheets/darkswarm/page_alert.css.scss b/app/assets/stylesheets/darkswarm/page_alert.css.scss
new file mode 100644
index 0000000000..e7bdcd53a6
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/page_alert.css.scss
@@ -0,0 +1,77 @@
+@import "branding";
+@import "animations";
+@import "compass/css3/transition";
+
+// Basic style \\
+.page-alert {
+ .alert-box {
+ height: 55px;
+ overflow: hidden;
+ border: 1px solid rgba($dark-grey, 0.35);
+ border-left: none;
+ border-right: none;
+ background-color: #bbb;
+ background-image: url("/assets/tile-wide.png");
+ background-position: center center;
+ padding: 12px 0 8px 0;
+ margin: 0;
+
+ h6 {
+ @media all and (max-width: 480px) {
+ font-size: 10px;
+ line-height: 24px;
+ }
+ }
+
+ .alert-cta {
+ &, & * {
+ @include csstrans;
+
+ color: #333;
+ }
+
+ strong {
+ letter-spacing: 0.5px;
+ }
+
+ a:hover, a:active, a:focus {
+ &, & * {
+ text-decoration: none;
+ color: white;
+ }
+ }
+ }
+ }
+}
+
+// Show-hide animation \\
+.off-canvas-wrap .inner-wrap, .off-canvas-wrap .inner-wrap .fixed, nav.tab-bar {
+ @include transition(all, 1000ms, ease-in-out);
+
+ &.move-down {
+ margin-top: 55px;
+
+ @include transition(all, 1000ms, ease-in-out);
+ }
+}
+
+.off-canvas-wrap .inner-wrap .page-alert.fixed {
+ top: -55px;
+ z-index: 1;
+
+ // TODO: Compass to disable transition
+ -moz-transition: none;
+ -webkit-transition: none;
+ -o-transition: color 0 ease-in;
+ transition: none;
+}
+
+.off-canvas-wrap.move-right .inner-wrap.move-down {
+ .page-alert {
+ top: -55px * 2;
+ }
+
+ .left-off-canvas-menu {
+ top: -55px;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/producer_node.css.sass b/app/assets/stylesheets/darkswarm/producer_node.css.sass
deleted file mode 100644
index 24eb0467c2..0000000000
--- a/app/assets/stylesheets/darkswarm/producer_node.css.sass
+++ /dev/null
@@ -1,97 +0,0 @@
-@import branding
-@import mixins
-
-.producers
- .active_table .active_table_node
-
- // Header row
- @media all and (max-width: 640px)
- .skinny-head
- background-color: $clr-turquoise-light
- @include border-radius-mixed(0.5em, 0.5em, 0, 0)
- margin-top: -1rem
- margin-bottom: 1rem
- padding-top: 1rem
- padding-bottom: 1rem
- .follow-icons
- &, & *
- font-size: 1.5rem
-
-
- // Producer icons
- i.ofn-i_059-producer, i.ofn-i_060-producer-reversed
- font-size: 2rem
- display: inline-block
- margin-right: 0.25rem
- float: left
- color: $clr-turquoise
-
- a
- &:hover, &:active, &:focus
- color: $clr-turquoise-bright
- span
- text-decoration: underline
-
- &.is_distributor, &.is_distributor i.ofn-i_059-producer, &.is_distributor i.ofn-i_060-producer-reversed
- color: $clr-brick
- &:hover, &:active, &:focus
- color: $clr-brick-bright
-
- a.cta-hub
- &:hover, &:focus, &:active
- &.secondary
- color: #666
- .hub-name, .button-address
- border-bottom: 1px solid #999
- &.primary
- color: $clr-brick-bright
- .hub-name, .button-address
- border-bottom: 1px solid $clr-brick-bright
-
- p.word-wrap
- margin-bottom: 0
- &:last-child
- margin-bottom: 1rem
-
- .fat-taxons
- background-color: $clr-turquoise-light
-
- .fat-properties
- background-color: $clr-turquoise-ultra-light
- border: 1px solid $clr-turquoise-light
-
- .producer-name
- color: $clr-turquoise
-
- //Open row
- &.open
- .active_table_row
- border-left: 1px solid $clr-turquoise-bright
- border-right: 1px solid $clr-turquoise-bright
- background-color: rgba(206,239,228,0.4)
- .cta-container
- background: none
- .columns img
- padding: 1rem 0
- max-height: 160px
- width: auto
- &.left
- padding: 0.25rem 1rem 0.25rem 0
- &.right
- padding: 0.25rem 0.5rem 0.25rem 2rem
-
- .active_table_row:first-child
- border-top: 1px solid $clr-turquoise-bright
-
- .active_table_row:last-child
- border-bottom: 1px solid $clr-turquoise-bright
- cursor: auto
-
- //Closed row
- &.closed
- .active_table_row.closed
- border: 1px solid transparent
- @media all and (max-width: 640px)
- border-color: $clr-turquoise-light
- &:hover, &:active, &:focus
- border-color: $clr-turquoise
diff --git a/app/assets/stylesheets/darkswarm/producer_node.css.scss b/app/assets/stylesheets/darkswarm/producer_node.css.scss
new file mode 100644
index 0000000000..921d8df544
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/producer_node.css.scss
@@ -0,0 +1,145 @@
+@import "branding";
+@import "mixins";
+
+.producers {
+ .active_table .active_table_node {
+ // Header row
+ @media all and (max-width: 640px) {
+ .skinny-head {
+ background-color: $clr-turquoise-light;
+
+ @include border-radius-mixed(0.5em, 0.5em, 0, 0);
+
+ margin-top: -1rem;
+ margin-bottom: 1rem;
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ }
+
+ .follow-icons {
+ &, & * {
+ font-size: 1.5rem;
+ }
+ }
+ }
+
+ // Producer icons
+ i.ofn-i_059-producer, i.ofn-i_060-producer-reversed {
+ font-size: 2rem;
+ display: inline-block;
+ margin-right: 0.25rem;
+ float: left;
+ color: $clr-turquoise;
+ }
+
+ a {
+ &:hover, &:active, &:focus {
+ color: $clr-turquoise-bright;
+
+ span {
+ text-decoration: underline;
+ }
+ }
+
+ &.is_distributor, &.is_distributor i.ofn-i_059-producer, &.is_distributor i.ofn-i_060-producer-reversed {
+ color: $clr-brick;
+
+ &:hover, &:active, &:focus {
+ color: $clr-brick-bright;
+ }
+ }
+ }
+
+ a.cta-hub {
+ &:hover, &:focus, &:active {
+ &.secondary {
+ color: #666;
+
+ .hub-name, .button-address {
+ border-bottom: 1px solid #999;
+ }
+ }
+
+ &.primary {
+ color: $clr-brick-bright;
+
+ .hub-name, .button-address {
+ border-bottom: 1px solid $clr-brick-bright;
+ }
+ }
+ }
+ }
+
+ p.word-wrap {
+ margin-bottom: 0;
+
+ &:last-child {
+ margin-bottom: 1rem;
+ }
+ }
+
+ .fat-taxons {
+ background-color: $clr-turquoise-light;
+ }
+
+ .fat-properties {
+ background-color: $clr-turquoise-ultra-light;
+ border: 1px solid $clr-turquoise-light;
+ }
+
+ .producer-name {
+ color: $clr-turquoise;
+ }
+
+ //Open row
+ &.open {
+ .active_table_row {
+ border-left: 1px solid $clr-turquoise-bright;
+ border-right: 1px solid $clr-turquoise-bright;
+ background-color: rgba(206, 239, 228, 0.4);
+
+ .cta-container {
+ background: none;
+ }
+
+ .columns img {
+ padding: 1rem 0;
+ max-height: 160px;
+ width: auto;
+
+ &.left {
+ padding: 0.25rem 1rem 0.25rem 0;
+ }
+
+ &.right {
+ padding: 0.25rem 0.5rem 0.25rem 2rem;
+ }
+ }
+ }
+
+ .active_table_row:first-child {
+ border-top: 1px solid $clr-turquoise-bright;
+ }
+
+ .active_table_row:last-child {
+ border-bottom: 1px solid $clr-turquoise-bright;
+ cursor: auto;
+ }
+ }
+
+ //Closed row
+ &.closed {
+ .active_table_row.closed {
+ border: 1px solid transparent;
+
+ @media all and (max-width: 640px) {
+ border-color: $clr-turquoise-light;
+ }
+
+ &:hover, &:active, &:focus {
+ border-color: $clr-turquoise;
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/producers.css.sass b/app/assets/stylesheets/darkswarm/producers.css.sass
deleted file mode 100644
index caa31f224d..0000000000
--- a/app/assets/stylesheets/darkswarm/producers.css.sass
+++ /dev/null
@@ -1,14 +0,0 @@
-@import branding
-@import mixins
-
-.producers
- @include producersbg
- @include sidepaddingSm
- @include panepadding
- a
- color: $clr-turquoise
- &:hover, &:active, &:focus
- color: $clr-turquoise-bright
- a.button.primary
- &:hover, &:active, &:focus
- color: white
diff --git a/app/assets/stylesheets/darkswarm/producers.css.scss b/app/assets/stylesheets/darkswarm/producers.css.scss
new file mode 100644
index 0000000000..e1a8c7a21b
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/producers.css.scss
@@ -0,0 +1,24 @@
+@import "branding";
+@import "mixins";
+
+.producers {
+ @include producersbg;
+
+ @include sidepaddingSm;
+
+ @include panepadding;
+
+ a {
+ color: $clr-turquoise;
+
+ &:hover, &:active, &:focus {
+ color: $clr-turquoise-bright;
+ }
+ }
+
+ a.button.primary {
+ &:hover, &:active, &:focus {
+ color: white;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/product_table.css.sass b/app/assets/stylesheets/darkswarm/product_table.css.sass
deleted file mode 100644
index 9b0a7b4598..0000000000
--- a/app/assets/stylesheets/darkswarm/product_table.css.sass
+++ /dev/null
@@ -1,4 +0,0 @@
-.product_table
- .row
- border: 1px solid black
- padding: 8px inherit
diff --git a/app/assets/stylesheets/darkswarm/product_table.css.scss b/app/assets/stylesheets/darkswarm/product_table.css.scss
new file mode 100644
index 0000000000..1d98464d4d
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/product_table.css.scss
@@ -0,0 +1,6 @@
+.product_table {
+ .row {
+ border: 1px solid black;
+ padding: 8px inherit;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/registration.css.sass b/app/assets/stylesheets/darkswarm/registration.css.sass
deleted file mode 100644
index ba56701600..0000000000
--- a/app/assets/stylesheets/darkswarm/registration.css.sass
+++ /dev/null
@@ -1,161 +0,0 @@
-@import branding
-@import mixins
-
-#registration-modal
- header
- text-align: center
- @media all and (max-width: 64em)
- text-align: left
- .container
- background-color: #ffffff
-
- i
- font-size: 150%
-
- .field
- margin-bottom: 1em
-
- .chunky
- padding: 8px
- font-size: 1rem
- margin: 0
- width: 100%
-
- label.indent-checkbox
- display: block
- padding-left: 20px
- text-indent: -17px
- input
- margin: 0px
-
- label
- margin-bottom: 3px
-
- ol, ul, p
- font-size: 0.875rem
- ol, ul
- padding: 0
- margin: 0
- ol
- list-style-type: decimal
-
- .highlight-box
- background: white
- padding: 1rem 1.2rem
- @media all and (max-width: 64em)
- margin-top: 1rem
-
- #progress-bar
- margin-bottom: 15px
- .item
- font-size: 0.75rem
- padding: 10px 0px
- text-transform: uppercase
- text-align: center
- background-color: $clr-blue
- border: 2px solid $clr-blue
- color: #fff
- .item.active
- background-color: $disabled-light
- border: 2px solid $clr-blue
- color: $clr-blue
- font-weight: 700
- @include box-shadow(inset 0 0 1px 0 #fff)
-
-
- .image-select
- label
- font-size: 18px
- padding: 21px 0px
- #logo-select
- display: none
-
- #image-over
- font-size: 18px
- padding: 41px 0px
- border: 3px dashed #494949
- text-align: center
- font-weight: bold
- color: #494949
- &.nv-file-over
- background-color: #78cd91
-
- #or
- text-align: center
- font-weight: bold
- font-size: 18px
- padding: 21px 0px
- &.horizontal
- padding: 41px 0px
-
- #image-placeholder
- font-size: 18px
- font-weight: bold
- color: #373737
- background-color: #f1f1f1
- text-align: center
- border: 3px dashed #494949
- margin-left: auto
- margin-right: auto
- .spinner
- width: 100px
- &.logo
- .message
- padding-top: 6em
- .loading
- padding-top: 4em
- width: 306px
- height: 306px
- &.promo
- .message
- padding-top: 4em
- .loading
- padding-top: 1em
- width: 726px
- height: 166px
-
-
-#registration-type
- #enterprise-types
- a.btnpanel
- display: block
- padding: 1rem
- margin-bottom: 1rem
- background-color: #efefef
- color: black
- text-align: center
- border: 1px solid transparent
- i
- font-size: 3rem
- h4
- margin-top: 1rem
-
- &:hover
- background-color: #fff
-
- producer-panel:hover
- border: 1px solid $clr-turquoise
- &, & *
- color: $clr-turquoise
-
- hub-panel:hover, both-panel:hover
- border: 1px solid $clr-brick
- &, & *
- color: $clr-brick
-
- &.selected
- &, & *
- color: #fff
- hub-panel, both-panel
- background-color: $clr-brick-bright
- &:hover
- &, & *
- color: white
- producer-panel
- background-color: $clr-turquoise-bright
- &:hover
- &, & *
- color: white
- p
- clear: both
- font-size: 0.875rem
diff --git a/app/assets/stylesheets/darkswarm/registration.css.scss b/app/assets/stylesheets/darkswarm/registration.css.scss
new file mode 100644
index 0000000000..1f80038f18
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/registration.css.scss
@@ -0,0 +1,239 @@
+@import "branding";
+@import "mixins";
+
+#registration-modal {
+ header {
+ text-align: center;
+
+ @media all and (max-width: 64em) {
+ text-align: left;
+ }
+ }
+
+ .container {
+ background-color: #ffffff;
+ }
+
+ i {
+ font-size: 150%;
+ }
+
+ .field {
+ margin-bottom: 1em;
+ }
+
+ .chunky {
+ padding: 8px;
+ font-size: 1rem;
+ margin: 0;
+ width: 100%;
+ }
+
+ label.indent-checkbox {
+ display: block;
+ padding-left: 20px;
+ text-indent: -17px;
+
+ input {
+ margin: 0px;
+ }
+ }
+
+ label {
+ margin-bottom: 3px;
+ }
+
+ ol, ul, p {
+ font-size: 0.875rem;
+ }
+
+ ol, ul {
+ padding: 0;
+ margin: 0;
+ }
+
+ ol {
+ list-style-type: decimal;
+ }
+
+ .highlight-box {
+ background: white;
+ padding: 1rem 1.2rem;
+
+ @media all and (max-width: 64em) {
+ margin-top: 1rem;
+ }
+ }
+
+ #progress-bar {
+ margin-bottom: 15px;
+
+ .item {
+ font-size: 0.75rem;
+ padding: 10px 0px;
+ text-transform: uppercase;
+ text-align: center;
+ background-color: $clr-blue;
+ border: 2px solid $clr-blue;
+ color: #fff;
+ }
+
+ .item.active {
+ background-color: $disabled-light;
+ border: 2px solid $clr-blue;
+ color: $clr-blue;
+ font-weight: 700;
+
+ @include box-shadow(inset 0 0 1px 0 #fff);
+ }
+ }
+
+ .image-select {
+ label {
+ font-size: 18px;
+ padding: 21px 0px;
+ }
+
+ #logo-select {
+ display: none;
+ }
+ }
+
+ #image-over {
+ font-size: 18px;
+ padding: 41px 0px;
+ border: 3px dashed #494949;
+ text-align: center;
+ font-weight: bold;
+ color: #494949;
+
+ &.nv-file-over {
+ background-color: #78cd91;
+ }
+ }
+
+ #or {
+ text-align: center;
+ font-weight: bold;
+ font-size: 18px;
+ padding: 21px 0px;
+
+ &.horizontal {
+ padding: 41px 0px;
+ }
+ }
+
+ #image-placeholder {
+ font-size: 18px;
+ font-weight: bold;
+ color: #373737;
+ background-color: #f1f1f1;
+ text-align: center;
+ border: 3px dashed #494949;
+ margin-left: auto;
+ margin-right: auto;
+
+ .spinner {
+ width: 100px;
+ }
+
+ &.logo {
+ .message {
+ padding-top: 6em;
+ }
+
+ .loading {
+ padding-top: 4em;
+ }
+
+ width: 306px;
+ height: 306px;
+ }
+
+ &.promo {
+ .message {
+ padding-top: 4em;
+ }
+
+ .loading {
+ padding-top: 1em;
+ }
+
+ width: 726px;
+ height: 166px;
+ }
+ }
+}
+
+#registration-type {
+ #enterprise-types {
+ a.btnpanel {
+ display: block;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ background-color: #efefef;
+ color: black;
+ text-align: center;
+ border: 1px solid transparent;
+
+ i {
+ font-size: 3rem;
+ }
+
+ h4 {
+ margin-top: 1rem;
+ }
+
+ &:hover {
+ background-color: #fff;
+ }
+
+ producer-panel:hover {
+ border: 1px solid $clr-turquoise;
+
+ &, & * {
+ color: $clr-turquoise;
+ }
+ }
+
+ hub-panel:hover, both-panel:hover {
+ border: 1px solid $clr-brick;
+
+ &, & * {
+ color: $clr-brick;
+ }
+ }
+
+ &.selected {
+ &, & * {
+ color: #fff;
+ }
+
+ hub-panel, both-panel {
+ background-color: $clr-brick-bright;
+
+ &:hover {
+ &, & * {
+ color: white;
+ }
+ }
+ }
+
+ producer-panel {
+ background-color: $clr-turquoise-bright;
+
+ &:hover {
+ &, & * {
+ color: white;
+ }
+ }
+ }
+ }
+
+ p {
+ clear: both;
+ font-size: 0.875rem;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass
deleted file mode 100644
index 5cfcef46b8..0000000000
--- a/app/assets/stylesheets/darkswarm/shop.css.sass
+++ /dev/null
@@ -1,111 +0,0 @@
-@import mixins
-@import animations
-@import variables
-@import branding
-@import big-input
-
-// Shop partials
-@import shop-inputs
-@import shop-navigation
-@import shop-product-rows
-@import shop-taxon-flag
-@import shop-popovers
-
-.darkswarm
- products
- display: block
- padding-top: 20px
- @media all and (max-width: 768px)
- input.button.right
- float: left
-
- @media all and (max-width: 480px)
- .add_to_cart
- margin-top: 2rem
-
- form
- input.small.button.primary.right.add_to_cart
- &.dirty
- padding-left: 3.2rem
- i.cart-spinner
- position: absolute
- top: 14px
- right: 146px
- color: white
- font-size: 1.2em
- // Necessary to be below Z index of cart popover:
- z-index: 98
- -webkit-animation: spin 2s infinite linear
- animation: spin 2s infinite linear
-
- product
- @include csstrans
- border-bottom: 1px solid #e5e5e5
- border-top: 1px solid #e5e5e5
- padding-bottom: 1px
- margin-bottom: 20px !important
- position: relative
- display: block
- color: $med-drk-grey
-
- &:hover, &:focus, &:active
- border-bottom: 1px solid $clr-brick-med-bright
- border-top: 1px solid $clr-brick-med-bright
-
- // BULK
- .bulk-buy
- font-size: 0.875rem
- @media all and (max-width: 768px)
- font-size: 0.75rem
-
- .bulk-buy, .bulk-buy i
- color: #888
-
- .inline
- display: inline
-
- .spinner
- width: 100px
- margin-bottom: 20px
-
- // ICONS
- i
- font-size: 0.75em
- padding-right: 0.9375rem
- @media all and (max-width: 640px)
- padding-right: 0.25rem
-
- i.ofn-i_056-bulk
- font-size: 1rem
- padding-right: 0rem
-
- i.ofn-i_036-producers
- padding-left: 0.2rem
- padding-right: 0rem
- font-size: 0.8rem
-
- .alert-box.shopfront-message
- border: 2px solid $clr-turquoise
- border-radius: 5px
- background-color: $clr-turquoise-light
- color: $clr-turquoise
- a
- color: #0096ad
- &:hover, &:focus, &:active
- text-decoration: none
- color: #4aadbd
-
-
- .shopfront_closed_message, .shopfront_hidden_message
- padding: 15px
- border-radius: 5px
-
- .shopfront_closed_message
- border: 2px solid #eb4c46
-
- .shopfront_closed_message
- margin: 2em 0em
-
- .shopfront_hidden_message
- border: 2px solid #db4
- margin: 2em 0em
diff --git a/app/assets/stylesheets/darkswarm/shop.css.scss b/app/assets/stylesheets/darkswarm/shop.css.scss
new file mode 100644
index 0000000000..33ccbb31e7
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/shop.css.scss
@@ -0,0 +1,146 @@
+@import "mixins";
+@import "animations";
+@import "variables";
+@import "branding";
+@import "big-input";
+
+// Shop partials
+@import "shop-inputs";
+@import "shop-navigation";
+@import "shop-product-rows";
+@import "shop-taxon-flag";
+@import "shop-popovers";
+
+.darkswarm {
+ products {
+ display: block;
+ padding-top: 20px;
+
+ @media all and (max-width: 768px) {
+ input.button.right {
+ float: left;
+ }
+ }
+
+ @media all and (max-width: 480px) {
+ .add_to_cart {
+ margin-top: 2rem;
+ }
+ }
+
+ form {
+ input.small.button.primary.right.add_to_cart {
+ &.dirty {
+ padding-left: 3.2rem;
+ }
+ }
+
+ i.cart-spinner {
+ position: absolute;
+ top: 14px;
+ right: 146px;
+ color: white;
+ font-size: 1.2em;
+
+ // Necessary to be below Z index of cart popover:
+ z-index: 98;
+ -webkit-animation: spin 2s infinite linear;
+ animation: spin 2s infinite linear;
+ }
+ }
+
+ product {
+ @include csstrans;
+
+ border-bottom: 1px solid #e5e5e5;
+ border-top: 1px solid #e5e5e5;
+ padding-bottom: 1px;
+ margin-bottom: 20px !important;
+ position: relative;
+ display: block;
+ color: $med-drk-grey;
+
+ &:hover, &:focus, &:active {
+ border-bottom: 1px solid $clr-brick-med-bright;
+ border-top: 1px solid $clr-brick-med-bright;
+ }
+
+ // BULK
+ .bulk-buy {
+ font-size: 0.875rem;
+
+ @media all and (max-width: 768px) {
+ font-size: 0.75rem;
+ }
+ }
+
+ .bulk-buy, .bulk-buy i {
+ color: #888;
+ }
+
+ .inline {
+ display: inline;
+ }
+
+ .spinner {
+ width: 100px;
+ margin-bottom: 20px;
+ }
+
+ // ICONS
+ i {
+ font-size: 0.75em;
+ padding-right: 0.9375rem;
+
+ @media all and (max-width: 640px) {
+ padding-right: 0.25rem;
+ }
+ }
+
+ i.ofn-i_056-bulk {
+ font-size: 1rem;
+ padding-right: 0rem;
+ }
+
+ i.ofn-i_036-producers {
+ padding-left: 0.2rem;
+ padding-right: 0rem;
+ font-size: 0.8rem;
+ }
+ }
+ }
+
+ .alert-box.shopfront-message {
+ border: 2px solid $clr-turquoise;
+ border-radius: 5px;
+ background-color: $clr-turquoise-light;
+ color: $clr-turquoise;
+
+ a {
+ color: #0096ad;
+
+ &:hover, &:focus, &:active {
+ text-decoration: none;
+ color: #4aadbd;
+ }
+ }
+ }
+
+ .shopfront_closed_message, .shopfront_hidden_message {
+ padding: 15px;
+ border-radius: 5px;
+ }
+
+ .shopfront_closed_message {
+ border: 2px solid #eb4c46;
+ }
+
+ .shopfront_closed_message {
+ margin: 2em 0em;
+ }
+
+ .shopfront_hidden_message {
+ border: 2px solid #db4;
+ margin: 2em 0em;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass
deleted file mode 100644
index 6fd48e0970..0000000000
--- a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass
+++ /dev/null
@@ -1,70 +0,0 @@
-@import mixins
-@import branding
-@import "compass/css3/user-interface"
-
-.cart
- @include user-select(none)
- .cart-span, .cart-span a
- display: inline-block
- .cart-span
- float: left
- .joyride-tip-guide
- display: block
- right: 10px
- top: 55px
- width: 480px
-
- @media screen and (min-width: 641px)
- overflow-y: auto
- max-height: calc(95vh - 55px)
-
- @media screen and (max-width: 640px)
- width: 96%
-
- .joyride-nub
- right: 22px !important
- left: auto
-
- table
- width: 100%
- border: none
- border-spacing: 0px
- margin-bottom: 5px
-
- tr.total-cart
- color: #fff
- background-color: #424242
- td
- color: #fff
- tr.product-cart
- background-color: #333333
- border-top: 1px solid #424242
- td
- padding: 4px 12px
- color: #fff
- .buttons
- margin-bottom: 0.1em
- .button
- height: auto
- top: 0px
-
-// Shopping cart
-#cart-detail
- .cart-item-delete
- a.delete
- font-size: 1.125em
-
-.item-thumb-image
- display: none
- @media screen and (min-width: 640px)
- display: inline-block
- float: left
- padding-right: 0.5em
- width: 36px
- height: 36px
-
-
-
-#edit-cart
- button, .button
- margin: 0
diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss
new file mode 100644
index 0000000000..25ed0ba930
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss
@@ -0,0 +1,98 @@
+@import "mixins";
+@import "branding";
+@import "compass/css3/user-interface";
+
+.cart {
+ @include user-select(none);
+
+ .cart-span, .cart-span a {
+ display: inline-block;
+ }
+
+ .cart-span {
+ float: left;
+ }
+
+ .joyride-tip-guide {
+ display: block;
+ right: 10px;
+ top: 55px;
+ width: 480px;
+
+ @media screen and (min-width: 641px) {
+ overflow-y: auto;
+ max-height: calc(95vh - 55px);
+ }
+
+ @media screen and (max-width: 640px) {
+ width: 96%;
+ }
+
+ .joyride-nub {
+ right: 22px !important;
+ left: auto;
+ }
+
+ table {
+ width: 100%;
+ border: none;
+ border-spacing: 0px;
+ margin-bottom: 5px;
+
+ tr.total-cart {
+ color: #fff;
+ background-color: #424242;
+
+ td {
+ color: #fff;
+ }
+ }
+
+ tr.product-cart {
+ background-color: #333333;
+ border-top: 1px solid #424242;
+
+ td {
+ padding: 4px 12px;
+ color: #fff;
+ }
+ }
+ }
+
+ .buttons {
+ margin-bottom: 0.1em;
+
+ .button {
+ height: auto;
+ top: 0px;
+ }
+ }
+ }
+}
+
+// Shopping cart
+#cart-detail {
+ .cart-item-delete {
+ a.delete {
+ font-size: 1.125em;
+ }
+ }
+}
+
+.item-thumb-image {
+ display: none;
+
+ @media screen and (min-width: 640px) {
+ display: inline-block;
+ float: left;
+ padding-right: 0.5em;
+ width: 36px;
+ height: 36px;
+ }
+}
+
+#edit-cart {
+ button, .button {
+ margin: 0;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/sidebar.css.sass b/app/assets/stylesheets/darkswarm/sidebar.css.sass
deleted file mode 100644
index 4addd035dc..0000000000
--- a/app/assets/stylesheets/darkswarm/sidebar.css.sass
+++ /dev/null
@@ -1,31 +0,0 @@
-// OMG
-// We can't import foundation components?
-// See https://github.com/zurb/foundation/issues/3855#issuecomment-30372252
-
-@import "variables"
-@import "components/global"
-@import "components/buttons"
-@import "components/panels"
-
-
-#sidebar
- margin-top: 1.875em
- $bg: #222
- $padding: emCalc(20)
- $adjust: true
- $adjust: true
- @include panel($bg, $padding, $adjust)
- .content
- background: white
-
- .tabs dd a
- padding: 0.5em 1em
-
- #account
- dl
- @include clearfix
- dt, dd
- display: inline-block
-
- p > strong
- display: block
diff --git a/app/assets/stylesheets/darkswarm/sidebar.css.scss b/app/assets/stylesheets/darkswarm/sidebar.css.scss
new file mode 100644
index 0000000000..18718062da
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/sidebar.css.scss
@@ -0,0 +1,41 @@
+// OMG
+// We can't import foundation components?
+// See https://github.com/zurb/foundation/issues/3855#issuecomment-30372252
+
+@import "variables";
+@import "components/global";
+@import "components/buttons";
+@import "components/panels";
+
+#sidebar {
+ margin-top: 1.875em;
+
+ $bg: #222;
+ $padding: emCalc(20);
+ $adjust: true;
+ $adjust: true;
+
+ @include panel($bg, $padding, $adjust);
+
+ .content {
+ background: white;
+ }
+
+ .tabs dd a {
+ padding: 0.5em 1em;
+ }
+
+ #account {
+ dl {
+ @include clearfix;
+ }
+
+ dt, dd {
+ display: inline-block;
+ }
+
+ p > strong {
+ display: block;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/signup.css.sass b/app/assets/stylesheets/darkswarm/signup.css.sass
deleted file mode 100644
index 12c01d0325..0000000000
--- a/app/assets/stylesheets/darkswarm/signup.css.sass
+++ /dev/null
@@ -1,119 +0,0 @@
-@import branding
-@import mixins
-@import typography
-@import animations
-@import variables
-
-
-#producer-signup.pane, #shops-signup.pane
- @include tiledPane
-
- h2
- margin-bottom: 2rem
- font-size: 4.4rem
- font-weight: 300
-
-#producer-details.pane, #hub-details.pane, .groups-details.pane
- background-color: lighten($ofn-grey, 44%)
-
-
-#producer-case-studies, #shops-case-studies
- @include hubsbg
- padding-top: 100px
- padding-bottom: 100px
- -webkit-filter: brightness(1.1)
- filter: brightness(1.1)
- h2
- color: $brand-colour
- font-size: 3rem
- .case-study
- background-color: rgba(255, 255, 255, 0.5)
- padding: 1rem
- margin-top: 2rem
- text-align: center
- .case-study-img
- background-color: white
- margin-bottom: 1rem
- @media all and (min-width: 768px)
- float: right
- margin-left: 2rem
- @media all and (min-width: 640px)
- text-align: left
- h4, a
- color: $brand-colour
- a
- &, & *
- @include csstrans
- opacity: 1
- &:hover, &:focus, &:active
- &, & *
- opacity: 0.75
-
-
-// Signup tables \\
-table.signup-table
- width: 100%
- border: 0
-
-table.signup-table.hubs-table, table.signup-table.producers-table
- tr
- td
- background-color: white
- border-bottom: 1px solid rgba($ofn-grey, 0.3)
- td:nth-child(2)
- background-color: lighten($ofn-grey, 46%)
- td:nth-child(3)
- background-color: lighten($ofn-grey, 41%)
- td:last-child
- &, & i
- color: $brand-colour
- border-bottom: 1px solid rgba($brand-colour, 0.3)
- background-color: lighten($brand-colour, 48%)
- thead
- background-color: transparent
- tr
- td
- border-bottom: 1px solid transparent
- td:nth-child(1)
- background-color: transparent
- td:nth-child(2)
- background: lighten($ofn-grey, 44%)
- td:nth-child(3)
- background: lighten($ofn-grey, 38%)
- td:last-child
- &, & *
- color: white
- background: $brand-colour
- h5
- text-transform: uppercase
- color: $ofn-grey
- font-weight: 400
- font-size: 0.875rem
- margin-bottom: 0.25em
-
- tfoot
- background-color: transparent
- tr
- td
- border-bottom: 1px solid transparent
- td:nth-child(1)
- background-color: transparent
- td:nth-child(2)
- background: lighten($ofn-grey, 44%)
- td:nth-child(3)
- background: lighten($ofn-grey, 38%)
- td:last-child
- &, & *
- color: white
- background: $brand-colour
- h2
- .text-small
- text-transform: uppercase
- display: inline-block
- font-weight: 400
- line-height: 1.5
- @include headingFont
-
-// Detail \\
-.enterprise-type-flowchart
- float: right
diff --git a/app/assets/stylesheets/darkswarm/signup.css.scss b/app/assets/stylesheets/darkswarm/signup.css.scss
new file mode 100644
index 0000000000..206d7d6656
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/signup.css.scss
@@ -0,0 +1,188 @@
+@import "branding";
+@import "mixins";
+@import "typography";
+@import "animations";
+@import "variables";
+
+#producer-signup.pane, #shops-signup.pane {
+ @include tiledPane;
+
+ h2 {
+ margin-bottom: 2rem;
+ font-size: 4.4rem;
+ font-weight: 300;
+ }
+}
+
+#producer-details.pane, #hub-details.pane, .groups-details.pane {
+ background-color: lighten($ofn-grey, 44%);
+}
+
+#producer-case-studies, #shops-case-studies {
+ @include hubsbg;
+
+ padding-top: 100px;
+ padding-bottom: 100px;
+ -webkit-filter: brightness(1.1);
+ filter: brightness(1.1);
+
+ h2 {
+ color: $brand-colour;
+ font-size: 3rem;
+ }
+
+ .case-study {
+ background-color: rgba(255, 255, 255, 0.5);
+ padding: 1rem;
+ margin-top: 2rem;
+ text-align: center;
+
+ .case-study-img {
+ background-color: white;
+ margin-bottom: 1rem;
+
+ @media all and (min-width: 768px) {
+ float: right;
+ margin-left: 2rem;
+ }
+ }
+
+ @media all and (min-width: 640px) {
+ text-align: left;
+ }
+
+ h4, a {
+ color: $brand-colour;
+ }
+
+ a {
+ &, & * {
+ @include csstrans;
+
+ opacity: 1;
+ }
+
+ &:hover, &:focus, &:active {
+ &, & * {
+ opacity: 0.75;
+ }
+ }
+ }
+ }
+}
+
+// Signup tables \\
+table.signup-table {
+ width: 100%;
+ border: 0;
+}
+
+table.signup-table.hubs-table, table.signup-table.producers-table {
+ tr {
+ td {
+ background-color: white;
+ border-bottom: 1px solid rgba($ofn-grey, 0.3);
+ }
+
+ td:nth-child(2) {
+ background-color: lighten($ofn-grey, 46%);
+ }
+
+ td:nth-child(3) {
+ background-color: lighten($ofn-grey, 41%);
+ }
+
+ td:last-child {
+ &, & i {
+ color: $brand-colour;
+ }
+
+ border-bottom: 1px solid rgba($brand-colour, 0.3);
+ background-color: lighten($brand-colour, 48%);
+ }
+ }
+
+ thead {
+ background-color: transparent;
+
+ tr {
+ td {
+ border-bottom: 1px solid transparent;
+ }
+
+ td:nth-child(1) {
+ background-color: transparent;
+ }
+
+ td:nth-child(2) {
+ background: lighten($ofn-grey, 44%);
+ }
+
+ td:nth-child(3) {
+ background: lighten($ofn-grey, 38%);
+ }
+
+ td:last-child {
+ &, & * {
+ color: white;
+ }
+
+ background: $brand-colour;
+ }
+ }
+
+ h5 {
+ text-transform: uppercase;
+ color: $ofn-grey;
+ font-weight: 400;
+ font-size: 0.875rem;
+ margin-bottom: 0.25em;
+ }
+ }
+
+ tfoot {
+ background-color: transparent;
+
+ tr {
+ td {
+ border-bottom: 1px solid transparent;
+ }
+
+ td:nth-child(1) {
+ background-color: transparent;
+ }
+
+ td:nth-child(2) {
+ background: lighten($ofn-grey, 44%);
+ }
+
+ td:nth-child(3) {
+ background: lighten($ofn-grey, 38%);
+ }
+
+ td:last-child {
+ &, & * {
+ color: white;
+ }
+
+ background: $brand-colour;
+ }
+ }
+
+ h2 {
+ .text-small {
+ text-transform: uppercase;
+ display: inline-block;
+ font-weight: 400;
+ line-height: 1.5;
+
+ @include headingFont;
+ }
+ }
+ }
+}
+
+// Detail \\
+.enterprise-type-flowchart {
+ float: right;
+}
diff --git a/app/assets/stylesheets/darkswarm/tables.css.sass b/app/assets/stylesheets/darkswarm/tables.css.sass
deleted file mode 100644
index 885eec815a..0000000000
--- a/app/assets/stylesheets/darkswarm/tables.css.sass
+++ /dev/null
@@ -1,7 +0,0 @@
-table
- thead tr, tbody tr
- th, td
- box-sizing: border-box
- padding-left: 12px
- padding-right: 12px
- overflow: hidden
diff --git a/app/assets/stylesheets/darkswarm/tables.css.scss b/app/assets/stylesheets/darkswarm/tables.css.scss
new file mode 100644
index 0000000000..b2632d52f1
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/tables.css.scss
@@ -0,0 +1,10 @@
+table {
+ thead tr, tbody tr {
+ th, td {
+ box-sizing: border-box;
+ padding-left: 12px;
+ padding-right: 12px;
+ overflow: hidden;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/tabs.css.sass b/app/assets/stylesheets/darkswarm/tabs.css.sass
deleted file mode 100644
index 12134a19e1..0000000000
--- a/app/assets/stylesheets/darkswarm/tabs.css.sass
+++ /dev/null
@@ -1,110 +0,0 @@
-@import typography
-@import mixins
-@import branding
-
-// Foundation overrides
-#tabs .tabs-content > .content p
- max-width: 100% !important
-
-.tabs-content > .content
- padding-top: 0 !important
-
-// Tabs styling
-
-#tabs
- background: url("/assets/gray_jean.png") top left repeat
- @include box-shadow(inset 0 2px 3px 0 rgba(0,0,0,0.15))
- display: block
- color: $dark-grey
- .header
- text-align: center
- text-transform: uppercase
- color: $dark-grey
- border-bottom: 1px solid $disabled-dark
- margin-top: 0.75rem
- margin-bottom: 0.75rem
- padding-bottom: 0.25rem
- font-size: 0.875rem
-
- .panel
- border-color: $clr-brick-bright
- background-color: rgba(255, 255, 255, 0)
-
- dl dd
-
- text-align: center
- @media all and (max-width: 640px)
- text-align: left
-
- a
- @include headingFont
- background: transparent
- text-transform: uppercase
- line-height: 1
- font-size: 0.875em
- text-shadow: 0 -1px 1px #ffffff
- padding: 1em
- border: none
- &:hover, &:focus, &:active
- color: $clr-brick-bright
- &, &:hover
- background: none
-
- @media all and (max-width: 640px)
- padding: 0.35em 0 0.65em 0
- text-shadow: none
-
- // inactive nav link
- dl
- dd
- border-top: 4px solid transparent
-
- a:after
- padding-left: 8px
- content: "\e633"
- visibility: hidden
- @include icon-font
- @media all and (max-width: 640px)
- content: "\e633"
- dd:hover
- a:after
- visibility: visible
-
- // active nav link
-
- dl
- dd.active
- border-top: 4px solid $clr-brick
- @media all and (max-width: 640px)
- border-top: 4px solid transparent
- background-color: $clr-brick
- a
- color: $clr-brick
- @media all and (max-width: 640px)
- color: white
- a:after
- content: "\e634"
- visibility: visible
- @include icon-font
- @media all and (max-width: 640px)
- content: "\e633"
-
- // content revealed in accordion
-
- .tabs-content
- margin-bottom: 0
- & > .content
- background: none
- border: none
- img
- margin: 0px 0px 0px 40px
- p
- max-width: 555px
- @media all and (max-width: 768px)
- height: auto !important
- ul
- list-style-type: none
- padding-left: none
- .panel
- padding-bottom: 1.25em
-
diff --git a/app/assets/stylesheets/darkswarm/tabs.css.scss b/app/assets/stylesheets/darkswarm/tabs.css.scss
new file mode 100644
index 0000000000..55b55f1189
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/tabs.css.scss
@@ -0,0 +1,161 @@
+@import "typography";
+@import "mixins";
+@import "branding";
+
+// Foundation overrides
+#tabs .tabs-content > .content p {
+ max-width: 100% !important;
+}
+
+.tabs-content > .content {
+ padding-top: 0 !important;
+}
+
+// Tabs styling
+
+#tabs {
+ background: url("/assets/gray_jean.png") top left repeat;
+
+ @include box-shadow(inset 0 2px 3px 0 rgba(0, 0, 0, 0.15));
+
+ display: block;
+ color: $dark-grey;
+
+ .header {
+ text-align: center;
+ text-transform: uppercase;
+ color: $dark-grey;
+ border-bottom: 1px solid $disabled-dark;
+ margin-top: 0.75rem;
+ margin-bottom: 0.75rem;
+ padding-bottom: 0.25rem;
+ font-size: 0.875rem;
+ }
+
+ .panel {
+ border-color: $clr-brick-bright;
+ background-color: rgba(255, 255, 255, 0);
+ }
+
+ dl dd {
+ text-align: center;
+
+ @media all and (max-width: 640px) {
+ text-align: left;
+ }
+
+ a {
+ @include headingFont;
+
+ background: transparent;
+ text-transform: uppercase;
+ line-height: 1;
+ font-size: 0.875em;
+ text-shadow: 0 -1px 1px #ffffff;
+ padding: 1em;
+ border: none;
+
+ &:hover, &:focus, &:active {
+ color: $clr-brick-bright;
+ }
+
+ &, &:hover {
+ background: none;
+ }
+
+ @media all and (max-width: 640px) {
+ padding: 0.35em 0 0.65em 0;
+ text-shadow: none;
+ }
+ }
+ }
+
+ // inactive nav link
+ dl {
+ dd {
+ border-top: 4px solid transparent;
+
+ a:after {
+ padding-left: 8px;
+ content: "";
+ visibility: hidden;
+
+ @include icon-font;
+
+ @media all and (max-width: 640px) {
+ content: "";
+ }
+ }
+ }
+
+ dd:hover {
+ a:after {
+ visibility: visible;
+ }
+ }
+ }
+
+ // active nav link
+
+ dl {
+ dd.active {
+ border-top: 4px solid $clr-brick;
+
+ @media all and (max-width: 640px) {
+ border-top: 4px solid transparent;
+ background-color: $clr-brick;
+ }
+
+ a {
+ color: $clr-brick;
+
+ @media all and (max-width: 640px) {
+ color: white;
+ }
+ }
+
+ a:after {
+ content: "";
+ visibility: visible;
+
+ @include icon-font;
+
+ @media all and (max-width: 640px) {
+ content: "";
+ }
+ }
+ }
+ }
+
+ // content revealed in accordion
+
+ .tabs-content {
+ margin-bottom: 0;
+
+ & > .content {
+ background: none;
+ border: none;
+
+ img {
+ margin: 0px 0px 0px 40px;
+ }
+
+ p {
+ max-width: 555px;
+
+ @media all and (max-width: 768px) {
+ height: auto !important;
+ }
+ }
+
+ ul {
+ list-style-type: none;
+ padding-left: none;
+ }
+
+ .panel {
+ padding-bottom: 1.25em;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/taxons.css.sass b/app/assets/stylesheets/darkswarm/taxons.css.sass
deleted file mode 100644
index 1d1e5b652f..0000000000
--- a/app/assets/stylesheets/darkswarm/taxons.css.sass
+++ /dev/null
@@ -1,52 +0,0 @@
-@import branding
-@import mixins
-
-.fat-taxons, .fat-properties
- display: inline-block
- line-height: 1
- margin-right: 0.5rem
- margin-bottom: 0.35rem
- text-transform: capitalize
- font-weight: 300
- font-size: 0.875rem
- background: rgba(215,215,215,0.5)
- color: #555
- @include border-radius(3px)
- padding: 0.25rem 0.5rem 0.35rem 0.35rem
- render-svg
- svg
- width: 16px
- height: 16px
- path
- fill: #555
- &, & *
- display: inline-block
- color: #555
-
-.inactive
- .fat-taxons
- render-svg
- svg
- path
- fill: $disabled-dark
-
-.product-header
- render-svg
- svg
- width: 32px
- height: 32px
- path
- fill: black
- @media all and (max-width: 640px)
- render-svg
- svg
- width: 24px
- height: 24px
-
-.summary-header
- render-svg
- svg
- width: 18px
- height: 18px
- path
- fill: $clr-brick
\ No newline at end of file
diff --git a/app/assets/stylesheets/darkswarm/taxons.css.scss b/app/assets/stylesheets/darkswarm/taxons.css.scss
new file mode 100644
index 0000000000..a5db89b324
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/taxons.css.scss
@@ -0,0 +1,81 @@
+@import "branding";
+@import "mixins";
+
+.fat-taxons, .fat-properties {
+ display: inline-block;
+ line-height: 1;
+ margin-right: 0.5rem;
+ margin-bottom: 0.35rem;
+ text-transform: capitalize;
+ font-weight: 300;
+ font-size: 0.875rem;
+ background: rgba(215, 215, 215, 0.5);
+ color: #555;
+
+ @include border-radius(3px);
+
+ padding: 0.25rem 0.5rem 0.35rem 0.35rem;
+
+ render-svg {
+ svg {
+ width: 16px;
+ height: 16px;
+
+ path {
+ fill: #555;
+ }
+ }
+ }
+
+ &, & * {
+ display: inline-block;
+ color: #555;
+ }
+}
+
+.inactive {
+ .fat-taxons {
+ render-svg {}
+
+ svg {
+ path {
+ fill: $disabled-dark;
+ }
+ }
+ }
+}
+
+.product-header {
+ render-svg {
+ svg {
+ width: 32px;
+ height: 32px;
+
+ path {
+ fill: black;
+ }
+ }
+ }
+
+ @media all and (max-width: 640px) {
+ render-svg {
+ svg {
+ width: 24px;
+ height: 24px;
+ }
+ }
+ }
+}
+
+.summary-header {
+ render-svg {
+ svg {
+ width: 18px;
+ height: 18px;
+
+ path {
+ fill: $clr-brick;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/typography.css.sass b/app/assets/stylesheets/darkswarm/typography.css.sass
deleted file mode 100644
index 8c151db832..0000000000
--- a/app/assets/stylesheets/darkswarm/typography.css.sass
+++ /dev/null
@@ -1,125 +0,0 @@
-@import branding
-
-@mixin headingFont
- font-family: 'Oswald', sans-serif
-
-@mixin bodyFont
- font-family: 'Roboto', Arial, sans-serif
-
-$headingFont: 'Oswald'
-$bodyFont: 'Roboto'
-
-body
- @include bodyFont
- font-weight: 400
-a
- color: $clr-brick
- &:hover, &:focus, &:active
- text-decoration: none
- color: $clr-brick-bright
-
-.text-vbig
- font-size: 2rem
- font-weight: 300
-
-.text-big
- font-size: 1.5rem
- font-weight: 300
-
-small, .small
- font-size: 0.75rem
-
-.text-small
- font-size: 0.875rem
- margin-bottom: 0.5rem
- font-family: $bodyFont
- &, & *
- font-size: 0.875rem
-
-.text-normal
- font-weight: 400
- font-family: $bodyFont
-
-.text-skinny
- font-weight: 300
- font-family: $bodyFont
-
-.word-wrap
- word-wrap: break-word
-
-.pre-wrap
- white-space: pre-wrap
-
-.pre-line
- white-space: pre-line
-
-.light
- color: #999
- display: inline
-
-.center
- text-align: center
-
-.turquoise
- color: $clr-turquoise
-
-.brick
- color: $clr-brick
-
-.hr-light
- border-color: rgba(#ddd, 0.25)
-
-h1, h2, h3, h4, h5, h6
- @include headingFont
- padding: 0px
-
-.inline-header
- display: inline-block
- margin: 0px
-
-ul.bullet-list, ul.check-list
- margin: 0 0 0 1.25em !important
- li
- list-style: none
- line-height: 1.5
- height: inherit
- li:before
- content: "\e609"
- font-family: "OFN"
- margin-left: -1.25em
- display: inline-block
- font-weight: normal
- font-style: normal
- font-variant: normal
- text-transform: none
-
-ul.check-list
- li:before
- content: "\e632"
-
-.light-grey
- color: #666666
-
-.pad
- padding: 1em
-
-.pad-top
- padding-top: 1em
-
-.not-bold
- font-weight: normal
-
-.footer-pad
- padding-bottom: 100px
-
-
-// These selectors match the default Foundation selectors
-// For clean overriden magic
-table tr th, table tr td
- color: #333333
-table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td
- color: #333333
-
-span.email
- direction: rtl
- unicode-bidi: bidi-override
diff --git a/app/assets/stylesheets/darkswarm/typography.css.scss b/app/assets/stylesheets/darkswarm/typography.css.scss
new file mode 100644
index 0000000000..0ac7cbb673
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/typography.css.scss
@@ -0,0 +1,167 @@
+@import "branding";
+
+@mixin headingFont {
+ font-family: "Oswald", sans-serif;
+}
+
+@mixin bodyFont {
+ font-family: "Roboto", Arial, sans-serif;
+}
+
+$headingFont: "Oswald";
+$bodyFont: "Roboto";
+
+body {
+ @include bodyFont;
+
+ font-weight: 400;
+}
+
+a {
+ color: $clr-brick;
+
+ &:hover, &:focus, &:active {
+ text-decoration: none;
+ color: $clr-brick-bright;
+ }
+}
+
+.text-vbig {
+ font-size: 2rem;
+ font-weight: 300;
+}
+
+.text-big {
+ font-size: 1.5rem;
+ font-weight: 300;
+}
+
+small, .small {
+ font-size: 0.75rem;
+}
+
+.text-small {
+ font-size: 0.875rem;
+ margin-bottom: 0.5rem;
+ font-family: $bodyFont;
+
+ &, & * {
+ font-size: 0.875rem;
+ }
+}
+
+.text-normal {
+ font-weight: 400;
+ font-family: $bodyFont;
+}
+
+.text-skinny {
+ font-weight: 300;
+ font-family: $bodyFont;
+}
+
+.word-wrap {
+ word-wrap: break-word;
+}
+
+.pre-wrap {
+ white-space: pre-wrap;
+}
+
+.pre-line {
+ white-space: pre-line;
+}
+
+.light {
+ color: #999;
+ display: inline;
+}
+
+.center {
+ text-align: center;
+}
+
+.turquoise {
+ color: $clr-turquoise;
+}
+
+.brick {
+ color: $clr-brick;
+}
+
+.hr-light {
+ border-color: rgba(#ddd, 0.25);
+}
+
+h1, h2, h3, h4, h5, h6 {
+ @include headingFont;
+
+ padding: 0px;
+}
+
+.inline-header {
+ display: inline-block;
+ margin: 0px;
+}
+
+ul.bullet-list, ul.check-list {
+ margin: 0 0 0 1.25em !important;
+
+ li {
+ list-style: none;
+ line-height: 1.5;
+ height: inherit;
+ }
+
+ li:before {
+ content: "";
+ font-family: "OFN";
+ margin-left: -1.25em;
+ display: inline-block;
+ font-weight: normal;
+ font-style: normal;
+ font-variant: normal;
+ text-transform: none;
+ }
+}
+
+ul.check-list {
+ li:before {
+ content: "";
+ }
+}
+
+.light-grey {
+ color: #666666;
+}
+
+.pad {
+ padding: 1em;
+}
+
+.pad-top {
+ padding-top: 1em;
+}
+
+.not-bold {
+ font-weight: normal;
+}
+
+.footer-pad {
+ padding-bottom: 100px;
+}
+
+// These selectors match the default Foundation selectors
+// For clean overriden magic
+table tr th, table tr td {
+ color: #333333;
+}
+
+table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td {
+ color: #333333;
+}
+
+span.email {
+ direction: rtl;
+ unicode-bidi: bidi-override;
+}
diff --git a/app/assets/stylesheets/darkswarm/ui.css.sass b/app/assets/stylesheets/darkswarm/ui.css.sass
deleted file mode 100644
index 5c049a2bba..0000000000
--- a/app/assets/stylesheets/darkswarm/ui.css.sass
+++ /dev/null
@@ -1,97 +0,0 @@
-@import foundation/components/buttons
-@import branding
-@import mixins
-@import typography
-
-// Button class extensions
-
-.neutral-btn
- @include button
- @include border-radius(0.5em)
- font-family: $bodyFont
- background-color: transparent
- border: 2px solid rgba(200, 200, 200, 1)
- color: #999
-
-.neutral-btn:hover, .neutral-btn:active, .neutral-btn:focus
- background-color: rgba(200, 200, 200, 0.2)
- border: 2px solid rgba(200, 200, 200, 0.8)
-
-.neutral-btn.dark
- border-color: #000
- color: #000
-
-.neutral-btn.dark:hover, .neutral-btn.dark:active, .neutral-btn.dark:focus
- background-color: rgba(0, 0, 0, 0.1)
- border: 2px solid rgba(0, 0, 0, 0.8)
- text-shadow: 0 1px 0 #fff
-
-.neutral-btn.light
- border-color: #fff
- color: #fff
-
-.neutral-btn.light:hover, .neutral-btn.light:active, .neutral-btn.light:focus
- background-color: rgba(255, 255, 255, 0.2)
- border: 2px solid rgba(255, 255, 255, 0.8)
- text-shadow: 0 1px 0 rgba(0,0,0,0.2)
-
-.neutral-btn.turquoise
- border-color: $clr-turquoise
- color: $clr-turquoise
-
-.neutral-btn.turquoise:hover, .neutral-btn.turquoise:active, .neutral-btn.turquoise:focus
- background-color: rgba(0, 0, 0, 0.1)
- // text-shadow: 0 1px 0 #fff
-
-// Rewrite foundation's .primary button style
-
-.button, button
- @include border-radius(0.5em)
- outline: none // Turn off blue highlight on chrome
-
-.button.primary, button.primary
- font-family: $bodyFont
- background: $clr-brick
- color: white
-
-.button.primary:hover, .button.primary:active, .button.primary:focus, button.primary:hover, button.primary:active, button.primary:focus
- background: $clr-brick-bright
- text-shadow: 0 1px 0 $clr-brick
-
-button.success, .button.success
- background: #0096ad
-
-.button.success:hover, .button.success:active, .button.success:focus, button.success:hover, button.success:active, button.success:focus
- background: #14b6cc
-
-.button.help-btn
- @include border-radius(999999px)
- &.tiny
- padding: 0rem
- margin: 0
- float: right
- i
- font-size: 1.25rem
-
-.profile-checkbox
- display: inline-block
- label
- margin: 0 0.2rem
- float: right
-
-// Transparent button
-.button.transparent
- @include headingFont
- font-size: 20px
- text-transform: uppercase
- background: rgba(0, 0, 0, 0.3)
- border: 3px solid #fff
- text-shadow: none
- &:hover
- background: rgba(0, 0, 0, 0.6)
- color: #fff
-
-// Responsive
-@media screen and (min-width: 768px)
- [role="main"]
- padding: 0
diff --git a/app/assets/stylesheets/darkswarm/ui.css.scss b/app/assets/stylesheets/darkswarm/ui.css.scss
new file mode 100644
index 0000000000..1d1b9e166a
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/ui.css.scss
@@ -0,0 +1,128 @@
+@import "foundation/components/buttons";
+@import "branding";
+@import "mixins";
+@import "typography";
+
+// Button class extensions
+
+.neutral-btn {
+ @include button;
+
+ @include border-radius(0.5em);
+
+ font-family: $bodyFont;
+ background-color: transparent;
+ border: 2px solid rgba(200, 200, 200, 1);
+ color: #999;
+}
+
+.neutral-btn:hover, .neutral-btn:active, .neutral-btn:focus {
+ background-color: rgba(200, 200, 200, 0.2);
+ border: 2px solid rgba(200, 200, 200, 0.8);
+}
+
+.neutral-btn.dark {
+ border-color: #000;
+ color: #000;
+}
+
+.neutral-btn.dark:hover, .neutral-btn.dark:active, .neutral-btn.dark:focus {
+ background-color: rgba(0, 0, 0, 0.1);
+ border: 2px solid rgba(0, 0, 0, 0.8);
+ text-shadow: 0 1px 0 #fff;
+}
+
+.neutral-btn.light {
+ border-color: #fff;
+ color: #fff;
+}
+
+.neutral-btn.light:hover, .neutral-btn.light:active, .neutral-btn.light:focus {
+ background-color: rgba(255, 255, 255, 0.2);
+ border: 2px solid rgba(255, 255, 255, 0.8);
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
+}
+
+.neutral-btn.turquoise {
+ border-color: $clr-turquoise;
+ color: $clr-turquoise;
+}
+
+.neutral-btn.turquoise:hover, .neutral-btn.turquoise:active, .neutral-btn.turquoise:focus {
+ background-color: rgba(0, 0, 0, 0.1);
+
+ // text-shadow: 0 1px 0 #fff
+}
+
+// Rewrite foundation's .primary button style
+
+.button, button {
+ @include border-radius(0.5em);
+
+ outline: none;
+}
+
+.button.primary, button.primary {
+ font-family: $bodyFont;
+ background: $clr-brick;
+ color: white;
+}
+
+.button.primary:hover, .button.primary:active, .button.primary:focus, button.primary:hover, button.primary:active, button.primary:focus {
+ background: $clr-brick-bright;
+ text-shadow: 0 1px 0 $clr-brick;
+}
+
+button.success, .button.success {
+ background: #0096ad;
+}
+
+.button.success:hover, .button.success:active, .button.success:focus, button.success:hover, button.success:active, button.success:focus {
+ background: #14b6cc;
+}
+
+.button.help-btn {
+ @include border-radius(999999px);
+
+ &.tiny {
+ padding: 0rem;
+ margin: 0;
+ float: right;
+ }
+
+ i {
+ font-size: 1.25rem;
+ }
+}
+
+.profile-checkbox {
+ display: inline-block;
+
+ label {
+ margin: 0 0.2rem;
+ float: right;
+ }
+}
+
+// Transparent button
+.button.transparent {
+ @include headingFont;
+
+ font-size: 20px;
+ text-transform: uppercase;
+ background: rgba(0, 0, 0, 0.3);
+ border: 3px solid #fff;
+ text-shadow: none;
+
+ &:hover {
+ background: rgba(0, 0, 0, 0.6);
+ color: #fff;
+ }
+}
+
+// Responsive
+@media screen and (min-width: 768px) {
+ [role="main"] {
+ padding: 0;
+ }
+}
diff --git a/app/assets/stylesheets/darkswarm/variables.css.sass b/app/assets/stylesheets/darkswarm/variables.css.sass
deleted file mode 100644
index ea87d11fc4..0000000000
--- a/app/assets/stylesheets/darkswarm/variables.css.sass
+++ /dev/null
@@ -1,32 +0,0 @@
-@import "foundation/functions"
-@import "foundation/components/global"
-
-// Brand guide colours:
-// International: #81c26e
-// Australia: #f35746
-// Africa: #f35e32
-// South Africa: #f9a72b
-// Norway: #4b83cc
-// Scandanavia: #0c8bbc
-// UK: #e6373f
-
-$brand-colour: #f27052
-
-
-// Topbar
-$topbar-height: rem-calc(75)
-$topbar-link-padding: $topbar-height / 3
-
-$topbar-bg: $white
-$topbar-bg-color: $topbar-bg
-
-$topbar-link-color: $black
-$topbar-link-color-hover: $brand-colour
-$topbar-link-color-active: $black
-$topbar-link-color-active-hover: $white
-$topbar-link-bg-hover: $white
-
-$topbar-dropdown-link-color: $black
-$topbar-dropdown-bg: $white
-$topbar-dropdown-link-bg: $white
-$topbar-dropdown-link-bg-hover: $white
diff --git a/app/assets/stylesheets/darkswarm/variables.css.scss b/app/assets/stylesheets/darkswarm/variables.css.scss
new file mode 100644
index 0000000000..12d77f0d09
--- /dev/null
+++ b/app/assets/stylesheets/darkswarm/variables.css.scss
@@ -0,0 +1,31 @@
+@import "foundation/functions";
+@import "foundation/components/global";
+
+// Brand guide colours:
+// International: #81c26e
+// Australia: #f35746
+// Africa: #f35e32
+// South Africa: #f9a72b
+// Norway: #4b83cc
+// Scandanavia: #0c8bbc
+// UK: #e6373f
+
+$brand-colour: #f27052;
+
+// Topbar
+$topbar-height: rem-calc(75);
+$topbar-link-padding: $topbar-height / 3;
+
+$topbar-bg: $white;
+$topbar-bg-color: $topbar-bg;
+
+$topbar-link-color: $black;
+$topbar-link-color-hover: $brand-colour;
+$topbar-link-color-active: $black;
+$topbar-link-color-active-hover: $white;
+$topbar-link-bg-hover: $white;
+
+$topbar-dropdown-link-color: $black;
+$topbar-dropdown-bg: $white;
+$topbar-dropdown-link-bg: $white;
+$topbar-dropdown-link-bg-hover: $white;
diff --git a/app/assets/stylesheets/mail/email.css.sass b/app/assets/stylesheets/mail/email.css.sass
deleted file mode 100644
index e9eabd4edb..0000000000
--- a/app/assets/stylesheets/mail/email.css.sass
+++ /dev/null
@@ -1,312 +0,0 @@
-/* -------------------------------------
- * GLOBAL
- *-------------------------------------
-
-*
- margin: 0
- padding: 0
- font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif
-
-img
- max-width: 100%
-
-.collapse
- margin: 0
- padding: 0
-
-body
- -webkit-font-smoothing: antialiased
- -webkit-text-size-adjust: none
- width: 100%!important
- height: 100%
-
-/* -------------------------------------
- * ELEMENTS
- *-------------------------------------
-
-a
- color: #0096ad
-
-.btn
- text-decoration: none
- color: #FFF
- background-color: #666
- padding: 10px 16px
- font-weight: bold
- margin-right: 10px
- text-align: center
- cursor: pointer
- display: inline-block
-
-p.callout
- padding: 15px
- background-color: #e1f0f5
- margin-bottom: 15px
-
-.callout a
- font-weight: bold
- color: #0096ad
-
-table.social
- background-color: #ebebeb
- &.white-bg
- background-color: white!important
- border: 1px solid #ebebeb
-
-table.order-summary
- border-collapse: separate
- border-spacing: 0px 10px
- tbody tr td
- padding-left: 5px
- padding-right: 5px
- thead tr th
- background-color: #f2f2f2
- border-bottom: 1px solid black
- padding-left: 5px
- padding-right: 5px
- h4
- margin-top: 15px
- tfoot
- tr:first-child td
- border-top: 1px solid black
- padding-top: 5px
- tr td
- padding-left: 5px
- padding-right: 5px
-
-.text-right
- text-align: right
-
-.social .soc-btn
- padding: 3px 7px
- font-size: 12px
- margin-bottom: 10px
- text-decoration: none
- color: #FFF
- font-weight: bold
- display: block
- text-align: center
-
-a
- &.fb
- background-color: #3B5998!important
- &.tw
- background-color: #1daced!important
- &.gp
- background-color: #DB4A39!important
- &.li
- background-color: #0073b2!important
- &.ms
- background-color: #000!important
-
-.sidebar .soc-btn
- display: block
- width: 100%
-
-img.float-right
- float: right
- display: block
-
-/* -------------------------------------
- * HEADER
- *-------------------------------------
-
-table.head-wrap
- width: 100%
-
-.header.container table td
- &.logo
- padding: 15px
- &.label
- padding: 15px
- padding-left: 0px
-
-/* -------------------------------------
- * BODY
- *-------------------------------------
-
-table
- &.body-wrap
- width: 100%
- &.footer-wrap
- width: 100%
- clear: both!important
-
-/* -------------------------------------
- * FOOTER
- *-------------------------------------
-
-.footer-wrap .container td.content p
- border-top: 1px solid rgb(215, 215, 215)
- padding-top: 15px
- font-size: 10px
- font-weight: bold
-
-/* -------------------------------------
- * TYPOGRAPHY
- *-------------------------------------
-
-h1, h2, h3, h4, h5, h6
- font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif
- line-height: 1.1
- margin-bottom: 15px
- color: #000
-
-h1 small, h2 small, h3 small, h4 small, h5 small, h6 small
- font-size: 60%
- color: #6f6f6f
- line-height: 0
- text-transform: none
-
-h1
- font-weight: 200
- font-size: 44px
-
-h2
- font-weight: 200
- font-size: 37px
-
-h3
- font-weight: 500
- font-size: 27px
-
-h4
- font-weight: 500
- font-size: 23px
-
-h5
- font-weight: 900
- font-size: 17px
-
-h6
- font-weight: 900
- font-size: 14px
- text-transform: uppercase
- color: #999
-
-.collapse
- margin: 0!important
-
-p, ul
- margin-bottom: 10px
- font-weight: normal
- font-size: 14px
- line-height: 1.6
-
-p
- &.lead
- font-size: 17px
- &.last
- margin-bottom: 0px
-
-ul
- li
- margin-left: 5px
- list-style-position: inside
- &.sidebar
- background: #ebebeb
- display: block
- list-style-type: none
- li
- display: block
- margin: 0
- a
- text-decoration: none
- color: #666
- padding: 10px 16px
- /* font-weight:bold;
- margin-right: 10px
- /* text-align:center;
- cursor: pointer
- border-bottom: 1px solid #777777
- border-top: 1px solid #FFFFFF
- display: block
- margin: 0
- &.last
- border-bottom-width: 0px
- h1, h2, h3, h4, h5, h6, p
- margin-bottom: 0!important
-
-/* -------------------------------------
- * SIDEBAR
- *-------------------------------------
-
-/* ---------------------------------------------------
- * RESPONSIVENESS
- * Nuke it from orbit. It's the only way to be sure.
- *------------------------------------------------------
-
-/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something
-
-.container
- display: block!important
- max-width: 600px!important
- margin: 0 auto!important
- /* makes it centered
- clear: both!important
-
-/* This should also be a block element, so that it will fill 100% of the .container
-
-.content
- padding: 15px
- max-width: 600px
- margin: 0 auto
- display: block
- table
- width: 100%
-
-/* Let's make sure tables in the content area are 100% wide
-
-/* Odds and ends
-
-.column
- width: 300px
- float: left
- tr td
- padding: 15px
-
-.pad
- tr td
- padding: 15px
-
-.column-wrap
- padding: 0!important
- margin: 0 auto
- max-width: 600px!important
-
-.column table
- width: 100%
-
-.social .column
- width: 280px
- min-width: 279px
- float: left
-
-/* Be sure to place a .clear element after each set of columns, just to be safe
-
-.clear
- display: block
- clear: both
-
-/* -------------------------------------------
- * PHONE
- * For clients that support media queries.
- * Nothing fancy.
- *--------------------------------------------
-@media only screen and (max-width: 600px)
- a[class="btn"]
- display: block!important
- margin-bottom: 10px!important
- background-image: none!important
- margin-right: 0!important
- div[class="column"]
- width: auto!important
- float: none!important
- table.social div[class="column"]
- width: auto!important
- img.float-right
- float: none!important
-
-.inline-header
- display: inline-block
- margin: 0px
diff --git a/app/assets/stylesheets/mail/email.css.scss b/app/assets/stylesheets/mail/email.css.scss
new file mode 100644
index 0000000000..0b2f641b4f
--- /dev/null
+++ b/app/assets/stylesheets/mail/email.css.scss
@@ -0,0 +1,410 @@
+/* -------------------------------------
+ * GLOBAL
+ *------------------------------------- */
+
+* {
+ margin: 0;
+ padding: 0;
+ font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
+}
+
+img {
+ max-width: 100%;
+}
+
+.collapse {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ -webkit-font-smoothing: antialiased;
+ -webkit-text-size-adjust: none;
+ width: 100% !important;
+ height: 100%;
+}
+
+/* -------------------------------------
+ * ELEMENTS
+ *------------------------------------- */
+
+a {
+ color: #0096ad;
+}
+
+.btn {
+ text-decoration: none;
+ color: #FFF;
+ background-color: #666;
+ padding: 10px 16px;
+ font-weight: bold;
+ margin-right: 10px;
+ text-align: center;
+ cursor: pointer;
+ display: inline-block;
+}
+
+p.callout {
+ padding: 15px;
+ background-color: #e1f0f5;
+ margin-bottom: 15px;
+}
+
+.callout a {
+ font-weight: bold;
+ color: #0096ad;
+}
+
+table.social {
+ background-color: #ebebeb;
+
+ &.white-bg {
+ background-color: white !important;
+ border: 1px solid #ebebeb;
+ }
+}
+
+table.order-summary {
+ border-collapse: separate;
+ border-spacing: 0px 10px;
+
+ tbody tr td {
+ padding-left: 5px;
+ padding-right: 5px;
+ }
+
+ thead tr th {
+ background-color: #f2f2f2;
+ border-bottom: 1px solid black;
+ padding-left: 5px;
+ padding-right: 5px;
+
+ h4 {
+ margin-top: 15px;
+ }
+ }
+
+ tfoot {
+ tr:first-child td {
+ border-top: 1px solid black;
+ padding-top: 5px;
+ }
+
+ tr td {
+ padding-left: 5px;
+ padding-right: 5px;
+ }
+ }
+}
+
+.text-right {
+ text-align: right;
+}
+
+.social .soc-btn {
+ padding: 3px 7px;
+ font-size: 12px;
+ margin-bottom: 10px;
+ text-decoration: none;
+ color: #FFF;
+ font-weight: bold;
+ display: block;
+ text-align: center;
+}
+
+a {
+ &.fb {
+ background-color: #3B5998 !important;
+ }
+
+ &.tw {
+ background-color: #1daced !important;
+ }
+
+ &.gp {
+ background-color: #DB4A39 !important;
+ }
+
+ &.li {
+ background-color: #0073b2 !important;
+ }
+
+ &.ms {
+ background-color: #000 !important;
+ }
+}
+
+.sidebar .soc-btn {
+ display: block;
+ width: 100%;
+}
+
+img.float-right {
+ float: right;
+ display: block;
+}
+
+/* -------------------------------------
+ * HEADER
+ *------------------------------------- */
+
+table.head-wrap {
+ width: 100%;
+}
+
+.header.container table td {
+ &.logo {
+ padding: 15px;
+ }
+
+ &.label {
+ padding: 15px;
+ padding-left: 0px;
+ }
+}
+
+/* -------------------------------------
+ * BODY
+ *------------------------------------- */
+
+table {
+ &.body-wrap {
+ width: 100%;
+ }
+
+ &.footer-wrap {
+ width: 100%;
+ clear: both !important;
+ }
+}
+
+/* -------------------------------------
+ * FOOTER
+ *------------------------------------- */
+
+.footer-wrap .container td.content p {
+ border-top: 1px solid rgb(215, 215, 215);
+ padding-top: 15px;
+ font-size: 10px;
+ font-weight: bold;
+}
+
+/* -------------------------------------
+ * TYPOGRAPHY
+ *------------------------------------- */
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+ line-height: 1.1;
+ margin-bottom: 15px;
+ color: #000;
+}
+
+h1 small, h2 small, h3 small, h4 small, h5 small, h6 small {
+ font-size: 60%;
+ color: #6f6f6f;
+ line-height: 0;
+ text-transform: none;
+}
+
+h1 {
+ font-weight: 200;
+ font-size: 44px;
+}
+
+h2 {
+ font-weight: 200;
+ font-size: 37px;
+}
+
+h3 {
+ font-weight: 500;
+ font-size: 27px;
+}
+
+h4 {
+ font-weight: 500;
+ font-size: 23px;
+}
+
+h5 {
+ font-weight: 900;
+ font-size: 17px;
+}
+
+h6 {
+ font-weight: 900;
+ font-size: 14px;
+ text-transform: uppercase;
+ color: #999;
+}
+
+.collapse {
+ margin: 0 !important;
+}
+
+p, ul {
+ margin-bottom: 10px;
+ font-weight: normal;
+ font-size: 14px;
+ line-height: 1.6;
+}
+
+p {
+ &.lead {
+ font-size: 17px;
+ }
+
+ &.last {
+ margin-bottom: 0px;
+ }
+}
+
+ul {
+ li {
+ margin-left: 5px;
+ list-style-position: inside;
+ }
+
+ &.sidebar {
+ background: #ebebeb;
+ display: block;
+ list-style-type: none;
+
+ li {
+ display: block;
+ margin: 0;
+
+ a {
+ text-decoration: none;
+ color: #666;
+ padding: 10px 16px;
+
+ /* font-weight:bold; */
+ margin-right: 10px;
+
+ /* text-align:center; */
+ cursor: pointer;
+ border-bottom: 1px solid #777777;
+ border-top: 1px solid #FFFFFF;
+ display: block;
+ margin: 0;
+
+ &.last {
+ border-bottom-width: 0px;
+ }
+
+ h1, h2, h3, h4, h5, h6, p {
+ margin-bottom: 0 !important;
+ }
+ }
+ }
+ }
+}
+
+/* -------------------------------------
+ * SIDEBAR
+ *------------------------------------- */
+
+/* ---------------------------------------------------
+ * RESPONSIVENESS
+ * Nuke it from orbit. It's the only way to be sure.
+ *------------------------------------------------------ */
+
+/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
+
+.container {
+ display: block !important;
+ max-width: 600px !important;
+ margin: 0 auto !important;
+
+ /* makes it centered */
+ clear: both !important;
+}
+
+/* This should also be a block element, so that it will fill 100% of the .container */
+
+.content {
+ padding: 15px;
+ max-width: 600px;
+ margin: 0 auto;
+ display: block;
+
+ table {
+ width: 100%;
+ }
+}
+
+/* Let's make sure tables in the content area are 100% wide */
+
+/* Odds and ends */
+
+.column {
+ width: 300px;
+ float: left;
+
+ tr td {
+ padding: 15px;
+ }
+}
+
+.pad {
+ tr td {
+ padding: 15px;
+ }
+}
+
+.column-wrap {
+ padding: 0 !important;
+ margin: 0 auto;
+ max-width: 600px !important;
+}
+
+.column table {
+ width: 100%;
+}
+
+.social .column {
+ width: 280px;
+ min-width: 279px;
+ float: left;
+}
+
+/* Be sure to place a .clear element after each set of columns, just to be safe */
+
+.clear {
+ display: block;
+ clear: both;
+}
+
+/* -------------------------------------------
+ * PHONE
+ * For clients that support media queries.
+ * Nothing fancy.
+ *-------------------------------------------- */
+@media only screen and (max-width: 600px) {
+ a[class="btn"] {
+ display: block !important;
+ margin-bottom: 10px !important;
+ background-image: none !important;
+ margin-right: 0 !important;
+ }
+
+ div[class="column"] {
+ width: auto !important;
+ float: none !important;
+ }
+
+ table.social div[class="column"] {
+ width: auto !important;
+ }
+
+ img.float-right {
+ float: none !important;
+ }
+}
+
+.inline-header {
+ display: inline-block;
+ margin: 0px;
+}
diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb
index 377186b604..f2c9552c4a 100644
--- a/app/controllers/admin/enterprises_controller.rb
+++ b/app/controllers/admin/enterprises_controller.rb
@@ -2,6 +2,10 @@ require 'open_food_network/referer_parser'
module Admin
class EnterprisesController < ResourceController
+ # These need to run before #load_resource so that @object is initialised with sanitised values
+ prepend_before_filter :override_owner, only: :create
+ prepend_before_filter :override_sells, only: :create
+
before_filter :load_enterprise_set, :only => :index
before_filter :load_countries, :except => [:index, :register, :check_permalink]
before_filter :load_methods_and_fees, :only => [:edit, :update]
@@ -9,8 +13,6 @@ module Admin
before_filter :load_taxons, :only => [:new, :edit, :update, :create]
before_filter :check_can_change_sells, only: :update
before_filter :check_can_change_bulk_sells, only: :bulk_update
- before_filter :override_owner, only: :create
- before_filter :override_sells, only: :create
before_filter :check_can_change_owner, only: :update
before_filter :check_can_change_bulk_owner, only: :bulk_update
before_filter :check_can_change_managers, only: :update
@@ -115,8 +117,8 @@ module Admin
def build_resource_with_address
enterprise = build_resource_without_address
- enterprise.address = Spree::Address.new
- enterprise.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id])
+ enterprise.address ||= Spree::Address.new
+ enterprise.address.country ||= Spree::Country.find_by_id(Spree::Config[:default_country_id])
enterprise
end
alias_method_chain :build_resource, :address
@@ -269,9 +271,10 @@ module Admin
# Overriding method on Spree's resource controller
def location_after_save
referer_path = OpenFoodNetwork::RefererParser::path(request.referer)
- refered_from_edit = referer_path =~ /\/edit$/
- if params[:enterprise].key?(:producer_properties_attributes) && !refered_from_edit
- main_app.admin_enterprises_path
+ refered_from_producer_properties = referer_path =~ /\/producer_properties$/
+
+ if refered_from_producer_properties
+ main_app.admin_enterprise_producer_properties_path(@enterprise)
else
main_app.edit_admin_enterprise_path(@enterprise)
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 7dfd404b69..c5eb745c05 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -20,6 +20,11 @@ class ApplicationController < ActionController::Base
private
+ def action
+ params[:action].to_sym
+ end
+
+
def require_distributor_chosen
unless @distributor = current_distributor
redirect_to spree.root_path
diff --git a/app/controllers/base_controller.rb b/app/controllers/base_controller.rb
index 58bf679dc3..36084c0225 100644
--- a/app/controllers/base_controller.rb
+++ b/app/controllers/base_controller.rb
@@ -1,8 +1,13 @@
+require 'spree/core/controller_helpers/respond_with_decorator'
require 'open_food_network/tag_rule_applicator'
class BaseController < ApplicationController
include Spree::Core::ControllerHelpers
+ include Spree::Core::ControllerHelpers::Auth
+ include Spree::Core::ControllerHelpers::Common
+ include Spree::Core::ControllerHelpers::Order
include Spree::Core::ControllerHelpers::RespondWith
+
include EnterprisesHelper
include OrderCyclesHelper
diff --git a/app/controllers/sitemap_controller.rb b/app/controllers/sitemap_controller.rb
new file mode 100644
index 0000000000..103b6e93ee
--- /dev/null
+++ b/app/controllers/sitemap_controller.rb
@@ -0,0 +1,11 @@
+class SitemapController < ApplicationController
+ layout nil
+
+ def index
+ headers['Content-Type'] = 'application/xml'
+ @page_urls = [shops_url, map_url, producers_url, groups_url]
+ @enterprises = Enterprise.is_hub
+ @groups = EnterpriseGroup.all
+ respond_to :xml
+ end
+end
diff --git a/app/controllers/spree/admin/adjustments_controller_decorator.rb b/app/controllers/spree/admin/adjustments_controller_decorator.rb
index 12c9ae2c60..d3059b4804 100644
--- a/app/controllers/spree/admin/adjustments_controller_decorator.rb
+++ b/app/controllers/spree/admin/adjustments_controller_decorator.rb
@@ -1,7 +1,7 @@
module Spree
module Admin
AdjustmentsController.class_eval do
- before_filter :set_included_tax, only: [:create, :update]
+ prepend_before_filter :set_included_tax, only: [:create, :update]
before_filter :set_default_tax_rate, only: :edit
diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb
index 9888967f58..d5e62469cb 100644
--- a/app/controllers/spree/admin/base_controller_decorator.rb
+++ b/app/controllers/spree/admin/base_controller_decorator.rb
@@ -1,3 +1,5 @@
+require 'spree/core/controller_helpers/respond_with_decorator'
+
Spree::Admin::BaseController.class_eval do
before_filter :warn_invalid_order_cycles
diff --git a/app/controllers/spree/admin/products_controller_decorator.rb b/app/controllers/spree/admin/products_controller_decorator.rb
index 5b1bb347a1..7929aa1df6 100644
--- a/app/controllers/spree/admin/products_controller_decorator.rb
+++ b/app/controllers/spree/admin/products_controller_decorator.rb
@@ -8,7 +8,6 @@ Spree::Admin::ProductsController.class_eval do
before_filter :load_spree_api_key, :only => [:bulk_edit, :variant_overrides]
before_filter :strip_new_properties, only: [:create, :update]
- alias_method :location_after_save_original, :location_after_save
respond_to :json, :only => :clone
@@ -53,14 +52,17 @@ Spree::Admin::ProductsController.class_eval do
protected
- def location_after_save
+
+ def location_after_save_with_bulk_edit
referer_path = OpenFoodNetwork::RefererParser::path(request.referer)
+
if referer_path == '/admin/products/bulk_edit'
bulk_edit_admin_products_url
else
- location_after_save_original
+ location_after_save_without_bulk_edit
end
end
+ alias_method_chain :location_after_save, :bulk_edit
def collection
# This method is copied directly from the spree product controller, except where we narrow the search below with the managed_by search to support
diff --git a/app/controllers/spree/admin/resource_controller_decorator.rb b/app/controllers/spree/admin/resource_controller_decorator.rb
new file mode 100644
index 0000000000..cb789d7330
--- /dev/null
+++ b/app/controllers/spree/admin/resource_controller_decorator.rb
@@ -0,0 +1,16 @@
+module AuthorizeOnLoadResource
+ def load_resource
+ super
+
+ if member_action?
+ # If we don't have access, clear the object
+ unless can? action, @object
+ instance_variable_set("@#{object_name}", nil)
+ end
+
+ authorize! action, @object
+ end
+ end
+end
+
+Spree::Admin::ResourceController.send(:prepend, AuthorizeOnLoadResource)
diff --git a/app/controllers/spree/api/users_controller.rb b/app/controllers/spree/api/users_controller.rb
new file mode 100644
index 0000000000..74f83f6709
--- /dev/null
+++ b/app/controllers/spree/api/users_controller.rb
@@ -0,0 +1,7 @@
+module Spree
+ module Api
+ class UsersController < Spree::Api::BaseController
+ respond_to :json
+ end
+ end
+end
diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb
index 2c0ff8562c..dd4f2eba81 100644
--- a/app/controllers/spree/orders_controller_decorator.rb
+++ b/app/controllers/spree/orders_controller_decorator.rb
@@ -40,7 +40,6 @@ Spree::OrdersController.class_eval do
if @order.update_attributes(params[:order])
@order.line_items = @order.line_items.select {|li| li.quantity > 0 }
- @order.restart_checkout_flow
render :edit and return unless apply_coupon_code
diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb
index 6db2e583bc..dad9cf11f9 100644
--- a/app/helpers/injection_helper.rb
+++ b/app/helpers/injection_helper.rb
@@ -45,7 +45,7 @@ module InjectionHelper
end
def inject_properties
- inject_json_ams "properties", Spree::Property.all, Api::IdNameSerializer
+ inject_json_ams "properties", Spree::Property.all, Api::PropertySerializer
end
def inject_currency_config
diff --git a/app/helpers/serializer_helper.rb b/app/helpers/serializer_helper.rb
new file mode 100644
index 0000000000..2e48e3741d
--- /dev/null
+++ b/app/helpers/serializer_helper.rb
@@ -0,0 +1,6 @@
+module SerializerHelper
+ def ids_to_objs(ids)
+ return [] if ids.blank?
+ ids.map { |id| {id: id} }
+ end
+end
diff --git a/app/helpers/spree/admin/base_helper_decorator.rb b/app/helpers/spree/admin/base_helper_decorator.rb
index 86e77431ba..5398cee35f 100644
--- a/app/helpers/spree/admin/base_helper_decorator.rb
+++ b/app/helpers/spree/admin/base_helper_decorator.rb
@@ -1,22 +1,6 @@
module Spree
module Admin
module BaseHelper
- # Add url option to pass in link URL
- def link_to_remove_fields(name, f, options = {})
- name = '' if options[:no_text]
- options[:class] = '' unless options[:class]
- options[:class] += 'no-text' if options[:no_text]
-
- url = if f.object.persisted?
- options[:url] || [:admin, f.object]
- else
- '#'
- end
-
- link_to_with_icon('icon-trash', name, url, :class => "remove_fields #{options[:class]}", :data => {:action => 'remove'}, :title => t(:remove)) + f.hidden_field(:_destroy)
- end
-
-
def preference_field_tag_with_files(name, value, options)
if options[:type] == :file
file_field_tag name, preference_field_options(options)
@@ -25,6 +9,20 @@ module Spree
end
end
alias_method_chain :preference_field_tag, :files
+
+
+ # Add support for options[:html], allowing additional HTML attributes
+ def link_to_remove_fields(name, f, options = {})
+ name = '' if options[:no_text]
+ options[:class] = '' unless options[:class]
+ options[:class] += 'no-text with-tip' if options[:no_text]
+
+ html_options = {class: "remove_fields #{options[:class]}", data: {action: 'remove'}, title: t(:remove)}
+ html_options.merge!(options[:html]) if options.key? :html
+
+ link_to_with_icon('icon-trash', name, '#', html_options) + f.hidden_field(:_destroy)
+ end
+
end
end
end
diff --git a/app/helpers/spree/admin/navigation_helper_decorator.rb b/app/helpers/spree/admin/navigation_helper_decorator.rb
index eb210ef482..8398df7de3 100644
--- a/app/helpers/spree/admin/navigation_helper_decorator.rb
+++ b/app/helpers/spree/admin/navigation_helper_decorator.rb
@@ -1,6 +1,15 @@
module Spree
module Admin
module NavigationHelper
+ # TEMP: import method until it is re-introduced into Spree.
+ def klass_for(name)
+ model_name = name.to_s
+
+ ["Spree::#{model_name.classify}", model_name.classify, model_name.gsub('_', '/').classify].find do |t|
+ t.safe_constantize
+ end.try(:safe_constantize)
+ end
+
# Make it so that the Reports admin tab can be enabled/disabled through the cancan
# :report resource, since it does not have a corresponding resource class (unlike
# eg. Spree::Product).
@@ -9,9 +18,22 @@ module Spree
klass ||= name.singularize.to_sym
klass = :overview if klass == :dashboard
klass = Spree::Order if klass == :bulk_order_management
+ klass = EnterpriseGroup if klass == :group
+ klass = VariantOverride if klass == :Inventory
klass
end
alias_method_chain :klass_for, :sym_fallback
+
+ # TEMP: override method until it is fixed in Spree.
+ def tab_with_cancan_check(*args)
+ options = {:label => args.first.to_s}
+ if args.last.is_a?(Hash)
+ options = options.merge(args.last)
+ end
+ return '' if klass = klass_for(options[:label]) and cannot?(:admin, klass)
+ tab_without_cancan_check(*args)
+ end
+ alias_method_chain :tab, :cancan_check
end
end
end
diff --git a/app/mailers/spree/base_mailer_decorator.rb b/app/mailers/spree/base_mailer_decorator.rb
index 339abd8901..949f51d2f0 100644
--- a/app/mailers/spree/base_mailer_decorator.rb
+++ b/app/mailers/spree/base_mailer_decorator.rb
@@ -6,6 +6,13 @@ Spree::BaseMailer.class_eval do
layout 'mailer'
protected
+
+ def from_address
+ Spree::MailMethod.current.andand.preferred_mails_from ||
+ 'test@example.com'
+ end
+
+
def roadie_options
# This lets us specify assets using relative paths in email templates
super.merge(url_options: {host: URI(spree.root_url).host })
diff --git a/app/mailers/spree/order_mailer_decorator.rb b/app/mailers/spree/order_mailer_decorator.rb
index 016b61efa4..13f014d5a0 100644
--- a/app/mailers/spree/order_mailer_decorator.rb
+++ b/app/mailers/spree/order_mailer_decorator.rb
@@ -3,6 +3,13 @@ Spree::OrderMailer.class_eval do
helper CheckoutHelper
helper SpreeCurrencyHelper
+ def cancel_email(order, resend = false)
+ @order = find_order(order)
+ subject = (resend ? "[#{t(:resend).upcase}] " : '')
+ subject += "#{Spree::Config[:site_name]} #{t('order_mailer.cancel_email.subject')} ##{order.number}"
+ mail(to: order.email, from: from_address, subject: subject)
+ end
+
def confirm_email_for_customer(order, resend = false)
find_order(order) # Finds an order instance from an id
subject = (resend ? "[#{t(:resend).upcase}] " : '')
@@ -31,4 +38,8 @@ Spree::OrderMailer.class_eval do
:subject => subject,
:reply_to => @order.distributor.email)
end
+
+ def find_order(order)
+ @order = order.respond_to?(:id) ? order : Spree::Order.find(order)
+ end
end
diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb
index 80414d5116..e9acbd51f6 100644
--- a/app/models/enterprise.rb
+++ b/app/models/enterprise.rb
@@ -78,6 +78,7 @@ class Enterprise < ActiveRecord::Base
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
validates_length_of :description, :maximum => 255
+
before_save :confirmation_check, if: lambda { email_changed? }
before_validation :initialize_permalink, if: lambda { permalink.nil? }
@@ -86,6 +87,7 @@ class Enterprise < ActiveRecord::Base
before_validation :set_unused_address_fields
after_validation :geocode_address
+ after_touch :touch_distributors
after_create :relate_to_owners_enterprises
# TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
after_update :welcome_after_confirm, if: lambda { confirmation_token_changed? && confirmation_token.nil? }
@@ -93,6 +95,7 @@ class Enterprise < ActiveRecord::Base
after_rollback :restore_permalink
+
scope :by_name, order('name')
scope :visible, where(visible: true)
scope :confirmed, where('confirmed_at IS NOT NULL')
@@ -159,16 +162,19 @@ class Enterprise < ActiveRecord::Base
select('DISTINCT enterprises.*')
}
- scope :distributing_product, lambda { |product|
- with_distributed_products_outer.with_order_cycles_and_exchange_variants_outer.
- where('product_distributions.product_id = ? OR spree_variants.product_id = ?', product, product).
- select('DISTINCT enterprises.*')
- }
- scope :distributing_any_product_of, lambda { |products|
- with_distributed_products_outer.with_order_cycles_and_exchange_variants_outer.
- where('product_distributions.product_id IN (?) OR spree_variants.product_id IN (?)', products, products).
- select('DISTINCT enterprises.*')
+ scope :distributing_products, lambda { |products|
+ # TODO: remove this when we pull out product distributions
+ pds = joins("INNER JOIN product_distributions ON product_distributions.distributor_id = enterprises.id").
+ where("product_distributions.product_id IN (?)", products).select('DISTINCT enterprises.id')
+
+ exs = joins("INNER JOIN exchanges ON (exchanges.receiver_id = enterprises.id AND exchanges.incoming = 'f')").
+ joins('INNER JOIN exchange_variants ON (exchange_variants.exchange_id = exchanges.id)').
+ joins('INNER JOIN spree_variants ON (spree_variants.id = exchange_variants.variant_id)').
+ where('spree_variants.product_id IN (?)', products).select('DISTINCT enterprises.id')
+
+ where(id: pds | exs)
}
+
scope :managed_by, lambda { |user|
if user.has_spree_role?('admin')
scoped
@@ -467,4 +473,10 @@ class Enterprise < ActiveRecord::Base
def initialize_permalink
self.permalink = Enterprise.find_available_permalink(name)
end
+
+ def touch_distributors
+ Enterprise.distributing_products(self.supplied_products).
+ where('enterprises.id != ?', self.id).
+ each(&:touch)
+ end
end
diff --git a/app/models/enterprise_fee.rb b/app/models/enterprise_fee.rb
index d1d0816340..ff118cf0aa 100644
--- a/app/models/enterprise_fee.rb
+++ b/app/models/enterprise_fee.rb
@@ -16,6 +16,7 @@ class EnterpriseFee < ActiveRecord::Base
calculated_adjustments
+
attr_accessible :enterprise_id, :fee_type, :name, :tax_category_id, :calculator_type, :inherits_tax_category
FEE_TYPES = %w(packing transport admin sales fundraising)
diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb
index 63eb63f0b3..8b96ca9163 100644
--- a/app/models/enterprise_group.rb
+++ b/app/models/enterprise_group.rb
@@ -58,14 +58,14 @@ class EnterpriseGroup < ActiveRecord::Base
}
def set_unused_address_fields
- address.firstname = address.lastname = 'unused' if address.present?
+ address.firstname = address.lastname = 'unused'
end
def set_undefined_address_fields
- return unless address.present?
address.phone.present? || address.phone = 'undefined'
address.address1.present? || address.address1 = 'undefined'
address.city.present? || address.city = 'undefined'
+ address.state.present? || address.state = address.country.states.first
address.zipcode.present? || address.zipcode = 'undefined'
end
diff --git a/app/models/exchange.rb b/app/models/exchange.rb
index 3d0e6417e6..f60c7289b6 100644
--- a/app/models/exchange.rb
+++ b/app/models/exchange.rb
@@ -2,18 +2,18 @@ class Exchange < ActiveRecord::Base
acts_as_taggable
belongs_to :order_cycle
- belongs_to :sender, :class_name => 'Enterprise'
- belongs_to :receiver, :class_name => 'Enterprise'
- belongs_to :payment_enterprise, :class_name => 'Enterprise'
+ belongs_to :sender, class_name: 'Enterprise'
+ belongs_to :receiver, class_name: 'Enterprise', touch: true
+ belongs_to :payment_enterprise, class_name: 'Enterprise'
- has_many :exchange_variants, :dependent => :destroy
- has_many :variants, :through => :exchange_variants
+ has_many :exchange_variants, dependent: :destroy
+ has_many :variants, through: :exchange_variants
- has_many :exchange_fees, :dependent => :destroy
- has_many :enterprise_fees, :through => :exchange_fees
+ has_many :exchange_fees, dependent: :destroy
+ has_many :enterprise_fees, through: :exchange_fees
validates_presence_of :order_cycle, :sender, :receiver
- validates_uniqueness_of :sender_id, :scope => [:order_cycle_id, :receiver_id, :incoming]
+ validates_uniqueness_of :sender_id, scope: [:order_cycle_id, :receiver_id, :incoming]
after_save :refresh_products_cache
after_destroy :refresh_products_cache_from_destroy
diff --git a/app/models/producer_property.rb b/app/models/producer_property.rb
index bf1f083936..a21b5eb5a3 100644
--- a/app/models/producer_property.rb
+++ b/app/models/producer_property.rb
@@ -1,5 +1,5 @@
class ProducerProperty < ActiveRecord::Base
- belongs_to :producer, class_name: 'Enterprise'
+ belongs_to :producer, class_name: 'Enterprise', touch: true
belongs_to :property, class_name: 'Spree::Property'
default_scope order("#{self.table_name}.position")
@@ -8,14 +8,18 @@ class ProducerProperty < ActiveRecord::Base
after_destroy :refresh_products_cache_from_destroy
- scope :sold_by, ->(shop) {
+ scope :ever_sold_by, ->(shop) {
joins(producer: {supplied_products: {variants: {exchanges: :order_cycle}}}).
merge(Exchange.outgoing).
merge(Exchange.to_enterprise(shop)).
- merge(OrderCycle.active).
select('DISTINCT producer_properties.*')
}
+ scope :currently_sold_by, ->(shop) {
+ ever_sold_by(shop).
+ merge(OrderCycle.active)
+ }
+
def property_name
property.name if property
diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb
index c2bd99bcdb..13efc7e109 100644
--- a/app/models/spree/ability_decorator.rb
+++ b/app/models/spree/ability_decorator.rb
@@ -57,6 +57,7 @@ class AbilityDecorator
def add_group_management_abilities(user)
can [:admin, :index], :overview
+ can [:admin, :sync], :analytic
can [:admin, :index], EnterpriseGroup
can [:read, :edit, :update], EnterpriseGroup do |group|
user.owned_groups.include? group
@@ -69,6 +70,7 @@ class AbilityDecorator
can [:create, :search], nil
can [:admin, :index], :overview
+ can [:admin, :sync], :analytic
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
@@ -110,12 +112,12 @@ class AbilityDecorator
def add_product_management_abilities(user)
# Enterprise User can only access products that they are a supplier for
can [:create], Spree::Product
- can [:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :destroy], Spree::Product do |product|
+ can [:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :delete, :destroy], Spree::Product do |product|
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
end
can [:create], Spree::Variant
- can [:admin, :index, :read, :edit, :update, :search, :destroy], Spree::Variant do |variant|
+ can [:admin, :index, :read, :edit, :update, :search, :delete, :destroy], Spree::Variant do |variant|
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? variant.product.supplier
end
diff --git a/app/models/spree/calculator/flat_percent_item_total_decorator.rb b/app/models/spree/calculator/flat_percent_item_total_decorator.rb
new file mode 100644
index 0000000000..9012261dab
--- /dev/null
+++ b/app/models/spree/calculator/flat_percent_item_total_decorator.rb
@@ -0,0 +1,9 @@
+module Spree
+ Calculator::FlatPercentItemTotal.class_eval do
+ def compute(object)
+ item_total = line_items_for(object).map(&:amount).sum
+ value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0
+ (value * 100).round.to_f / 100
+ end
+ end
+end
diff --git a/app/models/spree/calculator/flexi_rate_decorator.rb b/app/models/spree/calculator/flexi_rate_decorator.rb
new file mode 100644
index 0000000000..c4ef6183c2
--- /dev/null
+++ b/app/models/spree/calculator/flexi_rate_decorator.rb
@@ -0,0 +1,19 @@
+module Spree
+ Calculator::FlexiRate.class_eval do
+ def compute(object)
+ sum = 0
+ max = self.preferred_max_items.to_i
+ items_count = line_items_for(object).map(&:quantity).sum
+ items_count.times do |i|
+ # check max value to avoid divide by 0 errors
+ if (max == 0 && i == 0) || (max > 0) && (i % max == 0)
+ sum += self.preferred_first_item.to_f
+ else
+ sum += self.preferred_additional_item.to_f
+ end
+ end
+
+ sum
+ end
+ end
+end
diff --git a/app/models/spree/calculator/per_item_decorator.rb b/app/models/spree/calculator/per_item_decorator.rb
new file mode 100644
index 0000000000..ebaaf6fc1c
--- /dev/null
+++ b/app/models/spree/calculator/per_item_decorator.rb
@@ -0,0 +1,15 @@
+module Spree
+ Calculator::PerItem.class_eval do
+ def compute(object=nil)
+ return 0 if object.nil?
+ self.preferred_amount * line_items_for(object).reduce(0) do |sum, value|
+ if matching_products.blank? || matching_products.include?(value.product)
+ value_to_add = value.quantity
+ else
+ value_to_add = 0
+ end
+ sum + value_to_add
+ end
+ end
+ end
+end
diff --git a/app/models/spree/calculator_decorator.rb b/app/models/spree/calculator_decorator.rb
new file mode 100644
index 0000000000..f8be4d00ef
--- /dev/null
+++ b/app/models/spree/calculator_decorator.rb
@@ -0,0 +1,18 @@
+module Spree
+ Calculator.class_eval do
+
+
+ private
+
+ # Given an object which might be an Order or a LineItem (amongst
+ # others), return a collection of line items.
+ def line_items_for(object)
+ if object.respond_to? :line_items
+ object.line_items
+ else
+ [object]
+ end
+ end
+
+ end
+end
diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb
index f6128a736d..c62f114177 100644
--- a/app/models/spree/order_decorator.rb
+++ b/app/models/spree/order_decorator.rb
@@ -35,7 +35,7 @@ Spree::Order.class_eval do
order.payment_required?
}
go_to_state :confirm, :if => lambda { |order| order.confirmation_required? }
- go_to_state :complete, :if => lambda { |order| (order.payment_required? && order.has_unprocessed_payments?) || !order.payment_required? }
+ go_to_state :complete
remove_transition :from => :delivery, :to => :confirm
end
diff --git a/app/models/spree/payment_method_decorator.rb b/app/models/spree/payment_method_decorator.rb
index 4a718dfc16..fb5faaef4c 100644
--- a/app/models/spree/payment_method_decorator.rb
+++ b/app/models/spree/payment_method_decorator.rb
@@ -1,4 +1,6 @@
Spree::PaymentMethod.class_eval do
+ Spree::PaymentMethod::DISPLAY = [:both, :front_end, :back_end]
+
acts_as_taggable
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id'
diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb
index f8c177ceac..40c6a6910b 100644
--- a/app/models/spree/product_decorator.rb
+++ b/app/models/spree/product_decorator.rb
@@ -187,9 +187,15 @@ Spree::Product.class_eval do
def delete_with_delete_from_order_cycles
transaction do
- delete_without_delete_from_order_cycles
+ OpenFoodNetwork::ProductsCache.product_deleted(self) do
+ # Touch supplier and distributors as we would on #destroy
+ self.supplier.touch
+ touch_distributors
- ExchangeVariant.where('exchange_variants.variant_id IN (?)', self.variants_including_master_and_deleted).destroy_all
+ ExchangeVariant.where('exchange_variants.variant_id IN (?)', self.variants_including_master_and_deleted).destroy_all
+
+ delete_without_delete_from_order_cycles
+ end
end
end
alias_method_chain :delete, :delete_from_order_cycles
@@ -215,7 +221,7 @@ Spree::Product.class_eval do
end
def touch_distributors
- Enterprise.distributing_product(self).each(&:touch)
+ Enterprise.distributing_products(self).each(&:touch)
end
def add_primary_taxon_to_taxons
diff --git a/app/models/spree/product_property_decorator.rb b/app/models/spree/product_property_decorator.rb
index 0f3329c03d..47414e92dc 100644
--- a/app/models/spree/product_property_decorator.rb
+++ b/app/models/spree/product_property_decorator.rb
@@ -1,8 +1,11 @@
module Spree
ProductProperty.class_eval do
+ belongs_to :product, class_name: "Spree::Product", touch: true
+
after_save :refresh_products_cache
after_destroy :refresh_products_cache
+
def refresh_products_cache
product.refresh_products_cache
end
diff --git a/app/models/spree/property_decorator.rb b/app/models/spree/property_decorator.rb
index 50e450a03b..81577cef4e 100644
--- a/app/models/spree/property_decorator.rb
+++ b/app/models/spree/property_decorator.rb
@@ -8,14 +8,18 @@ module Spree
where('spree_product_properties.product_id IN (?)', enterprise.supplied_product_ids)
}
- scope :sold_by, ->(shop) {
+ scope :ever_sold_by, ->(shop) {
joins(products: {variants: {exchanges: :order_cycle}}).
merge(Exchange.outgoing).
merge(Exchange.to_enterprise(shop)).
- merge(OrderCycle.active).
select('DISTINCT spree_properties.*')
}
+ scope :currently_sold_by, ->(shop) {
+ ever_sold_by(shop).
+ merge(OrderCycle.active)
+ }
+
after_save :refresh_products_cache
diff --git a/app/models/spree/taxon_decorator.rb b/app/models/spree/taxon_decorator.rb
index a051de98fa..1878a20e49 100644
--- a/app/models/spree/taxon_decorator.rb
+++ b/app/models/spree/taxon_decorator.rb
@@ -32,21 +32,24 @@ Spree::Taxon.class_eval do
end
# Find all the taxons of distributed products for each enterprise, indexed by enterprise.
+ # May return :all taxons (distributed in open and closed order cycles),
+ # or :current taxons (distributed in an open order cycle).
+ #
# Format: {enterprise_id => [taxon_id, ...]}
- def self.distributed_taxons
- taxons = {}
+ def self.distributed_taxons(which_taxons=:all)
+ # TODO: Why can't we merge(Spree::Product.with_order_cycles_inner) here?
+ taxons = Spree::Taxon.
+ joins(products: {variants_including_master: {exchanges: :order_cycle}}).
+ merge(Exchange.outgoing).
+ select('spree_taxons.*, exchanges.receiver_id AS enterprise_id')
- Spree::Taxon.
- joins(:products).
- merge(Spree::Product.with_order_cycles_outer).
- where('o_exchanges.incoming = ?', false).
- select('spree_taxons.*, o_exchanges.receiver_id AS enterprise_id').
- each do |t|
- taxons[t.enterprise_id.to_i] ||= Set.new
- taxons[t.enterprise_id.to_i] << t.id
- end
+ taxons = taxons.merge(OrderCycle.active) if which_taxons == :current
- taxons
+ taxons.inject({}) do |ts, t|
+ ts[t.enterprise_id.to_i] ||= Set.new
+ ts[t.enterprise_id.to_i] << t.id
+ ts
+ end
end
diff --git a/app/overrides/spree/orders/edit/promo_cart_coupon_code_field.html.haml.deface b/app/overrides/spree/orders/edit/promo_cart_coupon_code_field.html.haml.deface
new file mode 100644
index 0000000000..dca5725b49
--- /dev/null
+++ b/app/overrides/spree/orders/edit/promo_cart_coupon_code_field.html.haml.deface
@@ -0,0 +1 @@
+/ disabled
diff --git a/app/serializers/api/currency_config_serializer.rb b/app/serializers/api/currency_config_serializer.rb
index ab17af8715..100a4a0b84 100644
--- a/app/serializers/api/currency_config_serializer.rb
+++ b/app/serializers/api/currency_config_serializer.rb
@@ -1,5 +1,5 @@
class Api::CurrencyConfigSerializer < ActiveModel::Serializer
- attributes :currency, :display_currency, :symbol, :symbol_position, :hide_cents, :decimal_mark, :thousands_separator
+ attributes :currency, :display_currency, :symbol, :symbol_position, :hide_cents
def currency
Spree::Config[:currency]
@@ -13,20 +13,12 @@ class Api::CurrencyConfigSerializer < ActiveModel::Serializer
::Money.new(1, Spree::Config[:currency]).symbol
end
- def symbol_position
+ def symbol_position
Spree::Config[:currency_symbol_position]
end
- def hide_cents
+ def hide_cents
Spree::Config[:hide_cents]
end
- def decimal_mark
- Spree::Config[:currency_decimal_mark]
- end
-
- def thousands_separator
- Spree::Config[:currency_thousands_separator]
- end
-
end
diff --git a/app/serializers/api/enterprise_serializer.rb b/app/serializers/api/enterprise_serializer.rb
index f68c8be679..e3829174a2 100644
--- a/app/serializers/api/enterprise_serializer.rb
+++ b/app/serializers/api/enterprise_serializer.rb
@@ -20,9 +20,9 @@ class Api::EnterpriseSerializer < ActiveModel::Serializer
end
class Api::UncachedEnterpriseSerializer < ActiveModel::Serializer
+ include SerializerHelper
+
attributes :orders_close_at, :active
- has_many :supplied_properties, serializer: Api::PropertySerializer
- has_many :distributed_properties, serializer: Api::PropertySerializer
def orders_close_at
options[:data].earliest_closing_times[object.id]
@@ -31,26 +31,11 @@ class Api::UncachedEnterpriseSerializer < ActiveModel::Serializer
def active
options[:data].active_distributors.andand.include? object
end
-
- def supplied_properties
- # This results in 3 queries per enterprise
- product_properties = Spree::Property.applied_by(object)
- producer_properties = object.properties
-
- OpenFoodNetwork::PropertyMerge.merge product_properties, producer_properties
- end
-
- def distributed_properties
- # This results in 3 queries per enterprise
- product_properties = Spree::Property.sold_by(object)
- ids = ProducerProperty.sold_by(object).pluck(:property_id)
- producer_properties = Spree::Property.where(id: ids)
-
- OpenFoodNetwork::PropertyMerge.merge product_properties, producer_properties
- end
end
class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
+ include SerializerHelper
+
cached
#delegate :cache_key, to: :object
@@ -68,13 +53,9 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
attributes :taxons, :supplied_taxons
has_one :address, serializer: Api::AddressSerializer
- def taxons
- ids_to_objs options[:data].distributed_taxons[object.id]
- end
- def supplied_taxons
- ids_to_objs options[:data].supplied_taxons[object.id]
- end
+ has_many :supplied_properties, serializer: Api::PropertySerializer
+ has_many :distributed_properties, serializer: Api::PropertySerializer
def pickup
services = options[:data].shipping_method_services[object.id]
@@ -116,6 +97,47 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
ids_to_objs(relatives.andand[:distributors])
end
+ def taxons
+ if active
+ ids_to_objs options[:data].current_distributed_taxons[object.id]
+ else
+ ids_to_objs options[:data].all_distributed_taxons[object.id]
+ end
+ end
+
+ def supplied_taxons
+ ids_to_objs options[:data].supplied_taxons[object.id]
+ end
+
+ def supplied_properties
+ # This results in 3 queries per enterprise
+ product_properties = Spree::Property.applied_by(object)
+ producer_properties = object.properties
+
+ OpenFoodNetwork::PropertyMerge.merge product_properties, producer_properties
+ end
+
+ def distributed_properties
+ # This results in 3 queries per enterprise
+
+ if active
+ product_properties = Spree::Property.currently_sold_by(object)
+ producer_property_ids = ProducerProperty.currently_sold_by(object).pluck(:property_id)
+
+ else
+ product_properties = Spree::Property.ever_sold_by(object)
+ producer_property_ids = ProducerProperty.ever_sold_by(object).pluck(:property_id)
+ end
+
+ producer_properties = Spree::Property.where(id: producer_property_ids)
+
+ OpenFoodNetwork::PropertyMerge.merge product_properties, producer_properties
+ end
+
+ def active
+ options[:data].active_distributors.andand.include? object
+ end
+
# Map svg icons.
def icon
icons = {
@@ -153,12 +175,4 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
}
icon_fonts[object.category]
end
-
-
- private
-
- def ids_to_objs(ids)
- return [] if ids.blank?
- ids.map { |id| {id: id} }
- end
end
diff --git a/app/serializers/api/property_serializer.rb b/app/serializers/api/property_serializer.rb
index 7da4fce990..cdb3f2bae3 100644
--- a/app/serializers/api/property_serializer.rb
+++ b/app/serializers/api/property_serializer.rb
@@ -1,3 +1,9 @@
class Api::PropertySerializer < ActiveModel::Serializer
attributes :id, :name, :presentation
+
+ # Client-side we don't care about the property name. Send the presentation
+ # since this is what we want to show to the user.
+ def name
+ object.presentation
+ end
end
diff --git a/app/views/admin/account/show.html.haml b/app/views/admin/account/show.html.haml
index 808402ed16..b052b5b0a0 100644
--- a/app/views/admin/account/show.html.haml
+++ b/app/views/admin/account/show.html.haml
@@ -1,8 +1,6 @@
-
- content_for :page_title do
= t(:account)
-
- if @invoices.empty?
%h4= t(:no_invoices_to_display)
diff --git a/app/views/admin/accounts_and_billing_settings/edit.html.haml b/app/views/admin/accounts_and_billing_settings/edit.html.haml
index 72ce7920a9..83cfbbb76e 100644
--- a/app/views/admin/accounts_and_billing_settings/edit.html.haml
+++ b/app/views/admin/accounts_and_billing_settings/edit.html.haml
@@ -9,7 +9,7 @@
%fieldset.no-border-bottom
%legend
- =t :admin_settings
+ = t(:admin_settings)
= form_for @settings, as: :settings, url: main_app.admin_accounts_and_billing_settings_path, :method => :put do |f|
.row{ ng: { app: 'admin.accounts_and_billing_settings' } }
.twelve.columns.alpha.omega
diff --git a/app/views/admin/cache_settings/show.html.haml b/app/views/admin/cache_settings/show.html.haml
index 79b3e5acaf..f2069f0e55 100644
--- a/app/views/admin/cache_settings/show.html.haml
+++ b/app/views/admin/cache_settings/show.html.haml
@@ -4,10 +4,10 @@
%table.index
%thead
%tr
- %th Distributor
- %th Order Cycle
- %th Status
- %th Diff
+ %th= t('.distributor')
+ %th= t('.order_cycle')
+ %th= t('.status')
+ %th= t('.diff')
%tbody
- @results.each do |result|
%tr
diff --git a/app/views/admin/contents/edit.html.haml b/app/views/admin/contents/edit.html.haml
index 82751abebc..e0bdb0adc0 100644
--- a/app/views/admin/contents/edit.html.haml
+++ b/app/views/admin/contents/edit.html.haml
@@ -1,8 +1,7 @@
= render 'spree/admin/shared/configuration_menu'
- content_for :page_title do
- Content
-
+ = t('.title')
= form_tag main_app.admin_content_path, method: :put, multipart: true do
#preferences
diff --git a/app/views/admin/enterprise_fees/index.html.haml b/app/views/admin/enterprise_fees/index.html.haml
index ec62fa5d36..3a2dae96b1 100644
--- a/app/views/admin/enterprise_fees/index.html.haml
+++ b/app/views/admin/enterprise_fees/index.html.haml
@@ -1,5 +1,5 @@
= content_for :page_title do
- =t :Enterprise_Fees
+ = t('.title')
= ng_form_for @enterprise_fee_set, :url => main_app.bulk_update_admin_enterprise_fees_path, :html => {'ng-app' => 'admin.enterpriseFees', 'ng-controller' => 'enterpriseFeesCtrl'} do |enterprise_fee_set_form|
= hidden_field_tag 'enterprise_id', @enterprise.id if @enterprise
@@ -12,17 +12,17 @@
%thead
%tr
%th
- =t'Enterprise'
+ = t('.enterprise')
%th
- =t'fee_type'
+ = t('.fee_type')
%th
- =t'name'
+ = t('.name')
%th
- =t'tax_category'
+ = t('.tax_category')
%th
- =t'calculator'
+ = t('.calculator')
%th
- =t'calculator_values'
+ = t('.calculator_values')
%th.actions
%tbody
= enterprise_fee_set_form.ng_fields_for :collection do |f|
diff --git a/app/views/admin/enterprise_groups/index.html.haml b/app/views/admin/enterprise_groups/index.html.haml
index 747eff0b94..2540c64980 100644
--- a/app/views/admin/enterprise_groups/index.html.haml
+++ b/app/views/admin/enterprise_groups/index.html.haml
@@ -3,7 +3,7 @@
- if admin_user?
= content_for :page_actions do
- %li= button_link_to "New Enterprise Group", main_app.new_admin_enterprise_group_path
+ %li= button_link_to t('.new_button'), main_app.new_admin_enterprise_group_path
%table.index#listing_enterprise_groups
%thead
diff --git a/app/views/admin/enterprises/_actions.html.haml b/app/views/admin/enterprises/_actions.html.haml
index 5bcfc7a512..d5b3ae14a9 100644
--- a/app/views/admin/enterprises/_actions.html.haml
+++ b/app/views/admin/enterprises/_actions.html.haml
@@ -1,4 +1,4 @@
-= link_to_with_icon('icon-edit', 'Edit Profile', main_app.edit_admin_enterprise_path(enterprise), class: 'edit')
+= link_to_with_icon('icon-edit', t('.edit_profile'), main_app.edit_admin_enterprise_path(enterprise), class: 'edit')
%br/
- if can? :destroy, enterprise
@@ -6,27 +6,27 @@
%br/
- if enterprise.is_primary_producer
- = link_to_with_icon 'icon-dashboard', 'Properties', main_app.admin_enterprise_producer_properties_path(enterprise_id: enterprise)
+ = link_to_with_icon 'icon-dashboard', t('.properties'), main_app.admin_enterprise_producer_properties_path(enterprise_id: enterprise)
(#{enterprise.producer_properties.count})
%br/
- if enterprise.is_distributor
- if can?(:admin, Spree::PaymentMethod) && can?(:manage_payment_methods, enterprise)
- = link_to_with_icon 'icon-chevron-right', 'Payment Methods', spree.admin_payment_methods_path(enterprise_id: enterprise.id)
+ = link_to_with_icon 'icon-chevron-right', t('.payment_methods'), spree.admin_payment_methods_path(enterprise_id: enterprise.id)
(#{enterprise.payment_methods.count})
- if enterprise.payment_methods.count == 0
- %span.icon-exclamation-sign{"ofn-with-tip" => "This enterprise has no payment methods", style: "font-size: 16px;color: #DA5354"}
+ %span.icon-exclamation-sign{"ofn-with-tip" => t('.payment_methods_tip'), style: "font-size: 16px;color: #DA5354"}
%br/
- if can?(:admin, Spree::ShippingMethod) && can?(:manage_shipping_methods, enterprise)
- = link_to_with_icon 'icon-plane', 'Shipping Methods', spree.admin_shipping_methods_path(enterprise_id: enterprise.id)
+ = link_to_with_icon 'icon-plane', t('.shipping_methods'), spree.admin_shipping_methods_path(enterprise_id: enterprise.id)
(#{enterprise.shipping_methods.count})
- if enterprise.shipping_methods.count == 0
- %span.icon-exclamation-sign{"ofn-with-tip" => "This enterprise has shipping methods", style: "font-size: 16px;color: #DA5354"}
+ %span.icon-exclamation-sign{"ofn-with-tip" => t('.shipping_methods_tip'), style: "font-size: 16px;color: #DA5354"}
%br/
- if can?(:admin, EnterpriseFee) && can?(:manage_enterprise_fees, enterprise)
- = link_to_with_icon 'icon-money', 'Enterprise Fees', main_app.admin_enterprise_fees_path(enterprise_id: enterprise.id)
+ = link_to_with_icon 'icon-money', t('.enterprise_fees'), main_app.admin_enterprise_fees_path(enterprise_id: enterprise.id)
(#{enterprise.enterprise_fees.count})
- if enterprise.enterprise_fees.count == 0
- %span.icon-warning-sign{"ofn-with-tip" => "This enterprise has no fees", style: "font-size: 16px;color: orange"}
+ %span.icon-warning-sign{"ofn-with-tip" => t('.enterprise_fees_tip'), style: "font-size: 16px;color: orange"}
diff --git a/app/views/admin/enterprises/_admin_index.html.haml b/app/views/admin/enterprises/_admin_index.html.haml
index 2359f45f78..5e1eb4c92c 100644
--- a/app/views/admin/enterprises/_admin_index.html.haml
+++ b/app/views/admin/enterprises/_admin_index.html.haml
@@ -15,13 +15,13 @@
%col{style: "width: 25%;"}/
%thead
%tr{"data-hook" => "enterprises_header"}
- %th Name
- %th Role
+ %th= t('.name')
+ %th= t('.role')
- if spree_current_user.admin?
- %th Sells
- %th Visible?
+ %th= t('.sells')
+ %th= t('.visible')
- if spree_current_user.admin?
- %th Owner
+ %th= t('.owner')
%th
%tbody
= f.fields_for :collection do |enterprise_form|
@@ -30,7 +30,7 @@
%td= link_to enterprise.name, main_app.edit_admin_enterprise_path(enterprise)
%td
= enterprise_form.check_box :is_primary_producer
- Producer
+ = t('.producer')
- if spree_current_user.admin?
%td= enterprise_form.select :sells, Enterprise::SELLS, {}, class: 'select2 fullwidth'
%td= enterprise_form.check_box :visible
@@ -41,4 +41,4 @@
- if @enterprises.empty?
%tr
%td{colspan: "4"}= t(:none)
- = f.submit 'Update'
+ = f.submit t(:update)
diff --git a/app/views/admin/enterprises/_change_type_form.html.haml b/app/views/admin/enterprises/_change_type_form.html.haml
index ac5ca55821..a7c07ab87b 100644
--- a/app/views/admin/enterprises/_change_type_form.html.haml
+++ b/app/views/admin/enterprises/_change_type_form.html.haml
@@ -12,36 +12,36 @@
.basic_producer.option.one-third.column.alpha
%a.full-width.button.selector{ ng: { click: "sells='none'", class: "{selected: sells=='none'}" } }
.top
- %h3 Producer Profile
- %p Connect through OFN
- .bottom ALWAYS FREE
+ %h3= t('.producer_profile')
+ %p= t('.connect_ofn')
+ .bottom= t('.always_free')
%p.description
- Add your products to Open Food Network, allowing hubs to stock your products in their stores.
+ = t('.producer_description_text')
.producer_shop.option.one-third.column
%a.full-width.button.selector{ ng: { click: "sells='own'", class: "{selected: sells=='own'}" } }
.top
- %h3 Producer Shop
- %p Sell your own produce
+ %h3= t('.producer_shop')
+ %p= t('.sell_your_produce')
.bottom
%monthly-pricing-description{ joiner: "newline" }
%p.description
- Sell your products directly to customers through your very own Open Food Network shopfront.
+ = t('.producer_description_text')
%br
%br
- A Producer Shop is for your produce only, if you want to sell produce grown/produced off site, select 'Producer Hub'.
+ = t('.producer_description_text2')
.full_hub.option.one-third.column.omega
%a.full-width.button.selector{ ng: { click: "sells='any'", class: "{selected: sells=='any'}" } }
.top
- %h3 Producer Hub
- %p Sell produce from self and others
+ %h3= t('.producer_hub')
+ %p= t('.producer_hub_text')
.bottom
%monthly-pricing-description{ joiner: "newline" }
%p.description
- Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network.
+ = t('.producer_hub_description_text')
-# %p.description
-# Test out having your own shopfront with full access to all Shopfront features for 30 days.
@@ -55,38 +55,38 @@
.shop_profile.option.six.columns
%a.full-width.button.selector{ ng: { click: "sells='none'", class: "{selected: sells=='none'}" } }
.top
- %h3 Profile Only
- %p Get a listing
- .bottom ALWAYS FREE
+ %h3= t('.profile')
+ %p= t('.get_listing')
+ .bottom= t('.always_free')
%p.description
- People can find and contact you on the Open Food Network. Your enterprise will be visible on the map, and will be searchable in listings.
+ = t('.profile_description_text')
.full_hub.option.six.columns
%a.full-width.button.selector{ ng: { click: "sells='any'", class: "{selected: sells=='any'}" } }
.top
- %h3 Hub Shop
- %p Sell produce from others
+ %h3= t('.hub_shop')
+ %p= t('.hub_shop_text')
.bottom
%monthly-pricing-description{ joiner: "newline" }
%p.description
- Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network.
+ = t('.hub_shop_description_text')
.two.columns.omega
.row
.sixteen.columns.alpha
%span.error{ ng: { show: "(change_type.sells.$error.required || change_type.sells.$error.pattern) && submitted" } }
- Please choose one of the options above.
+ = t('.choose_option')
- if @enterprise.sells == 'unspecified' && @enterprise.shop_trial_start_date.nil?
-if free_use?
- %input.button.big{ type: 'submit', value: 'Select and continue', ng: { click: "submit(change_type)" } }
+ %input.button.big{ type: 'submit', value: t(:select_continue), ng: { click: "submit(change_type)" } }
- else
- trial_length = Spree::Config[:shop_trial_length_days]
%input.button.big{ type: 'submit', value: "Start #{trial_length}-Day Shop Trial", ng: { click: "submit(change_type)", show: "sells=='own' || sells=='any'" } }
- %input.button.big{ type: 'submit', value: 'Select and continue', ng: { click: "submit(change_type)", hide: "sells=='own' || sells=='any'" } }
+ %input.button.big{ type: 'submit', value: t(:select_continue), ng: { click: "submit(change_type)", hide: "sells=='own' || sells=='any'" } }
- elsif @enterprise.sells == 'unspecified'
- %input.button.big{ type: 'submit', value: 'Select and continue', ng: { click: "submit(change_type)" } }
+ %input.button.big{ type: 'submit', value: t(:select_continue), ng: { click: "submit(change_type)" } }
- else
- %input.button.big{ type: 'submit', value: 'Change now', ng: { click: "submit(change_type)" } }
+ %input.button.big{ type: 'submit', value: t('.change_now'), ng: { click: "submit(change_type)" } }
%br
%hr
diff --git a/app/views/admin/enterprises/_enterprise_user_index.html.haml b/app/views/admin/enterprises/_enterprise_user_index.html.haml
index d89970946d..4b777e127b 100644
--- a/app/views/admin/enterprises/_enterprise_user_index.html.haml
+++ b/app/views/admin/enterprises/_enterprise_user_index.html.haml
@@ -2,7 +2,7 @@
.row{ 'ng-hide' => '!loaded' }
.controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" }
.four.columns.alpha
- %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Search By Name' }
+ %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => t('.search_placeholder') }
.six.columns
-# = render 'admin/shared/bulk_actions_dropdown'
.three.columns
@@ -41,7 +41,7 @@
%i.icon-status{ ng: { class: "enterprise.status" } }
%td.manage{ ng: { show: 'columns.manage.visible' } }
%a.button.fullwidth{ ng: { href: '{{::enterprise.edit_path}}' } }
- Manage
+ = t('.manage')
%i.icon-arrow-right
%tr.panel-row{ object: "enterprise", panels: "{producer: 'enterprise_producer', package: 'enterprise_package', status: 'enterprise_status'}" }
diff --git a/app/views/admin/enterprises/_new_form.html.haml b/app/views/admin/enterprises/_new_form.html.haml
index ba8fce56ae..f04e55acd6 100644
--- a/app/views/admin/enterprises/_new_form.html.haml
+++ b/app/views/admin/enterprises/_new_form.html.haml
@@ -1,98 +1,97 @@
.row
.three.columns.alpha
- = f.label :name
+ = f.label :name, t('admin.enterprises.form.primary_details.name')
%span.required *
.nine.columns.omega
- = f.text_field :name, { placeholder: "eg. Professor Plum's Biodynamic Truffles", class: "fullwidth" }
+ = f.text_field :name, { placeholder: t('admin.enterprises.form.primary_details.name_placeholder'), class: "fullwidth" }
- if spree_current_user.admin?
.row
.three.columns.alpha
- =f.label :owner_id, 'Owner'
+ =f.label :owner_id, t('.owner')
%span.required *
- %div{'ofn-with-tip' => "The primary user responsible for this enterprise."}
- %a What's this?
+ %div{'ofn-with-tip' => t('.owner_tip')}
+ %a= t('admin.whats_this')
.nine.columns.omega
- owner_email = @enterprise.andand.owner.andand.email || ""
= f.hidden_field :owner_id, class: "select2 fullwidth", 'user-select' => 'Enterprise.owner'
.row
.three.columns.alpha
- %label Primary Producer?
- %div{'ofn-with-tip' => "Select 'Producer' if you are a primary producer of food."}
- %a What's this?
+ %label= t('admin.enterprises.form.primary_details.primary_producer')
+ %div{'ofn-with-tip' => t('admin.enterprises.form.primary_details.primary_producer_tip')}
+ %a= t('admin.whats_this')
.five.columns.omega
= f.check_box :is_primary_producer, 'ng-model' => 'Enterprise.is_primary_producer'
- = f.label :is_primary_producer, 'I am a Producer'
+ = f.label :is_primary_producer, t('.i_am_producer')
- if spree_current_user.admin?
.row
.alpha.eleven.columns
.three.columns.alpha
- = f.label :sells, 'Sells'
- %div{'ofn-with-tip' => "None - enterprise does not sell to customers directly.
Own - Enterprise sells own products to customers.
Any - Enterprise can sell own or other enterprises products.
"}
+ = f.label :sells, t('admin.enterprises.form.primary_details.sells')
+ %div{'ofn-with-tip' => t('admin.enterprises.form.primary_details.sells_tip')}
%a What's this?
.two.columns
= f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells'
- = f.label :sells, "None", value: "none"
+ = f.label :sells, t('admin.enterprises.form.primary_details.none'), value: "none"
.two.columns
= f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells'
- = f.label :sells, "Own", value: "own"
+ = f.label :sells, t('admin.enterprises.form.primary_details.own'), value: "own"
.four.columns.omega
= f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells'
- = f.label :sells, "Any", value: "any"
-
+ = f.label :sells, t('admin.enterprises.form.primary_details.any'), value: "any"
.row
.alpha.three.columns
- = f.label :contact, 'Contact Name'
+ = f.label :contact, t('.contact_name')
.omega.nine.columns
- = f.text_field :contact, { placeholder: "eg. Gustav Plum"}
+ = f.text_field :contact, { placeholder: t('admin.enterprises.form.contact.name_placeholder')}
.row
.alpha.three.columns
- = f.label :email_address
+ = f.label :email_address, t('admin.enterprises.form.contact.email_address')
.omega.nine.columns
- = f.text_field :email_address, { placeholder: "eg. gustav@truffles.com", "ng-model" => "Enterprise.email_address" }
+ = f.text_field :email_address, { placeholder: t('admin.enterprises.form.contact.email_address_placeholder'), "ng-model" => "Enterprise.email_address" }
.row
.alpha.three.columns
- = f.label :phone
+ = f.label :phone, t('admin.enterprises.form.contact.phone')
.omega.nine.columns
- = f.text_field :phone, { placeholder: "eg. 98 7654 3210"}
+ = f.text_field :phone, { placeholder: t('admin.enterprises.form.contact.phone_placeholder')}
.row
.alpha.three.columns
- = f.label :website
+ = f.label :website, t('admin.enterprises.form.contact.website')
.omega.nine.columns
- = f.text_field :website, { placeholder: "eg. www.truffles.com"}
+ = f.text_field :website, { placeholder: t('admin.enterprises.form.contact.website_placeholder')}
= f.fields_for :address do |af|
.row
.three.columns.alpha
- = af.label :address1
+ = af.label :address1, t(:address)
%span.required *
.nine.columns.omega
- = af.text_field :address1, { placeholder: "eg. 123 High Street"}
+ = af.text_field :address1, { placeholder: t(:address_placeholder)}
.row
.alpha.three.columns
- = af.label :address2
+ = af.label :address2, t(:address2)
.nine.columns.omega
= af.text_field :address2
.row
.three.columns.alpha
- = af.label :city, 'Suburb'
+ = af.label :city, t(:city)
\/
- = af.label :zipcode, 'Postcode'
+ = af.label :zipcode, t(:postcode)
%span.required *
.four.columns
- = af.text_field :city, { placeholder: "eg. Northcote"}
+ = af.text_field :city, { placeholder: t(:city_placeholder)}
.five.columns.omega
- = af.text_field :zipcode, { placeholder: "eg. 3070"}
+ = af.text_field :zipcode, { placeholder: t(:postcode_placeholder)}
.row
.three.columns.alpha
- = af.label :state_id, 'State'
+ = af.label :state_id, t(:state)
\/
- = af.label :country_id, 'Country'
+ = af.label :country_id, t(:country)
.four.columns
= af.collection_select :state_id, af.object.country.states, :id, :name, {}, :class => "select2 fullwidth"
.five.columns.omega
diff --git a/app/views/admin/enterprises/_ng_form.html.haml b/app/views/admin/enterprises/_ng_form.html.haml
index ca38b7eca4..17b649bcc6 100644
--- a/app/views/admin/enterprises/_ng_form.html.haml
+++ b/app/views/admin/enterprises/_ng_form.html.haml
@@ -8,8 +8,8 @@
} do |f|
%save-bar{ dirty: "enterprise_form.$dirty", persist: "true" }
- %input.red{ type: "button", value: "Update", ng: { click: "submit()", disabled: "!enterprise_form.$dirty" } }
- %input{ type: "button", ng: { value: "enterprise_form.$dirty ? 'Cancel' : 'Close'", click: "cancel('#{main_app.admin_enterprises_path}')" } }
+ %input.red{ type: "button", value: t(:update), ng: { click: "submit()", disabled: "!enterprise_form.$dirty" } }
+ %input{ type: "button", ng: { value: "enterprise_form.$dirty ? '#{t(:cancel)}' : '#{t(:close)}'", click: "cancel('#{main_app.admin_enterprises_path}')" } }
diff --git a/app/views/admin/enterprises/edit.html.haml b/app/views/admin/enterprises/edit.html.haml
index 5d3a623f40..2e53f3e2c0 100644
--- a/app/views/admin/enterprises/edit.html.haml
+++ b/app/views/admin/enterprises/edit.html.haml
@@ -1,12 +1,11 @@
-= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise }
+= render partial: 'spree/shared/error_messages', locals: { target: @enterprise }
- content_for :page_title do
- Editing:
+ = t('.editing')
= @enterprise.name
- content_for :page_actions do
- %li= button_link_to "Back to enterprises list", main_app.admin_enterprises_path, icon: 'icon-arrow-left'
-
+ %li= button_link_to t('.back_link'), main_app.admin_enterprises_path, icon: 'icon-arrow-left'
= render 'admin/enterprises/form_data'
diff --git a/app/views/admin/enterprises/form/_about_us.html.haml b/app/views/admin/enterprises/form/_about_us.html.haml
index a04437dad0..32550b711b 100644
--- a/app/views/admin/enterprises/form/_about_us.html.haml
+++ b/app/views/admin/enterprises/form/_about_us.html.haml
@@ -1,11 +1,11 @@
.row
.alpha.three.columns
- = f.label :description, 'Short Description'
+ = f.label :description, t('.desc_short')
.omega.eight.columns
- = f.text_field :description, maxlength: 255, placeholder: 'Tell us about your enterprise in one or two sentences'
+ = f.text_field :description, maxlength: 255, placeholder: t('.desc_short_placeholder')
.row
.alpha.three.columns
- = f.label :long_description, 'About Us'
+ = f.label :long_description, t('.desc_long')
.omega.eight.columns
-# textAngular toolbar options, add to the ta-toolbar array below and separate into groups with extra ],[ if needed:
-# ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'quote'],
@@ -14,4 +14,4 @@
-# ['html', 'insertImage', 'insertLink', 'insertVideo']
%text-angular{'ng-model' => 'Enterprise.long_description', 'id' => 'enterprise_long_description', 'name' => 'enterprise[long_description]', 'class' => 'text-angular',
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
- 'placeholder' => 'Tell customers about yourself. This information appears on your public profile.'}
\ No newline at end of file
+ 'placeholder' => t('.desc_long_placeholder')}
\ No newline at end of file
diff --git a/app/views/admin/enterprises/form/_address.html.haml b/app/views/admin/enterprises/form/_address.html.haml
index 68ae7d68bf..a1485d485f 100644
--- a/app/views/admin/enterprises/form/_address.html.haml
+++ b/app/views/admin/enterprises/form/_address.html.haml
@@ -1,34 +1,35 @@
-# redo denoting required fields in the whole project
.row
- Required fields are denoted with an asterisk (
+ = t(:required_fields)
+ (
%span.required *
)
.row
.three.columns.alpha
- = af.label :address1
+ = af.label :address1, t(:address)
%span.required *
.eight.columns.omega
- = af.text_field :address1, { placeholder: "eg. 123 High Street"}
+ = af.text_field :address1, { placeholder: t(:address_placeholder) }
.row
.alpha.three.columns
- = af.label :address2
+ = af.label :address2, t(:address2)
.eight.columns.omega
= af.text_field :address2
.row
.three.columns.alpha
- = af.label :city, 'Suburb'
+ = af.label :city, t(:city)
\/
- = af.label :zipcode, 'Postcode'
+ = af.label :zipcode, t(:postcode)
%span.required *
.four.columns
- = af.text_field :city, { placeholder: "eg. Northcote"}
+ = af.text_field :city, { placeholder: t(:city_placeholder) }
.four.columns.omega
- = af.text_field :zipcode, { placeholder: "eg. 3070"}
+ = af.text_field :zipcode, { placeholder: t(:postcode_placeholder) }
.row
.three.columns.alpha
- = af.label :state_id, 'State'
+ = af.label :state_id, t(:state)
\/
- = af.label :country_id, 'Country'
+ = af.label :country_id, t(:country)
%span.required *
.four.columns
= af.collection_select :state_id, af.object.country.states, :id, :name, {}, :class => "select2 fullwidth"
diff --git a/app/views/admin/enterprises/form/_business_details.html.haml b/app/views/admin/enterprises/form/_business_details.html.haml
index 92f727d8d3..4015e51282 100644
--- a/app/views/admin/enterprises/form/_business_details.html.haml
+++ b/app/views/admin/enterprises/form/_business_details.html.haml
@@ -1,14 +1,14 @@
.row
.alpha.three.columns
- = f.label :abn, 'ABN'
+ = f.label :abn, t('.abn')
.omega.eight.columns
- = f.text_field :abn, { placeholder: "eg. 99 123 456 789"}
+ = f.text_field :abn, { placeholder: t('.abn_placeholder') }
.row
.alpha.three.columns
- = f.label :acn, 'ACN'
+ = f.label :acn, t('.acn')
.omega.eight.columns
- = f.text_field :acn, { placeholder: "eg. 123 456 789"}
+ = f.text_field :acn, { placeholder: t('.acn_placeholder') }
.row
.three.columns.alpha
@@ -16,8 +16,8 @@
.two.columns
= f.radio_button :charges_sales_tax, true
- = f.label :charges_sales_tax, "Yes", :value => "true"
+ = f.label :charges_sales_tax, t(:say_yes), value: 'true'
.five.columns.omega
= f.radio_button :charges_sales_tax, false
- = f.label :charges_sales_tax, "No", :value => "false"
+ = f.label :charges_sales_tax, t(:say_no), value: 'false'
diff --git a/app/views/admin/enterprises/form/_contact.html.haml b/app/views/admin/enterprises/form/_contact.html.haml
index 28bbd6014b..1a7fa792f1 100644
--- a/app/views/admin/enterprises/form/_contact.html.haml
+++ b/app/views/admin/enterprises/form/_contact.html.haml
@@ -1,20 +1,20 @@
.row
.alpha.three.columns
- = f.label :contact, 'Name'
+ = f.label :contact, t('.name')
.omega.eight.columns
- = f.text_field :contact, { placeholder: "eg. Gustav Plum"}
+ = f.text_field :contact, { placeholder: t('.name_placeholder') }
.row
.alpha.three.columns
- = f.label :email_address
+ = f.label :email_address, t('.email_address')
.omega.eight.columns
- = f.text_field :email_address, { placeholder: "eg. gustav@truffles.com" }
+ = f.text_field :email_address, { placeholder: t('.email_address_placeholder') }
.row
.alpha.three.columns
- = f.label :phone
+ = f.label :phone, t('.phone')
.omega.eight.columns
- = f.text_field :phone, { placeholder: "eg. 98 7654 3210"}
+ = f.text_field :phone, { placeholder: t('.phone_placeholder') }
.row
.alpha.three.columns
- = f.label :website
+ = f.label :website, t('.website')
.omega.eight.columns
- = f.text_field :website, { placeholder: "eg. www.truffles.com"}
+ = f.text_field :website, { placeholder: t('.website_placeholder') }
diff --git a/app/views/admin/enterprises/form/_enterprise_fees.html.haml b/app/views/admin/enterprises/form/_enterprise_fees.html.haml
index 53e48f1be9..dcae9afbc4 100644
--- a/app/views/admin/enterprises/form/_enterprise_fees.html.haml
+++ b/app/views/admin/enterprises/form/_enterprise_fees.html.haml
@@ -2,8 +2,8 @@
%table
%thead
%tr
- %th Name
- %th Fee Type
+ %th= t('.name')
+ %th= t('.fee_type')
-# %th Calculator
-# %th Calculator Values
%tbody
@@ -16,15 +16,15 @@
%br
%div
%a.button{ href: "#{main_app.admin_enterprise_fees_path}"}
- Manage Enterprise Fees
+ = t('.manage_fees')
%i.icon-arrow-right
- else
%p.text-center
- You don't have any enterprise fees yet.
+ = t('.no_fees_yet')
%br
.text-center
%a.button{ href: "#{main_app.admin_enterprise_fees_path}"}
- Create One Now
+ = t('.create_button')
%i.icon-arrow-right
diff --git a/app/views/admin/enterprises/form/_images.html.haml b/app/views/admin/enterprises/form/_images.html.haml
index c03be2caa3..97d31dabcc 100644
--- a/app/views/admin/enterprises/form/_images.html.haml
+++ b/app/views/admin/enterprises/form/_images.html.haml
@@ -8,11 +8,13 @@
= f.file_field :logo
.row
.alpha.three.columns
- = f.label :promo_image, 'ofn-with-tip' => 'This image is displayed in "About Us"'
+ = f.label :promo_image, 'ofn-with-tip' => t('.promo_image_placeholder')
%br/
- %span{ style: 'font-weight:bold' } PLEASE NOTE:
- Any promo image uploaded here will be cropped to 1200 x 260.
- The promo image is displayed at the top of an enterprise's profile page and pop-ups.
+ %span{ style: 'font-weight:bold' }= t('.promo_image_note1')
+ %br
+ = t('.promo_image_note2')
+ %br
+ = t('.promo_image_note3')
.omega.eight.columns
= image_tag @object.promo_image(:large) if @object.promo_image.present?
diff --git a/app/views/admin/enterprises/form/_inventory_settings.html.haml b/app/views/admin/enterprises/form/_inventory_settings.html.haml
index 0df0fdb35f..c055a1231f 100644
--- a/app/views/admin/enterprises/form/_inventory_settings.html.haml
+++ b/app/views/admin/enterprises/form/_inventory_settings.html.haml
@@ -3,16 +3,17 @@
-# their inventory if they so choose
.row
.alpha.eleven.columns
- You may opt to manage stock levels and prices in via your
+ = t('.text1')
= succeed "." do
%strong
- %a{href: main_app.admin_inventory_path } inventory
- If you are using the inventory tool, you can select whether new products added by your suppliers need to be added to your inventory before they can be stocked. If you are not using your inventory to manage your products you should select the 'recommended' option below:
+ %a{href: main_app.admin_inventory_path }= t('.inventory')
+ %br
+ = t('.text2')
.row
.alpha.eleven.columns
.five.columns.alpha
= radio_button :enterprise, :preferred_product_selection_from_inventory_only, "0", { 'ng-model' => 'Enterprise.preferred_product_selection_from_inventory_only' }
- = label :enterprise, :preferred_product_selection_from_inventory_only, "New products can be put into my shopfront (recommended)"
+ = label :enterprise, :preferred_product_selection_from_inventory_only, t('.preferred_product_selection_from_inventory_only_yes')
.six.columns.omega
= radio_button :enterprise, :preferred_product_selection_from_inventory_only, "1", { 'ng-model' => 'Enterprise.preferred_product_selection_from_inventory_only' }
- = label :enterprise, :preferred_product_selection_from_inventory_only, "New products must be added to my inventory before they can be put into my shopfront"
+ = label :enterprise, :preferred_product_selection_from_inventory_only, t('.preferred_product_selection_from_inventory_only_no')
diff --git a/app/views/admin/enterprises/form/_payment_methods.html.haml b/app/views/admin/enterprises/form/_payment_methods.html.haml
index 57d9426d03..efcde16dc0 100644
--- a/app/views/admin/enterprises/form/_payment_methods.html.haml
+++ b/app/views/admin/enterprises/form/_payment_methods.html.haml
@@ -2,32 +2,32 @@
%table
%thead
%tr
- %th Name
- %th Applies?
+ %th= t('.name')
+ %th= t('.applies')
%th
%tbody
- @payment_methods.each do |payment_method|
%tr{ ng: { controller: 'paymentMethodsCtrl', init: "findPaymentMethodByID(#{payment_method.id})" } }
%td= payment_method.name
%td= f.check_box :payment_method_ids, { multiple: true, 'ng-model' => 'PaymentMethod.selected' }, payment_method.id, nil
- %td= link_to "Edit", edit_admin_payment_method_path(payment_method)
+ %td= link_to t(:edit), edit_admin_payment_method_path(payment_method)
%br
.row
.six.columns.alpha
%a.button{ href: "#{admin_payment_methods_path}"}
- Manage Payment Methods
+ = t('.manage')
%i.icon-arrow-right
.five.columns.omega.text-right
%a.button{ href: "#{new_admin_payment_method_path}"}
- Create New Payment Method
+ = t('.create_button')
%i.icon-plus
- else
%p.text-center
- You don't have any payment methods yet.
+ = t('.no_method_yet')
%br
.text-center
%a.button{ href: "#{new_admin_payment_method_path}"}
- Create One Now
+ = t('.create_one_button')
%i.icon-arrow-right
diff --git a/app/views/admin/enterprises/form/_primary_details.html.haml b/app/views/admin/enterprises/form/_primary_details.html.haml
index 52b2ffebce..aad869288e 100644
--- a/app/views/admin/enterprises/form/_primary_details.html.haml
+++ b/app/views/admin/enterprises/form/_primary_details.html.haml
@@ -1,61 +1,61 @@
.row
.alpha.eleven.columns
.three.columns.alpha
- = f.label :name
+ = f.label :name, t('.name')
%span.required *
.eight.columns.omega
- = f.text_field :name, { placeholder: "eg. Professor Plum's Biodynamic Truffles" }
+ = f.text_field :name, { placeholder: t('.name_placeholder') }
- if @groups.present?
.row
.alpha.eleven.columns
.three.columns.alpha
- = f.label :group_ids, 'Groups'
- %div{'ofn-with-tip' => "Select any groups or regions that you are a member of. This will help customers find your enterprise."}
- %a What's this?
+ = f.label :group_ids, t('.groups')
+ %div{'ofn-with-tip' => t('.groups_tip')}
+ %a= t('admin.whats_this')
.eight.columns.omega
- = f.collection_select :group_ids, @groups, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: "Start typing to search available groups..."
+ = f.collection_select :group_ids, @groups, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: t('.groups_placeholder')
.row
.three.columns.alpha
- %label Primary Producer
- %div{'ofn-with-tip' => "Select 'Producer' if you are a primary producer of food."}
- %a What's this?
+ %label= t('.primary_producer')
+ %div{'ofn-with-tip' => t('.primary_producer_tip')}
+ %a= t('admin.whats_this')
.five.columns.omega
= f.check_box :is_primary_producer, 'ng-model' => 'Enterprise.is_primary_producer'
- = f.label :is_primary_producer, 'Producer'
+ = f.label :is_primary_producer, t('.producer')
- if spree_current_user.admin?
.row
.alpha.eleven.columns
.three.columns.alpha
- = f.label :sells, 'Sells'
- %div{'ofn-with-tip' => "None - enterprise does not sell to customers directly.
Own - Enterprise sells own products to customers.
Any - Enterprise can sell own or other enterprises products.
"}
- %a What's this?
+ = f.label :sells, t('.sells')
+ %div{'ofn-with-tip' => t('.sells_tip')}
+ %a= t('admin.whats_this')
.two.columns
= f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells'
- = f.label :sells, "None", value: "none"
+ = f.label :sells, t('.none'), value: "none"
.two.columns
= f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells'
- = f.label :sells, "Own", value: "own"
+ = f.label :sells, t('.own'), value: "own"
.four.columns.omega
= f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells'
- = f.label :sells, "Any", value: "any"
+ = f.label :sells, t('.any'), value: "any"
.row
.three.columns.alpha
- %label Visible in search?
- %div{'ofn-with-tip' => "Determines whether this enterprise will be visible to customers when searching the site."}
- %a What's this?
+ %label= t('.visible_in_search')
+ %div{'ofn-with-tip' => t('.visible_in_search_tip')}
+ %a= t('admin.whats_this')
.two.columns
= f.radio_button :visible, true
- = f.label :visible, "Visible", :value => "true"
+ = f.label :visible, t('.visible'), value: 'true'
.five.columns.omega
= f.radio_button :visible, false
- = f.label :visible, "Not Visible", :value => "false"
+ = f.label :visible, t('.not_visible'), value: 'false'
.permalink{ ng: { controller: "permalinkCtrl" } }
.row{ ng: { show: "Enterprise.sells == 'own' || Enterprise.sells == 'any'" } }
.three.columns.alpha
- = f.label :permalink, 'Permalink (no spaces)'
- %div{'ofn-with-tip' => "This permalink is used to create the url to your shop: #{spree.root_url}your-shop-name/shop"}
- %a What's this?
+ = f.label :permalink, t('.permalink')
+ %div{'ofn-with-tip' => t('.permalink_tip', link: spree.root_url)}
+ %a= t('admin.whats_this')
.six.columns
= f.text_field :permalink, { 'ng-model' => "Enterprise.permalink", placeholder: "eg. your-shop-name", 'ng-model-options' => "{ updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }" }
.two.columns.omega
@@ -65,9 +65,9 @@
%i{ ng: { class: "{'icon-ok-sign': availability == 'Available', 'icon-remove-sign': availability == 'Unavailable'}" } }
.row{ ng: { show: "Enterprise.sells == 'own' || Enterprise.sells == 'any'" } }
.three.columns.alpha
- %label Link to shop front
- %div{'ofn-with-tip' => "A direct link to your shopfront on the Open Food Network."}
- %a What's this?
+ %label= t('.link_to_front')
+ %div{'ofn-with-tip' => t('.link_to_front_tip')}
+ %a= t('admin.whats_this')
.eight.columns.omega
= surround spree.root_url, "/shop" do
{{Enterprise.permalink}}
diff --git a/app/views/admin/enterprises/form/_properties.html.haml b/app/views/admin/enterprises/form/_properties.html.haml
index 795a104f1a..e3271435db 100644
--- a/app/views/admin/enterprises/form/_properties.html.haml
+++ b/app/views/admin/enterprises/form/_properties.html.haml
@@ -1,12 +1 @@
= render 'admin/producer_properties/form', f: f
-
-// :javascript
-// var properties = #{raw(@properties.to_json)};
-//
-// $("#producer_properties input.autocomplete").live("keydown", function() {
-// already_auto_completed = $(this).is('ac_input');
-// if (!already_auto_completed) {
-// $(this).autocomplete({source: properties});
-// $(this).focus();
-// }
-// });
diff --git a/app/views/admin/enterprises/form/_shipping_methods.html.haml b/app/views/admin/enterprises/form/_shipping_methods.html.haml
index 5ccc22a720..db7daa5b98 100644
--- a/app/views/admin/enterprises/form/_shipping_methods.html.haml
+++ b/app/views/admin/enterprises/form/_shipping_methods.html.haml
@@ -2,8 +2,8 @@
%table
%thead
%tr
- %th Name
- %th Applies?
+ %th= t('.name')
+ %th= t('.applies')
%th
%tbody
- @shipping_methods.each do |shipping_method|
@@ -15,19 +15,19 @@
.row
.six.columns.alpha
%a.button{ href: "#{admin_shipping_methods_path}"}
- Manage Shipping Methods
+ = t('.manage')
%i.icon-arrow-right
.five.columns.omega.text-right
%a.button{ href: "#{new_admin_shipping_method_path}"}
- Create New Shipping Method
+ = t('.create_button')
%i.icon-plus
- else
%p.text-center
- You don't have any shipping methods yet.
+ = t('.no_method_yet')
%br
.text-center
%a.button{ href: "#{new_admin_shipping_method_path}"}
- Create One Now
+ = t('.create_one_button')
%i.icon-arrow-right
diff --git a/app/views/admin/enterprises/form/_shop_preferences.html.haml b/app/views/admin/enterprises/form/_shop_preferences.html.haml
index 6573e4f3b4..0e5a1096f0 100644
--- a/app/views/admin/enterprises/form/_shop_preferences.html.haml
+++ b/app/views/admin/enterprises/form/_shop_preferences.html.haml
@@ -5,7 +5,7 @@
.eight.columns.omega
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_message', 'id' => 'enterprise_preferred_shopfront_message', 'name' => 'enterprise[preferred_shopfront_message]', 'class' => 'text-angular',
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
- 'placeholder' => 'An optional explanation for customers detailing how your shopfront works, to be displayed above the product list on your shop page.'}
+ 'placeholder' => t('.shopfront_message_placeholder')}
.row
.alpha.eleven.columns
.three.columns.alpha
@@ -13,7 +13,7 @@
.eight.columns.omega
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular',
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
- 'placeholder' => 'A message which provides a more detailed explanation about why your shop is closed and/or when customers can expect it to open again. This is displayed on your shop only when you have no active order cycles (ie. shop is closed).'}
+ 'placeholder' => t('.shopfront_closed_message_placeholder')}
.row
.alpha.eleven.columns
.three.columns.alpha
@@ -29,10 +29,10 @@
= f.label "enterprise_preferred_shopfront_order_cycle_order", t(:sort_order_cycles_on_shopfront_by)
.three.columns
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_open_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
- = label :enterprise, :preferred_shopfront_order_cycle_order_orders_open_at, "Open Date"
+ = label :enterprise, :preferred_shopfront_order_cycle_order_orders_open_at, t('.open_date')
.five.columns.omega
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_close_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
- = label :enterprise, :preferred_shopfront_order_cycle_order_orders_close_at, "Close Date"
+ = label :enterprise, :preferred_shopfront_order_cycle_order_orders_close_at, t('.close_date')
.row
.alpha.eleven.columns
.three.columns.alpha
diff --git a/app/views/admin/enterprises/form/_social.html.haml b/app/views/admin/enterprises/form/_social.html.haml
index 1909a6fc4a..11939739c1 100644
--- a/app/views/admin/enterprises/form/_social.html.haml
+++ b/app/views/admin/enterprises/form/_social.html.haml
@@ -17,4 +17,4 @@
.alpha.three.columns
= f.label :twitter
.omega.eight.columns
- = f.text_field :twitter, { placeholder: "eg. @the_prof" }
\ No newline at end of file
+ = f.text_field :twitter, { placeholder: t('.twitter_placeholder') }
\ No newline at end of file
diff --git a/app/views/admin/enterprises/form/_tag_rules.html.haml b/app/views/admin/enterprises/form/_tag_rules.html.haml
index e58f7c5a62..822ea3f1ff 100644
--- a/app/views/admin/enterprises/form/_tag_rules.html.haml
+++ b/app/views/admin/enterprises/form/_tag_rules.html.haml
@@ -2,7 +2,7 @@
.eleven.columns.alpha.omega
%ofn-sortable{ axis: "y", handle: ".header", items: '.customer_tag', position: "tagGroup.position", after: { sort: "updateRuleCounts()" } }
.no_tags{ ng: { show: "tagGroups.length == 0" } }
- No tags apply to this enterprise yet
+ = t('.no_tags_yet')
= render 'admin/enterprises/form/tag_rules/default_rules'
-# = render 'customer_tags'
.customer_tag{ id: "tg_{{tagGroup.position}}", ng: { repeat: "tagGroup in tagGroups" } }
@@ -14,14 +14,14 @@
%tr
%td
%h5
- For customers tagged:
+ = t('.for_customers_tagged')
%td
%tags-with-translation{ object: "tagGroup", max: 1, on: { tag: { added: "updateTagsRulesFor(tagGroup)", removed: "updateTagsRulesFor(tagGroup)" } } }
.no_rules{ ng: { show: "tagGroup.rules.length == 0" } }
- No rules apply to this tag yet
+ = t('.no_rules_yet')
.tag_rule{ ng: { repeat: "rule in tagGroup.rules" } }
.add_rule.text-center
- %input.button.icon-plus{ type: 'button', value: "+ Add A New Rule", "add-new-rule-to" => "addNewRuleTo", "tag-group" => "tagGroup", "new-tag-rule-dialog" => true }
+ %input.button.icon-plus{ type: 'button', value: t('.add_new_rule'), "add-new-rule-to" => "addNewRuleTo", "tag-group" => "tagGroup", "new-tag-rule-dialog" => true }
.add_tag
- %input.button.red.icon-plus{ type: 'button', value: "+ Add A New Tag", ng: { click: 'addNewTag()' } }
+ %input.button.red.icon-plus{ type: 'button', value: t('.add_new_tag'), ng: { click: 'addNewTag()' } }
diff --git a/app/views/admin/enterprises/form/_users.html.haml b/app/views/admin/enterprises/form/_users.html.haml
index 42e25fad0a..a0b5b7e662 100644
--- a/app/views/admin/enterprises/form/_users.html.haml
+++ b/app/views/admin/enterprises/form/_users.html.haml
@@ -4,19 +4,17 @@
-if @enterprise.pending_any_confirmation?
.alert-box
- email = @enterprise.confirmed? ? @enterprise.unconfirmed_email : @enterprise.email
- Email confirmation is pending.
- We've sent a confirmation email to
- %strong= "#{email}."
- = link_to('Resend', main_app.enterprise_confirmation_path(enterprise: { id: @enterprise.id, email: email } ), method: :post)
+ = t('.email_confirmation_notice_html', {email: "#{email}".html_safe})
+ = link_to(t('.resend'), main_app.enterprise_confirmation_path(enterprise: { id: @enterprise.id, email: email } ), method: :post)
%a.close{ href: "#" } ×
.row
.three.columns.alpha
- =f.label :owner_id, 'Owner'
+ =f.label :owner_id, t('.owner')
- if full_permissions
%span.required *
- %div{'ofn-with-tip' => "The primary user responsible for this enterprise."}
- %a What's this?
+ %div{'ofn-with-tip' => t('.owner_tip')}
+ %a= t('admin.whats_this')
.eight.columns.omega
- if full_permissions
= f.hidden_field :owner_id, class: "select2 fullwidth", 'user-select' => 'Enterprise.owner'
@@ -25,29 +23,29 @@
.row
.three.columns.alpha
- = f.label :email, 'Notifications'
+ = f.label :email, t('.notifications')
- if full_permissions
%span.required *
- .with-tip{'data-powertip' => "Notifications about orders will be send to this email address."}
- %a What's this?
+ .with-tip{'data-powertip' => t('.notifications_tip')}
+ %a= t('admin.whats_this')
.eight.columns.omega
- if full_permissions
- = f.text_field :email, { placeholder: "eg. gustav@truffles.com", "ng-model" => "Enterprise.email" }
+ = f.text_field :email, { placeholder: t('.notifications_placeholder'), "ng-model" => "Enterprise.email" }
- else
= @enterprise.email
.row{ ng: { hide: "pristineEmail == null || pristineEmail == Enterprise.email"} }
.alpha.three.columns
.omega.eight.columns
- Note: A new email address may need to be confirmed prior to use
+ = t('.notifications_note')
.row
.three.columns.alpha
- =f.label :user_ids, 'Managers'
+ =f.label :user_ids, t('.managers')
- if full_permissions
%span.required *
- %div{'ofn-with-tip' => "The other users with permission to manage this enterprise."}
- %a What's this?
+ %div{'ofn-with-tip' => t('.managers_tip')}
+ %a= t('admin.whats_this')
.eight.columns.omega
- if full_permissions
%table
diff --git a/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml b/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml
index 09c78f9c8c..a6e149d238 100644
--- a/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml
+++ b/app/views/admin/enterprises/form/tag_rules/_default_rules.html.haml
@@ -6,10 +6,10 @@
%tr
%td
%h5
- By Default
+ = t('.by_default')
%i.text-big.icon-question-sign.help-modal{ template: 'admin/modals/tag_rule_help.html' }
.no_rules{ ng: { show: "defaultTagGroup.rules.length == 0" } }
- No default rules apply yet
+ = t('.no_rules_yet')
.tag_rule{ ng: { repeat: "rule in defaultTagGroup.rules" } }
.add_rule.text-center
- %input.button.icon-plus{ type: 'button', value: "+ Add A New Default Rule", "add-new-rule-to" => "addNewRuleTo", "tag-group" => "defaultTagGroup", "new-tag-rule-dialog" => true }
+ %input.button.icon-plus{ type: 'button', value: t('.add_new_button'), "add-new-rule-to" => "addNewRuleTo", "tag-group" => "defaultTagGroup", "new-tag-rule-dialog" => true }
diff --git a/app/views/admin/enterprises/index.html.haml b/app/views/admin/enterprises/index.html.haml
index b84659738c..a233bc3146 100644
--- a/app/views/admin/enterprises/index.html.haml
+++ b/app/views/admin/enterprises/index.html.haml
@@ -1,19 +1,19 @@
- content_for :page_title do
- Enterprises
+ = t('.title')
- content_for :page_actions do
= render 'admin/shared/user_guide_link'
- if spree_current_user.can_own_more_enterprises?
%li#new_product_link
- = button_link_to "New Enterprise", main_app.new_admin_enterprise_path, :icon => 'icon-plus', :id => 'admin_new_enterprise_link'
+ = button_link_to t('.new_enterprise'), main_app.new_admin_enterprise_path, icon: 'icon-plus', id: 'admin_new_enterprise_link'
= admin_inject_monthly_bill_description
= admin_inject_column_preferences module: 'admin.enterprises', action: "enterprises_index"
= render 'admin/shared/enterprises_sub_menu'
-= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise_set }
+= render partial: 'spree/shared/error_messages', locals: { target: @enterprise_set }
- if spree_current_user.admin?
= render 'admin_index'
diff --git a/app/views/admin/enterprises/new.html.haml b/app/views/admin/enterprises/new.html.haml
index 4413acfc2c..4676d117fb 100644
--- a/app/views/admin/enterprises/new.html.haml
+++ b/app/views/admin/enterprises/new.html.haml
@@ -1,10 +1,10 @@
-= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise }
+= render partial: 'spree/shared/error_messages', locals: { target: @enterprise }
- content_for :page_title do
- New Enterprise
+ = t('.title')
- content_for :page_actions do
- %li= button_link_to "Back to enterprises list", main_app.admin_enterprises_path, icon: 'icon-arrow-left'
+ %li= button_link_to t('.back_link'), main_app.admin_enterprises_path, icon: 'icon-arrow-left'
-# Form
diff --git a/app/views/admin/enterprises/welcome.html.haml b/app/views/admin/enterprises/welcome.html.haml
index cfe5593d99..8f70211e88 100644
--- a/app/views/admin/enterprises/welcome.html.haml
+++ b/app/views/admin/enterprises/welcome.html.haml
@@ -1,13 +1,13 @@
#welcome_page.sixteen.columns.alpha
%header
- %h1 Welcome to the Open Food Network!
+ %h1= t('.welcome_title')
%p
- You have successfully created a
+ = t('.welcome_text')
%strong
= "#{"producer " if @enterprise.is_primary_producer}profile"
%section
- %h2 Next step
- %p Choose your starting point:
+ %h2= t('.next_step')
+ %p= t('.choose_starting_point')
= render partial: "change_type_form"
diff --git a/app/views/admin/order_cycles/_advanced_settings.html.haml b/app/views/admin/order_cycles/_advanced_settings.html.haml
index f8f71d0b93..bfbd6e9c91 100644
--- a/app/views/admin/order_cycles/_advanced_settings.html.haml
+++ b/app/views/admin/order_cycles/_advanced_settings.html.haml
@@ -1,22 +1,22 @@
.row
.alpha.omega.sixteen.columns
- %h3 Advanced Settings
+ %h3= t('.title')
= form_for [main_app, :admin, @order_cycle] do |f|
.row
.six.columns.alpha
= f.label "enterprise_preferred_product_selection_from_coordinator_inventory_only", t('admin.order_cycles.edit.choose_products_from')
- .with-tip{'data-powertip' => "You can opt to restrict all available products (both incoming and outgoing), to only those in #{@order_cycle.coordinator.name}'s inventory."}
- %a What's this?
+ .with-tip{'data-powertip' => t('.choose_product_tip', inventory: @order_cycle.coordinator.name)}
+ %a= t('admin.whats_this')
.four.columns
= f.radio_button :preferred_product_selection_from_coordinator_inventory_only, true
- = f.label :preferred_product_selection_from_coordinator_inventory_only, "Coordinator's Inventory Only"
+ = f.label :preferred_product_selection_from_coordinator_inventory_only, t('.preferred_product_selection_from_coordinator_inventory_only_here')
.six.columns.omega
= f.radio_button :preferred_product_selection_from_coordinator_inventory_only, false
- = f.label :preferred_product_selection_from_coordinator_inventory_only, "All Available Products"
+ = f.label :preferred_product_selection_from_coordinator_inventory_only, t('.preferred_product_selection_from_coordinator_inventory_only_all')
.row
.sixteen.columns.alpha.omega.text-center
- %input{ type: 'submit', value: 'Save and Reload Page' }
- or
- %a{ href: "#", onClick: "toggleSettings()" } Close
+ %input{ type: 'submit', value: t('.save_reload') }
+ = t(:or)
+ %a{ href: "#", onClick: "toggleSettings()" }= t(:close)
diff --git a/app/views/admin/order_cycles/_coordinator_fees.html.haml b/app/views/admin/order_cycles/_coordinator_fees.html.haml
index 86e0d0a7af..a22deee37f 100644
--- a/app/views/admin/order_cycles/_coordinator_fees.html.haml
+++ b/app/views/admin/order_cycles/_coordinator_fees.html.haml
@@ -1,6 +1,6 @@
%ol.coordinator-fees
%li{'ng-repeat' => 'enterprise_fee in order_cycle.coordinator_fees'}
= select_tag 'order_cycle_coordinator_fee_{{ $index }}_id', nil, {'ng-model' => 'enterprise_fee.id', 'ng-options' => 'enterprise_fee.id as enterprise_fee.name for enterprise_fee in enterpriseFeesForEnterprise(order_cycle.coordinator_id)'}
- = link_to 'Remove', '#', {'id' => 'order_cycle_coordinator_fee_{{ $index }}_remove', 'ng-click' => 'removeCoordinatorFee($event, $index)'}
+ = link_to t(:remove), '#', {'id' => 'order_cycle_coordinator_fee_{{ $index }}_remove', 'ng-click' => 'removeCoordinatorFee($event, $index)'}
-= f.submit 'Add coordinator fee', 'ng-click' => 'addCoordinatorFee($event)'
+= f.submit t('.add'), 'ng-click' => 'addCoordinatorFee($event)'
diff --git a/app/views/admin/order_cycles/_form.html.haml b/app/views/admin/order_cycles/_form.html.haml
index ebe9e45905..f075c2cf33 100644
--- a/app/views/admin/order_cycles/_form.html.haml
+++ b/app/views/admin/order_cycles/_form.html.haml
@@ -3,55 +3,54 @@
-if Enterprise.managed_by(spree_current_user).include? @order_cycle.coordinator
= render 'coordinator_fees', f: f
-%h2 Incoming
+%h2= t('.incoming')
%table.exchanges
%thead
%tr
- %th Supplier
+ %th= t('.supplier')
%th
- Products
+ =t('.products')
= surround '(', ')' do
%a{href: '#', 'ng-click' => "OrderCycle.toggleAllProducts('incoming')"}
- %span{'ng-show' => "OrderCycle.showProducts['incoming']"} Collapse all
- %span{'ng-hide' => "OrderCycle.showProducts['incoming']"} Expand all
- %th Receival details
- %th Fees
+ %span{'ng-show' => "OrderCycle.showProducts['incoming']"}= t(:collapse_all)
+ %span{'ng-hide' => "OrderCycle.showProducts['incoming']"}= t(:expand_all)
+ %th= t('.receival_details')
+ %th= t('.fees')
%th.actions
%tbody.panel-ctrl{ object: 'exchange', 'ng-repeat' => 'exchange in order_cycle.incoming_exchanges'}
- = render 'exchange_form', :f => f, :type => 'supplier'
+ = render 'exchange_form', f: f, type: 'supplier'
- if Enterprise.managed_by(spree_current_user).include? @order_cycle.coordinator
= render 'add_exchange_form', f: f, type: 'supplier'
-%h2 Outgoing
+%h2= t('.outgoing')
%table.exchanges
%thead
%tr
- %th Distributor
+ %th= t('.distributor')
%th
- Products
+ = t('.products')
= surround '(', ')' do
%a{href: '#', 'ng-click' => "OrderCycle.toggleAllProducts('outgoing')"}
- %span{'ng-show' => "OrderCycle.showProducts['outgoing']"} Collapse all
- %span{'ng-hide' => "OrderCycle.showProducts['outgoing']"} Expand all
- %th{ ng: { if: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } } Tags
- %th Pickup / Delivery details
+ %span{'ng-show' => "OrderCycle.showProducts['outgoing']"}= t(:collapse_all)
+ %span{'ng-hide' => "OrderCycle.showProducts['outgoing']"}= t(:expand_all)
+ %th{ ng: { if: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
+ = t('.tags')
+ %th= t('.delivery_details')
%th Fees
%th.actions
%tbody.panel-ctrl{ object: 'exchange', 'ng-repeat' => 'exchange in order_cycle.outgoing_exchanges'}
- = render 'exchange_form', :f => f, :type => 'distributor'
-
+ = render 'exchange_form', f: f, type: 'distributor'
- if Enterprise.managed_by(spree_current_user).include? @order_cycle.coordinator
= render 'add_exchange_form', f: f, type: 'distributor'
.actions
- %span{'ng-hide' => 'loaded()'} Loading...
-
+ %span{'ng-hide' => 'loaded()'}= t(:loading)
- unless Rails.env.production?
#order-cycles-debug
- %h2 Debug information
+ %h2= t('.debug_info')
%pre loaded = {{ loaded() | json }}
%hr/
diff --git a/app/views/admin/order_cycles/_name_and_timing_form.html.haml b/app/views/admin/order_cycles/_name_and_timing_form.html.haml
index 39fa19f287..d081120210 100644
--- a/app/views/admin/order_cycles/_name_and_timing_form.html.haml
+++ b/app/views/admin/order_cycles/_name_and_timing_form.html.haml
@@ -1,13 +1,13 @@
.row
.alpha.two.columns
- = f.label :name
+ = f.label :name, t('.name')
.six.columns.omega
- if viewing_as_coordinator_of?(@order_cycle)
= f.text_field :name, 'ng-model' => 'order_cycle.name', 'required' => true, 'ng-disabled' => '!loaded()'
- else
{{ order_cycle.name }}
.two.columns
- = f.label :orders_open_at, 'Orders open'
+ = f.label :orders_open_at, t('.orders_open')
.omega.six.columns
- if viewing_as_coordinator_of?(@order_cycle)
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-disabled' => '!loaded()'
@@ -16,11 +16,11 @@
.row
.alpha.two.columns
- = f.label :coordinator
+ = f.label :coordinator, t('.coordinator')
.six.columns.omega
= @order_cycle.coordinator.name
.two.columns
- = f.label :orders_close_at, 'Orders close'
+ = f.label :orders_close, t('.orders_close')
.six.columns.omega
- if viewing_as_coordinator_of?(@order_cycle)
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-disabled' => '!loaded()'
diff --git a/app/views/admin/order_cycles/_row.html.haml b/app/views/admin/order_cycles/_row.html.haml
index d75a97bbb5..cbfde7f546 100644
--- a/app/views/admin/order_cycles/_row.html.haml
+++ b/app/views/admin/order_cycles/_row.html.haml
@@ -13,7 +13,7 @@
- if suppliers.count > 3
%span{'ofn-with-tip' => supplier_list}
= suppliers.count
- suppliers
+ = t('.suppliers')
- else
= supplier_list
%td= order_cycle.coordinator.name
@@ -23,12 +23,12 @@
- if distributors.count > 3
%span{'ofn-with-tip' => distributor_list}
= distributors.count
- distributors
+ = t('.distributors')
- else
= distributor_list
%td.products
- %span= "#{order_cycle.variants.count} variants"
+ %span= "#{order_cycle.variants.count} #{t('.variants')}"
%td.actions
= link_to '', main_app.edit_admin_order_cycle_path(order_cycle), class: 'edit-order-cycle icon-edit no-text'
@@ -36,4 +36,4 @@
= link_to '', main_app.clone_admin_order_cycle_path(order_cycle), class: 'clone-order-cycle icon-copy no-text'
- if can_delete?(order_cycle)
%td.actions
- = link_to '', main_app.admin_order_cycle_path(order_cycle), class: 'delete-order-cycle icon-trash no-text', :method => :delete, data: { confirm: "Are you sure?" }
+ = link_to '', main_app.admin_order_cycle_path(order_cycle), class: 'delete-order-cycle icon-trash no-text', :method => :delete, data: { confirm: t(:are_you_sure) }
diff --git a/app/views/admin/order_cycles/_simple_form.html.haml b/app/views/admin/order_cycles/_simple_form.html.haml
index a7a0363cd3..15303b1f5d 100644
--- a/app/views/admin/order_cycles/_simple_form.html.haml
+++ b/app/views/admin/order_cycles/_simple_form.html.haml
@@ -2,23 +2,23 @@
.row
.alpha.two.columns
- = label_tag 'Ready for'
+ = label_tag t('.ready_for')
.six.columns
- = text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'placeholder' => 'Date / time', 'ng-model' => 'outgoing_exchange.pickup_time', 'size' => 30
+ = text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'size' => 30
.two.columns
- = label_tag 'Customer instructions'
+ = label_tag t('.customer_instructions')
.six.columns.omega
- = text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => 'Pick-up or delivery notes', 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
+ = text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => t('.customer_instructions_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
-= label_tag 'Products'
+= label_tag t('.products')
%table.exchanges
%tbody{ng: {repeat: "exchange in order_cycle.incoming_exchanges"}}
%tr.products
%td{ ng: { include: "'admin/panels/exchange_supplied_products.html'" } }
%br/
-= label_tag 'Fees'
+= label_tag t('.fees')
= render 'coordinator_fees', f: f
.actions
- %span{'ng-hide' => 'loaded()'} Loading...
+ %span{'ng-hide' => 'loaded()'}= t(:loading)
diff --git a/app/views/admin/order_cycles/edit.html.haml b/app/views/admin/order_cycles/edit.html.haml
index 4712566dfd..34f64c1ee7 100644
--- a/app/views/admin/order_cycles/edit.html.haml
+++ b/app/views/admin/order_cycles/edit.html.haml
@@ -12,26 +12,24 @@
- if can? :notify_producers, @order_cycle
%li
- = button_to "Notify producers", main_app.notify_producers_admin_order_cycle_path, :id => 'admin_notify_producers', :confirm => 'Are you sure?'
+ = button_to "Notify producers", main_app.notify_producers_admin_order_cycle_path, :id => 'admin_notify_producers', :confirm => t(:are_you_sure)
%li
%button#toggle_settings{ onClick: 'toggleSettings()' }
- Advanced Settings
+ = t('.advanced_settings')
%i.icon-chevron-down
-
#advanced_settings{ hidden: true }
= render partial: "/admin/order_cycles/advanced_settings"
%h1
= t :edit_order_cycle
-
- ng_controller = order_cycles_simple_form ? 'AdminSimpleEditOrderCycleCtrl' : 'AdminEditOrderCycleCtrl'
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.orderCycles', 'ng-controller' => ng_controller, name: 'order_cycle_form'} do |f|
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
- %input.red{ type: "button", value: "Update", ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty" } }
- %input.red{ type: "button", value: "Update and Close", ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty" } }
+ %input.red{ type: "button", value: t(:update), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty" } }
+ %input.red{ type: "button", value: t('.update_and_close'), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty" } }
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? 'Cancel' : 'Close'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
- if order_cycles_simple_form
diff --git a/app/views/admin/order_cycles/index.html.haml b/app/views/admin/order_cycles/index.html.haml
index 824aa66ee8..989983b5b0 100644
--- a/app/views/admin/order_cycles/index.html.haml
+++ b/app/views/admin/order_cycles/index.html.haml
@@ -3,7 +3,7 @@
= content_for :page_actions do
%li#new_order_cycle_link
- = button_link_to t(:new_order_cycle), main_app.new_admin_order_cycle_path, :icon => 'icon-plus', :id => 'admin_new_order_cycle_link'
+ = button_link_to t(:new_order_cycle), main_app.new_admin_order_cycle_path, icon: 'icon-plus', id: 'admin_new_order_cycle_link'
- if @show_more
%li
= button_link_to t(:label_less), main_app.admin_order_cycles_path
diff --git a/app/views/admin/order_cycles/new.html.haml b/app/views/admin/order_cycles/new.html.haml
index 4e5a95544c..6bc0946f01 100644
--- a/app/views/admin/order_cycles/new.html.haml
+++ b/app/views/admin/order_cycles/new.html.haml
@@ -7,7 +7,7 @@
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.orderCycles', 'ng-controller' => ng_controller, name: 'order_cycle_form'} do |f|
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
- %input.red{ type: "button", value: "Create", ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty" } }
+ %input.red{ type: "button", value: t(:create), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty" } }
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? 'Cancel' : 'Close'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
- if order_cycles_simple_form
diff --git a/app/views/admin/producer_properties/_form.html.haml b/app/views/admin/producer_properties/_form.html.haml
index dcd83f8ec4..249301ae40 100644
--- a/app/views/admin/producer_properties/_form.html.haml
+++ b/app/views/admin/producer_properties/_form.html.haml
@@ -4,8 +4,8 @@
%table.index.sortable{"data-hook" => "", "data-sortable-link" => main_app.update_positions_admin_enterprise_producer_properties_url(@enterprise)}
%thead
%tr{"data-hook" => "producer_properties_header"}
- %th{colspan: "2"} Property
- %th Value
+ %th{colspan: "2"}= t('.property')
+ %th= t('.value')
%th.actions
%tbody#producer_properties{"data-hook" => ""}
= f.fields_for :producer_properties do |pp_form|
diff --git a/app/views/admin/producer_properties/_producer_property_fields.html.haml b/app/views/admin/producer_properties/_producer_property_fields.html.haml
index 314cbfc31a..6fe0b1d7ad 100644
--- a/app/views/admin/producer_properties/_producer_property_fields.html.haml
+++ b/app/views/admin/producer_properties/_producer_property_fields.html.haml
@@ -12,4 +12,4 @@
= f.text_field :value, :class => 'autocomplete'
%td.actions
- unless @enterprise.producer_properties.empty?
- = link_to_remove_fields t(:remove), f, no_text: true, url: (f.object.persisted? && main_app.admin_enterprise_producer_property_path(@enterprise, f.object))
+ = link_to_remove_fields t(:remove), f, no_text: true, url: (f.object.persisted? && main_app.admin_enterprise_producer_property_path(@enterprise, f.object)), html: {"onclick" => "if(typeof(enterprise_form) != 'undefined') { angular.element(enterprise_form).scope().setFormDirty() }".html_safe}
diff --git a/app/views/admin/producer_properties/index.html.haml b/app/views/admin/producer_properties/index.html.haml
index d898860cb1..c66f02a32e 100644
--- a/app/views/admin/producer_properties/index.html.haml
+++ b/app/views/admin/producer_properties/index.html.haml
@@ -1,17 +1,14 @@
- content_for :page_title do
= "#{@enterprise.name}:"
- Producer Properties
-
+ = t('.title')
- content_for :page_actions do
%ul.tollbar.inline-menu
%li
= link_to_add_fields t(:add_producer_property), 'tbody#producer_properties', class: 'icon-plus button'
-
= render 'spree/shared/error_messages', target: @enterprise
-
= form_for @enterprise, url: main_app.admin_enterprise_path(@enterprise), method: :put do |f|
= render 'form', f: f
diff --git a/app/views/admin/shared/_user_guide_link.html.haml b/app/views/admin/shared/_user_guide_link.html.haml
index 6081422aba..cd1b0dba86 100644
--- a/app/views/admin/shared/_user_guide_link.html.haml
+++ b/app/views/admin/shared/_user_guide_link.html.haml
@@ -1 +1 @@
-= button_link_to "User Guide", "http://www.openfoodnetwork.org/platform/user-guide/", :icon => 'icon-external-link', target: '_blank'
+= button_link_to t('.user_guide'), "http://www.openfoodnetwork.org/platform/user-guide/", icon: 'icon-external-link', target: '_blank'
diff --git a/app/views/admin/variant_overrides/_loading_flash.html.haml b/app/views/admin/variant_overrides/_loading_flash.html.haml
index c543a5517c..2baa04a473 100644
--- a/app/views/admin/variant_overrides/_loading_flash.html.haml
+++ b/app/views/admin/variant_overrides/_loading_flash.html.haml
@@ -1,3 +1,3 @@
%div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'hub_id && products.length == 0 && RequestMonitor.loading' } }
%img.spinner{ src: "/assets/spinning-circles.svg" }
- %h1 LOADING INVENTORY
+ %h1= t('.loading_inventory')
diff --git a/app/views/admin/variant_overrides/_show_more.html.haml b/app/views/admin/variant_overrides/_show_more.html.haml
index 21e927e443..5e8274d99c 100644
--- a/app/views/admin/variant_overrides/_show_more.html.haml
+++ b/app/views/admin/variant_overrides/_show_more.html.haml
@@ -1,5 +1,5 @@
-# %show-more.text-center{ data: "filteredProducts", limit: "productLimit", increment: "10" }
.text-center{ ng: { show: "filteredProducts.length > productLimit" } }
- %input{ type: 'button', value: 'Show More', ng: { click: 'productLimit = productLimit + 10' } }
- or
- %input{ type: 'button', value: "Show All ({{ filteredProducts.length - productLimit }} More)", ng: { click: 'productLimit = filteredProducts.length' } }
+ %input{ type: 'button', value: t(:show_more), ng: { click: 'productLimit = productLimit + 10' } }
+ = t(:or)
+ %input{ type: 'button', value: "#{t(:show_all)} ({{ filteredProducts.length - productLimit }} More)", ng: { click: 'productLimit = filteredProducts.length' } }
diff --git a/app/views/checkout/_authentication.html.haml b/app/views/checkout/_authentication.html.haml
index 45d977d8e3..d157901059 100644
--- a/app/views/checkout/_authentication.html.haml
+++ b/app/views/checkout/_authentication.html.haml
@@ -9,7 +9,7 @@
%button.primary.expand{"auth" => "login"}
= t :label_login
.small-2.columns.text-center
- %p.pad-top= "-#{t :action_or}-"
+ %p.pad-top= "#{t :action_or}"
.small-5.columns.text-center
%button.neutral-btn.dark.expand{"ng-click" => "enabled = true"}
= t :checkout_as_guest
diff --git a/app/views/checkout/_payment.html.haml b/app/views/checkout/_payment.html.haml
index 8d387145d5..928578158f 100644
--- a/app/views/checkout/_payment.html.haml
+++ b/app/views/checkout/_payment.html.haml
@@ -16,7 +16,7 @@
-# TODO render this in Angular instead of server-side
-# The problem being how to render the partials
.row
- .small-6.columns
+ .small-12.medium-12.large-6.columns
- available_payment_methods.each do |method|
.row
.small-12.columns
@@ -34,6 +34,6 @@
.row{"ng-if" => "order.payment_method_id == #{method.id}"}
.small-12.columns
= render partial: "spree/checkout/payment/#{method.method_type}", :locals => { :payment_method => method }
- .small-12.columns.medium-6.columns.large-6.columns
+ .small-12.medium-12.large-6.columns
#distributor_address.panel{"ng-show" => "Checkout.paymentMethod().description"}
%span.pre-wrap {{ Checkout.paymentMethod().description }}
diff --git a/app/views/checkout/_shipping.html.haml b/app/views/checkout/_shipping.html.haml
index 4e6e63d666..6cba461be0 100644
--- a/app/views/checkout/_shipping.html.haml
+++ b/app/views/checkout/_shipping.html.haml
@@ -13,7 +13,7 @@
"ng-class" => "{valid: shipping.$valid, open: accordion.shipping}"}
= render 'checkout/accordion_heading'
- .small-12.columns.medium-6.columns.large-6.columns
+ .small-12.columns.medium-12.columns.large-6.columns
%label{"ng-repeat" => "method in ShippingMethods.shipping_methods"}
%input{type: :radio,
required: true,
@@ -38,7 +38,7 @@
%input{type: :checkbox, "ng-model" => "Checkout.default_ship_address"}
= t :checkout_default_ship_address
- .small-12.columns.medium-6.columns.large-6.columns
+ .small-12.columns.medium-12.columns.large-6.columns
#distributor_address.panel{"ng-show" => "Checkout.shippingMethod().description"}
%span{ style: "white-space: pre-wrap;" }{{ Checkout.shippingMethod().description }}
%br/
diff --git a/app/views/groups/_hub_filters.html.haml b/app/views/groups/_hub_filters.html.haml
deleted file mode 100644
index 71924d5e85..0000000000
--- a/app/views/groups/_hub_filters.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-.row
- = render partial: 'shared/components/filter_controls'
- = render partial: 'shared/components/show_profiles'
-
-.row.animate-show{"ng-show" => "filtersActive"}
- .small-12.columns
- .row.filter-box
- .small-12.large-9.columns
- %h5.tdhead
- .light
- = t :hubs_filter_by
- = t :hubs_filter_type
- %filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{"selector-set" => "filterSelectors", objects: "group_hubs | searchEnterprises:query | shipping:shippingTypes | showHubProfiles:show_profiles | taxonsOf", "active-selectors" => "activeTaxons"}
- .small-12.large-3.columns
- %h5.tdhead
- .light
- = t :hubs_filter_by
- = t :hubs_filter_delivery
- %shipping-type-selector
-
-= render partial: 'shared/components/filter_box'
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index ef9e281155..90b74c0b42 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -60,23 +60,23 @@
.small-12.columns
%h1
= t :groups_producers
- = render partial: "shared/components/enterprise_search"
- = render partial: "producers/filters"
+ = render "shared/components/enterprise_search"
+ = render "producers/filters"
.row
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
- "ng-repeat" => "producer in filteredEnterprises = (group_producers | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties)",
+ "ng-repeat" => "producer in filteredEnterprises = (group_producers | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties:'supplied_properties')",
"ng-controller" => "GroupEnterpriseNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",
id: "{{producer.hash}}"}
.small-12.columns
- = render partial: 'producers/skinny'
- = render partial: 'producers/fat'
+ = render "producers/skinny"
+ = render "producers/fat"
- = render partial: 'shared/components/enterprise_no_results'
+ = render 'shared/components/enterprise_no_results'
%tab{heading: t(:groups_hubs),
active: "tabs.hubs.active",
@@ -87,24 +87,24 @@
%h1
= t :groups_hubs
- = render partial: "shared/components/enterprise_search"
- = render partial: "hub_filters"
+ = render "shared/components/enterprise_search"
+ = render "shops/filters", resource: "group_hubs", property_filters: "| searchEnterprises:query | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles"
.row
.small-12.columns
.active_table
%hub.active_table_node.row.animate-repeat{id: "{{hub.hash}}",
- "ng-repeat" => "hub in filteredEnterprises = (group_hubs | searchEnterprises:query | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles | orderBy:['-active', '+orders_close_at'])",
+ "ng-repeat" => "hub in filteredEnterprises = (group_hubs | searchEnterprises:query | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles | properties:activeProperties:'distributed_properties' | orderBy:['-active', '+orders_close_at'])",
"ng-class" => "{'is_profile' : hub.category == 'hub_profile', 'closed' : !open(), 'open' : open(), 'inactive' : !hub.active, 'current' : current()}",
"ng-controller" => "GroupEnterpriseNodeCtrl"}
.small-12.columns
- = render partial: 'home/skinny'
- = render partial: 'home/fat'
+ = render 'shops/skinny'
+ = render 'shops/fat'
- = render partial: 'shared/components/enterprise_no_results'
+ = render 'shared/components/enterprise_no_results'
.small-12.medium-12.large-3.columns
- = render partial: 'contact'
+ = render 'contact'
.small-12.columns.pad-top
.row.pad-top
@@ -122,4 +122,4 @@
%p
-= render partial: "shared/footer"
+= render "shared/footer"
diff --git a/app/views/home/_filters.html.haml b/app/views/home/_filters.html.haml
deleted file mode 100644
index bfd13fdf54..0000000000
--- a/app/views/home/_filters.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-.row
- = render partial: 'shared/components/filter_controls'
- -# .small-12.medium-6.columns
- = render partial: 'shared/components/show_profiles'
-
-.row.animate-show{"ng-show" => "filtersActive"}
- .small-12.columns
- .row.filter-box
- .small-12.large-9.columns
- %h5.tdhead
- .light
- = t :hubs_filter_by
- = t :hubs_filter_type
- %filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{ "selector-set" => "filterSelectors", objects: "visibleMatches | visible | taxonsOf", "active-selectors" => "activeTaxons" }
- .small-12.large-3.columns
- %h5.tdhead
- .light
- = t :hubs_filter_by
- = t :hubs_filter_delivery
- %shipping-type-selector
-
-= render partial: 'shared/components/filter_box'
diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml
index d3f0a78087..20a47be970 100644
--- a/app/views/layouts/darkswarm.html.haml
+++ b/app/views/layouts/darkswarm.html.haml
@@ -13,7 +13,7 @@
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
= yield :scripts
- %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry"}
+ %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "}
= split_stylesheet_link_tag "darkswarm/all"
= javascript_include_tag "darkswarm/all"
diff --git a/app/views/producers/_filters.html.haml b/app/views/producers/_filters.html.haml
index 771ed932c9..17f260196a 100644
--- a/app/views/producers/_filters.html.haml
+++ b/app/views/producers/_filters.html.haml
@@ -18,6 +18,6 @@
= t :producers_filter
= t :producers_filter_property
.filter-shopfront.property-selectors
- %single-line-selectors{ selectors: "filterSelectors", objects: "producers_to_filter | searchEnterprises:query | propertiesOf", "active-selectors" => "activeProperties"}
+ %filter-selector{ "selector-set" => "filterSelectors", objects: "producers_to_filter | searchEnterprises:query | taxons:activeTaxons | propertiesOf:'supplied_properties'", "active-selectors" => "activeProperties"}
= render partial: 'shared/components/filter_box'
diff --git a/app/views/producers/index.html.haml b/app/views/producers/index.html.haml
index 04048ef77e..af6c2e4fd1 100644
--- a/app/views/producers/index.html.haml
+++ b/app/views/producers/index.html.haml
@@ -16,7 +16,7 @@
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
- "ng-repeat" => "producer in filteredEnterprises = (Enterprises.producers | visible | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties)",
+ "ng-repeat" => "producer in filteredEnterprises = (Enterprises.producers | visible | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties:'supplied_properties')",
"ng-controller" => "ProducerNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",
id: "{{producer.hash}}"}
diff --git a/app/views/shared/_copyright.html.haml b/app/views/shared/_copyright.html.haml
deleted file mode 100644
index 66ee8d9b4e..0000000000
--- a/app/views/shared/_copyright.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
--##copyright.text-center
- -#%img.copyright{src: "/assets/logo.png", alt: "Open Food Network"}
- -#© Copyright 2013 Open Food Foundation
diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml
index 1ae4439cd9..69757a02a6 100644
--- a/app/views/shared/menu/_mobile_menu.html.haml
+++ b/app/views/shared/menu/_mobile_menu.html.haml
@@ -40,16 +40,28 @@
%span.nav-primary
%i.ofn-i_036-producers
= t 'label_producers'
- %li.li-menu
- %a{href: "https://openfoodnetwork.org/au/connect/"}
- %span.nav-primary
- %i.ofn-i_035-groups
- = t 'label_connect'
- %li.li-menu
- %a{href: "https://openfoodnetwork.org/au/learn/"}
- %span.nav-primary
- %i.ofn-i_013-help
- = t 'label_learn'
+ - if feature? :connect_learn_homepage
+ %li.li-menu
+ %a{href: "https://openfoodnetwork.org/au/connect/"}
+ %span.nav-primary
+ %i.ofn-i_035-groups
+ = t 'label_connect'
+ %li.li-menu
+ %a{href: "https://openfoodnetwork.org/au/learn/"}
+ %span.nav-primary
+ %i.ofn-i_013-help
+ = t 'label_learn'
+ - else
+ %li.li-menu
+ %a{href: main_app.groups_path}
+ %span.nav-primary
+ %i.ofn-i_035-groups
+ = t 'label_groups'
+ %li.li-menu
+ %a{href: ContentConfig.footer_about_url}
+ %span.nav-primary
+ %i.ofn-i_013-help
+ = t 'label_about'
%li
- if spree_current_user.nil?
diff --git a/app/views/shop/_messages.html.haml b/app/views/shop/_messages.html.haml
index 9e5d3b8e82..8debaff82e 100644
--- a/app/views/shop/_messages.html.haml
+++ b/app/views/shop/_messages.html.haml
@@ -10,7 +10,7 @@
register: ('' + t('.register') + '').html_safe}
- else
= t '.require_customer_html',
- {contact: ('' + t('.contact') + '').html_safe,
+ {contact: link_to(t('.contact'), '#contact'),
enterprise: current_distributor.name}
- elsif @order_cycles and @order_cycles.empty?
- if current_distributor.preferred_shopfront_closed_message.present?
diff --git a/app/views/shop/products/_filters.html.haml b/app/views/shop/products/_filters.html.haml
index 7efaba6cc9..10c7c20deb 100644
--- a/app/views/shop/products/_filters.html.haml
+++ b/app/views/shop/products/_filters.html.haml
@@ -1,5 +1,5 @@
.filter-shopfront.taxon-selectors.text-right
- %single-line-selectors{ selectors: "taxonSelectors", objects: "Products.products | products:query | properties: activeProperties | taxonsOf", "active-selectors" => "activeTaxons"}
+ %single-line-selectors{ selectors: "taxonSelectors", objects: "Products.products | products:query | properties:activeProperties | taxonsOf", "active-selectors" => "activeTaxons"}
.filter-shopfront.property-selectors.text-right
%single-line-selectors{ selectors: "propertySelectors", objects: "Products.products | products:query | taxons:activeTaxons | propertiesOf", "active-selectors" => "activeProperties"}
diff --git a/app/views/home/_fat.html.haml b/app/views/shops/_fat.html.haml
similarity index 100%
rename from app/views/home/_fat.html.haml
rename to app/views/shops/_fat.html.haml
diff --git a/app/views/shops/_filters.html.haml b/app/views/shops/_filters.html.haml
new file mode 100644
index 0000000000..42e2b2ec28
--- /dev/null
+++ b/app/views/shops/_filters.html.haml
@@ -0,0 +1,34 @@
+- resource ||= "visibleMatches"
+- property_filters ||= "| filter:filterExpression | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles"
+
+.row
+ = render 'shared/components/filter_controls'
+ -# .small-12.medium-6.columns
+ = render 'shared/components/show_profiles'
+
+.row.animate-show.filter-row{"ng-show" => "filtersActive"}
+ .small-12.columns
+ .row.filter-box
+ .small-12.large-9.columns
+ %h5.tdhead
+ .light
+ = t :hubs_filter_by
+ = t :hubs_filter_type
+
+ %filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{ "selector-set" => "filterSelectors", objects: "#{resource} | visible | taxonsOf", "active-selectors" => "activeTaxons" }
+ .small-12.large-3.columns
+ %h5.tdhead
+ .light
+ = t :hubs_filter_by
+ = t :hubs_filter_delivery
+ %shipping-type-selector
+
+ .small-12.large-12.columns
+ %h5.tdhead
+ .light
+ = t :hubs_filter_by
+ = t :hubs_filter_property
+ .filter-shopfront.property-selectors
+ %filter-selector{ "selector-set" => "filterSelectors", objects: "#{resource} #{property_filters} | propertiesOf:'distributed_properties'", "active-selectors" => "activeProperties"}
+
+= render 'shared/components/filter_box'
diff --git a/app/views/home/_hubs.html.haml b/app/views/shops/_hubs.html.haml
similarity index 89%
rename from app/views/home/_hubs.html.haml
rename to app/views/shops/_hubs.html.haml
index e899270efc..6087d2330c 100644
--- a/app/views/home/_hubs.html.haml
+++ b/app/views/shops/_hubs.html.haml
@@ -7,14 +7,14 @@
= t :hubs_intro
= render "shared/components/enterprise_search"
- = render "home/filters"
+ = render "filters"
.row
.small-12.columns
.name-matches{"ng-show" => "nameMatchesFiltered.length > 0"}
%h2
= t :hubs_matches
- = render "home/hubs_table", enterprises: "nameMatches"
+ = render "hubs_table", enterprises: "nameMatches"
.distance-matches{"ng-if" => "nameMatchesFiltered.length == 0 || distanceMatchesShown"}
%h2{"ng-show" => "nameMatchesFiltered.length > 0 || query.length > 0"}
@@ -22,7 +22,7 @@
%span{"ng-show" => "nameMatchesFiltered.length > 0"} {{ nameMatchesFiltered[0].name }}...
%span{"ng-hide" => "nameMatchesFiltered.length > 0"} {{ query }}...
- = render "home/hubs_table", enterprises: "distanceMatches"
+ = render "hubs_table", enterprises: "distanceMatches"
.show-distance-matches{"ng-show" => "nameMatchesFiltered.length > 0 && !distanceMatchesShown"}
%a{href: "", "ng-click" => "showDistanceMatches()"}
diff --git a/app/views/home/_hubs_table.html.haml b/app/views/shops/_hubs_table.html.haml
similarity index 67%
rename from app/views/home/_hubs_table.html.haml
rename to app/views/shops/_hubs_table.html.haml
index edf9eb5ec8..6d5803b477 100644
--- a/app/views/home/_hubs_table.html.haml
+++ b/app/views/shops/_hubs_table.html.haml
@@ -1,10 +1,10 @@
.active_table
- %hub.active_table_node.row{"ng-repeat" => "hub in #{enterprises}Filtered = (#{enterprises} | filter:filterExpression | taxons:activeTaxons | shipping:shippingTypes | showHubProfiles:show_profiles | orderBy:['-active', '+distance', '+orders_close_at'])",
+ %hub.active_table_node.row{"ng-repeat" => "hub in #{enterprises}Filtered = (#{enterprises} | filter:filterExpression | taxons:activeTaxons | properties:activeProperties:'distributed_properties' | shipping:shippingTypes | showHubProfiles:show_profiles | orderBy:['-active', '+distance', '+orders_close_at'])",
"ng-class" => "{'is_profile' : hub.category == 'hub_profile', 'closed' : !open(), 'open' : open(), 'inactive' : !hub.active, 'current' : current()}",
"ng-controller" => "HubNodeCtrl",
id: "{{hub.hash}}"}
.small-12.columns
- = render 'home/skinny'
- = render 'home/fat'
+ = render 'skinny'
+ = render 'fat'
= render 'shared/components/enterprise_no_results', enterprises: "#{enterprises}Filtered"
diff --git a/app/views/home/_skinny.html.haml b/app/views/shops/_skinny.html.haml
similarity index 100%
rename from app/views/home/_skinny.html.haml
rename to app/views/shops/_skinny.html.haml
diff --git a/app/views/shops/index.html.haml b/app/views/shops/index.html.haml
index 1b3cf547a8..7e288f4157 100644
--- a/app/views/shops/index.html.haml
+++ b/app/views/shops/index.html.haml
@@ -10,5 +10,5 @@
%p.text-big
= t :shops_text
-= render partial: "home/hubs"
-= render partial: "shared/footer"
+= render "hubs"
+= render "shared/footer"
diff --git a/app/views/sitemap/index.xml.haml b/app/views/sitemap/index.xml.haml
new file mode 100644
index 0000000000..dac6032a15
--- /dev/null
+++ b/app/views/sitemap/index.xml.haml
@@ -0,0 +1,17 @@
+!!! XML
+%urlset{xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9"}
+ - for page_url in @page_urls
+ %url
+ %loc= page_url
+ %changefreq monthly
+
+ - for enterprise in @enterprises
+ %url
+ %loc= enterprise_shop_url(enterprise)
+ %lastmod= enterprise.updated_at.strftime('%Y-%m-%d')
+ %changefreq weekly
+
+ - for group in @groups
+ %url
+ %loc= group_url(group)
+ %changefreq monthly
diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml
index 520d2376a4..5f6764e8d9 100644
--- a/app/views/spree/admin/orders/bulk_management.html.haml
+++ b/app/views/spree/admin/orders/bulk_management.html.haml
@@ -31,17 +31,17 @@
%label{ :for => 'supplier_filter' }
= t("admin.producer")
%br
- %select{ :class => "three columns alpha", :id => 'supplier_filter', 'select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.id as s.name for s in suppliers' }
+ %input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', blank: "{ id: 0, name: 'All' }", ng: { model: 'supplierFilter' } }
.filter_select{ :class => "three columns" }
%label{ :for => 'distributor_filter' }
= t("admin.shop")
%br
- %select{ :class => "three columns alpha", :id => 'distributor_filter', 'select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.id as d.name for d in distributors'}
+ %input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', blank: "{ id: 0, name: 'All' }", ng: { model: 'distributorFilter' } }
.filter_select{ :class => "three columns" }
%label{ :for => 'order_cycle_filter' }
= t("admin.order_cycle")
%br
- %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.id as oc.name for oc in orderCycles', 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()'}
+ %input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', blank: "{ id: 0, name: 'All' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } }
.filter_clear{ :class => "two columns omega" }
%label{ :for => 'clear_all_filters' }
%br
@@ -151,7 +151,7 @@
%th.final_weight_volume{ 'ng-show' => 'columns.final_weight_volume.visible' }
= t("admin.orders.bulk_management.weight_volume")
%th.price{ 'ng-show' => 'columns.price.visible' }
- = t("admin.price")
+ = t("admin.price (#{currency_symbol})")
%th.actions
%th.actions
= t("admin.orders.bulk_management.ask")
@@ -178,7 +178,7 @@
%input.show-dirty{ :type => 'number', :name => 'final_weight_volume', :id => 'final_weight_volume', ng: { model: "line_item.final_weight_volume", readonly: "unitValueLessThanZero(line_item)", change: "weightAdjustedPrice(line_item)", required: "true", class: '{"update-error": line_item.errors.final_weight_volume}' }, min: 0, 'ng-pattern' => '/[1-9]+/' }
%span.error{ ng: { bind: 'line_item.errors.final_weight_volume' } }
%td.price{ 'ng-show' => 'columns.price.visible' }
- %input.show-dirty{ :type => 'text', :name => 'price', :id => 'price', :ng => { value: 'line_item.price * line_item.quantity | currency', readonly: "true", class: '{"update-error": line_item.errors.price}' } }
+ %input.show-dirty{ :type => 'text', :name => 'price', :id => 'price', :ng => { value: 'line_item.price * line_item.quantity | currency:""', readonly: "true", class: '{"update-error": line_item.errors.price}' } }
%span.error{ ng: { bind: 'line_item.errors.price' } }
%td.actions
%a{ href: "/admin/orders/{{line_item.order.number}}/edit", :class => "edit-order icon-edit no-text", 'confirm-link-click' => 'confirmRefresh()' }
diff --git a/app/views/spree/checkout/payment/_paypal.html.haml b/app/views/spree/checkout/payment/_paypal.html.haml
index e69de29bb2..1cc8aa25a7 100644
--- a/app/views/spree/checkout/payment/_paypal.html.haml
+++ b/app/views/spree/checkout/payment/_paypal.html.haml
@@ -0,0 +1 @@
+-# This file intentionally overrides the view in the spree_paypal_express gem
diff --git a/app/views/spree/products/_source.html.haml b/app/views/spree/products/_source.html.haml
index 24f66f2add..dfcd091d67 100644
--- a/app/views/spree/products/_source.html.haml
+++ b/app/views/spree/products/_source.html.haml
@@ -12,7 +12,7 @@
%tbody
- order = current_order(false)
- validator = DistributionChangeValidator.new(order)
- - Enterprise.distributing_product(@product).each do |distributor|
+ - Enterprise.distributing_products(@product).each do |distributor|
- if !order.nil? && distributor == order.distributor
%tr.odd
%td
diff --git a/config/application.yml.example b/config/application.yml.example
index 0b1871466b..5b38a6da60 100644
--- a/config/application.yml.example
+++ b/config/application.yml.example
@@ -21,3 +21,6 @@ CURRENCY: AUD
#
# DISCOURSE_URL must be the URL of your Discourse instance.
#DISCOURSE_URL: "https://noticeboard.openfoodnetwork.org.au"
+
+# see: https://developers.google.com/maps/documentation/javascript/get-api-key
+# GOOGLE_MAPS_API_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb
index 30182ef63a..f439e779cf 100644
--- a/config/initializers/spree.rb
+++ b/config/initializers/spree.rb
@@ -8,6 +8,7 @@
require 'spree/product_filters'
+require 'spree/core/calculated_adjustments_decorator'
require "#{Rails.root}/app/models/spree/payment_method_decorator"
require "#{Rails.root}/app/models/spree/gateway_decorator"
diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml
index 2a8d9bc0fb..39f54d07ba 100644
--- a/config/locales/en-GB.yml
+++ b/config/locales/en-GB.yml
@@ -6,7 +6,7 @@ en-GB:
shipment_state: Shipment State
devise:
failure:
- invalid:
+ invalid: |
Invalid email or password.
Were you a guest last time? Perhaps you need to create an account or reset your password.
enterprise_confirmations:
@@ -23,7 +23,7 @@ en-GB:
title: Open Food Network
welcome_to: 'Welcome to '
site_meta_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can seriously change the world."
- search_by_name: Search by name...
+ search_by_name: Search by name, town, county or postcode...
producers: 'UK Producers'
producers_join: UK producers are now welcome to join Open Food Network UK.
charges_sales_tax: Charges VAT?
@@ -43,7 +43,7 @@ en-GB:
monthly_cap_excl_tax: "monthly cap (excl. VAT)"
capped_at_cap: "capped at %{cap}"
per_month: "per month"
- free: "free"
+ free: "pay what you can"
free_trial: "free trial"
plus_tax: "plus VAT"
total_monthly_bill_incl_tax: "Total Monthly Bill (Incl. VAT)"
@@ -90,6 +90,18 @@ en-GB:
add_a_new_customer_for: Add a new customer for %{shop_name}
code: Code
duplicate_code: "This code is used already."
+ bill_address: "Billing Address"
+ ship_address: "Shipping Address"
+ update_address_success: 'Address updated successfully.'
+ update_address_error: 'Sorry! Please input all of the required fields!'
+ edit_bill_address: 'Edit Billing Address'
+ edit_ship_address: 'Edit Shipping Address'
+ required_fileds: 'Required fields are denoted with an asterisk'
+ select_country: 'Select Country'
+ select_state: 'Select County'
+ edit: 'Edit'
+ update_address: 'Update Address'
+ confirm_delete: 'Sure to delete?'
products:
bulk_edit:
unit: Unit
@@ -154,11 +166,15 @@ en-GB:
status: Status
manage: Manage
form:
- primary_details:
- shopfront_requires_login: "Shopfront requires login?"
- shopfront_requires_login_tip: "Choose whether customers must login to view the shopfront."
+ shop_preferences:
+ shopfront_requires_login: "Publicly visible shopfront?"
+ shopfront_requires_login_tip: "Choose whether customers must login to view the shopfront or if it's visible to everybody."
shopfront_requires_login_false: "Public"
- shopfront_requires_login_true: "Require customers to login"
+ shopfront_requires_login_true: "Visible to registered customers only"
+ allow_guest_orders: "Guest orders"
+ allow_guest_orders_tip: "Allow checkout as guest or require a registered user."
+ allow_guest_orders_false: "Require login to order"
+ allow_guest_orders_true: "Allow guest checkout"
home:
hubs:
show_closed_shops: "Show closed shops"
@@ -310,7 +326,9 @@ en-GB:
checkout_as_guest: "Checkout as guest"
checkout_details: "Your details"
checkout_billing: "Billing info"
+ checkout_default_bill_address: "Save as default billing address"
checkout_shipping: Shipping info
+ checkout_default_ship_address: "Save as default shipping address"
checkout_method_free: Free
checkout_address_same: Shipping address same as billing address?
checkout_ready_for: "Ready for:"
@@ -349,6 +367,7 @@ en-GB:
email_userguide_html: "The User Guide with detailed support for setting up your Producer or Hub is here: %{link}"
email_admin_html: "You can manage your account by logging into the %{link} or by clicking on the cog in the top right hand side of the homepage, and selecting Administration."
email_community_html: "We also have an online forum for community discussion related to OFN software and the unique challenges of running a food enterprise. You are encouraged to join in. We are constantly evolving and your input into this forum will shape what happens next. %{link}"
+ join_community: "Join the community"
email_help: "If you have any difficulties, check out our FAQs, browse the forum or post a 'Support' topic and someone will help you out!"
email_confirmation_greeting: "Hi, %{contact}!"
email_confirmation_profile_created: "A profile for %{name} has been successfully created! To activate your Profile we need to confirm this email address."
@@ -390,7 +409,7 @@ en-GB:
email_signup_email: Your login email is
email_signup_shop_html: "You can start shopping online now at %{link}."
email_signup_text: "Thanks for joining the network. If you are a customer, we look forward to introducing you to many fantastic farmers, wonderful food hubs and delicious food! If you are a producer or food enterprise, we are excited to have you as a part of the network."
- email_signup_help_html: "We welcome all your questions and feedback; you can use the Send Feedback button on the site or email us at"
+ email_signup_help_html: "We welcome all your questions and feedback; you can use the Send Feedback button on the site or email us at %{email}"
producer_mail_greeting: "Dear"
producer_mail_text_before: "We now have all the consumer orders for the next food delivery."
producer_mail_order_text: "Here is a summary of the orders for your products:"
@@ -505,14 +524,14 @@ en-GB:
producers_title: Producers
producers_headline: Find local producers
producers_signup_title: Sign up as a producer
- producers_signup_headline: Food producers, empowered.
- producers_signup_motivation: Sell your food and tell your stories to diverse new markets. Save time and money on every overhead. We support innovation without the risk. We've levelled the playing field.
- producers_signup_send: Join now
- producers_signup_enterprise: Enterprise Accounts
+ producers_signup_headline: Food producers. Meet OFN.
+ producers_signup_motivation: Sell your food and tell your stories. Save time and money on every overhead. We support innovation without the risk. We're levelling the playing field.
+ producers_signup_send: Register
+ producers_signup_enterprise: Why the Open Food Network?
producers_signup_studies: Stories from our producers.
producers_signup_cta_headline: Join now!
- producers_signup_cta_action: Join now
- producers_signup_detail: Here's the detail.
+ producers_signup_cta_action: Register
+ producers_signup_detail: Got a question?
products_item: Item
products_description: Description
products_variant: Variant
@@ -520,7 +539,7 @@ en-GB:
products_available: Available?
products_producer: "Producer"
products_price: "Price"
- register_title: Register
+ register_title: Find out more
sell_title: "Register"
sell_headline: "Get on the Open Food Network!"
sell_motivation: "Showcase your beautiful food."
@@ -531,8 +550,8 @@ en-GB:
sell_hubs_detail: "Set up a profile for your food enterprise or organisation on the OFN. At any time you can upgrade your profile to a multi-producer shop."
sell_groups_detail: "Set up a tailored directory of enterprises (producers and other food enterprises) for your region or for your organisation."
sell_user_guide: "Find out more in our user guide."
- sell_listing_price: "Listing on OFN is free. Opening and running a shop on OFN is free for six months and always free for small enterprises. We charge just 2% of sales for enterprises turning over more than £5000/year."
- sell_embed: "We can also embed an OFN shop in your own customised website or build a customised local food network website for your region."
+ sell_listing_price: "Selling through OFN UK is free!\n\nOFN UK is a Platform Cooperative - part of the Solidarity or Sharing Economy. Our goal is to support the distribution of as much local food as possible. As such OFN UK asks users to 'Pay What You Feel' toward the running costs and maintenance. We think 2% of sales is fair for all the services that OFN UK provide. But more importantly, we think that getting good local food to people at a fair price is more important than paying for software. So pay what you feel our services are worth to your enterprise."
+ sell_embed: "We collectively budget for new feature development from the international OFN community. This way the huge cost of good software development can be shared. If you want a new feature, chances are someone in France, South Africa, Australia, India or Brazil might want it too! Use the Community Forum to suggest features you'd like to see."
sell_ask_services: "Ask us about OFN services."
shops_title: Shops
shops_headline: Shopping, transformed.
@@ -708,30 +727,30 @@ en-GB:
registration_type_producer: "Yes, I'm a producer"
registration_type_no_producer: "No, I'm not a producer"
registration_type_error: "Please choose one. Are you are producer?"
- registration_type_producer_help: "Producers make yummy things to eat and/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it."
+ registration_type_producer_help: "Producers make things to eat and/or drink. You're a producer if you might grow it, raise it, brew it, bake it or ferment it."
registration_type_no_producer_help: "If you’re not a producer, you’re probably someone who sells and distributes food. You might be a hub, coop, buying group, retailer, wholesaler or other."
create_profile: "Create profile"
registration_images_headline: "Thanks!"
- registration_images_description: "Let's upload some pretty pictures so your profile looks great! :)"
+ registration_images_description: "Let's upload some pictures so your profile looks great! :)"
registration_detail_headline: "Let's get started"
- registration_detail_enterprise: "Woot! First we need to know a little bit about your enterprise:"
- registration_detail_producer: "Woot! First we need to know a little bit about your farm:"
+ registration_detail_enterprise: "First we need to know a little bit about your enterprise:"
+ registration_detail_producer: "First we need to know a little bit about your farm:"
registration_detail_name_enterprise: "Enterprise name:"
registration_detail_name_producer: "Farm name:"
- registration_detail_name_placeholder: "e.g. Charlie's Awesome Farm"
+ registration_detail_name_placeholder: "e.g. Charlie's Farm"
registration_detail_name_error: "Please choose a unique name for your enterprise"
registration_detail_address1: "Address line 1:"
- registration_detail_address1_placeholder: "e.g. 123 Cranberry Drive"
+ registration_detail_address1_placeholder: "e.g. 123 Apple Drive"
registration_detail_address1_error: "Please enter an address"
registration_detail_address2: "Address line 2:"
- registration_detail_suburb: "Suburb:"
- registration_detail_suburb_placeholder: "e.g. Northcote"
- registration_detail_suburb_error: "Please enter a suburb"
+ registration_detail_suburb: "Town:"
+ registration_detail_suburb_placeholder: "e.g. Taunton"
+ registration_detail_suburb_error: "Please enter a town"
registration_detail_postcode: "Postcode:"
- registration_detail_postcode_placeholder: "e.g. 3070"
+ registration_detail_postcode_placeholder: "e.g. TA1 1AA"
registration_detail_postcode_error: "Postcode required"
- registration_detail_state: "State:"
- registration_detail_state_error: "State required"
+ registration_detail_state: "County:"
+ registration_detail_state_error: "County required"
registration_detail_country: "Country:"
registration_detail_country_error: "Please select a country"
fees: "Fees"
@@ -799,6 +818,7 @@ en-GB:
tax_category: "Tax Category"
calculator: "Calculator"
calculator_values: "Calculator values"
+ flat_percent_per_item: "Flat Percent (per item)"
new_order_cycles: "New Order Cycles"
select_a_coordinator_for_your_order_cycle: "Select a coordinator for your order cycle"
edit_order_cycle: "Edit Order Cycle"
@@ -949,6 +969,7 @@ en-GB:
validation_msg_tax_category_cant_be_blank: "^Tax Category can't be blank"
validation_msg_is_associated_with_an_exising_customer: "is associated with an existing customer"
spree:
+ zipcode: Postcode
shipment_states:
backorder: backorder
partial: partial
diff --git a/config/locales/en-US.yml b/config/locales/en-US.yml
index e86100ba93..f7e4b29abf 100644
--- a/config/locales/en-US.yml
+++ b/config/locales/en-US.yml
@@ -29,7 +29,7 @@ en-US:
Were you a guest last time? Perhaps you need to create an account or reset your password.
enterprise_confirmations:
enterprise:
- confirmed: Thankyou, your email address has been confirmed.
+ confirmed: Thank you, your email address has been confirmed.
not_confirmed: Your email address could not be confirmed. Perhaps you have already completed this step?
confirmation_sent: "Confirmation email sent!"
confirmation_not_sent: "Could not send a confirmation email."
@@ -911,7 +911,7 @@ Please follow the instructions there to make your enterprise visible on the Open
spree_admin_single_enterprise_alert_mail_confirmation: "Please confirm the email address for"
spree_admin_single_enterprise_alert_mail_sent: "We've sent an email to"
spree_admin_overview_action_required: "Action Required"
- spree_admin_overview_check_your_inbox: "Please check you inbox for furher instructions. Thanks!"
+ spree_admin_overview_check_your_inbox: "Please check your inbox for further instructions. Thanks!"
change_package: "Change Package"
spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under"
your_profil_live: "Your profile live"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 6f80f0f1b7..184fcb372f 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -28,7 +28,7 @@ en:
Were you a guest last time? Perhaps you need to create an account or reset your password.
enterprise_confirmations:
enterprise:
- confirmed: Thankyou, your email address has been confirmed.
+ confirmed: Thank you, your email address has been confirmed.
not_confirmed: Your email address could not be confirmed. Perhaps you have already completed this step?
confirmation_sent: "Confirmation email sent!"
confirmation_not_sent: "Could not send a confirmation email."
@@ -70,9 +70,17 @@ en:
say_no: "No"
say_yes: "Yes"
then: then
-
sort_order_cycles_on_shopfront_by: "Sort Order Cycles On Shopfront By"
-
+ required_fields: Required fields are denoted with an asterisk
+ select_continue: Select and Continue
+ remove: Remove
+ or: or
+ collapse_all: Collapse all
+ expand_all: Expand all
+ loading: Loading...
+ show_more: Show more
+ show_all: Show all
+ cancel: Cancel
admin:
# Common properties / models
@@ -131,6 +139,31 @@ en:
update_address: 'Update Address'
confirm_delete: 'Sure to delete?'
+ cache_settings:
+ show:
+ distributor: Distributor
+ order_cycle: Order Cycle
+ status: Status
+ diff: Diff
+
+ contents:
+ edit:
+ title: Content
+
+ enterprise_fees:
+ index:
+ title: Entreprise Fees
+ enterprise: Enterprise
+ fee_type: Fee Type
+ name: Name
+ tax_category: Tax Category
+ calculator: Calculator
+ calculator_values: Calculator Values
+
+ enterprise_groups:
+ index:
+ new_button: New Enterprise Group
+
products:
bulk_edit:
unit: Unit
@@ -144,6 +177,8 @@ en:
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
variant_overrides:
+ loading_flash:
+ loading_inventory: LOADING INVENTORY
index:
title: Inventory
description: Use this page to manage inventories for your enterprises. Any product details set here will override those set on the 'Products' page
@@ -195,11 +230,89 @@ en:
enterprises:
index:
- producer?: Producer?
+ title: Enterprises
+ new_enterprise: New Enterprise
+ producer?: "Producer?"
package: Package
status: Status
manage: Manage
form:
+ about_us:
+ desc_short: Short Description
+ desc_short_placeholder: Tell us about your enterprise in one or two sentences
+ desc_long: About Us
+ desc_long_placeholder: Tell customers about yourself. This information appears on your public profile.
+ business_details:
+ abn: ABN
+ abn_placeholder: eg. 99 123 456 789
+ acn: ACN
+ acn_placeholder: eg. 123 456 789
+ contact:
+ name: Name
+ name_placeholder: eg. Gustav Plum
+ email_address: Email Address
+ email_address_placeholder: eg. gustav@truffles.com
+ phone: Phone
+ phone_placeholder: eg. 98 7654 3210
+ website: Website
+ website_placeholder: eg. www.truffles.com
+ enterprise_fees:
+ name: Name
+ fee_type: Fee Type
+ manage_fees: Manage Enterprise Fees
+ no_fees_yet: You don't have any enterprise fees yet.
+ create_button: Create One Now
+ images:
+ logo: Logo
+ promo_image_placeholder: 'This image is displayed in "About Us"'
+ promo_image_note1: 'PLEASE NOTE:'
+ promo_image_note2: Any promo image uploaded here will be cropped to 1200 x 260.
+ promo_image_note3: The promo image is displayed at the top of an enterprise's profile page and pop-ups.
+ inventory_settings:
+ text1: You may opt to manage stock levels and prices in via your
+ inventory: inventory
+ text2: "If you are using the inventory tool, you can select whether new products \
+ added by your suppliers need to be added to your inventory before they can be \
+ stocked. If you are not using your inventory to manage your products you should \
+ select the 'recommended' option below:"
+ preferred_product_selection_from_inventory_only_yes: New products can be put into my shopfront (recommended)
+ preferred_product_selection_from_inventory_only_no: New products must be added to my inventory before they can be put into my shopfront
+ payment_methods:
+ name: Name
+ applies: Applies?
+ manage: Manage Payment Methods
+ not_method_yet: You don't have any payment methods yet.
+ create_button: Create New Payment Method
+ create_one_button: Create One Now
+ primary_details:
+ name: Name
+ name_placeholder: eg. Professor Plum's Biodynamic Truffles
+ groups: Groups
+ groups_tip: Select any groups or regions that you are a member of. This will help customers find your enterprise.
+ groups_placeholder: Start typing to search available groups...
+ primary_producer: Primary Producer?
+ primary_producer_tip: Select 'Producer' if you are a primary producer of food.
+ producer: Producer
+ any: Any
+ none: None
+ own: Own
+ sells: Sells
+ sells_tip: "None - enterprise does not sell to customers directly.
Own - Enterprise sells own products to customers.
Any - Enterprise can sell own or other enterprises products.
"
+ visible_in_search: Visible in search?
+ visible_in_search_tip: Determines whether this enterprise will be visible to customers when searching the site.
+ visible: Visible
+ not_visible: Not visible
+ permalink: Permalink (no spaces)
+ permalink_tip: "This permalink is used to create the url to your shop: {{link}} your-shop-name/shop"
+ link_to_front: Link to shop front
+ link_to_front_tip: A direct link to your shopfront on the Open Food Network.
+ shipping_methods:
+ name: Name
+ applies: Applies?
+ manage: Manage Shipping Methods
+ create_button: Create New Shipping Method
+ create_one_button: Create One Now
+ no_method_yet: You don't have any shipping methods yet.
shop_preferences:
shopfront_requires_login: "Publicly visible shopfront?"
shopfront_requires_login_tip: "Choose whether customers must login to view the shopfront or if it's visible to everybody."
@@ -209,6 +322,142 @@ en:
allow_guest_orders_tip: "Allow checkout as guest or require a registered user."
allow_guest_orders_false: "Require login to order"
allow_guest_orders_true: "Allow guest checkout"
+ shopfront_message_placeholder: \
+ An optional explanation for customers detailing how your shopfront works, \
+ to be displayed above the product list on your shop page.
+ shopfront_closed_message_placeholder: \
+ A message which provides a more detailed explanation about why your shop is \
+ closed and/or when customers can expect it to open again. This is displayed \
+ on your shop only when you have no active order cycles (ie. shop is closed).
+ open_date: Open Date
+ close_date: Close Date
+ social:
+ twitter_placeholder: eg. @the_prof
+ tag_rules:
+ default_rules:
+ by_default: By Default
+ no_rules_yet: No default rules apply yet
+ add_new_button: '+ Add A New Default Rule'
+ no_tags_yet: No tags apply to this enterprise yet
+ no_rules_yet: No rules apply to this tag yet
+ for_customers_tagged: 'For customers tagged:'
+ add_new_rule: '+ Add A New Rule'
+ add_new_tag: '+ Add A New Tag'
+ users:
+ email_confirmation_notice_html: "Email confirmation is pending. We've sent a confirmation email to %{email}."
+ resend: Resend
+ owner: 'Owner'
+ owner_tip: The primary user responsible for this enterprise.
+ notifications: Notifications
+ notifications_tip: Notifications about orders will be send to this email address.
+ notifications_placeholder: eg. gustav@truffles.com
+ notifications_note: 'Note: A new email address may need to be confirmed prior to use'
+ managers: Managers
+ managers_tip: The other users with permission to manage this enterprise.
+ actions:
+ edit_profile: Edit Profile
+ properties: Properties
+ payment_methods: Payment Methods
+ payment_methods_tip: This enterprise has no payment methods
+ shipping_methods: Shipping Methods
+ shipping_methods_tip: This enterprise has shipping methods
+ enterprise_fees: Enterprise Fees
+ enterprise_fees_tip: This enterprise has no fees
+ admin_index:
+ name: Name
+ role: Role
+ sells: Sells
+ visible: Visible?
+ owner: Owner
+ producer: Producer
+ change_type_form:
+ producer_profile: Producer Profile
+ connect_ofn: Connect through OFN
+ always_free: ALWAYS FREE
+ producer_description_text: Add your products to Open Food Network, allowing hubs to stock your products in their stores.
+ producer_shop: Producer Shop
+ sell_your_produce: Sell your own produce
+ sell_description_text: Sell your products directly to customers through your very own Open Food Network shopfront.
+ sell_description_text2: A Producer Shop is for your produce only, if you want to sell produce grown/produced off site, select 'Producer Hub'.
+ producer_hub: Producer Hub
+ producer_hub_text: Sell produce from self and others
+ producer_hub_description_text: Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network.
+ profile: Profile Only
+ get_listing: Get a listing
+ profile_description_text: People can find and contact you on the Open Food Network. Your enterprise will be visible on the map, and will be searchable in listings.
+ hub_shop: Hub Shop
+ hub_shop_text: Sell produce from others
+ hub_shop_description_text: Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network.
+ choose_option: Please choose one of the options above.
+ change_now: Change now
+ enterprise_user_index:
+ search_placeholder: Search By Name
+ manage: Manage
+ new_form:
+ owner: Owner
+ owner_tip: The primary user responsible for this enterprise.
+ i_am_producer: I am a Producer
+ contact_name: Contact Name
+ edit:
+ editing: 'Editing:'
+ back_link: Back to enterprises list
+ new:
+ title: New Enterprise
+ back_link: Back to enterprises list
+ welcome:
+ welcome_title: Welcome to the Open Food Network!
+ welcome_text: You have successfully created a
+ next_step: Next step
+ choose_starting_point: 'Choose your starting point:'
+ order_cycles:
+ advanced_settings:
+ title: Advanced Settings
+ choose_product_tip: You can opt to restrict all available products (both incoming and outgoing), to only those in {{inventory}}'s inventory.
+ preferred_product_selection_from_coordinator_inventory_only_here: Coordinator's Inventory Only
+ preferred_product_selection_from_coordinator_inventory_only_all: All Available Products
+ save_reload: Save and Reload Page
+ coordinator_fees:
+ add: Add coordinator fee
+ form:
+ incoming: Incoming
+ supplier: Supplier
+ products: Products
+ receival_details: Receival details
+ fees: Fees
+ outgoing: Outgoing
+ distributor: Distributor
+ products: Products
+ tags: Tags
+ delivery_detaisl: Pickup / Delivery details
+ debug_info: Debug information
+ name_and_timing_form:
+ name: Name
+ orders_open: Orders open at
+ coordinator: Coordinator
+ order_closes: Orders close
+ row:
+ suppliers: suppliers
+ distributors: distributors
+ variants: variants
+ simple_form:
+ ready_for: Ready for
+ ready_for_placeholder: Date / time
+ customer_instructions: Customer instructions
+ customer_instructions_placeholder: Pick-up or delivery notes
+ products: Products
+ fees: Fees
+ edit:
+ advanced_settings: Advanced Settings
+ update_and_close: Update and Close
+ producer_properties:
+ form:
+ property: Property
+ value: Value
+ index:
+ title: Producer Properties
+ shared:
+ user_guide_link:
+ user_guide: User Guide
home:
hubs:
@@ -258,10 +507,14 @@ en:
phone: Phone
next: Next
address: Address
+ address_placeholder: eg. 123 High Street
address2: Address (contd.)
city: City
+ city_placeholder: eg. Northcote
state: State
postcode: Postcode
+ postcode_placeholder: eg. 3070
+ state: State
country: Country
unauthorized: Unauthorized
terms_of_service: "Terms of service"
@@ -415,6 +668,8 @@ en:
order_payment_paypal_successful: Your payment via PayPal has been processed successfully.
order_hub_info: Hub Info
+ bom_tip: "Use this page to alter product quantities across multiple orders. Products may also be removed from orders entirely, if required."
+
unsaved_changes_warning: "Unsaved changes exist and will be lost if you continue."
unsaved_changes_error: "Fields with red borders contain errors."
@@ -515,6 +770,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
hubs_filter_by: "Filter by"
hubs_filter_type: "Type"
hubs_filter_delivery: "Delivery"
+ hubs_filter_property: "Property"
hubs_matches: "Did you mean?"
hubs_intro: Shop in your local area
hubs_distance: Closest to
@@ -981,7 +1237,7 @@ Please follow the instructions there to make your enterprise visible on the Open
spree_admin_single_enterprise_alert_mail_confirmation: "Please confirm the email address for"
spree_admin_single_enterprise_alert_mail_sent: "We've sent an email to"
spree_admin_overview_action_required: "Action Required"
- spree_admin_overview_check_your_inbox: "Please check you inbox for furher instructions. Thanks!"
+ spree_admin_overview_check_your_inbox: "Please check your inbox for further instructions. Thanks!"
change_package: "Change Package"
spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under"
your_profil_live: "Your profile live"
@@ -1076,6 +1332,9 @@ Please follow the instructions there to make your enterprise visible on the Open
validation_msg_is_associated_with_an_exising_customer: "is associated with an existing customer"
spree:
+ date_picker:
+ format: ! '%Y-%m-%d'
+ js_format: 'yy-mm-dd'
zipcode: Postcode
shipment_states:
backorder: backorder
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 0594d8a112..74fdc54336 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -53,6 +53,17 @@ fr:
say_yes: "Oui"
then: puis
sort_order_cycles_on_shopfront_by: "Trier les cycles de vente par"
+ required_fields: "Les champs obligatoires sont annotés d'une astérisque"
+ select_continue: Sélectionner et Continuer
+ remove: Supprimer
+ or: ou
+ collapse_all: Réduire
+ expand_all: Etendre
+ loading: Chargement...
+ show_more: Voir plus
+ show_all: Voir tout
+ cancel: Annuler
+
admin:
date: Date
email: Email
@@ -100,6 +111,27 @@ fr:
select_country: 'Choisir le pays'
select_state: 'Choisir le département'
edit: 'Modifier'
+ cache_settings:
+ show:
+ distributor: Distributeur
+ order_cycle: Cycle de vente
+ status: Statut
+ diff: Diff
+ contents:
+ edit:
+ title: Contenu
+ enterprise_fees:
+ index:
+ title: Marges de l'entreprise
+ enterprise: Entreprise
+ fee_type: Type de marge
+ name: Nom
+ tax_category: TVA appliquée
+ calculator: Calculateur
+ calculator_values: Valeurs applicables
+ enterprise_groups:
+ index:
+ new_button: Nouveau groupe d'entreprise
products:
bulk_edit:
unit: Unité
@@ -110,6 +142,8 @@ fr:
available_on: Disponible sur
av_on: "Disp. sur"
variant_overrides:
+ loading_flash:
+ loading_inventory: LOADING INVENTORY
index:
title: Stock
description: Utilisez cette page pour gérer le catalogue de votre entreprise. Les détails produits saisis ici remplaceront ceux de la page "Produit" pour votre entreprise uniquement.
@@ -162,11 +196,231 @@ fr:
status: Statut
manage: Gérer
form:
+ about_us:
+ desc_short: Description courte
+ desc_short_placeholder: Dites nous à propos de votre entreprise en 2 lignes
+ desc_long: Description publique
+ desc_long_placeholder: Décrivez-vous à vos clients. Cette information apparaîtra sur votre profil public.
+ business_details:
+ abn: ABN
+ abn_placeholder: "ex: 99 123 456 789"
+ acn: ACN
+ acn_placeholder: "ex: 123 456 789"
+ contact:
+ name: Prénom/Nom
+ name_placeholder: "ex: Maurice Batot"
+ email_address: Email Address
+ email_address_placeholder: "ex: maurice@tomates.fr"
+ phone: Téléphone
+ phone_placeholder: "ex: 98 7654 3210"
+ website: Site Web
+ website_placeholder: "ex: www.tomates.fr"
+ enterprise_fees:
+ name: Nom
+ fee_type: Type de marge
+ manage_fees: Gérer vos marges
+ no_fees_yet: Vous n'avez pas encore de marges définies.
+ create_button: Créer une nouvelle marge
+ images:
+ logo: Logo
+ promo_image_placeholder: 'Cette image est affichée dans la partie "A Propos"'
+ promo_image_note1: 'NOTES :'
+ promo_image_note2: Toutes les images uploadées ici seront coupées pour 1200x260 pixels.
+ promo_image_note3: L'image promotionelle est affichée en haut de la page profil de l'entreprise et sur les pop-ups.
+ inventory_settings:
+ text1: Vous pouvez gérer votre stock et vos prix via votre
+ inventory: inventaire
+ text2: "If you are using the inventory tool, you can select whether new products \
+ added by your suppliers need to be added to your inventory before they can be \
+ stocked. If you are not using your inventory to manage your products you should \
+ select the 'recommended' option below:"
+ preferred_product_selection_from_inventory_only_yes: Les nouveaux produits peuvent être mis dans mon magasin (Recommendé)
+ preferred_product_selection_from_inventory_only_no: Les nouveaux produits doivent être ajouté dans mon magasin avant de pouvoir être ajouté dans mon magasin
+ payment_methods:
+ name: Nom
+ applies: Applies?
+ manage: Gérer les moyens de paiement
+ not_method_yet: Vous n'avez encore aucun moyen de paiement.
+ create_button: Ajouter un nouveau moyen de paiement
+ create_one_button: Ajouter un nouveau moyen de paiement
primary_details:
+ name: Nom
+ name_placeholder: 'ex: Les Oranges Bleues'
+ groups: Groupes
+ groups_tip: Select any groups or regions that you are a member of. This will help customers find your enterprise.
+ groups_placeholder: Commencer à taper dans rechercher les groupes disponibles...
+ primary_producer: Primary Producer
+ primary_producer_tip: Select 'Producer' if you are a primary producer of food.
+ producer: Producteur
+ any: Any
+ none: None
+ own: Own
+ sells: Sells
+ sells_tip: "None - enterprise does not sell to customers directly.
Own - Enterprise sells own products to customers.
Any - Enterprise can sell own or other enterprises products.
"
+ visible_in_seach: Visible dans la recherche?
+ visible_in_seach_tip: Determines whether this enterprise will be visible to customers when searching the site.
+ visible: Visible
+ not_visible: Pas visible
+ permalink: Lien (pas d'espace)
+ permalink_tip: "This permalink is used to create the url to your shop: {{link}} your-shop-name/shop"
+ link_to_front: Link to shop front
+ link_to_front_tip: A direct link to your shopfront on the Open Food Network.
+ shipping_methods:
+ name: Nom
+ applies: Applies?
+ manage: Gérer les moyens de livraison
+ create_button: Ajouter un nouveau moyen de livraison
+ create_one_button: Ajouter un nouveau moyen de livraison
+ no_method_yet: Vous n'avez encore aucun moyen de livraison défini.
+ shop_preferences:
shopfront_requires_login: "Cette boutique exige un login?"
shopfront_requires_login_tip: "Les acheteurs doivent-ils se connecter pour accéder à la boutique?"
shopfront_requires_login_false: "Public"
shopfront_requires_login_true: "Demander aux acheteurs de se connecter"
+ allow_guest_orders: "Guest orders"
+ allow_guest_orders_tip: "Allow checkout as guest or require a registered user."
+ allow_guest_orders_false: "Require login to order"
+ allow_guest_orders_true: "Allow guest checkout"
+ shopfront_message_placeholder: \
+ An optional explanation for customers detailing how your shopfront works, \
+ to be displayed above the product list on your shop page.
+ shopfront_closed_message_placeholder: \
+ A message which provides a more detailed explanation about why your shop is \
+ closed and/or when customers can expect it to open again. This is displayed \
+ on your shop only when you have no active order cycles (ie. shop is closed).
+ open_date: Open Date
+ close_date: Close Date
+ social:
+ twitter_placeholder: 'ex: @lesorangesbleues'
+ tag_rules:
+ default_rules:
+ by_default: Par défaut
+ no_rules_yet: Aucune règle encore ajoutée
+ add_new_button: + Ajouter une nouvelle règle
+ no_tags_yet: Aucun tag encore défini pour cette entreprise
+ no_rules_yet: Aucun régle encore définie pour ce tag
+ for_customers_tagged: 'For customers tagged:'
+ add_new_rule: '+ Ajouter une nouvelle régle'
+ add_new_tag: '+ Ajouter un nouveau tag'
+ users:
+ email_confirmation_text: Email confirmation is pending.
We've sent a confirmation email to
+ resend: Renvoyer
+ owner: Propriétaire
+ owner_tip: Le premier utilisateur responsable pour l'entreprise.
+ notifications: Notifications
+ notifications_tip: Notifications about orders will be send to this email address.
+ notifications_placeholder: 'ex: gustav@truffles.com'
+ notifications_note: 'Note: A new email address may need to be confirmed prior to use'
+ managers: Managers
+ managers_tip: The other users with permission to manage this enterprise.
+ actions:
+ edit_profile: Mettre à jour le profil
+ properties: Propriétés
+ payment_methods: Méthodes de paiement
+ payment_methods_tip: Cette entreprise n'a pas de méthode de paiement
+ shipping_methods: Méthodes de livraison
+ shipping_methods_tip: Cette entreprise n'a pas de méthode de livraisons
+ enterprise_fees: Enterprise Fees
+ enterprise_fees_tip: This enterprise has no fees
+ admin_index:
+ name: Nom
+ role: Role
+ sells: Sells
+ visible: Visible?
+ owner: Owner
+ producer: Producer
+ change_type_form:
+ producer_profile: Producer Profile
+ connect_ofn: Connect through OFN
+ always_free: ALWAYS FREE
+ producer_description_text: Add your products to Open Food Network, allowing hubs to stock your products in their stores.
+ producer_shop: Producer Shop
+ sell_your_produce: Sell your own produce
+ sell_description_text: Sell your products directly to customers through your very own Open Food Network shopfront.
+ sell_description_text2: A Producer Shop is for your produce only, if you want to sell produce grown/produced off site, select 'Producer Hub'.
+ producer_hub: Producer Hub
+ producer_hub_text: Sell produce from self and others
+ producer_hub_description_text: Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network.
+ profile: Profile Only
+ get_listing: Get a listing
+ profile_description_text: People can find and contact you on the Open Food Network. Your enterprise will be visible on the map, and will be searchable in listings.
+ hub_shop: Hub Shop
+ hub_shop_text: Sell produce from others
+ hub_shop_description_text: Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network.
+ choose_option: Please choose one of the options above.
+ change_now: Change now
+ enterprise_user_index:
+ search_placeholder: Search By Name
+ manage: Manage
+ new_form:
+ owner: Owner
+ owner_tip: The primary user responsible for this enterprise.
+ i_am_producer: I am a Producer
+ contact_name: Nom du contact
+ edit:
+ editing: 'Editing:'
+ back_link: Retour à la liste d'entreprise
+ index:
+ title: Enterprises
+ new_enterprise: Ajouter une nouvelle entreprise
+ new:
+ title: Nouvelle entreprise
+ back_link: Retour à la liste d'entreprise
+ welcome:
+ welcome_title: Bienvenue chez Open Food France !
+ welcome_text: Vous avez bien créé une
+ next_step: Etape suivante
+ choose_starting_point: 'Choose your starting point:'
+ order_cycles:
+ advanced_settings:
+ title: Advanced Settings
+ choose_product_tip: You can opt to restrict all available products (both incoming and outgoing), to only those in {{inventory}}'s inventory.
+ preferred_product_selection_from_coordinator_inventory_only_here: Coordinator's Inventory Only
+ preferred_product_selection_from_coordinator_inventory_only_all: All Available Products
+ save_reload: Save and Reload Page
+ coordinator_fees:
+ add: Add coordinator fee
+ form:
+ incoming: Incoming
+ supplier: Supplier
+ products: Products
+ receival_details: Receival details
+ fees: Fees
+ outgoing: Outgoing
+ distributor: Distributor
+ products: Products
+ tags: Tags
+ delivery_detaisl: Pickup / Delivery details
+ debug_info: Debug information
+ name_and_timing_form:
+ name: Name
+ orders_open: Orders open
+ coordinator: Coordinator
+ order_closes: Orders close
+ row:
+ suppliers: suppliers
+ distributors: distributors
+ variants: variants
+ simple_form:
+ ready_for: Ready for
+ ready_for_placeholder: Date / time
+ customer_instructions: Customer instructions
+ customer_instructions_placeholder: Pick-up or delivery notes
+ products: Products
+ fees: Fees
+ edit:
+ advanced_settings: Advanced Settings
+ update_and_close: Update and Close
+ producer_properties:
+ form:
+ property: Propriété
+ value: Valeur
+ index:
+ title: Producer Properties
+ shared:
+ user_guide_link:
+ user_guide: Guide l'utilisateur
+
home:
hubs:
show_closed_shops: "Aficher les boutiques fermées"
@@ -211,10 +465,14 @@ fr:
phone: Téléphone
next: Suivant
address: Adresse
+ address_placeholder: "ex: 16, rue du Marché"
address2: Adresse (suite)
city: Ville
+ city_placeholder: "ex: Lille"
state: Département
postcode: Code postal
+ postcode_placeholder: "ex: 59000"
+ state: Région
country: Pays
unauthorized: Non authorisé
terms_of_service: "Conditions d'utilisation"
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
new file mode 100644
index 0000000000..80d83fdb3a
--- /dev/null
+++ b/config/locales/pt-BR.yml
@@ -0,0 +1,987 @@
+pt-BR:
+ activerecord:
+ attributes:
+ spree/order:
+ payment_state: Situação do pagamento
+ shipment_state: Situação do Envio
+ devise:
+ failure:
+ invalid: |
+ Email ou senha incorretos.
+ Você entrou como visitante da última vez? Talvez você precise criar uma conta ou criar uma nova senha.
+ enterprise_confirmations:
+ enterprise:
+ confirmed: Obrigado, seu endereço de email foi confirmado.
+ not_confirmed: Não foi possível confirmar seu endereço de email. Talvez você já tenha completado esse passo?
+ confirmation_sent: "Email de confirmação enviado!"
+ confirmation_not_sent: "Não foi possível enviar a confirmação de email."
+ enterprise_mailer:
+ confirmation_instructions:
+ subject: "Favor confirmar o endereço de email para %{enterprise}"
+ welcome:
+ subject: "%{enterprise} está agora em %{sitename}"
+ title: Open Food Network
+ welcome_to: 'Bem vindo a'
+ site_meta_description: "A gente começa por quem produz os alimentos, contando suas histórias e de seus cultivos, passando por quem distribui de modo justo e sem desperdício, até chegar em quem acredita que suas decisões de consumo podem..."
+ search_by_name: Procurar por nome ou localidade
+ producers: 'Produtores Nacionais'
+ producers_join: Produtores nacionais estão convidados a se unirem à Open Food Network.
+ print_invoice: "Imprimir fatura"
+ send_invoice: "Enviar fatura"
+ resend_confirmation: "Enviar confirmação novamente"
+ view_order: "Ver pedido"
+ edit_order: "Editar pedido"
+ ship_order: "Enviar pedido"
+ cancel_order: "Cancelar pedido"
+ confirm_send_invoice: "Uma fatura desse pedido será enviada ao cliente. Tem certeza que deseja continuar?"
+ confirm_resend_order_confirmation: "Tem certeza que deseja enviar novamente o pedido de confirmação do email?"
+ invoice: "Fatura"
+ percentage_of_sales: "%{percentage} de vendas"
+ percentage_of_turnover: " \"Percentual de faturamento\""
+ monthly_cap_excl_tax: "limite mensal (taxas exclusas)"
+ capped_at_cap: "limitado em %{cap}"
+ per_month: "ao mês"
+ free: "grátis"
+ free_trial: "faça um teste grátis"
+ plus_tax: "mais taxas"
+ total_monthly_bill_incl_tax: "Total mensal (taxas inclusas)"
+ min_bill_turnover_desc: "uma vez que o volume de negócio exceder %{mbt_amount}"
+ business_model_configuration: "Configuração do modelo de negócios"
+ say_no: "Não"
+ say_yes: "Sim"
+ then: então
+ sort_order_cycles_on_shopfront_by: "Ordenar Ciclo de Pedidos no Mercado Por"
+ admin:
+ date: Data
+ email: Email
+ name: Nome
+ on_hand: Disponível
+ on_demand: Sob Encomenda
+ on_demand?: Sob Encomenda
+ order_cycle: Ciclo de Pedidos
+ phone: Telefone
+ price: Preço
+ producer: Produtor
+ product: Produto
+ quantity: Quantidade
+ shop: Loja
+ tags: Tags
+ variant: Variante
+ quick_search: Busca Rápida
+ clear_all: apagar tudo
+ start_date: "Data de Início"
+ end_date: "Data de Término"
+ columns: Colunas
+ actions: Ações
+ viewing: "Visualizando: %{current_view_name}"
+ whats_this: O que é isso
+ tag_has_rules: "Regras existentes para essa tag: %{num}"
+ has_one_rule: "possui uma regra"
+ has_n_rules: "tem %{num} regras"
+ customers:
+ index:
+ add_customer: "Adicionar Cliente"
+ new_customer: "Novo Cliente"
+ customer_placeholder: "cliente@exemplo.org"
+ valid_email_error: Favor usar um endereço de email válido
+ add_a_new_customer_for: Adicionar novo cliente para %{shop_name}
+ code: Código
+ duplicate_code: "Esse código já está sendo usado."
+ bill_address: "Endereço de Fatura"
+ ship_address: "Endereço de Entrega"
+ update_address_success: 'Endereço atualizado com sucesso'
+ update_address_error: 'Favor preencher todos os campos obrigatórios'
+ edit_bill_address: 'Editar Endereço de Fatura'
+ edit_ship_address: 'Editar Endereço de Entrega'
+ required_fileds: 'Os campos obrigatórios estão marcados com um asterisco'
+ select_country: 'Selecionar País'
+ select_state: 'Selecionar Estado'
+ edit: 'Editar'
+ update_address: 'Atualizar Endereço'
+ confirm_delete: 'Certeza que quer excluir?'
+ products:
+ bulk_edit:
+ unit: Unidade
+ display_as: Mostrar Como
+ category: Categoria
+ tax_category: Categoria de taxa
+ inherits_properties?: Herdar Propriedades?
+ available_on: Disponível Em
+ av_on: "Disp. Em"
+ variant_overrides:
+ index:
+ title: Inventário
+ description: Utilize essa página para gerenciar inventários para seus empreendimentos. Qualquer detalhe de produtos especificado aqui irá substituir o que foi especificado na página de 'Produtos'
+ enable_reset?: Ativar Restauração do Estoque
+ inherit?: Herdar?
+ add: Adicionar
+ hide: Esconder
+ select_a_shop: Selecionar Uma Loja
+ review_now: Avaliar Agora
+ new_products_alert_message: Há %{new_product_count} novos produtos disponíveis para serem adicionados ao seu inventário.
+ currently_empty: Seu inventário está vazio no momento
+ no_matching_products: enhum produto correspondente encontrado no seu inventário
+ no_hidden_products: Nenhum produto foi ocultado nesse inventário
+ no_matching_hidden_products: Nenhum produto oculto corresponde à sua busca
+ no_new_products: Nenhum novo produto está disponível para ser adicionado a este inventário
+ no_matching_new_products: Nenhum novo produto corresponde à sua busca
+ inventory_powertip: Este é seu inventário de produtos. Para adicionar produtos ao seu inventário, selecione 'Novos Produtos' no menu Exibição
+ hidden_powertip: Estes produtos foram escondidos no seu inventário e não estarão disponíveis para serem adicionados à sua loja. Você pode clicar em 'Adicionar' para adicionar um produto a seu inventário.
+ new_powertip: 'Estes produtos estão disponíveis para serem adicionados ao seu inventário. Clique em ''Adicionar'' para adicionar um produto em seu inventário, ou ''Ocultar'' para escondê-lo. Você pode voltar atrás quando quiser! '
+ orders:
+ bulk_management:
+ tip: "Use essa página para alterar a quantidade de produtos dentre múltiplos pedidos. Produtos podem ser removidos completamente dos pedidos, se necessário"
+ shared: "Recurso Compartilhado?"
+ order_no: "Pedido nº"
+ order_date: "Data do Pedido"
+ max: "Máximo"
+ product_unit: "Produto: Unidade"
+ weight_volume: "Peso/Volume"
+ ask: "Perguntar?"
+ page_title: "Gestão de Pedidos a Granel"
+ actions_delete: "Deletar Selecionado"
+ loading: "Carregando pedidos"
+ no_results: "Nenhum pedido encontrado. "
+ group_buy_unit_size: "Tamanho de Unidade para Compras de Grupo"
+ total_qtt_ordered: "Quantidade Total do Pedido"
+ max_qtt_ordered: "Quantidade Máxima do Pedido"
+ current_fulfilled_units: "Unidades Completadas no Momento"
+ max_fulfilled_units: "Máximo de Unidades Completadas "
+ order_error: "Alguns erros devem ser corrigidos antes de atualizar os pedidos.\nOs campos com bordas vermelhas contém erros."
+ variants_without_unit_value: "AVISO: Algumas variantes não possuem unidade de valor"
+ order_cycles:
+ edit:
+ choose_products_from: "Escolha Produtos De:"
+ enterprises:
+ index:
+ producer?: Produtor?
+ package: Embalagem
+ status: Status
+ manage: Administrar
+ form:
+ shop_preferences:
+ shopfront_requires_login: "Mercado visível publicamente?"
+ shopfront_requires_login_tip: "Escolha se os clientes precisarão fazer o login para ver os produtos do mercado, ou se eles estarão visíveis para todos."
+ shopfront_requires_login_false: "Publico"
+ shopfront_requires_login_true: "Disponível somente para clientes registrados"
+ allow_guest_orders: "Pedidos dos convidados"
+ allow_guest_orders_tip: "Permitir o checkout como convidado, ou requisitar um usuário registrado. "
+ allow_guest_orders_false: "Requisitar o registro para fazer pedidos"
+ allow_guest_orders_true: "Permitir checkout de convidados"
+ home:
+ hubs:
+ show_closed_shops: "Mostrar lojas fechadas"
+ hide_closed_shops: "Esconder lojas fechadas"
+ show_on_map: "Mostrar todas no mapa"
+ shared:
+ register_call:
+ selling_on_ofn: "Interessado em participar da Open Food Network?"
+ register: "Registre-se aqui"
+ shop:
+ messages:
+ login: "Entrar"
+ register: "registro"
+ contact: "contato"
+ require_customer_login: "Essa loja é somente para clientes."
+ require_login_html: "Fazer o %{login} se você já possui uma conta. Caso contrário, %{register} para se tornar cliente. "
+ require_customer_html: "Favor %{contact} %{enterprise} para se tornar um cliente. "
+ invoice_column_item: "Ítem"
+ invoice_column_qty: "Quantidade"
+ invoice_column_price: "Preço"
+ logo: "Logo (640x130)"
+ logo_mobile: "logo mobile (75x26)"
+ logo_mobile_svg: "Logo mobile (svg)"
+ home_hero: "Imagem de capa"
+ home_show_stats: "Mostrar estatísticas"
+ footer_logo: "Logo (220x76)"
+ footer_facebook_url: "URL Facebook"
+ footer_twitter_url: "URL Twitter"
+ footer_instagram_url: "URL Instagram"
+ footer_linkedin_url: "URL Linkedln "
+ footer_googleplus_url: "URL Google Plus"
+ footer_pinterest_url: "URL Pinterest"
+ footer_email: "Email"
+ footer_links_md: "Links"
+ footer_about_url: "URL Sobre"
+ footer_tos_url: "URL Termos de Serviço"
+ name: Nome
+ first_name: Primeiro Nome
+ last_name: Último Nome
+ email: Email
+ phone: Telefon
+ next: Próximo
+ address: Endereço
+ address2: Complemento
+ city: Cidade
+ state: Estado
+ postcode: CEP
+ country: País
+ unauthorized: Não autorizado
+ terms_of_service: "Termos de Serviço"
+ on_demand: Sob encomenda
+ none: Nenhum
+ label_shops: "Lojas"
+ label_map: "Mapa"
+ label_producers: "Produtores"
+ label_groups: "Grupos"
+ label_about: "Sobre"
+ label_connect: "Conectar"
+ label_learn: "Aprender"
+ label_shopping: "Compras"
+ label_login: "Entrar"
+ label_logout: "Sair"
+ label_signup: "Registre-se"
+ label_administration: "Administração"
+ label_admin: "Admin"
+ label_account: "Conta"
+ label_more: "Mostrar mais"
+ label_less: "Mostrar menos"
+ label_notices: "Avisos"
+ items: "itens"
+ cart_headline: "seu carrinho de compras"
+ total: "Total"
+ checkout: "Checkout"
+ cart_updating: "Atualizando carrinho"
+ cart_empty: "Carrinho vazio"
+ cart_edit: "Edite seu carrinho"
+ card_number: Número do Cartão
+ card_securitycode: "Código de Segurança"
+ card_expiry_date: Data de Vencimento
+ ofn_cart_headline: "Carrinho atual para:"
+ ofn_cart_distributor: "Distribuidor:"
+ ofn_cart_oc: "Ciclo de pedidos"
+ ofn_cart_from: "De:"
+ ofn_cart_to: "Para:"
+ ofn_cart_product: "Produto:"
+ ofn_cart_quantitiy: "Quantidade:"
+ ofn_cart_send: "Me compre"
+ ie_warning_headline: "Seu navegador está desatualizado :-("
+ ie_warning_text: "Para a melhor experiência na Open Food Network, recomendamos que você atualize seu navegador:"
+ ie_warning_chrome: Baixar Chrome
+ ie_warning_firefox: Baixar Firefox
+ ie_warning_ie: Atualizar Internet Explorer
+ ie_warning_other: "Não consegue atualizar o navegador? Tente acessar a OFN pelo smartphone :-)"
+ footer_global_headline: "OFN Global"
+ footer_global_home: "Início"
+ footer_global_news: "Novidades"
+ footer_global_about: "Sobre"
+ footer_global_contact: "Contato"
+ footer_sites_headline: "Páginas OFN"
+ footer_sites_developer: "Desenvolvedores"
+ footer_sites_community: "Comunidade"
+ footer_sites_userguide: "Guia do Usuário"
+ footer_secure: "Seguro e confiável."
+ footer_secure_text: "A Open Food Network utiliza a criptografia SSL (2048 bit RSA) para manter suas informações em segurança. Nossos servidores não guardam os detalhes do seu cartão de crédito e os pagamentos são processados por serviços compatíveis com PCI."
+ footer_contact_headline: "Mantenha contato"
+ footer_contact_email: "Envie-nos um email"
+ footer_nav_headline: "Navegar"
+ footer_join_headline: "Junte-se a nós"
+ footer_join_body: "Criar uma lista de ofertas, mercado ou cooperativa na Open Food Network"
+ footer_join_cta: "Quero saber mais!"
+ footer_legal_call: "Leia nosso"
+ footer_legal_tos: "Termos e condições"
+ footer_legal_visit: "Nos encontre em "
+ footer_legal_text_html: "A Open Food Network é uma plataforma grátis e open-source. Nosso conteúdo está sob licensa %{content_license} e nosso código %{code_license}."
+ home_shop: Compre Agora
+ brandstory_headline: "Alimentos, com liberdade"
+ brandstory_intro: "Às vezes, a melhor maneira de consertar o sistema é construir um novo..."
+ brandstory_part1: "A gente começa por quem produz os alimentos, contando suas histórias e de seus cultivos, passando por quem distribui de modo justo e sem desperdício, até chegar em quem acredita que suas decisões de consumo podem..."
+ brandstory_part2: "Precisamos de uma ferramenta para empoderar a todos que produzem, vendem e compram comida. Uma maneira de contar histórias, e controlar toda a logística. "
+ brandstory_part3: "Por isso construímos um mercado online, transparente, capaz de criar conexões verdadeiras. O código é aberto, e pode ser modificado para melhor se adaptar as particularidades de cada canto do planeta. "
+ brandstory_part4: "Queremos de volta o controle sobre os alimentos que consumimos."
+ brandstory_part5_strong: "Bem vindos à Open Food Network"
+ brandstory_part6: "Todos amamos comida. Agora a gente também pode amar nosso sistema alimentar. "
+ learn_body: "Conheça novos modelos, histórias e fornecedores para dar suporte à sua iniciativa, mercado ou organização. Encontre oportunidades para aprender com quem faz parte do seu setor. "
+ learn_cta: "Inspire-se"
+ connect_body: "Procure em nossa lista por produtores, distribuidores e cooperativas para encontrar um comércio justo, perto de você. Registre seu negócio na OFN para que os consumidores possam te encontrar. Junte-se à comunidade para trocar experiências e resolver problemas, juntos. "
+ connect_cta: "Explore"
+ system_headline: "Comprar, funciona assim:"
+ system_step1: "1. Busca"
+ system_step1_text: "Escolha entre diversos mercados independentes por alimentos locais, da estação. Procure por região, tipo de alimentos, ou se você prefere retirar ou receber em casa. "
+ system_step2: "2. Compra"
+ system_step2_text: "Transforme seu comércio com fornecedores de alimentos locais. Conheça as histórias por trás do seu produto, e daqueles que o fazem!"
+ system_step3: "3. Coleta / Entrega"
+ system_step3_text: "Espere que sua compre chegue até você, ou retire nos pontos de entrega determinados pelo seu fornecedor. Simples assim!"
+ cta_headline: "A feira que incentiva a economia local."
+ cta_label: "Estou pronto"
+ stats_headline: "Estamos criando um novo sistema alimentar"
+ stats_producers: "produtores"
+ stats_shops: "lojas"
+ stats_shoppers: "compradores"
+ stats_orders: "pedidos"
+ checkout_title: Fechar pedido
+ checkout_now: Fechar pedido agora
+ checkout_order_ready: Pedido pronto para
+ checkout_hide: Ocultar
+ checkout_expand: Expandir
+ checkout_headline: "Ok, pronto para fechar o pedido?"
+ checkout_as_guest: "Fechar pedido como convidado"
+ checkout_details: "Seus detalhes"
+ checkout_billing: "Informações para fatura"
+ checkout_default_bill_address: "Salvar como endereço de faturamento padrão"
+ checkout_shipping: Informações para envio
+ checkout_default_ship_address: "Salvar como endereço para entrega padrão"
+ checkout_method_free: Grátis
+ checkout_address_same: O endereço de entrega é o mesmo endereço da fatura?
+ checkout_ready_for: "Pronto para"
+ checkout_instructions: "Algum comentário ou instruções especiais?"
+ checkout_payment: Pagamento
+ checkout_send: Fechar pedido agora
+ checkout_your_order: Seu pedido
+ checkout_cart_total: Total do carrinho
+ checkout_shipping_price: Envio
+ checkout_total_price: Total
+ checkout_back_to_cart: "De volta para o Carrinho"
+ order_paid: PAGO
+ order_not_paid: NÃO PAGO
+ order_total: Total do pedido
+ order_payment: "Pagando com:"
+ order_billing_address: Endereço de fatura
+ order_delivery_on: Entrega em
+ order_delivery_address: Endereço para entrega
+ order_special_instructions: "Suas anotações"
+ order_pickup_time: Pronto para retirada
+ order_pickup_instructions: Instruções para retirada
+ order_produce: Produtos
+ order_total_price: Total
+ order_includes_tax: (inclui taxas)
+ order_payment_paypal_successful: Seu pagamento via Paypal foi processado com sucesso.
+ order_hub_info: Informações do distribuidor
+ unsaved_changes_warning: "Existem modificações não salvas que serão perdidas se você continuar"
+ unsaved_changes_error: "Campos com bordas vermelhas contem erros. "
+ products: "Produtos"
+ products_in: "em %{oc}"
+ products_at: "em %{distributor}"
+ products_elsewhere: "Produtos encontrados em outros lugares"
+ email_welcome: "Bem vindo"
+ email_confirmed: "Obrigado por confirmar seu endereço"
+ email_registered: "é agora parte de"
+ email_userguide_html: "O Guia de Usuário com suporte detalhado para gerenciar sua loja está aqui:"
+ email_admin_html: "Você pode gerenciar sua conta entrando no %{link} ou clicando na engrenagem no canto superior direito da página, e selecionando Administração."
+ email_community_html: "Também temos um fórum online para discussão sobre a plataforma e as dificuldades únicas de se negociar alimentos. Você está convidade a participar. Estamos evoluindo constantemente e suas idéias vão nos ajudar a melhorar.\n%{link}"
+ join_community: "Faça parte da comunidade"
+ email_help: "Se tiver quaisquer dificuldades, leia nosso FAQs, navegue no fórum ou crie um post no tópico 'Support' e alguém irá te ajudar!"
+ email_confirmation_greeting: "Olá, %{contact}!"
+ email_confirmation_profile_created: "Um perfil para %{name} foi criado com sucesso!\nPara ativar seu Perfil precisamos que você confirme seu endereço de email."
+ email_confirmation_click_link: "Clique no link abaixo para confirma seu email e continuar criando seu perfil."
+ email_confirmation_link_label: "Confirme esse endereço de email »"
+ email_confirmation_help_html: "Depois de confirmar seu email você pode acessar a conta de administração desse empreendimento. Veja o %{link} para descobrir mais sobre %{sitename} e para começar a utilizar seu perfil ou loja online."
+ email_confirmation_userguide: "Guia do Usuário"
+ email_social: "Conecte-se com a gente:"
+ email_contact: "Envie-nos um email:"
+ email_signoff: "Olá,"
+ email_signature: "%{sitename} Equipe"
+ email_confirm_customer_greeting: "Olá %{name}, "
+ email_confirm_customer_intro_html: "Obrigado por comprar com %{distributor}!"
+ email_confirm_customer_number_html: "Confirmação de pedido #%{number}"
+ email_confirm_customer_details_html: "Aqui estão os detalhes de pedido de %{distributor}:"
+ email_confirm_customer_signoff: "Atenciosamente,"
+ email_confirm_shop_greeting: "Olá %{name}, "
+ email_confirm_shop_order_html: "Parabéns! Você tem um novo pedido para %{distributor}:"
+ email_confirm_shop_number_html: "Confirmação de pedido #%{number}"
+ email_order_summary_item: "Item"
+ email_order_summary_quantity: "Qtd"
+ email_order_summary_price: "Preço"
+ email_order_summary_subtotal: "Subtotal:"
+ email_order_summary_total: "Total:"
+ email_payment_paid: PAGO
+ email_payment_not_paid: NÃO PAGO
+ email_payment_summary: Resumo do pagamento
+ email_payment_method: "Pagando com:"
+ email_shipping_delivery_details: Detalhes da entrega
+ email_shipping_delivery_time: "Entrega "
+ email_shipping_delivery_address: "Endereço de entrega:"
+ email_shipping_collection_details: Detalhes para retirada
+ email_shipping_collection_time: "Pronto para retirada"
+ email_shipping_collection_instructions: "Instruções para retirada:"
+ email_special_instructions: "Suas anotações"
+ email_signup_greeting: Olá!
+ email_signup_welcome: "Bem vindo a %{sitename}!"
+ email_signup_login: Seu login
+ email_signup_email: 'O seu email de login é '
+ email_signup_shop_html: "Você pode começar a comprar agora em %{link}."
+ email_signup_text: "Obrigado por se juntar à rede. Se você é um cliente, esperamos te apresentar a vários produtores fantásticos, incríveis distribuidores e comidas deliciosas! Se você é um produtor ou empreendedor, estamos felizes em ter você como parte de nossa rede"
+ email_signup_help_html: "Dúvidas e comentários são sempre benvindos; você pode usar o botão Enviar Comentário no site, ou enviar um e-mail para %{email}"
+ producer_mail_greeting: "Querido"
+ producer_mail_text_before: "Agora temos todos os pedidos do cliente para a próxima entrega."
+ producer_mail_order_text: "Aqui está um resumo de pedidos para seus produtos:"
+ producer_mail_delivery_instructions: "Instruções para retirada/entrega do estoque:"
+ producer_mail_signoff: "Obrigado e até breve"
+ shopping_oc_closed: Fechado para pedidos
+ shopping_oc_closed_description: "Favor aguardar até que o próximo ciclo seja aberto (ou entre em contato diretamente para saber se podemos aceitar pedidos atrasados)"
+ shopping_oc_last_closed: "A último ciclo fechou a %{distance_of_time} atrás"
+ shopping_oc_next_open: "A próximo ciclo abre em %{distance_of_time}"
+ shopping_tabs_about: "Sobre %{distributor}"
+ shopping_tabs_contact: "Contato"
+ shopping_contact_address: "Endereço"
+ shopping_contact_web: "Contato"
+ shopping_contact_social: "Seguir"
+ shopping_groups_part_of: "é parte de:"
+ shopping_producers_of_hub: "produtores de %{hub}:"
+ enterprises_next_closing: "Próximo fechamento de pedido"
+ enterprises_ready_for: "Pronto para"
+ enterprises_choose: "Escolha para quando você quer seu pedido:"
+ hubs_buy: "Compre por:"
+ hubs_shopping_here: "Comprando aqui"
+ hubs_orders_closed: "Fechado para pedidos"
+ hubs_profile_only: "Somente perfil"
+ hubs_delivery_options: "Opções de entrega"
+ hubs_pickup: "Coleta"
+ hubs_delivery: "Entrega"
+ hubs_producers: "Nosso produtores"
+ hubs_filter_by: "Filtrar por"
+ hubs_filter_type: "Tipo"
+ hubs_filter_delivery: "Entrega"
+ hubs_matches: "Você quis dizer?"
+ hubs_intro: Compre na sua região
+ hubs_distance: Mais próximo a
+ hubs_distance_filter: "Mostrar lojas próximas a %{location}"
+ products_clear_all: Apagar tudo
+ products_showing: "Mostrando:"
+ products_with: com
+ products_search: "Procurar por produto ou produtor"
+ products_loading: "Carregando produtos..."
+ products_updating_cart: "Atualizando carrinho..."
+ products_cart_empty: "Carrinho vazio"
+ products_edit_cart: "Edite seu carrinho"
+ products_from: de
+ products_change: "Nenhuma modificação a ser salva."
+ products_update_error: "Falha ao salvar, com os seguintes erros:"
+ products_update_error_msg: "Falha ao salvar."
+ products_update_error_data: "Falha no salvamento devido a dados inválidos:"
+ products_changes_saved: "Modificações salvas."
+ search_no_results_html: "Desculpe, nenhum resultado encontrado para %{query}. Que tal tentar outra busca?"
+ components_profiles_popover: "Perfis não possuem mercaods na Open Food Network, mas pode ter suas próprias lojas físicas ou online em outro endereço"
+ components_profiles_show: "Mostrar perfis"
+ components_filters_nofilters: "Nenhum filtro"
+ components_filters_clearfilters: "Eliminar filtros"
+ groups_title: Grupos
+ groups_headline: Grupos / Regiões
+ groups_text: "Todo produtor é único. Todo negócio tem algo de diferente para oferecer. Nossos grupos são coletivos de produtores, armazéns e distribuidores que compartilham algo em comum, como localização, mercado ou filosofia. Isso faz com que sua experiência de compra fique mais fácil. Explore a curadoria feita por cada um de nosso grupos. "
+ groups_search: "Procurar por nome ou localidade"
+ groups_no_groups: "Nenhum grupo encontrado. "
+ groups_about: "Sobre nós"
+ groups_producers: "Nosso produtores"
+ groups_hubs: "Nossas"
+ groups_contact_web: Contato
+ groups_contact_social: Seguir
+ groups_contact_address: Endereço
+ groups_contact_email: Envie-nos um email
+ groups_contact_website: Visite nosso website
+ groups_contact_facebook: Siga
+ groups_signup_title: Inscreva-se como grupo
+ groups_signup_headline: Inscrição de grupos
+ groups_signup_intro: "Somos uma plataforma incrível para marketing colaborativo: a maneira mais fácil para que seus membros alcancem novos mercados. Não temos fins lucrativos, somos simples e acessíveis."
+ groups_signup_email: Envie-nos um email
+ groups_signup_motivation1: Transformamos o sistema alimentar de maneira justa.
+ groups_signup_motivation2: 'Trabalhos para isso. Somos uma organização global, sem fins lucrativos, baseada em código open source. Jogamos limpo, sem mistério. '
+ groups_signup_motivation3: 'Sabemos que você tem grandes planos, e queremos ajudar. Podemos compartilhar conhecimento, redes e recurso. Sabemos que ninguém muda nada sozinho, por isso queremos você como parceiro. '
+ groups_signup_motivation4: Vamos até onde você está.
+ groups_signup_motivation5: 'Seja uma cooperativa de produtores, distribuidores, indústria ou governo local. '
+ groups_signup_motivation6: 'Seja qual for o seu papel, estamos aqui para ajudar. Entre em contato com a gente e conte-nos sobre suas ideias e projetos. '
+ groups_signup_motivation7: 'Queremos dar sentido para os movimentos por boa comida. '
+ groups_signup_motivation8: 'Se você precisa engajar sua rede de contatos, nós oferecemos a plataforma para isso. Conectamos todos os agentes e setores envolvidos no sistema alimentar. '
+ groups_signup_motivation9: 'Se você precisa de recursos, nós te conectamos a uma rede global de parceiros. '
+ groups_signup_pricing: Conta de Grupos
+ groups_signup_studies: Estudos de Caso
+ groups_signup_contact: Pronto para discutir?
+ groups_signup_contact_text: "Entre em contato para descobrir o que a OFN pode fazer por você"
+ groups_signup_detail: "Aqui está o detalhe. "
+ login_invalid: "Email ou senha inválidos"
+ modal_hubs: "Centrais de Alimentos"
+ modal_hubs_abstract: Nossas centrais de alimentos são o ponto de contato entre você e as pessoas que produzem sua comida!
+ modal_hubs_content1: 'Você pode procurar pelo mercado mais próximo, por localização ou por nome. Alguns distribuidores possuem múltiplos pontos de entrega, onde você pode retirar suas compras, e outros ainda entregam na sua casa. Cada mercado é um ponto de venda independente, e por isso as ofertas e maneira de operar podem variar de um para outro. '
+ modal_hubs_content2: Você só pode comprar em uma central de alimentos por vez.
+ modal_groups: "Grupos / Regiões"
+ modal_groups_content1: Essas são as organizações e relações entre as centrais que constroem a Open Food Network
+ modal_groups_content2: Alguns grupos estão organizados por localização, outros por similaridades não geográficas.
+ modal_how: "Como funciona"
+ modal_how_shop: Compra na Open Food Network
+ modal_how_shop_explained: Procure por um mercado próximo e comece suas compras! Em cada mercado você pode ver, em detalhe, quais produtos são oferecidos (você só pode comprar em um mercado de cada vez).
+ modal_how_pickup: 'Custos de coleta e entrega. '
+ modal_how_pickup_explained: 'Alguns mercados entregam na sua casa, outros oferecem um local para que você mesmo retire os produtos. É possível ver quais opções estão disponíveis no perfil individual de cada um, e fazer sua escolha no momento do checkout. Provavelmente será cobrada uma taxa de entrega, que pode variar de mercado para mercado. '
+ modal_how_more: Saiba mais
+ modal_how_more_explained: "Para saber mais sobre a Open Food Network, como funciona, e se envolver:"
+ modal_producers: "Produtores"
+ modal_producers_explained: "Nosso produtores são quem disponibilizam toda a oferta da Open Food Network"
+ producers_about: Sobre nós
+ producers_buy: Compre por
+ producers_contact: Contato
+ producers_contact_phone: Ligue
+ producers_contact_social: Seguir
+ producers_buy_at_html: "Compre por produtos oferecidos por %{enterprise} em:"
+ producers_filter: Filtrar por
+ producers_filter_type: Tipo
+ producers_filter_property: Propriedades
+ producers_title: Produtores
+ producers_headline: Encontre produtores locais
+ producers_signup_title: Inscreva-se como produtor
+ producers_signup_headline: Mais liberdade para quem produz comida.
+ producers_signup_motivation: Comercialize seus produtos e conte sua história para um mercado novo e diferenciado. Economize tempo e dinheiro em comunicação e logística.
+ producers_signup_send: Cadastre-se agora
+ producers_signup_enterprise: Contas de Empreendimentos
+ producers_signup_studies: Histórias de nossos produtores
+ producers_signup_cta_headline: Cadastre-se agora!
+ producers_signup_cta_action: Cadastre-se agora
+ producers_signup_detail: Aqui está o detalhe/
+ products_item: Ítem
+ products_description: Descrição
+ products_variant: Variante
+ products_quantity: Quantidade
+ products_available: Disponível?
+ products_producer: "Produtor"
+ products_price: "Preço"
+ register_title: Registro
+ sell_title: "\bRegistrar"
+ sell_headline: "Fazer parte da Open Food Network!"
+ sell_motivation: "Mostre seus produtos deliciosos."
+ sell_producers: "Produtores"
+ sell_hubs: "Centrais"
+ sell_groups: "Grupos"
+ sell_producers_detail: "Crie um perfil para seu negócio em apenas alguns minutos. A qualquer momento você poderá fazer se tornar um mercado online e vender seus produtos diretamente ao consumidor."
+ sell_hubs_detail: "Crie um perfil para seu negócio ou organização na OFN. A qualquer momento você poderá fazer um upgrade para um mercado de multi-produtores. "
+ sell_groups_detail: "Organize um lista personalizada de negócios (cultivos, cooperativas, comércios, etc.) para sua região ou organização. "
+ sell_user_guide: "Saiba mais acessando nosso guia. "
+ sell_listing_price: "Criar um perfil na OFN é grátis. Abrir e gerenciar um mercado na OFN é grátis. Organizar um grupo de empresas na OFN é grátis."
+ sell_embed: "Você também pode embutir um mercado da OFN no seu próprio site, ou construir um site específico para a sua região. "
+ sell_ask_services: "Pergunte-nos sobre nossos serviços."
+ shops_title: Lojas
+ shops_headline: 'Compras, transformadas. '
+ shops_text: 'A colheita é feita em ciclos, a comida é produzida em ciclos, e nós fazemos nossos pedidos em ciclos. Se você encontrar um ciclo de pedidos fechado, volte em breve para tentar novamente. '
+ shops_signup_title: Registre-se como uma central
+ shops_signup_headline: 'Um mercado de alimentos sem tamanho. '
+ shops_signup_motivation: 'Seja qual for seu perfil, nos oferecemos suporte. Somos sem fins lucrativos, independentes, e open source. '
+ shops_signup_action: Cadastre-se agora
+ shops_signup_pricing: Contas de Empreendimentos
+ shops_signup_stories: Histórias de nossas centrais.
+ shops_signup_help: Estamos prontos para ajudar
+ shops_signup_help_text: Você precisa de mais retorno, novos compradores e parceiros de logística. Você precisa contar a sua história.
+ shops_signup_detail: Aqui está o detalhe.
+ orders_fees: Taxas...
+ orders_edit_title: Carrinho de compras
+ orders_edit_headline: seu carrinho de compras
+ orders_edit_time: Pedido pronto para
+ orders_edit_continue: Continuar comprando
+ orders_edit_checkout: Fechar pedido
+ orders_form_empty_cart: "Carrinho vazio"
+ orders_form_subtotal: Subtotal dos produtos
+ orders_form_admin: Administração e manejo
+ orders_form_total: Total
+ orders_oc_expired_headline: Este ciclo de pedidos está fechado para pedidos
+ orders_oc_expired_text: "Desculpe, este ciclo de pedidos fechou há %{time} atrás. Favor entrar em contato diretamente com sua central para saber se podem aceitar pedidos atrasados."
+ orders_oc_expired_text_others_html: "Desculpe, este ciclo de pedidos fechou há %{time} atrás. Favor entrar em contato diretamente com sua central para saber se podem aceitar pedidos atrasados %{link}."
+ orders_oc_expired_text_link: "ou veja os outros ciclos de pedidos disponíveis nessa central"
+ orders_oc_expired_email: "Email:"
+ orders_oc_expired_phone: "Telefone:"
+ orders_show_title: Confimação de Pedido
+ orders_show_time: Pedido pronto em
+ orders_show_number: Confirmação de pedido
+ products_cart_distributor_choice: "Distribuidor para seu pedido:"
+ products_cart_distributor_change: "O distribuidor para este pedido será trocado para %{name} se você adicionar este produto no carrinho."
+ products_cart_distributor_is: "O distribuidor para este pedido é %{name}."
+ products_distributor_error: "Favor completar seu pedido no %{link} antes de comprar com outro distribuidor."
+ products_oc: "Ciclo de pedido para seu pedido:"
+ products_oc_change: "O ciclo de pedido para esse pedido será trocada para %{name} se você adicionar este produto ao carrinho."
+ products_oc_is: "O ciclo de pedido para este pedido é %{name}."
+ products_oc_error: "Favor completar seu pedido no %{link} antes de comprar em outro ciclo de pedido."
+ products_oc_current: "seu ciclo de pedido atual"
+ products_max_quantity: Quantidade máxima
+ products_distributor: Distribuidor
+ products_distributor_info: Quando você selecionar um distribuidor para seu pedido, o endereço e data para retirada serão exibidos aqui.
+ shop_trial_length: "Duração de Avaliação da Loja (dias)"
+ shop_trial_expires_in: "O período de avaliação do mercado termina em "
+ shop_trial_expired_notice: "Boa notícia! Decidimos extender o período avaliação do mercado até segunda ordem. "
+ password: Senha
+ remember_me: Lembre-me
+ are_you_sure: "Tem certeza?"
+ orders_open: Pedidos abertos
+ closing: "Fechando"
+ going_back_to_home_page: "Voltando à pagina inicial"
+ creating: Criando
+ updating: Atualizando
+ failed_to_create_enterprise: "Falha ao criar seu empreendimento"
+ failed_to_create_enterprise_unknown: "Falha ao criar seu empreendimento. \nFavor verificar se todos os campos foram preenchidos corretamente."
+ failed_to_update_enterprise_unknown: "Falha ao atualizar seu empreendimento. \nFavor verificar se todos os campos foram preenchidos corretamente."
+ order_not_saved_yet: "Seu pedido ainda não foi salvo. Aguarde um momento. "
+ filter_by: "Filtrar por"
+ hide_filters: "Esconder filtros"
+ one_filter_applied: "1 filtro aplicado"
+ x_filters_applied: "filtros aplicados"
+ submitting_order: "Processando seu pedido: favor aguardar"
+ confirm_hub_change: "Tem certeza? Isso irá mudar a central selecionada e remover todos os ítens do carrinho de compras."
+ confirm_oc_change: "Tem certeza? Isso irá mudar o ciclo de pedidos selecionado e remover todos os ítens do carrinho de compras."
+ location_placeholder: "Digite uma localidade..."
+ error_required: "Não pode ser vazio"
+ error_number: "Precisa ser um número"
+ error_email: "Precisa ser um endereço de email"
+ item_handling_fees: "Taxas de Manejo do Produto (incluídas no total do produto)"
+ january: "Janeiro"
+ february: "Fevereiro"
+ march: "Março"
+ april: "Abril"
+ may: "Maio"
+ june: "Junho"
+ july: "Julho"
+ august: "Agosto "
+ september: "Setembro"
+ october: "Outubro"
+ november: "Novembro"
+ december: "Dezembro"
+ email_not_found: "Endereço de email não encontrado"
+ email_required: "Você precisa providenciar um endereço de email"
+ logging_in: "Fazendo o login, aguarde um momento"
+ signup_email: "Seu email"
+ choose_password: "Escolha uma senha"
+ confirm_password: "Confirme a senha"
+ action_signup: "Cadastre-se agora"
+ welcome_to_ofn: "Bem-vindo à Open Food Network!"
+ signup_or_login: "Faça seu cadastro ou login para começar"
+ have_an_account: "Já possui um conta?"
+ action_login: "Entrar agora"
+ forgot_password: "Esqueceu sua senha?"
+ password_reset_sent: "Um email foi enviado com instruções para resetar sua senha!"
+ reset_password: "Resetar password"
+ who_is_managing_enterprise: "Quem é responsável por gerenciar %{enterprise}? "
+ enterprise_contact: "Contato Principal"
+ enterprise_contact_required: "Você precisa adicionar um contato principal"
+ enterprise_email_address: "Endereço de e-mail"
+ enterprise_phone: "n"
+ back: "Voltar"
+ continue: "Continuar"
+ limit_reached_headline: "Oh não!"
+ limit_reached_message: "Você chegou ao limite!"
+ limit_reached_text: "Você chegou ao limite para o número de empreendimentos permitidos"
+ limit_reached_action: "Voltar à página principal"
+ select_promo_image: "Passo 3. Selecionar Imagem Promocional"
+ promo_image_tip: "Tamanho preferencial: 1200x260px"
+ promo_image_label: "Escolher uma imagem promocional"
+ action_or: "OU"
+ promo_image_drag: "Arraste e solte sua imagem aqui"
+ review_promo_image: "Passo 4. Avalie Sua Imagem Promocional"
+ review_promo_image_tip: "Dica: para melhores resultados, sua imagem deve preencher o espaço disponível"
+ promo_image_placeholder: "Seu logo aparecerá aqui para avaliação assim que for carregado"
+ uploading: "Carregando..."
+ select_logo: "Passo 1. Selecionar imagem de perfil"
+ logo_tip: "Dica: Imagens quadradas funcionam melhor, com mínimo de 300x300px"
+ logo_label: "Escolha uma imagem de perfil"
+ logo_drag: "Arraste e solte sua imagem aqui"
+ review_logo: "Passo 2. Avalie sua imagem de perfil"
+ review_logo_tip: "Dica: para melhores resultados, sua imagem deve preencher o espaço disponível"
+ logo_placeholder: "Seu logo aparecerá aqui para avaliação assim que for carregado`"
+ enterprise_about_headline: "Boa!"
+ enterprise_about_message: "Vamos inserir mais detalhes sobre"
+ enterprise_success: "Sucesso! %{enterprise} foi adicionada a Open Food Network"
+ enterprise_registration_exit_message: "Se você fechar esse guia a qualquer momento, você precisa clicar no link de confirmação que você recebeu no email. Isso te levará até sua interface de administração onde você pode continuar construindo seu perfil."
+ enterprise_description: "Descrição Curta"
+ enterprise_description_placeholder: "Uma pequena frase descrevendo sua empresa"
+ enterprise_long_desc: "Descrição completa"
+ enterprise_long_desc_placeholder: "Essa é a oportunidade de contar a história da sua empresa. Sugerimos um parágrafo, no máximo, 600 caracteres ou 150 palavras. "
+ enterprise_long_desc_length: "%{num} caracteres / recomendamos até 600"
+ enterprise_tax_required: "Você precisa fazer uma seleção."
+ enterprise_final_step: "Último passo!"
+ enterprise_social_text: "Como as pessoas podem encontrar o/a %{enterprise} online?"
+ website: "Website"
+ website_placeholder: "eg. openfoodnetwork.com.br"
+ facebook: "Facebook"
+ facebook_placeholder: "ex. www.facebook.com/suapagina"
+ linkedin: "LinkedIn"
+ linkedin_placeholder: "ex. www.linkedin.com/seunome"
+ twitter: "Twitter"
+ twitter_placeholder: "ex. @conta_twitter"
+ instagram: "Instagram"
+ instagram_placeholder: "ex. @conta_instagram"
+ registration_greeting: "Olá!"
+ registration_intro: "Você pode criar um perfil para seu Produtor ou Distribuidor"
+ registration_action: "Vamos começar!"
+ registration_checklist: "Você vai precisar"
+ registration_time: "5-10 minutos"
+ registration_enterprise_address: "Endereço do empreendimento"
+ registration_contact_details: "Informações para contato"
+ registration_logo: "Sua imagem de perfil"
+ registration_promo_image: "Imagem horizontal para seu perfil"
+ registration_about_us: "'Sobre Nós'"
+ registration_outcome_headline: "O que eu ganho?"
+ registration_outcome1_html: "Seu perfil ajuda as pessoas a te encontrarem e entrarem em contato com você na Open Food Network"
+ registration_outcome2: "Use este espaço para contar a história da sua empresa, e ajudar a criar conexões entre sua presença física e virtual."
+ registration_outcome3: "Esse é também o primeiro passo para começar a comercializar na Open Food Network, ou abrir uma loja online"
+ registration_finished_headline: "Pronto!"
+ registration_finished_thanks: "Obrigado por preencher os detalhes para %{enterprise}."
+ registration_finished_login: "Você pode alterar ou atualizar suas informações a qualquer momento fazendo o login na Open Food Network e entrando na seção 'Admin'."
+ registration_finished_activate: "Ativar %{enterprise}."
+ registration_finished_activate_instruction_html: "Enviamos um email de confirmação para %{email}. Favor seguir as instruções do email para que seu negócio seja visível na Open Food Network. "
+ registration_finished_action: "Página principal"
+ registration_type_headline: "Último passo para adicionar %{enterprise}!"
+ registration_type_question: "Você é um produtor?"
+ registration_type_producer: "Sim, sou um produtor"
+ registration_type_no_producer: "Não, não sou um produtor"
+ registration_type_error: "Favor escolher um. Você é um produtor?"
+ registration_type_producer_help: "Produtores fazem coisas deliciosas de comer e beber. "
+ registration_type_no_producer_help: "Se você não é um produtor, você provavelmente é alguém que vende e distribui comida. Você pode ser uma central, cooperativa, grupo de compras, lojista, etc."
+ create_profile: "Crir perfil"
+ registration_images_headline: "Obrigado!"
+ registration_images_description: "Vamos adicionar umas belas imagens para seu perfil ficar lindão!"
+ registration_detail_headline: "Vamos Começar"
+ registration_detail_enterprise: "Primeiro precisamos saber mais sobre sua empresa:"
+ registration_detail_producer: "Primeiro precisamos saber mais sobre sua produção:"
+ registration_detail_name_enterprise: "Nome da Atividade:"
+ registration_detail_name_producer: "Nome da Produção"
+ registration_detail_name_placeholder: "ex. Fazenda da Nina"
+ registration_detail_name_error: "Escolha um nome para sua empresa"
+ registration_detail_address1: "Linha de endereço 1:"
+ registration_detail_address1_placeholder: "ex. Rua Mármore, 123"
+ registration_detail_address1_error: "Favor inserir um endereço"
+ registration_detail_address2: "Linha de endereço 2:"
+ registration_detail_suburb: "Município"
+ registration_detail_suburb_placeholder: "ex. Contagem"
+ registration_detail_suburb_error: "Favor inserir um município"
+ registration_detail_postcode: "Código postal"
+ registration_detail_postcode_placeholder: "ex. 3070"
+ registration_detail_postcode_error: "Código postal requisitado"
+ registration_detail_state: "Estado"
+ registration_detail_state_error: "É obrigatório inserir o Estado"
+ registration_detail_country: "País"
+ registration_detail_country_error: "Favor inserir um país"
+ fees: "Taxas"
+ item_cost: "Custo da unidade"
+ bulk: "Atacado"
+ shop_variant_quantity_min: "mín."
+ shop_variant_quantity_max: "max."
+ follow: "Seguir"
+ shop_for_products_html: "Compre produtos da %{enterprise} em:"
+ change_shop: "Mudar loja para:"
+ shop_at: "Compre agora em:"
+ price_breakdown: "Preço detalhado"
+ admin_fee: "Taxa de manejo"
+ sales_fee: "Taxa de venda"
+ packing_fee: "Taxa de embalagem"
+ transport_fee: "Taxa de transporte"
+ fundraising_fee: "Taxa de poupança"
+ price_graph: "Gráfico de preços"
+ included_tax: "Taxas incluídas"
+ balance: "Balanço"
+ transaction: "Transação"
+ transaction_date: "DataData"
+ payment_state: "Status do Pagamento"
+ shipping_state: "Status da entrega"
+ value: "Valor"
+ balance_due: "saldo devedor"
+ credit: "Crédito"
+ Paid: "Pago"
+ Ready: "Pronto"
+ you_have_no_orders_yet: "Você ainda não tem pedidos"
+ running_balance: "Balanço corrente"
+ outstanding_balance: "Saldo devedor"
+ admin_entreprise_relationships: "Relações da empresa"
+ admin_entreprise_relationships_everything: "Tudo"
+ admin_entreprise_relationships_permits: "permite"
+ admin_entreprise_relationships_seach_placeholder: "Busca"
+ admin_entreprise_relationships_button_create: "Criar"
+ admin_entreprise_groups: "Grupos de empresas"
+ admin_entreprise_groups_name: "Nome"
+ admin_entreprise_groups_owner: "Dono"
+ admin_entreprise_groups_on_front_page: "Na página inicial?"
+ admin_entreprise_groups_entreprise: "Empreendimentos"
+ admin_entreprise_groups_data_powertip: "Usuário responsável pelo grupo"
+ admin_entreprise_groups_data_powertip_logo: "Esse é o logo do grupo"
+ admin_entreprise_groups_data_powertip_promo_image: "Essa é a imagem que aparecerá no topo do perfil do Grupo"
+ admin_entreprise_groups_contact: "Contato"
+ admin_entreprise_groups_contact_city: "Município"
+ admin_entreprise_groups_contact_city_placeholder: "ex. Contagem"
+ admin_entreprise_groups_contact_zipcode: "Código Postal "
+ admin_entreprise_groups_contact_zipcode_placeholder: "ex. 3078"
+ admin_entreprise_groups_contact_state_id: "Estadi"
+ admin_entreprise_groups_contact_country_id: "País"
+ admin_entreprise_groups_web: "Recursos Web"
+ admin_entreprise_groups_web_twitter: "ex. @nome_perfil"
+ admin_entreprise_groups_web_website_placeholder: "ex. www.cogumelos.com.br"
+ admin_order_cycles: "Ciclo de Pedidos do Administrador"
+ open: "Aberto"
+ close: "Fechado"
+ supplier: "Fornecedor"
+ coordinator: "Coordenador"
+ distributor: "Distribuidor"
+ fee_type: "Tipo de Taxa"
+ tax_category: "Categoria de taxa"
+ calculator: "Calculadora"
+ calculator_values: "Valores da calculadora"
+ flat_percent_per_item: "Percentual (por unidade)"
+ new_order_cycles: "Novo Ciclo de Pedidos"
+ select_a_coordinator_for_your_order_cycle: "Escolher um coordenador para novo ciclo de pedidos"
+ edit_order_cycle: "Editar Ciclo de Pedidos"
+ roles: "Papeis"
+ update: "Atualizar"
+ add_producer_property: "Adicionar produtor"
+ admin_settings: "Preferências do Sistema"
+ update_invoice: "Atualizar faturas"
+ finalise_invoice: "Finalizar Faturas"
+ finalise_user_invoices: "Finalizar Faturas de Usuário"
+ finalise_user_invoice_explained: "Usar este botão para finalizar todos as faturas no sistema para o calendário do mês anterior. "
+ manually_run_task: "Rodar Tarefa Manualmente"
+ update_user_invoices: "Atualizar Fatura de Usuário"
+ update_user_invoice_explained: "Usar este botão para atualizar imediamente todas as faturas no sistema para o mês atual, para cada usuário da empresa no sistema. Essa tarefa pode ser automatizada para rodar automaticamente toda noite. "
+ auto_finalise_invoices: "Finalizar automaticamente as faturas no dia 2 de cada mês, à 1:30am"
+ auto_update_invoices: "Atualizar automaticamente faturas toda as noites, a 1:00 am"
+ in_progress: "Em andamento"
+ started_at: "Começou em "
+ queued: "Aguardando"
+ scheduled_for: "Agendado para"
+ customers: "Clientes"
+ please_select_hub: "Favor selecionar uma Central"
+ loading_customers: "Carregando Clientes"
+ no_customers_found: "Nenhum cliente encontrado"
+ go: "Ir"
+ hub: "Central"
+ accounts_administration_distributor: "distribuidor de administração de contas"
+ accounts_and_billing: "Contas e Faturamento"
+ producer: "Produtor"
+ product: "Produto"
+ price: "Preço"
+ on_hand: "Disponível"
+ save_changes: "Salvar Modificações"
+ spree_admin_overview_enterprises_header: "Minhas Empresas"
+ spree_admin_overview_enterprises_footer: "GERENCIAR MINHAS EMPRESAS"
+ spree_admin_enterprises_hubs_name: "Nome"
+ spree_admin_enterprises_create_new: "CRIAR NOVA"
+ spree_admin_enterprises_shipping_methods: "Métodos de Entrega"
+ spree_admin_enterprises_fees: "Taxas da Empresa"
+ spree_admin_enterprises_none_create_a_new_enterprise: "CRIAR NOVA EMPRESA"
+ spree_admin_enterprises_none_text: "Você ainda não possui nenhuma empresa"
+ spree_admin_enterprises_producers_name: "Nome"
+ spree_admin_enterprises_producers_total_products: "Total de Produtos"
+ spree_admin_enterprises_producers_active_products: "Produtos Ativos"
+ spree_admin_enterprises_tabs_hubs: "CENTRAIS"
+ spree_admin_enterprises_tabs_producers: "PRODUTORES"
+ spree_admin_enterprises_producers_manage_order_cycles: "GERENCIAR CICLO DE PEDIDOS"
+ spree_admin_enterprises_producers_manage_products: "GERENCIAR PRODUTOS"
+ spree_admin_enterprises_producers_orders_cycle_text: "Você ainda não possui nenhum ciclo de pedidos ativo."
+ spree_admin_enterprises_any_active_products_text: "Você ainda não tem nenhum produto ativo."
+ spree_admin_enterprises_create_new_product: "CRIAR UM NOVO PRODUTO"
+ spree_admin_order_cycles: "Ciclo de Pedidos"
+ spree_admin_order_cycles_tip: "O ciclo de pedido determina quando e onde seus produtos estarão disponíveis para clientes."
+ dashbord: "Painel"
+ spree_admin_single_enterprise_alert_mail_confirmation: "Favor confirmar o endereço de email para"
+ spree_admin_single_enterprise_alert_mail_sent: "Enviamos um e-mail para"
+ spree_admin_overview_action_required: "Medida Solicitada"
+ spree_admin_overview_check_your_inbox: "Favor verificar sua caixa de entrada para maiores informações. Obrigado!"
+ change_package: "Modificar Embalagem"
+ spree_admin_single_enterprise_hint: "Dica: Para permitir que as pessoas te encontrem, ative sua visibilidade em"
+ your_profil_live: "Seu perfil online"
+ on_ofn_map: "O mapa da Open Food Network"
+ see: "Ver"
+ live: "online"
+ manage: "Gerenciar"
+ resend: "Re-enviar"
+ add_and_manage_products: "Adicionar e gerenciar produtos"
+ add_and_manage_order_cycles: "Adicionar e enviar ciclos de pedidos"
+ manage_order_cycles: "Gerenciar ciclos de pedidos"
+ manage_products: "Gerenciar produtos"
+ edit_profile_details: "Editar detalhes de perfil "
+ edit_profile_details_etc: "Modificar a descrição dos seu perfil, imagem, etc."
+ order_cycle: "Ciclo de Pedidos"
+ remove_tax: "Remover taxa"
+ tax_settings: "Configurações de Taxas"
+ products_require_tax_category: "produtos necessitam uma categoria de taxa"
+ admin_shared_address_1: "Endereço"
+ admin_shared_address_2: "Endereço (cont.)"
+ admin_share_city: "Cidade"
+ admin_share_zipcode: "Código Postal "
+ admin_share_country: "País"
+ admin_share_state: "Estadi"
+ hub_sidebar_hubs: "Centrais"
+ hub_sidebar_none_available: "Nada Disponível"
+ hub_sidebar_manage: "Gerenciar"
+ hub_sidebar_at_least: "Ao menos uma central deve ser selecionada"
+ hub_sidebar_blue: "azul"
+ hub_sidebar_red: "vermelho"
+ shop_trial_in_progress: "O período de avaliação do mercado termina em %{days}."
+ shop_trial_expired: "Boa notícia! Decidimos extender a avaliação da loja até segunda ordem. "
+ report_customers_distributor: "Distribuidor"
+ report_customers_supplier: "Fornecedor"
+ report_customers_cycle: "Ciclo de Pedidos"
+ report_customers_type: "Relatar Tipo"
+ report_customers_csv: "Fazer download como csv"
+ report_producers: "Produtores:"
+ report_type: "Relatar Tipo:"
+ report_hubs: "Centrais:"
+ report_payment: "Métodos de Pagamento"
+ report_distributor: "Distribuidor:"
+ report_payment_by: 'Pagamentos Por Tipo'
+ report_itemised_payment: 'Totais dos Pagamentos Discriminados'
+ report_payment_totals: 'Totais dos Pagamanetos'
+ report_all: 'todos'
+ report_order_cycle: "Ciclo de Pedidos:"
+ report_entreprises: "Empresas:"
+ report_users: "Usuários:"
+ initial_invoice_number: "Número de recibo inicial:"
+ invoice_date: "Data de recibo:"
+ due_date: "Data limite:"
+ account_code: "Código de conta:"
+ equals: "Igual a:"
+ contains: "contém:"
+ discount: "Desconto"
+ filter_products: "Filtrar Produtos"
+ delete_product_variant: "A última variante não pode ser deletada!"
+ progress: "progresso"
+ saving: "Salvando.."
+ success: "Sucesso"
+ failure: "falha"
+ unsaved_changes_confirmation: "Modificações não salvas serão perdidas. Continuar mesmo assim?"
+ one_product_unsaved: "Modificações para um produto permanecem não salvas."
+ products_unsaved: "Modificações para %{n} produtos permanecem não salvas."
+ is_already_manager: "já é um gestor!"
+ no_change_to_save: "Nenhuma modificação a ser salva"
+ add_manager: "Adicionar um gestor"
+ users: "Usuários"
+ about: "Sobre"
+ images: "Imagens"
+ web: "Web"
+ primary_details: "Detalhes principais"
+ adrdress: "Endereço"
+ contact: "Contato"
+ social: "Social"
+ business_details: "Detalhes do negócio"
+ properties: "Propriedades"
+ shipping_methods: "Métodos de Entrega"
+ payment_methods: "Métodos de Pagamento"
+ payment_method_fee: "Taxa de transação"
+ enterprise_fees: "Taxas da Empresa"
+ inventory_settings: "Configurações de Inventário"
+ tag_rules: "Regras para tag"
+ shop_preferences: "Preferências da Loja"
+ validation_msg_relationship_already_established: "^Esse relacionamento já foi estabelecido."
+ validation_msg_at_least_one_hub: "^Pelo menos uma central deve ser selecionada"
+ validation_msg_product_category_cant_be_blank: "^A Categoria do Produto deve ser preenchida"
+ validation_msg_tax_category_cant_be_blank: "^A Categoria da taxa deve ser preenchida"
+ validation_msg_is_associated_with_an_exising_customer: "está associado com um cliente existente"
+ spree:
+ zipcode: CEP
+ shipment_states:
+ backorder: atrasos
+ partial: parcial
+ pending: pendente
+ ready: pronto
+ shipped: enviado
+ payment_states:
+ balance_due: saldo devedor
+ completed: completado
+ checkout: fechar pedido
+ credit_owed: crédito devido
+ failed: falha
+ paid: pago
+ pending: pendente
+ processing: processando
+ void: vazio
+ invalid: inváliod
+ order_state:
+ address: endereço
+ adjustments: ajustes
+ awaiting_return: aguardando retorno
+ canceled: cancelado
+ cart: carrinho
+ complete: completo
+ confirm: confirmado
+ delivery: entrega
+ payment: pagamento
+ resumed: retomado
+ returned: retornado
+ skrill: skrill
diff --git a/config/routes.rb b/config/routes.rb
index 69319ae84a..607e6308a2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -169,6 +169,8 @@ Openfoodnetwork::Application.routes.draw do
end
end
+ get 'sitemap.xml', to: 'sitemap#index', defaults: { format: 'xml' }
+
# Mount Spree's routes
mount Spree::Core::Engine, :at => '/'
diff --git a/lib/open_food_network/distribution_change_validator.rb b/lib/open_food_network/distribution_change_validator.rb
index 6f7edc2c0f..ba6d21b247 100644
--- a/lib/open_food_network/distribution_change_validator.rb
+++ b/lib/open_food_network/distribution_change_validator.rb
@@ -1,5 +1,5 @@
class DistributionChangeValidator
-
+
def initialize order
@order = order
end
@@ -29,7 +29,7 @@ class DistributionChangeValidator
end
def available_distributors_for(product)
- distributors = Enterprise.distributing_product(product)
+ distributors = Enterprise.distributing_products(product)
if @order.andand.line_items.present?
distributors = available_distributors(distributors)
diff --git a/lib/open_food_network/enterprise_injection_data.rb b/lib/open_food_network/enterprise_injection_data.rb
index 87516007c6..938c8b3aab 100644
--- a/lib/open_food_network/enterprise_injection_data.rb
+++ b/lib/open_food_network/enterprise_injection_data.rb
@@ -20,8 +20,12 @@ module OpenFoodNetwork
@supplied_taxons ||= Spree::Taxon.supplied_taxons
end
- def distributed_taxons
- @distributed_taxons ||= Spree::Taxon.distributed_taxons
+ def all_distributed_taxons
+ @all_distributed_taxons ||= Spree::Taxon.distributed_taxons(:all)
+ end
+
+ def current_distributed_taxons
+ @current_distributed_taxons ||= Spree::Taxon.distributed_taxons(:current)
end
end
end
diff --git a/lib/open_food_network/products_cache.rb b/lib/open_food_network/products_cache.rb
index f6ef15829f..fc3caec111 100644
--- a/lib/open_food_network/products_cache.rb
+++ b/lib/open_food_network/products_cache.rb
@@ -28,6 +28,15 @@ module OpenFoodNetwork
end
end
+ def self.product_deleted(product, &block)
+ exchanges = exchanges_featuring_variants(product.reload.variants).to_a
+
+ block.call
+
+ exchanges.each do |exchange|
+ refresh_cache exchange.receiver, exchange.order_cycle
+ end
+ end
def self.variant_override_changed(variant_override)
exchanges_featuring_variants(variant_override.variant, distributor: variant_override.hub).each do |exchange|
diff --git a/lib/open_food_network/referer_parser.rb b/lib/open_food_network/referer_parser.rb
index b90ef21829..20be289f44 100644
--- a/lib/open_food_network/referer_parser.rb
+++ b/lib/open_food_network/referer_parser.rb
@@ -5,13 +5,11 @@ module OpenFoodNetwork
end
def self.parse_uri(string)
- begin
- # TODO: make this operation obsolete by fixing URLs generated by AngularJS
- string.sub!('##', '#')
- URI(string)
- rescue URI::InvalidURIError
- nil
- end
+ # TODO: make this operation obsolete by fixing URLs generated by AngularJS
+ string.sub!('##', '#')
+ URI(string)
+ rescue URI::InvalidURIError
+ nil
end
end
end
diff --git a/lib/spree/core/calculated_adjustments_decorator.rb b/lib/spree/core/calculated_adjustments_decorator.rb
new file mode 100644
index 0000000000..6a42eb68c5
--- /dev/null
+++ b/lib/spree/core/calculated_adjustments_decorator.rb
@@ -0,0 +1,14 @@
+module Spree
+ module Core
+ module CalculatedAdjustments
+ module ClassMethods
+ def calculated_adjustments_with_explicit_class_name
+ calculated_adjustments_without_explicit_class_name
+ # Class name is mis-inferred outside of Spree namespace
+ has_one :calculator, as: :calculable, dependent: :destroy, class_name: 'Spree::Calculator'
+ end
+ alias_method_chain :calculated_adjustments, :explicit_class_name
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers/respond_with_decorator.rb b/lib/spree/core/controller_helpers/respond_with_decorator.rb
new file mode 100644
index 0000000000..4910591b9c
--- /dev/null
+++ b/lib/spree/core/controller_helpers/respond_with_decorator.rb
@@ -0,0 +1,26 @@
+module ActionController
+ class Base
+ def respond_with(*resources, &block)
+ raise "In order to use respond_with, first you need to declare the formats your " <<
+ "controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
+
+ if collector = retrieve_collector_from_mimes(&block)
+ options = resources.size == 1 ? {} : resources.extract_options!
+
+ # Fix spree issues #3531 and #2210 (patch provided by leiyangyou)
+ if defined_response = collector.response and !(Spree::BaseController.spree_responders[self.class.to_s.to_sym].try(:[], action_name.to_sym))
+ if action = options.delete(:action)
+ render :action => action
+ else
+ defined_response.call
+ end
+ else
+ # The action name is needed for processing
+ options.merge!(:action_name => action_name.to_sym)
+ # If responder is not specified then pass in Spree::Responder
+ (options.delete(:responder) || Spree::Responder).call(self, resources, options)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/money_decorator.rb b/lib/spree/money_decorator.rb
index 3479bbd9a2..755041df0e 100644
--- a/lib/spree/money_decorator.rb
+++ b/lib/spree/money_decorator.rb
@@ -6,7 +6,18 @@ Spree::Money.class_eval do
end
def rounded
- @options[:no_cents] = true if @money.amount % 1 == 0
+ @options[:no_cents] = true if @money.dollars % 1 == 0
to_s
end
+
+ def to_html(options = { :html => true })
+ output = @money.format(@options.merge(options))
+ if options[:html]
+ # 1) prevent blank, breaking spaces
+ # 2) prevent escaping of HTML character entities
+ output = output.sub(" ", " ").html_safe
+ end
+ output
+ end
+
end
diff --git a/public/Terms-of-ServiceUK.pdf b/public/Terms-of-ServiceUK.pdf
new file mode 100644
index 0000000000..e69c013f23
Binary files /dev/null and b/public/Terms-of-ServiceUK.pdf differ
diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb
index 05498010bb..94282e6c2c 100644
--- a/spec/controllers/admin/enterprises_controller_spec.rb
+++ b/spec/controllers/admin/enterprises_controller_spec.rb
@@ -28,6 +28,7 @@ module Admin
spree_put :create, enterprise_params
enterprise = Enterprise.find_by_name 'zzz'
+ response.should redirect_to edit_admin_enterprise_path enterprise
distributor_manager.enterprise_roles.where(enterprise_id: enterprise).first.should be
end
@@ -37,15 +38,17 @@ module Admin
spree_put :create, enterprise_params
enterprise = Enterprise.find_by_name 'zzz'
+ response.should redirect_to edit_admin_enterprise_path enterprise
admin_user.enterprise_roles.where(enterprise_id: enterprise).should be_empty
end
- it "overrides the owner_id submitted by the user unless current_user is super admin" do
+ it "overrides the owner_id submitted by the user (when not super admin)" do
controller.stub spree_current_user: distributor_manager
enterprise_params[:enterprise][:owner_id] = user
spree_put :create, enterprise_params
enterprise = Enterprise.find_by_name 'zzz'
+ response.should redirect_to edit_admin_enterprise_path enterprise
distributor_manager.enterprise_roles.where(enterprise_id: enterprise).first.should be
end
@@ -58,6 +61,7 @@ module Admin
spree_put :create, enterprise_params
enterprise = Enterprise.find_by_name 'zzz'
+ response.should redirect_to edit_admin_enterprise_path enterprise
enterprise.sells.should == 'any'
end
@@ -68,6 +72,7 @@ module Admin
spree_put :create, enterprise_params
enterprise = Enterprise.find_by_name 'zzz'
+ response.should redirect_to edit_admin_enterprise_path enterprise
enterprise.sells.should == 'none'
end
@@ -80,6 +85,7 @@ module Admin
spree_put :create, enterprise_params
enterprise = Enterprise.find_by_name 'zzz'
+ response.should redirect_to edit_admin_enterprise_path enterprise
enterprise.sells.should == 'none'
end
end
diff --git a/spec/controllers/spree/api/variants_controller_spec.rb b/spec/controllers/spree/api/variants_controller_spec.rb
index 5fb9f2f2a0..39c6439999 100644
--- a/spec/controllers/spree/api/variants_controller_spec.rb
+++ b/spec/controllers/spree/api/variants_controller_spec.rb
@@ -47,7 +47,7 @@ module Spree
spree_delete :soft_delete, {variant_id: variant.to_param, product_id: product.to_param, format: :json}
response.status.should == 204
lambda { variant.reload }.should_not raise_error
- variant.deleted_at.should_not be_nil
+ variant.deleted_at.should be_present
end
it "is denied access to soft deleting another enterprises' variant" do
diff --git a/spec/factories.rb b/spec/factories.rb
index 9875d22652..d4193c11aa 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -319,10 +319,6 @@ end
FactoryGirl.modify do
- factory :base_product do
- unit_value 1
- unit_description ''
- end
factory :product do
primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) }
end
@@ -336,12 +332,15 @@ FactoryGirl.modify do
primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) }
on_hand 3
+ unit_value 1
+ unit_description ''
+
variant_unit 'weight'
variant_unit_scale 1
variant_unit_name ''
end
- factory :base_variant do
+ factory :variant do
unit_value 1
unit_description ''
end
diff --git a/spec/features/admin/authentication_spec.rb b/spec/features/admin/authentication_spec.rb
index fe2eb156c5..5cdbbbd6de 100644
--- a/spec/features/admin/authentication_spec.rb
+++ b/spec/features/admin/authentication_spec.rb
@@ -18,6 +18,7 @@ feature "Authentication", js: true do
click_login_button
expect(page).to have_content "DASHBOARD"
expect(page).to have_current_path spree.admin_path
+ expect(page).to have_no_content "CONFIGURATION"
end
end
diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb
index ef4fc13e39..74c10c7b72 100644
--- a/spec/features/admin/bulk_order_management_spec.rb
+++ b/spec/features/admin/bulk_order_management_spec.rb
@@ -162,9 +162,9 @@ feature %q{
# hide dropdown
find("div#columns-dropdown", :text => "COLUMNS").click
within "tr#li_#{li1.id}" do
- expect(page).to have_field "price", with: "$50.00"
+ expect(page).to have_field "price", with: "50.00"
fill_in "final_weight_volume", :with => 2000
- expect(page).to have_field "price", with: "$100.00"
+ expect(page).to have_field "price", with: "100.00"
end
click_button "Save Changes"
expect(page).to have_no_selector "#save-bar"
@@ -181,9 +181,9 @@ feature %q{
find("div#columns-dropdown div.menu div.menu_item", text: "Price").click
find("div#columns-dropdown", :text => "COLUMNS").click
within "tr#li_#{li1.id}" do
- expect(page).to have_field "price", with: "$#{format("%.2f",li1.price * 5)}"
+ expect(page).to have_field "price", with: "#{format("%.2f",li1.price * 5)}"
fill_in "quantity", :with => 6
- expect(page).to have_field "price", with: "$#{format("%.2f",li1.price * 6)}"
+ expect(page).to have_field "price", with: "#{format("%.2f",li1.price * 6)}"
end
end
end
diff --git a/spec/features/admin/enterprise_groups_spec.rb b/spec/features/admin/enterprise_groups_spec.rb
index 2adb96c0a5..d973dfd557 100644
--- a/spec/features/admin/enterprise_groups_spec.rb
+++ b/spec/features/admin/enterprise_groups_spec.rb
@@ -105,6 +105,17 @@ feature %q{
end
context "as an enterprise user" do
+ let(:user) { create_enterprise_user }
+ let!(:enterprise) { create(:distributor_enterprise, owner: user) }
+ let!(:group) { create(:enterprise_group, name: 'My Group', owner: user) }
+
+ it "lets me access enterprise groups" do
+ quick_login_as user
+ visit spree.admin_path
+ click_link 'Groups'
+ expect(page).to have_content 'My Group'
+ end
+
xit "should show me only enterprises I manage when creating a new enterprise group"
end
end
diff --git a/spec/features/admin/enterprises_spec.rb b/spec/features/admin/enterprises_spec.rb
index b436c0c3ee..c051c9eade 100644
--- a/spec/features/admin/enterprises_spec.rb
+++ b/spec/features/admin/enterprises_spec.rb
@@ -77,7 +77,7 @@ feature %q{
visit '/admin/enterprises'
within "tr.enterprise-#{@enterprise.id}" do
- all("a", text: 'Edit Profile').first.click
+ first("a", text: 'Edit Profile').trigger 'click'
end
fill_in 'enterprise_name', :with => 'Eaterprises'
@@ -210,8 +210,8 @@ feature %q{
fill_in 'enterprise_producer_properties_attributes_0_value', with: "NASAA 12345"
click_button 'Update'
- # Then I should be returned to the enterprises page
- page.should have_selector '#listing_enterprises a', text: s.name
+ # Then I should remain on the producer properties page
+ expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s)
# And the producer should have the property
s.producer_properties(true).count.should == 1
@@ -233,8 +233,8 @@ feature %q{
fill_in 'enterprise_producer_properties_attributes_0_value', with: "Shininess"
click_button 'Update'
- # Then I should be returned to the enterprises
- page.should have_selector '#listing_enterprises a', text: s.name
+ # Then I should remain on the producer properties page
+ expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s)
# And the property should be updated
s.producer_properties(true).count.should == 1
@@ -254,9 +254,10 @@ feature %q{
# And I remove the property
page.should have_field 'enterprise_producer_properties_attributes_0_property_name', with: 'Certified Organic'
within("#spree_producer_property_#{pp.id}") { page.find('a.remove_fields').click }
+ click_button 'Update'
# Then the property should have been removed
- page.should_not have_selector '#progress'
+ expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s)
page.should_not have_field 'enterprise_producer_properties_attributes_0_property_name', with: 'Certified Organic'
s.producer_properties(true).should be_empty
end
@@ -438,7 +439,10 @@ feature %q{
end
within("#spree_producer_property_#{pp.id}") { page.find('a.remove_fields').click }
- page.should_not have_selector '#progress'
+
+ click_button 'Update'
+
+ expect(page).to have_content 'Enterprise "First Supplier" has been successfully updated!'
supplier1.producer_properties(true).should be_empty
end
end
diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb
index 74b2e88453..212fafd026 100644
--- a/spec/features/admin/order_cycles_spec.rb
+++ b/spec/features/admin/order_cycles_spec.rb
@@ -409,11 +409,11 @@ feature %q{
end
- scenario "updating many order cycle opening/closing times at once" do
+ scenario "updating many order cycle opening/closing times at once", js: true do
# Given three order cycles
oc1 = create(:simple_order_cycle)
oc2 = create(:simple_order_cycle)
- oc3 = create(:simple_order_cycle)
+ oc3 = create(:simple_order_cycle, orders_open_at: Time.zone.local(2040, 12, 12, 12, 12, 12))
# When I go to the order cycles page
login_to_admin_section
@@ -430,7 +430,28 @@ feature %q{
all('input').last.set '2040-12-01 12:00:03'
end
+ # And I fill in a time using the datepicker
within("tr.order-cycle-#{oc3.id}") do
+ # When I trigger the datepicker
+ find('img.ui-datepicker-trigger', match: :first).click
+ end
+
+ within("#ui-datepicker-div") do
+ # Then it should display the correct date/time
+ expect(page).to have_selector 'span.ui-datepicker-month', text: 'DECEMBER'
+ expect(page).to have_selector 'span.ui-datepicker-year', text: '2040'
+ expect(page).to have_selector 'a.ui-state-active', text: '12'
+
+ # When I fill in a new date/time
+ click_link '1'
+ click_button 'Done'
+ end
+
+ within("tr.order-cycle-#{oc3.id}") do
+ # Then that date/time should appear on the form
+ expect(all('input').first.value).to eq '2040-12-01 00:00'
+
+ # Manually fill out time
all('input').first.set '2040-12-01 12:00:04'
all('input').last.set '2040-12-01 12:00:05'
end
diff --git a/spec/features/admin/overview_spec.rb b/spec/features/admin/overview_spec.rb
index 590c8528e8..30f2cc0336 100644
--- a/spec/features/admin/overview_spec.rb
+++ b/spec/features/admin/overview_spec.rb
@@ -3,31 +3,18 @@ require 'spec_helper'
feature %q{
As a backend user
I want to be given information about the state of my enterprises, products and order cycles
-} , js: true do
+}, js: true do
include AuthenticationWorkflow
include AuthorizationHelpers
include WebHelper
- stub_authorization!
-
context "as an enterprise user" do
- before :each do
+ before do
@enterprise_user = create_enterprise_user
Spree::Admin::OverviewController.any_instance.stub(:spree_current_user).and_return @enterprise_user
quick_login_as @enterprise_user
end
- context "with no enterprises" do
- it "prompts the user to create a new enteprise" do
- visit '/admin'
- page.should have_selector ".dashboard_item#enterprises h3", text: "My Enterprises"
- page.should have_selector ".dashboard_item#enterprises .list-item", text: "You don't have any enterprises yet"
- page.should have_selector ".dashboard_item#enterprises .button.bottom", text: "CREATE A NEW ENTERPRISE"
- page.should_not have_selector ".dashboard_item#products"
- page.should_not have_selector ".dashboard_item#order_cycles"
- end
- end
-
context "with an enterprise" do
let(:d1) { create(:distributor_enterprise) }
@@ -123,5 +110,45 @@ feature %q{
end
end
end
+
+ context "with the spree dash configured" do
+ let(:d1) { create(:distributor_enterprise) }
+
+ before do
+ stub_jirafe
+ @enterprise_user.enterprise_roles.build(enterprise: d1).save
+ end
+
+ around do |example|
+ with_dash_configured { example.run }
+ end
+
+ it "has permission to sync analytics" do
+ visit '/admin'
+ expect(page).to have_content d1.name
+ end
+ end
end
-end
\ No newline at end of file
+
+ private
+
+ def stub_jirafe
+ stub_request(:post, "https://api.jirafe.com/v1/applications/abc123/resources?token=").
+ to_return(:status => 200, :body => "", :headers => {})
+ end
+
+ def with_dash_configured(&block)
+ Spree::Dash::Config.preferred_app_id = 'abc123'
+ Spree::Dash::Config.preferred_site_id = 'abc123'
+ Spree::Dash::Config.preferred_token = 'abc123'
+ expect(Spree::Dash::Config.configured?).to be true
+
+ block.call
+
+ ensure
+ Spree::Dash::Config.preferred_app_id = nil
+ Spree::Dash::Config.preferred_site_id = nil
+ Spree::Dash::Config.preferred_token = nil
+ expect(Spree::Dash::Config.configured?).to be false
+ end
+end
diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb
index 2aafc82b02..445844d97b 100644
--- a/spec/features/admin/products_spec.rb
+++ b/spec/features/admin/products_spec.rb
@@ -39,6 +39,7 @@ feature %q{
click_button 'Create'
+ expect(current_path).to eq spree.bulk_edit_admin_products_path
flash_message.should == 'Product "A new product !!!" has been successfully created!'
product = Spree::Product.find_by_name('A new product !!!')
product.supplier.should == @supplier
@@ -56,22 +57,6 @@ feature %q{
product.group_buy.should be_false
product.master.option_values.map(&:name).should == ['5kg']
product.master.options_text.should == "5kg"
-
- # Distributors
- visit spree.product_distributions_admin_product_path(product)
-
- check @distributors[0].name
- select2_select @enterprise_fees[0].name, :from => 'product_product_distributions_attributes_0_enterprise_fee_id'
- check @distributors[2].name
- select2_select @enterprise_fees[2].name, :from => 'product_product_distributions_attributes_2_enterprise_fee_id'
-
- click_button 'Update'
-
- product.reload
- product.distributors.should match_array [@distributors[0], @distributors[2]]
-
-
- product.product_distributions.map { |pd| pd.enterprise_fee }.should match_array [@enterprise_fees[0], @enterprise_fees[2]]
end
scenario "making a product into a group buy product" do
@@ -185,7 +170,7 @@ feature %q{
scenario "deleting product properties", js: true do
# Given a product with a property
- p = create(:simple_product, supplier: @supplier)
+ p = create(:simple_product, supplier: @supplier2)
p.set_property('fooprop', 'fooval')
# When I navigate to the product properties page
@@ -195,11 +180,12 @@ feature %q{
# And I delete the property
page.all('a.remove_fields').first.click
- wait_until { p.reload.property('fooprop').nil? }
+ click_button 'Update'
# Then the property should have been deleted
page.should_not have_field 'product_product_properties_attributes_0_property_name', with: 'fooprop'
page.should_not have_field 'product_product_properties_attributes_0_value', with: 'fooval'
+ expect(p.reload.property('fooprop')).to be_nil
end
diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb
index 1cb559a653..d21c0998e5 100644
--- a/spec/features/admin/variant_overrides_spec.rb
+++ b/spec/features/admin/variant_overrides_spec.rb
@@ -29,7 +29,9 @@ feature %q{
permissions_list: [:add_to_order_cycle]) } # This er should not confer ability to create VOs for hub2
it "displays a list of hub choices (ie. only those managed by the user)" do
- visit '/admin/inventory'
+ visit spree.admin_path
+ click_link 'Products'
+ click_link 'Inventory'
page.should have_select2 'hub_id', options: [hub.name] # Selects the hub automatically when only one is available
end
diff --git a/spec/features/consumer/groups_spec.rb b/spec/features/consumer/groups_spec.rb
index 039322b379..4a5f166d7d 100644
--- a/spec/features/consumer/groups_spec.rb
+++ b/spec/features/consumer/groups_spec.rb
@@ -54,4 +54,43 @@ feature 'Groups', js: true do
end
end
end
+
+ describe "shops" do
+ describe "filtering by product property" do
+ let!(:group) { create(:enterprise_group, enterprises: [d1, d2], on_front_page: true) }
+ let!(:order_cycle) { create(:simple_order_cycle, distributors: [d1, d2], coordinator: create(:distributor_enterprise)) }
+ let(:producer) { create(:supplier_enterprise) }
+ let(:d1) { create(:distributor_enterprise) }
+ let(:d2) { create(:distributor_enterprise) }
+ let(:p1) { create(:simple_product, supplier: producer) }
+ let(:p2) { create(:simple_product, supplier: create(:supplier_enterprise)) }
+ let(:ex_d1) { order_cycle.exchanges.outgoing.where(receiver_id: d1).first }
+ let(:ex_d2) { order_cycle.exchanges.outgoing.where(receiver_id: d2).first }
+
+ before do
+ producer.set_producer_property 'Organic', 'NASAA 12345'
+ p2.set_property 'Local', 'XYZ 123'
+
+ ex_d1.variants << p1.variants.first
+ ex_d2.variants << p2.variants.first
+
+ visit group_path(group, anchor: "/hubs")
+ end
+
+ it "filters" do
+ toggle_filters
+
+ toggle_filter 'Organic'
+
+ expect(page).to have_content d1.name
+ expect(page).not_to have_content d2.name
+
+ toggle_filter 'Organic'
+ toggle_filter 'Local'
+
+ expect(page).not_to have_content d1.name
+ expect(page).to have_content d2.name
+ end
+ end
+ end
end
diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb
index 7bd540169f..16bdb27ec1 100644
--- a/spec/features/consumer/shopping/checkout_spec.rb
+++ b/spec/features/consumer/shopping/checkout_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
-feature "As a consumer I want to check out my cart", js: true do
+feature "As a consumer I want to check out my cart", js: true, retry: 3 do
include AuthenticationWorkflow
include ShopWorkflow
include CheckoutWorkflow
diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb
index b449b4d083..e11f929f6a 100644
--- a/spec/features/consumer/shopping/shopping_spec.rb
+++ b/spec/features/consumer/shopping/shopping_spec.rb
@@ -142,7 +142,9 @@ feature "As a consumer I want to shop with a distributor", js: true do
describe "after selecting an order cycle with products visible" do
let(:variant1) { create(:variant, product: product, price: 20) }
- let(:variant2) { create(:variant, product: product, price: 30) }
+ let(:variant2) { create(:variant, product: product, price: 30, display_name: "Badgers") }
+ let(:product2) { create(:simple_product, supplier: supplier, name: "Meercats") }
+ let(:variant3) { create(:variant, product: product2, price: 40, display_name: "Ferrets") }
let(:exchange) { Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id) }
before do
@@ -150,6 +152,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
add_variant_to_order_cycle(exchange, variant)
add_variant_to_order_cycle(exchange, variant1)
add_variant_to_order_cycle(exchange, variant2)
+ add_variant_to_order_cycle(exchange, variant3)
order.order_cycle = oc1
end
@@ -171,6 +174,35 @@ feature "As a consumer I want to shop with a distributor", js: true do
# Product price should be listed as the lesser of these
page.should have_price "$43.00"
end
+
+ it "filters search results properly" do
+ visit shop_path
+ select "frogs", :from => "order_cycle_id"
+
+ fill_in "search", with: "74576345634XXXXXX"
+ page.should have_content "Sorry, no results found"
+ page.should_not have_content product2.name
+
+ fill_in "search", with: "Meer" # For product named "Meercats"
+ page.should have_content product2.name
+ page.should_not have_content product.name
+ end
+
+ it "returns search results for products where the search term matches one of the product's variant names" do
+ visit shop_path
+ select "frogs", :from => "order_cycle_id"
+
+ fill_in "search", with: "Badg" # For variant with display_name "Badgers"
+
+ within('div.pad-top') do
+ page.should have_content product.name
+ page.should have_content variant2.display_name
+ page.should_not have_content product2.name
+ page.should_not have_content variant3.display_name
+ end
+
+ end
+
end
describe "group buy products" do
diff --git a/spec/features/consumer/shops_spec.rb b/spec/features/consumer/shops_spec.rb
index 2a65a73aef..c9e8063e72 100644
--- a/spec/features/consumer/shops_spec.rb
+++ b/spec/features/consumer/shops_spec.rb
@@ -47,7 +47,7 @@ feature 'Shops', js: true do
it "should show closed shops after clicking the button" do
create(:simple_product, distributors: [d1, d2])
visit shops_path
- click_link_and_ensure("Show closed shops", -> { page.has_selector? 'hub.inactive' })
+ click_link_and_ensure("Show Closed Shops", -> { page.has_selector? 'hub.inactive' })
page.should have_selector 'hub.inactive', text: d2.name
end
@@ -55,46 +55,108 @@ feature 'Shops', js: true do
follow_active_table_node distributor.name
expect(page).to have_current_path enterprise_shop_path(distributor)
end
+ end
- describe "property badges" do
- let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise), variants: [product.variants.first]) }
- let(:product) { create(:simple_product, supplier: producer) }
+ describe "filtering by product property" do
+ let!(:order_cycle) { create(:simple_order_cycle, distributors: [d1, d2], coordinator: create(:distributor_enterprise)) }
+ let!(:p1) { create(:simple_product, supplier: producer) }
+ let!(:p2) { create(:simple_product, supplier: create(:supplier_enterprise)) }
+ let(:ex_d1) { order_cycle.exchanges.outgoing.where(receiver_id: d1).first }
+ let(:ex_d2) { order_cycle.exchanges.outgoing.where(receiver_id: d2).first }
- before do
- product.set_property 'Local', 'XYZ 123'
- end
+ before do
+ ex_d1.variants << p1.variants.first
+ ex_d2.variants << p2.variants.first
- it "shows property badges" do
- # Given a shop with a product with a property
- # And the product's producer has a producer property
+ p2.set_property 'Local', 'XYZ 123'
- # When I go to the shops path
+ visit shops_path
+ end
+
+ it "filters" do
+ toggle_filters
+
+ toggle_filter 'Organic'
+
+ expect(page).to have_content d1.name
+ expect(page).not_to have_content d2.name
+
+ toggle_filter 'Organic'
+ toggle_filter 'Local'
+
+ expect(page).not_to have_content d1.name
+ expect(page).to have_content d2.name
+ end
+ end
+
+ describe "taxon badges" do
+ let!(:closed_oc) { create(:closed_order_cycle, distributors: [shop], variants: [p_closed.variants.first]) }
+ let!(:p_closed) { create(:simple_product, taxons: [taxon_closed]) }
+ let(:shop) { create(:distributor_enterprise) }
+ let(:taxon_closed) { create(:taxon, name: 'Closed') }
+
+ describe "open shops" do
+ let!(:open_oc) { create(:open_order_cycle, distributors: [shop], variants: [p_open.variants.first]) }
+ let!(:p_open) { create(:simple_product, taxons: [taxon_open]) }
+ let(:taxon_open) { create(:taxon, name: 'Open') }
+
+ it "shows taxons for open order cycles only" do
visit shops_path
-
- # And I open the shop
- expand_active_table_node distributor.name
-
- # Then I should see both properties
- expect(page).to have_content 'Local' # Product property
- expect(page).to have_content 'Organic' # Producer property
+ expand_active_table_node shop.name
+ expect(page).to have_selector '.fat-taxons', text: 'Open'
+ expect(page).not_to have_selector '.fat-taxons', text: 'Closed'
end
end
- describe "hub producer modal" do
- let!(:product) { create(:simple_product, supplier: producer, taxons: [taxon]) }
- let!(:taxon) { create(:taxon, name: 'Fruit') }
- let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise), variants: [product.variants.first]) }
+ describe "closed shops" do
+ it "shows taxons for any order cycle" do
+ visit shops_path
+ click_link 'Show Closed Shops'
+ expand_active_table_node shop.name
+ expect(page).to have_selector '.fat-taxons', text: 'Closed'
+ end
+ end
+ end
- it "shows hub producer modals" do
- expand_active_table_node distributor.name
- expect(page).to have_content producer.name
- open_enterprise_modal producer
- modal_should_be_open_for producer
+ describe "property badges" do
+ let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise), variants: [product.variants.first]) }
+ let(:product) { create(:simple_product, supplier: producer) }
- within ".reveal-modal" do
- expect(page).to have_content 'Fruit' # Taxon
- expect(page).to have_content 'Organic' # Producer property
- end
+ before do
+ product.set_property 'Local', 'XYZ 123'
+ end
+
+ it "shows property badges" do
+ # Given a shop with a product with a property
+ # And the product's producer has a producer property
+
+ # When I go to the shops path
+ visit shops_path
+
+ # And I open the shop
+ expand_active_table_node distributor.name
+
+ # Then I should see both properties
+ expect(page).to have_content 'Local' # Product property
+ expect(page).to have_content 'Organic' # Producer property
+ end
+ end
+
+ describe "hub producer modal" do
+ let!(:product) { create(:simple_product, supplier: producer, taxons: [taxon]) }
+ let!(:taxon) { create(:taxon, name: 'Fruit') }
+ let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise), variants: [product.variants.first]) }
+
+ it "shows hub producer modals" do
+ visit shops_path
+ expand_active_table_node distributor.name
+ expect(page).to have_content producer.name
+ open_enterprise_modal producer
+ modal_should_be_open_for producer
+
+ within ".reveal-modal" do
+ expect(page).to have_content 'Fruit' # Taxon
+ expect(page).to have_content 'Organic' # Producer property
end
end
end
diff --git a/spec/features/consumer/sitemap_spec.rb b/spec/features/consumer/sitemap_spec.rb
new file mode 100644
index 0000000000..6ec913de32
--- /dev/null
+++ b/spec/features/consumer/sitemap_spec.rb
@@ -0,0 +1,12 @@
+require 'spec_helper'
+
+feature 'sitemap' do
+ let(:enterprise) { create(:distributor_enterprise) }
+ let!(:group) { create(:enterprise_group, enterprises: [enterprise], on_front_page: true) }
+
+ it "renders sitemap" do
+ visit '/sitemap.xml'
+ expect(page).to have_content enterprise_shop_url(enterprise)
+ expect(page).to have_content group_url(group)
+ end
+end
diff --git a/spec/helpers/navigation_helper_spec.rb b/spec/helpers/navigation_helper_spec.rb
index 76fe9573f2..360dd57495 100644
--- a/spec/helpers/navigation_helper_spec.rb
+++ b/spec/helpers/navigation_helper_spec.rb
@@ -19,6 +19,14 @@ module Spree
it "returns Spree::Order for bulk_order_management" do
helper.klass_for('bulk_order_management').should == Spree::Order
end
+
+ it "returns EnterpriseGroup for group" do
+ helper.klass_for('group').should == EnterpriseGroup
+ end
+
+ it "returns VariantOverride for Inventory" do
+ helper.klass_for('Inventory').should == VariantOverride
+ end
end
end
end
diff --git a/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee b/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee
index 5f3deff550..ce4b967f90 100644
--- a/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee
+++ b/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee
@@ -62,28 +62,17 @@ describe "CustomersCtrl", ->
as = scope.findByCode('b')
expect(as).toDeepEqual []
- describe "scope.add", ->
- it "creates a new customer", ->
- email = "customer@example.org"
- newCustomer = {id: 6, email: email}
- customers.unshift(newCustomer)
- http.expectPOST('/admin/customers.json?email=' + email + '&enterprise_id=3').respond 200, newCustomer
- scope.add(email)
- http.flush()
- expect(scope.customers).toDeepEqual customers
-
describe "scope.deleteCustomer", ->
beforeEach ->
spyOn(window, 'confirm').and.returnValue(true)
it "deletes a customer", ->
- expect(scope.customers.length).toBe 2
+ expect(scope.customers.length).toBe 1
customer = scope.customers[0]
http.expectDELETE('/admin/customers/' + customer.id + '.json').respond 200
scope.deleteCustomer(customer)
http.flush()
- expect(scope.customers.length).toBe 1
- expect(scope.customers[0]).not.toDeepEqual customer
+ expect(scope.customers.length).toBe 0
describe "scope.findTags", ->
tags = [
diff --git a/spec/javascripts/unit/admin/customers/services/customers_spec.js.coffee b/spec/javascripts/unit/admin/customers/services/customers_spec.js.coffee
new file mode 100644
index 0000000000..569701d29c
--- /dev/null
+++ b/spec/javascripts/unit/admin/customers/services/customers_spec.js.coffee
@@ -0,0 +1,23 @@
+describe "Customers", ->
+ Customers = CurrentShop = customers = $httpBackend = null
+
+ beforeEach ->
+ module 'admin.customers'
+
+ jasmine.addMatchers
+ toDeepEqual: (util, customEqualityTesters) ->
+ compare: (actual, expected) ->
+ { pass: angular.equals(actual, expected) }
+
+ inject ($q, _$httpBackend_, _Customers_, _CurrentShop_) ->
+ Customers = _Customers_
+
+ describe "scope.add", ->
+ it "creates a new customer", inject ($httpBackend, CurrentShop) ->
+ email = "customer@example.org"
+ newCustomer = {id: 6, email: email}
+ CurrentShop.shop = { id: 3 }
+ $httpBackend.expectPOST('/admin/customers.json?email=' + email + '&enterprise_id=3').respond 200, newCustomer
+ Customers.add(email)
+ $httpBackend.flush()
+ expect(Customers.all).toDeepEqual [newCustomer]
diff --git a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee
index 702ef2cc1c..8c088b1715 100644
--- a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee
+++ b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee
@@ -26,9 +26,9 @@ describe "Enterprises service", ->
result = Enterprises.index()
$httpBackend.flush()
- it "stores returned data in @enterprisesByID, with ids as keys", ->
+ it "stores returned data in @byID, with ids as keys", ->
# EnterpriseResource returns instances of Resource rather than raw objects
- expect(Enterprises.enterprisesByID).toDeepEqual { 5: response[0] }
+ expect(Enterprises.byID).toDeepEqual { 5: response[0] }
it "stores returned data in @pristineByID, with ids as keys", ->
expect(Enterprises.pristineByID).toDeepEqual { 5: response[0] }
@@ -37,25 +37,14 @@ describe "Enterprises service", ->
expect(result).toDeepEqual response
describe "when params are passed", ->
- describe "where includeBlank param is truthy", ->
- beforeEach ->
- params = {includeBlank: true, someParam: 'someVal'}
- $httpBackend.expectGET('/admin/enterprises.json?someParam=someVal').respond 200, response
- result = Enterprises.index(params)
- $httpBackend.flush()
+ beforeEach ->
+ params = { someParam: 'someVal'}
+ $httpBackend.expectGET('/admin/enterprises.json?someParam=someVal').respond 200, response
+ result = Enterprises.index(params)
+ $httpBackend.flush()
- it "returns an array of enterprises, with a blank option appended to the beginning", ->
- expect(result).toDeepEqual [{id: '0', name: 'All'} ,{ id: 5, name: 'Enterprise 1'}]
-
- describe "where includeBlank param is falsey", ->
- beforeEach ->
- params = {includeBlank: false, someParam: 'someVal'}
- $httpBackend.expectGET('/admin/enterprises.json?someParam=someVal').respond 200, response
- result = Enterprises.index(params)
- $httpBackend.flush()
-
- it "returns an array of enterprises, with a blank option appended to the beginning", ->
- expect(result).toDeepEqual response
+ it "returns an array of enterprises", ->
+ expect(result).toDeepEqual response
describe "#save", ->
diff --git a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee
index a1c291f5b0..23c42efde0 100644
--- a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee
+++ b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee
@@ -63,17 +63,17 @@ describe "LineItemsCtrl", ->
$timeout.flush()
describe "initialisation", ->
- it "gets suppliers, adds a blank option as the first in the list", ->
- expect(scope.suppliers).toDeepEqual [ { id : '0', name : 'All' }, supplier ]
+ it "gets suppliers", ->
+ expect(scope.suppliers).toDeepEqual [supplier ]
- it "gets distributors, adds a blank option as the first in the list", ->
- expect(scope.distributors).toDeepEqual [ { id : '0', name : 'All' }, distributor ]
+ it "gets distributors", ->
+ expect(scope.distributors).toDeepEqual [ distributor ]
it "stores enterprises in an list that is accessible by id", ->
- expect(Enterprises.enterprisesByID[1]).toDeepEqual supplier
+ expect(Enterprises.byID[1]).toDeepEqual supplier
- it "gets order cycles, adds a blank option as the first in the list", ->
- expect(scope.orderCycles).toDeepEqual [ { id : '0', name : 'All' }, orderCycle ]
+ it "gets order cycles", ->
+ expect(scope.orderCycles).toDeepEqual [ orderCycle ]
it "gets orders, with dereferenced order cycles and distributors", ->
expect(scope.orders).toDeepEqual [ { id: 9, order_cycle: orderCycle, distributor: distributor, number: "R123456" } ]
@@ -85,9 +85,9 @@ describe "LineItemsCtrl", ->
expect(scope.RequestMonitor.loading).toBe false
it "resets the select filters", ->
- expect(scope.distributorFilter).toBe '0'
- expect(scope.supplierFilter).toBe '0'
- expect(scope.orderCycleFilter).toBe '0'
+ expect(scope.distributorFilter).toBe 0
+ expect(scope.supplierFilter).toBe 0
+ expect(scope.orderCycleFilter).toBe 0
expect(scope.quickSearch).toBe = ""
it "resets the form state to pristine", ->
diff --git a/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee b/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee
index ef428377c0..3de04003e5 100644
--- a/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee
+++ b/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee
@@ -23,9 +23,9 @@ describe "LineItems service", ->
result = LineItems.index()
$httpBackend.flush()
- it "stores returned data in @lineItemsByID, with ids as keys", ->
+ it "stores returned data in @byID, with ids as keys", ->
# LineItemResource returns instances of Resource rather than raw objects
- expect(LineItems.lineItemsByID).toDeepEqual { 5: response[0] }
+ expect(LineItems.byID).toDeepEqual { 5: response[0] }
it "stores returned data in @pristineByID, with ids as keys", ->
expect(LineItems.pristineByID).toDeepEqual { 5: response[0] }
@@ -114,14 +114,14 @@ describe "LineItems service", ->
beforeEach ->
lineItem = new LineItemResource({ id: 15, order: { number: '12345678'} })
LineItems.pristineByID[15] = lineItem
- LineItems.lineItemsByID[15] = lineItem
+ LineItems.byID[15] = lineItem
$httpBackend.expectDELETE('/admin/orders/12345678/line_items/15.json').respond 200, { id: 15, name: 'LineItem 1'}
LineItems.delete(lineItem, callback).then( -> resolved = true).catch( -> rejected = true)
$httpBackend.flush()
it "updates the pristine copy of the lineItem", ->
expect(LineItems.pristineByID[15]).toBeUndefined()
- expect(LineItems.lineItemsByID[15]).toBeUndefined()
+ expect(LineItems.byID[15]).toBeUndefined()
it "runs the callback", ->
expect(callback).toHaveBeenCalled()
@@ -139,14 +139,14 @@ describe "LineItems service", ->
beforeEach ->
lineItem = new LineItemResource({ id: 15, order: { number: '12345678'} })
LineItems.pristineByID[15] = lineItem
- LineItems.lineItemsByID[15] = lineItem
+ LineItems.byID[15] = lineItem
$httpBackend.expectDELETE('/admin/orders/12345678/line_items/15.json').respond 422, { error: 'obj' }
LineItems.delete(lineItem, callback).then( -> resolved = true).catch( -> rejected = true)
$httpBackend.flush()
it "does not update the pristine copy of the lineItem", ->
expect(LineItems.pristineByID[15]).toBeDefined()
- expect(LineItems.lineItemsByID[15]).toBeDefined()
+ expect(LineItems.byID[15]).toBeDefined()
it "does not run the callback", ->
expect(callback).not.toHaveBeenCalled()
diff --git a/spec/javascripts/unit/admin/order_cycles/services/order_cycles_spec.js.coffee b/spec/javascripts/unit/admin/order_cycles/services/order_cycles_spec.js.coffee
index aebdb19f6f..f2ac4983f2 100644
--- a/spec/javascripts/unit/admin/order_cycles/services/order_cycles_spec.js.coffee
+++ b/spec/javascripts/unit/admin/order_cycles/services/order_cycles_spec.js.coffee
@@ -26,9 +26,9 @@ describe "OrderCycles service", ->
result = OrderCycles.index()
$httpBackend.flush()
- it "stores returned data in @orderCyclesByID, with ids as keys", ->
+ it "stores returned data in @byID, with ids as keys", ->
# OrderCycleResource returns instances of Resource rather than raw objects
- expect(OrderCycles.orderCyclesByID).toDeepEqual { 5: response[0] }
+ expect(OrderCycles.byID).toDeepEqual { 5: response[0] }
it "stores returned data in @pristineByID, with ids as keys", ->
expect(OrderCycles.pristineByID).toDeepEqual { 5: response[0] }
@@ -37,25 +37,14 @@ describe "OrderCycles service", ->
expect(result).toDeepEqual response
describe "when no params are passed", ->
- describe "where includeBlank param is truthy", ->
- beforeEach ->
- params = {includeBlank: true, someParam: 'someVal'}
- $httpBackend.expectGET('/admin/order_cycles.json?someParam=someVal').respond 200, response
- result = OrderCycles.index(params)
- $httpBackend.flush()
+ beforeEach ->
+ params = { someParam: 'someVal'}
+ $httpBackend.expectGET('/admin/order_cycles.json?someParam=someVal').respond 200, response
+ result = OrderCycles.index(params)
+ $httpBackend.flush()
- it "returns an array of orderCycles", ->
- expect(result).toDeepEqual [{id: '0', name: 'All'} ,{ id: 5, name: 'OrderCycle 1'}]
-
- describe "where includeBlank param is falsey", ->
- beforeEach ->
- params = {includeBlank: false, someParam: 'someVal'}
- $httpBackend.expectGET('/admin/order_cycles.json?someParam=someVal').respond 200, response
- result = OrderCycles.index(params)
- $httpBackend.flush()
-
- it "returns an array of orderCycles", ->
- expect(result).toDeepEqual response
+ it "returns an array of orderCycles", ->
+ expect(result).toDeepEqual response
describe "#save", ->
diff --git a/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee b/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee
index c3d6646144..3d41ded40a 100644
--- a/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee
+++ b/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee
@@ -23,9 +23,9 @@ describe "Orders service", ->
result = Orders.index()
$httpBackend.flush()
- it "stores returned data in @ordersByID, with ids as keys", ->
+ it "stores returned data in @byID, with ids as keys", ->
# OrderResource returns instances of Resource rather than raw objects
- expect(Orders.ordersByID).toDeepEqual { 5: response[0] }
+ expect(Orders.byID).toDeepEqual { 5: response[0] }
it "stores returned data in @pristineByID, with ids as keys", ->
expect(Orders.pristineByID).toDeepEqual { 5: response[0] }
diff --git a/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee b/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee
index 0d21c7de6c..2a690ed0a7 100644
--- a/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee
@@ -7,9 +7,6 @@ describe 'convert number to localised currency ', ->
symbol_position: "before"
currency: "D"
hide_cents: "false"
- # Not used yet...
- # decimal_mark: "."
- # thousands_separator: ","
module 'Darkswarm'
module ($provide)->
$provide.value "currencyConfig", currencyconfig
@@ -38,5 +35,3 @@ describe 'convert number to localised currency ', ->
it "can hide cents", ->
currencyconfig.hide_cents = "true"
expect(filter(5)).toEqual "$5"
-
-
diff --git a/spec/javascripts/unit/order_cycle_spec.js.coffee b/spec/javascripts/unit/order_cycle_spec.js.coffee
index 5fec8b93f5..ac7e52a366 100644
--- a/spec/javascripts/unit/order_cycle_spec.js.coffee
+++ b/spec/javascripts/unit/order_cycle_spec.js.coffee
@@ -300,6 +300,7 @@ describe 'OrderCycle controllers', ->
scope.removeCoordinatorFee(event, 0)
expect(event.preventDefault).toHaveBeenCalled()
expect(OrderCycle.removeCoordinatorFee).toHaveBeenCalledWith(0)
+ expect(scope.order_cycle_form.$dirty).toEqual true
it 'Adds exchange fees', ->
scope.addExchangeFee(event)
@@ -310,6 +311,7 @@ describe 'OrderCycle controllers', ->
scope.removeExchangeFee(event, 'exchange', 0)
expect(event.preventDefault).toHaveBeenCalled()
expect(OrderCycle.removeExchangeFee).toHaveBeenCalledWith('exchange', 0)
+ expect(scope.order_cycle_form.$dirty).toEqual true
it 'Removes distribution of a variant', ->
scope.removeDistributionOfVariant('variant')
diff --git a/spec/lib/open_food_network/distribution_change_validator_spec.rb b/spec/lib/open_food_network/distribution_change_validator_spec.rb
index 7e2a4b3274..8e324f961e 100644
--- a/spec/lib/open_food_network/distribution_change_validator_spec.rb
+++ b/spec/lib/open_food_network/distribution_change_validator_spec.rb
@@ -87,7 +87,7 @@ describe DistributionChangeValidator do
enterprise_with_some_variants.stub(:distributed_variants) { [variant1, variant3] } # Only some variants
enterprise_with_some_plus_extras = double(:enterprise)
enterprise_with_some_plus_extras.stub(:distributed_variants) { [variant1, variant2, variant3, variant4] } # Only some variants, plus extras
-
+
subject.available_distributors([enterprise_with_some_variants]).should_not include enterprise_with_some_variants
subject.available_distributors([enterprise_with_some_plus_extras]).should_not include enterprise_with_some_plus_extras
end
@@ -97,10 +97,10 @@ describe DistributionChangeValidator do
order.stub(:line_item_variants) { line_item_variants }
enterprise = double(:enterprise)
enterprise.stub(:distributed_variants) { [variant1, variant2, variant3, variant4, variant5] } # Excess variants
-
+
subject.available_distributors([enterprise]).should == [enterprise]
end
-
+
it "matches no enterprises when none are provided" do
subject.available_distributors([]).should == []
end
@@ -201,7 +201,7 @@ describe DistributionChangeValidator do
describe "finding available distributors for a product" do
it "returns enterprises distributing the product when there's no order" do
subject = DistributionChangeValidator.new(nil)
- Enterprise.stub(:distributing_product).and_return([1, 2, 3])
+ Enterprise.stub(:distributing_products).and_return([1, 2, 3])
subject.should_receive(:available_distributors).never
subject.available_distributors_for(product).should == [1, 2, 3]
@@ -209,7 +209,7 @@ describe DistributionChangeValidator do
it "returns enterprises distributing the product when there's no order items" do
order.stub(:line_items) { [] }
- Enterprise.stub(:distributing_product).and_return([1, 2, 3])
+ Enterprise.stub(:distributing_products).and_return([1, 2, 3])
subject.should_receive(:available_distributors).never
subject.available_distributors_for(product).should == [1, 2, 3]
@@ -217,7 +217,7 @@ describe DistributionChangeValidator do
it "filters by available distributors when there are order items" do
order.stub(:line_items) { [1, 2, 3] }
- Enterprise.stub(:distributing_product).and_return([1, 2, 3])
+ Enterprise.stub(:distributing_products).and_return([1, 2, 3])
subject.should_receive(:available_distributors).and_return([2])
subject.available_distributors_for(product).should == [2]
diff --git a/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb b/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb
index 9ad1d222b3..b1a9074efb 100644
--- a/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb
+++ b/spec/lib/open_food_network/enterprise_fee_applicator_spec.rb
@@ -1,3 +1,4 @@
+require 'spec_helper'
require 'open_food_network/enterprise_fee_applicator'
module OpenFoodNetwork
diff --git a/spec/lib/open_food_network/products_cache_spec.rb b/spec/lib/open_food_network/products_cache_spec.rb
index a395873f45..d48f131087 100644
--- a/spec/lib/open_food_network/products_cache_spec.rb
+++ b/spec/lib/open_food_network/products_cache_spec.rb
@@ -89,6 +89,26 @@ module OpenFoodNetwork
end
end
+ describe "when a product is deleted" do
+ let(:product) { create(:simple_product) }
+ let(:variant) { create(:variant, product: product) }
+ let(:distributor) { create(:distributor_enterprise) }
+ let!(:oc) { create(:open_order_cycle, distributors: [distributor], variants: [variant]) }
+
+ it "refreshes the cache based on exchanges the variant was in before destruction" do
+ expect(ProductsCache).to receive(:refresh_cache).with(distributor, oc)
+ product.delete
+ end
+
+ it "performs the cache refresh after the product has been removed from the order cycle" do
+ expect(ProductsCache).to receive(:refresh_cache).with(distributor, oc) do
+ expect(product.reload.deleted_at).not_to be_nil
+ end
+
+ product.delete
+ end
+ end
+
describe "when a variant override changes" do
let(:variant) { create(:variant) }
let(:d1) { create(:distributor_enterprise) }
diff --git a/spec/models/enterprise_caching_spec.rb b/spec/models/enterprise_caching_spec.rb
index 72b356df21..047fc6ab02 100644
--- a/spec/models/enterprise_caching_spec.rb
+++ b/spec/models/enterprise_caching_spec.rb
@@ -5,50 +5,107 @@ describe Enterprise do
describe "is touched when a(n)" do
let(:enterprise) { create(:distributor_enterprise, updated_at: 1.week.ago) }
let(:taxon) { create(:taxon) }
+ let(:supplier2) { create(:supplier_enterprise) }
describe "with a supplied product" do
let(:product) { create(:simple_product, supplier: enterprise) }
let!(:classification) { create(:classification, taxon: taxon, product: product) }
+ let(:property) { product.product_properties.last }
+ let(:producer_property) { enterprise.producer_properties.last }
+
+ before do
+ product.set_property 'Organic', 'NASAA 12345'
+ enterprise.set_producer_property 'Biodynamic', 'ASDF 4321'
+ end
+
it "touches enterprise when a classification on that product changes" do
- expect{classification.save!}.to change{enterprise.updated_at}
+ expect { classification.save! }.to change { enterprise.updated_at }
+ end
+
+ it "touches enterprise when a property on that product changes" do
+ expect { property.save! }.to change { enterprise.reload.updated_at }
+ end
+
+ it "touches enterprise when a producer property on that product changes" do
+ expect { producer_property.save! }.to change { enterprise.reload.updated_at }
+ end
+
+ it "touches enterprise when the supplier of a product changes" do
+ expect {
+ product.update_attributes!(supplier: supplier2)
+ }.to change { enterprise.updated_at }
end
end
describe "with a distributed product" do
let(:product) { create(:simple_product) }
- let!(:oc) { create(:simple_order_cycle, distributors: [enterprise], variants: [product.master]) }
+ let(:oc) { create(:simple_order_cycle, distributors: [enterprise], variants: [product.variants.first]) }
+ let(:supplier) { product.supplier }
let!(:classification) { create(:classification, taxon: taxon, product: product) }
- it "touches enterprise when a classification on that product changes" do
- expect{classification.save!}.to change{enterprise.reload.updated_at}
+ let(:property) { product.product_properties.last }
+ let(:producer_property) { supplier.producer_properties.last }
+
+ before do
+ product.set_property 'Organic', 'NASAA 12345'
+ supplier.set_producer_property 'Biodynamic', 'ASDF 4321'
+ end
+
+ context "with an order cycle" do
+ before { oc }
+
+ it "touches enterprise when a classification on that product changes" do
+ expect { classification.save! }.to change { enterprise.reload.updated_at }
+ end
+
+ it "touches enterprise when a property on that product changes" do
+ expect { property.save! }.to change { enterprise.reload.updated_at }
+ end
+
+ it "touches enterprise when a producer property on that product changes" do
+ expect { producer_property.save! }.to change { enterprise.reload.updated_at }
+ end
+
+ it "touches enterprise when the supplier of a product changes" do
+ expect {
+ product.update_attributes!(supplier: supplier2)
+ }.to change { enterprise.reload.updated_at }
+ end
+ end
+
+ it "touches enterprise when the product's variant is added to order cycle" do
+ expect { oc }.to change { enterprise.reload.updated_at }
end
end
describe "with relatives" do
let(:child_enterprise) { create(:supplier_enterprise) }
let!(:er) { create(:enterprise_relationship, parent: enterprise, child: child_enterprise) }
+
it "touches enterprise when enterprise relationship is updated" do
- expect{er.save!}.to change {enterprise.reload.updated_at }
+ expect { er.save! }.to change { enterprise.reload.updated_at }
end
end
-
+
describe "with shipping methods" do
let(:sm) { create(:shipping_method) }
+
before do
enterprise.shipping_methods << sm
end
+
it "touches enterprise when distributor_shipping_method is updated" do
expect {
enterprise.distributor_shipping_methods.first.save!
- }.to change {enterprise.reload.updated_at}
+ }.to change { enterprise.reload.updated_at }
end
it "touches enterprise when shipping method is updated" do
- expect{sm.save!}.to change {enterprise.reload.updated_at }
+ expect { sm.save! }.to change { enterprise.reload.updated_at }
end
end
-
+
it "touches enterprise when address is updated" do
- expect{enterprise.address.save!}.to change {enterprise.reload.updated_at }
+ expect{ enterprise.address.save! }.to change { enterprise.reload.updated_at }
end
end
end
diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb
index b8360094ec..8c16ac39eb 100644
--- a/spec/models/enterprise_spec.rb
+++ b/spec/models/enterprise_spec.rb
@@ -542,40 +542,38 @@ describe Enterprise do
end
end
- describe "distributing_product" do
+ describe "distributing_products" do
it "returns enterprises distributing via a product distribution" do
d = create(:distributor_enterprise)
p = create(:product, distributors: [d])
- Enterprise.distributing_product(p).should == [d]
+ Enterprise.distributing_products(p).should == [d]
end
it "returns enterprises distributing via an order cycle" do
d = create(:distributor_enterprise)
p = create(:product)
oc = create(:simple_order_cycle, distributors: [d], variants: [p.master])
- Enterprise.distributing_product(p).should == [d]
+ Enterprise.distributing_products(p).should == [d]
end
- end
- describe "distributing_any_product_of" do
it "returns enterprises distributing via a product distribution" do
d = create(:distributor_enterprise)
p = create(:product, distributors: [d])
- Enterprise.distributing_any_product_of([p]).should == [d]
+ Enterprise.distributing_products([p]).should == [d]
end
it "returns enterprises distributing via an order cycle" do
d = create(:distributor_enterprise)
p = create(:product)
oc = create(:simple_order_cycle, distributors: [d], variants: [p.master])
- Enterprise.distributing_any_product_of([p]).should == [d]
+ Enterprise.distributing_products([p]).should == [d]
end
it "does not return duplicate enterprises" do
d = create(:distributor_enterprise)
p1 = create(:product, distributors: [d])
p2 = create(:product, distributors: [d])
- Enterprise.distributing_any_product_of([p1, p2]).should == [d]
+ Enterprise.distributing_products([p1, p2]).should == [d]
end
end
diff --git a/spec/models/producer_property_spec.rb b/spec/models/producer_property_spec.rb
index 2d0009ce12..0de7aae19b 100644
--- a/spec/models/producer_property_spec.rb
+++ b/spec/models/producer_property_spec.rb
@@ -8,7 +8,7 @@ describe ProducerProperty do
producer.set_producer_property 'Organic Certified', 'NASAA 54321'
end
- describe ".sold_by" do
+ describe ".currently_sold_by and .ever_sold_by" do
let!(:shop) { create(:distributor_enterprise) }
let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first]) }
let(:product) { create(:simple_product, supplier: producer) }
@@ -22,7 +22,8 @@ describe ProducerProperty do
describe "with an associated producer property" do
it "returns the producer property" do
- expect(ProducerProperty.sold_by(shop)).to eq [pp]
+ expect(ProducerProperty.currently_sold_by(shop)).to eq [pp]
+ expect(ProducerProperty.ever_sold_by(shop)).to eq [pp]
end
end
@@ -30,7 +31,8 @@ describe ProducerProperty do
let!(:exchange) { create(:exchange, order_cycle: oc, incoming: true, sender: producer_other, receiver: oc.coordinator) }
it "doesn't return the producer property" do
- expect(ProducerProperty.sold_by(shop)).not_to include pp_other
+ expect(ProducerProperty.currently_sold_by(shop)).not_to include pp_other
+ expect(ProducerProperty.ever_sold_by(shop)).not_to include pp_other
end
end
@@ -40,7 +42,8 @@ describe ProducerProperty do
let!(:exchange) { create(:exchange, order_cycle: oc, incoming: false, sender: oc.coordinator, receiver: shop_other, variants: [product_other.variants.first]) }
it "doesn't return the producer property" do
- expect(ProducerProperty.sold_by(shop)).not_to include pp_other
+ expect(ProducerProperty.currently_sold_by(shop)).not_to include pp_other
+ expect(ProducerProperty.ever_sold_by(shop)).not_to include pp_other
end
end
@@ -49,8 +52,12 @@ describe ProducerProperty do
oc.update_attributes! orders_close_at: 1.week.ago
end
- it "doesn't return the producer property" do
- expect(ProducerProperty.sold_by(shop)).not_to include pp
+ it "doesn't return the producer property for .currently_sold_by" do
+ expect(ProducerProperty.currently_sold_by(shop)).not_to include pp
+ end
+
+ it "returns the producer property for .ever_sold_by" do
+ expect(ProducerProperty.ever_sold_by(shop)).to include pp
end
end
@@ -59,7 +66,8 @@ describe ProducerProperty do
let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first, product2.variants.first]) }
it "doesn't return duplicates" do
- expect(ProducerProperty.sold_by(shop).to_a.count).to eq 1
+ expect(ProducerProperty.currently_sold_by(shop).to_a.count).to eq 1
+ expect(ProducerProperty.ever_sold_by(shop).to_a.count).to eq 1
end
end
end
diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb
index 44321353fe..0057d377e7 100644
--- a/spec/models/spree/ability_spec.rb
+++ b/spec/models/spree/ability_spec.rb
@@ -149,13 +149,13 @@ module Spree
it "should be able to read/write their enterprises' products and variants" do
should have_ability([:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :destroy], for: p1)
- should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy], for: p1.master)
+ should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p1.master)
end
it "should be able to read/write related enterprises' products and variants with manage_products permission" do
er_ps
should have_ability([:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :destroy], for: p_related)
- should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy], for: p_related.master)
+ should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p_related.master)
end
it "should not be able to read/write other enterprises' products and variants" do
@@ -173,7 +173,7 @@ module Spree
it "should be able to read/write their enterprises' product variants" do
should have_ability([:create], for: Spree::Variant)
- should have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy], for: p1.master)
+ should have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy, :delete], for: p1.master)
end
it "should not be able to read/write other enterprises' product variants" do
diff --git a/spec/models/spree/calculator/flat_percent_item_total_spec.rb b/spec/models/spree/calculator/flat_percent_item_total_spec.rb
new file mode 100644
index 0000000000..02b6e5d1ae
--- /dev/null
+++ b/spec/models/spree/calculator/flat_percent_item_total_spec.rb
@@ -0,0 +1,10 @@
+ describe Spree::Calculator::FlatPercentItemTotal do
+ let(:calculator) { Spree::Calculator::FlatPercentItemTotal.new }
+ let(:line_item) { mock_model(Spree::LineItem, amount: 10) }
+
+ before { calculator.stub :preferred_flat_percent => 10 }
+
+ it "should compute amount correctly for a single line item" do
+ calculator.compute(line_item).should == 1.0
+ end
+end
diff --git a/spec/models/spree/calculator/flexi_rate_spec.rb b/spec/models/spree/calculator/flexi_rate_spec.rb
new file mode 100644
index 0000000000..a242429dca
--- /dev/null
+++ b/spec/models/spree/calculator/flexi_rate_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Spree::Calculator::FlexiRate do
+ let(:calculator) { Spree::Calculator::FlexiRate.new }
+ let(:line_item) { mock_model(Spree::LineItem, amount: 10, quantity: 4) }
+
+ describe "computing for a single line item" do
+ it "returns the first item rate" do
+ calculator.stub preferred_first_item: 1.0
+ calculator.compute(line_item).round(2).should == 1.0
+ end
+ end
+
+ it "allows creation of new object with all the attributes" do
+ Spree::Calculator::FlexiRate.new(preferred_first_item: 1, preferred_additional_item: 1, preferred_max_items: 1)
+ end
+end
diff --git a/spec/models/spree/calculator/per_item_spec.rb b/spec/models/spree/calculator/per_item_spec.rb
new file mode 100644
index 0000000000..09c2fb02f6
--- /dev/null
+++ b/spec/models/spree/calculator/per_item_spec.rb
@@ -0,0 +1,12 @@
+require 'spec_helper'
+
+describe Spree::Calculator::PerItem do
+ let(:calculator) { Spree::Calculator::PerItem.new(preferred_amount: 10) }
+ let(:shipping_calculable) { double(:calculable) }
+ let(:line_item) { double(:line_item, quantity: 5, product: double(:product)) }
+
+ it "correctly calculates on a single line item object" do
+ calculator.stub(calculable: shipping_calculable)
+ calculator.compute(line_item).to_f.should == 50 # 5 x 10
+ end
+end
diff --git a/spec/models/spree/calculator/price_sack_spec.rb b/spec/models/spree/calculator/price_sack_spec.rb
new file mode 100644
index 0000000000..b34771c720
--- /dev/null
+++ b/spec/models/spree/calculator/price_sack_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Spree::Calculator::PriceSack do
+ let(:calculator) do
+ calculator = Spree::Calculator::PriceSack.new
+ calculator.preferred_minimal_amount = 5
+ calculator.preferred_normal_amount = 10
+ calculator.preferred_discount_amount = 1
+ calculator
+ end
+
+ let(:line_item) { stub_model(Spree::LineItem, price: 1, quantity: 2) }
+
+ it "computes with a line item object" do
+ calculator.compute(line_item)
+ end
+end
diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb
index 10e67e5900..4f63fe882b 100644
--- a/spec/models/spree/product_spec.rb
+++ b/spec/models/spree/product_spec.rb
@@ -33,9 +33,10 @@ module Spree
end
it "defaults available_on to now" do
- Timecop.freeze
- product = Product.new
- product.available_on.should == Time.zone.now
+ Timecop.freeze do
+ product = Product.new
+ product.available_on.should == Time.zone.now
+ end
end
describe "tax category" do
@@ -170,8 +171,28 @@ module Spree
product.save
end
+ it "refreshes the products cache on delete" do
+ expect(OpenFoodNetwork::ProductsCache).to receive(:product_deleted).with(product)
+ product.delete
+ end
+
# On destroy, all distributed variants are refreshed by a Variant around_destroy
# callback, so we don't need to do anything on the product model.
+
+ describe "touching affected enterprises when the product is deleted" do
+ let(:product) { create(:simple_product) }
+ let(:supplier) { product.supplier }
+ let(:distributor) { create(:distributor_enterprise) }
+ let!(:oc) { create(:simple_order_cycle, distributors: [distributor], variants: [product.variants.first]) }
+
+ it "touches the supplier" do
+ expect { product.delete }.to change { supplier.reload.updated_at }
+ end
+
+ it "touches all distributors" do
+ expect { product.delete }.to change { distributor.reload.updated_at }
+ end
+ end
end
describe "scopes" do
@@ -585,10 +606,10 @@ module Spree
describe "finding products in stock for a particular distribution" do
it "returns on-demand products" do
p = create(:simple_product, on_demand: true)
- p.master.update_attribute(:count_on_hand, 0)
+ p.variants.first.update_attributes!(count_on_hand: 0, on_demand: true)
d = create(:distributor_enterprise)
oc = create(:simple_order_cycle, distributors: [d])
- oc.exchanges.outgoing.first.variants << p.master
+ oc.exchanges.outgoing.first.variants << p.variants.first
p.should have_stock_for_distribution(oc, d)
end
diff --git a/spec/models/spree/property_spec.rb b/spec/models/spree/property_spec.rb
index 6e6ed2d780..29046a8782 100644
--- a/spec/models/spree/property_spec.rb
+++ b/spec/models/spree/property_spec.rb
@@ -31,42 +31,53 @@ module Spree
end
end
- describe ".sold_by" do
+ describe ".currently_sold_by and .ever_sold_by" do
let!(:shop) { create(:distributor_enterprise) }
let!(:shop_other) { create(:distributor_enterprise) }
let!(:product) { create(:simple_product) }
let!(:product_other_ex) { create(:simple_product) }
let!(:product_no_oc) { create(:simple_product) }
- let!(:product_closed_oc) { create(:simple_product) }
let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first]) }
- let!(:oc_closed) { create(:closed_order_cycle, distributors: [shop], variants: [product_closed_oc.variants.first]) }
let!(:exchange_other_shop) { create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: shop_other, variants: [product_other_ex.variants.first]) }
let(:property) { product.properties.last }
let(:property_other_ex) { product_other_ex.properties.last }
let(:property_no_oc) { product_no_oc.properties.last }
- let(:property_closed_oc) { product_closed_oc.properties.last }
before do
product.set_property 'Organic', 'NASAA 12345'
product_other_ex.set_property 'Biodynamic', 'ASDF 12345'
product_no_oc.set_property 'Shiny', 'Very'
- product_closed_oc.set_property 'Spiffy', 'Ooh yeah'
end
it "returns the property" do
- expect(Property.sold_by(shop)).to eq [property]
+ expect(Property.currently_sold_by(shop)).to eq [property]
+ expect(Property.ever_sold_by(shop)).to eq [property]
end
it "doesn't return the property from another exchange" do
- expect(Property.sold_by(shop)).not_to include property_other_ex
+ expect(Property.currently_sold_by(shop)).not_to include property_other_ex
+ expect(Property.ever_sold_by(shop)).not_to include property_other_ex
end
it "doesn't return the property with no order cycle" do
- expect(Property.sold_by(shop)).not_to include property_no_oc
+ expect(Property.currently_sold_by(shop)).not_to include property_no_oc
+ expect(Property.ever_sold_by(shop)).not_to include property_no_oc
end
- it "doesn't return the property from a closed order cycle" do
- expect(Property.sold_by(shop)).not_to include property_closed_oc
+ describe "closed order cyces" do
+ let!(:product_closed_oc) { create(:simple_product) }
+ let!(:oc_closed) { create(:closed_order_cycle, distributors: [shop], variants: [product_closed_oc.variants.first]) }
+ let(:property_closed_oc) { product_closed_oc.properties.last }
+
+ before { product_closed_oc.set_property 'Spiffy', 'Ooh yeah' }
+
+ it "doesn't return the property for .currently_sold_by" do
+ expect(Property.currently_sold_by(shop)).not_to include property_closed_oc
+ end
+
+ it "returns the property for .ever_sold_by" do
+ expect(Property.ever_sold_by(shop)).to include property_closed_oc
+ end
end
context "with another product in the order cycle" do
@@ -78,7 +89,8 @@ module Spree
end
it "doesn't return duplicates" do
- expect(Property.sold_by(shop).to_a.count).to eq 1
+ expect(Property.currently_sold_by(shop).to_a.count).to eq 1
+ expect(Property.ever_sold_by(shop).to_a.count).to eq 1
end
end
end
diff --git a/spec/models/spree/taxon_spec.rb b/spec/models/spree/taxon_spec.rb
index 8fb4b22dc5..a031823bee 100644
--- a/spec/models/spree/taxon_spec.rb
+++ b/spec/models/spree/taxon_spec.rb
@@ -7,7 +7,7 @@ module Spree
let!(:t2) { create(:taxon) }
describe "callbacks" do
- let!(:p2) { create(:simple_product, taxons: [t1]) }
+ let!(:p2) { create(:simple_product, taxons: [t1], primary_taxon: t2) }
it "refreshes the products cache on save" do
expect(OpenFoodNetwork::ProductsCache).to receive(:product_changed).with(p2)
@@ -29,13 +29,18 @@ module Spree
end
end
- describe "finding all distributed taxons" do
- let!(:oc) { create(:simple_order_cycle, distributors: [e], variants: [p1.master]) }
- let!(:s) { create(:supplier_enterprise) }
- let!(:p1) { create(:simple_product, supplier: s, taxons: [t1, t2]) }
+ describe "finding distributed taxons" do
+ let!(:oc_open) { create(:open_order_cycle, distributors: [e], variants: [p_open.variants.first]) }
+ let!(:oc_closed) { create(:closed_order_cycle, distributors: [e], variants: [p_closed.variants.first]) }
+ let!(:p_open) { create(:simple_product, primary_taxon: t1) }
+ let!(:p_closed) { create(:simple_product, primary_taxon: t2) }
- it "finds taxons" do
- Taxon.distributed_taxons.should == {e.id => Set.new(p1.taxons.map(&:id))}
+ it "finds all distributed taxons" do
+ expect(Taxon.distributed_taxons(:all)).to eq({e.id => Set.new([t1.id, t2.id])})
+ end
+
+ it "finds currently distributed taxons" do
+ expect(Taxon.distributed_taxons(:current)).to eq({e.id => Set.new([t1.id])})
end
end
end
diff --git a/spec/serializers/enterprise_serializer_spec.rb b/spec/serializers/enterprise_serializer_spec.rb
index f5eff4f771..bea2672157 100644
--- a/spec/serializers/enterprise_serializer_spec.rb
+++ b/spec/serializers/enterprise_serializer_spec.rb
@@ -6,7 +6,8 @@ describe Api::EnterpriseSerializer do
let(:taxon) { create(:taxon) }
let(:data) { OpenStruct.new(earliest_closing_times: {},
active_distributors: [],
- distributed_taxons: {enterprise.id => [123]},
+ all_distributed_taxons: {enterprise.id => [123]},
+ current_distributed_taxons: {enterprise.id => [123]},
supplied_taxons: {enterprise.id => [456]},
shipping_method_services: {},
relatives: {enterprise.id => {producers: [123], distributors: [456]}}) }
diff --git a/spec/support/request/web_helper.rb b/spec/support/request/web_helper.rb
index 23f9757c5b..bca12c46ab 100644
--- a/spec/support/request/web_helper.rb
+++ b/spec/support/request/web_helper.rb
@@ -78,7 +78,7 @@ module WebHelper
end
def flash_message
- find('.flash').text.strip
+ find('.flash', visible: false).text.strip
end
def errors
diff --git a/spec/support/timecop.rb b/spec/support/timecop.rb
new file mode 100644
index 0000000000..f14c7d622d
--- /dev/null
+++ b/spec/support/timecop.rb
@@ -0,0 +1 @@
+Timecop.safe_mode = true
diff --git a/test/fixtures/.gitkeep b/test/fixtures/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/functional/.gitkeep b/test/functional/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/integration/.gitkeep b/test/integration/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/performance/browsing_test.rb b/test/performance/browsing_test.rb
deleted file mode 100644
index 3fea27b916..0000000000
--- a/test/performance/browsing_test.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require 'test_helper'
-require 'rails/performance_test_help'
-
-class BrowsingTest < ActionDispatch::PerformanceTest
- # Refer to the documentation for all available options
- # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
- # :output => 'tmp/performance', :formats => [:flat] }
-
- def test_homepage
- get '/'
- end
-end
diff --git a/test/test_helper.rb b/test/test_helper.rb
deleted file mode 100644
index 7d57a78563..0000000000
--- a/test/test_helper.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-ENV["RAILS_ENV"] = "test"
-require_relative '../config/environment'
-require 'rails/test_help'
-
-class ActiveSupport::TestCase
- # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
- #
- # Note: You'll currently still have to declare fixtures explicitly in integration tests
- # -- they do not yet inherit this setting
- fixtures :all
-
- # Add more helper methods to be used by all tests here...
-end
diff --git a/test/unit/.gitkeep b/test/unit/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000