mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-04 22:16:08 +00:00
Merge branch 'master' into fix_units
Conflicts: app/assets/javascripts/admin/products/units_controller.js.coffee
This commit is contained in:
@@ -1 +1 @@
|
||||
ruby-1.9.3-p392
|
||||
1.9.3-p392
|
||||
|
||||
@@ -10,3 +10,5 @@ before_script:
|
||||
script:
|
||||
- RAILS_ENV=test bundle exec rake db:migrate --trace
|
||||
- bundle exec rake spec
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -32,6 +32,7 @@ gem "active_model_serializers"
|
||||
gem 'oj'
|
||||
gem 'deface', :github => 'spree/deface', :ref => '1110a13'
|
||||
gem 'paperclip'
|
||||
gem 'dalli'
|
||||
gem 'geocoder'
|
||||
gem 'gmaps4rails'
|
||||
gem 'spinjs-rails'
|
||||
@@ -85,6 +86,7 @@ end
|
||||
|
||||
group :test do
|
||||
gem 'webmock'
|
||||
gem 'perftools.rb'
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
||||
81
Gemfile.lock
81
Gemfile.lock
@@ -14,45 +14,45 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: da651b40f5c6cdd32e00b060729eb9aefd4f615f
|
||||
revision: bbe5e779bcb883a1726ad4006d7c06b06c3f5372
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
spree (1.3.3)
|
||||
spree_api (= 1.3.3)
|
||||
spree_cmd (= 1.3.3)
|
||||
spree_core (= 1.3.3)
|
||||
spree_promo (= 1.3.3)
|
||||
spree_sample (= 1.3.3)
|
||||
spree_api (1.3.3)
|
||||
spree_core (= 1.3.3)
|
||||
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)
|
||||
versioncake (= 0.4.0)
|
||||
spree_cmd (1.3.3)
|
||||
spree_cmd (1.3.6.beta)
|
||||
thor (>= 0.14.6)
|
||||
spree_core (1.3.3)
|
||||
spree_core (1.3.6.beta)
|
||||
activemerchant (~> 1.34)
|
||||
acts_as_list (= 0.1.4)
|
||||
awesome_nested_set (= 2.1.5)
|
||||
aws-sdk (~> 1.3.4)
|
||||
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)
|
||||
json (>= 1.5.5)
|
||||
kaminari (= 0.13.0)
|
||||
money (= 5.0.0)
|
||||
kaminari (= 0.14.1)
|
||||
money (= 5.1.1)
|
||||
paperclip (~> 2.8)
|
||||
rabl (= 0.7.2)
|
||||
rails (~> 3.2.14)
|
||||
rails (~> 3.2.16)
|
||||
ransack (= 0.7.2)
|
||||
select2-rails (= 3.2.1)
|
||||
state_machine (= 1.1.2)
|
||||
stringex (~> 1.3.2)
|
||||
truncate_html (~> 0.5.5)
|
||||
spree_promo (1.3.3)
|
||||
spree_core (= 1.3.3)
|
||||
spree_sample (1.3.3)
|
||||
spree_core (= 1.3.3)
|
||||
spree_promo (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_sample (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree_paypal_express.git
|
||||
@@ -74,10 +74,10 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/spree_auth_devise.git
|
||||
revision: 6a50345b73bcec614a8fbd358a2367c00c8ab56f
|
||||
revision: ba95589a85368297c844f096c2a0c121e5b08138
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
spree_auth_devise (1.0.0)
|
||||
spree_auth_devise (1.3.0)
|
||||
cancan (~> 1.6.7)
|
||||
devise (~> 2.2.3)
|
||||
devise-encryptable (= 0.1.2)
|
||||
@@ -120,10 +120,10 @@ GEM
|
||||
active_link_to (1.0.0)
|
||||
active_model_serializers (0.8.1)
|
||||
activemodel (>= 3.0)
|
||||
active_utils (2.0.2)
|
||||
active_utils (2.2.1)
|
||||
activesupport (>= 2.3.11)
|
||||
i18n
|
||||
activemerchant (1.43.0)
|
||||
activemerchant (1.43.1)
|
||||
active_utils (~> 2.0, >= 2.0.1)
|
||||
activesupport (>= 2.3.14, < 5.0.0)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
@@ -158,12 +158,13 @@ GEM
|
||||
awesome_nested_set (2.1.5)
|
||||
activerecord (>= 3.0.0)
|
||||
awesome_print (1.0.2)
|
||||
aws-sdk (1.3.9)
|
||||
httparty (~> 0.7)
|
||||
aws-sdk (1.11.1)
|
||||
json (~> 1.4)
|
||||
nokogiri (>= 1.4.4)
|
||||
uuidtools (~> 2.1)
|
||||
bcrypt-ruby (3.1.2)
|
||||
bcrypt (3.1.7)
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
bugsnag (1.5.2)
|
||||
httparty (>= 0.6, < 1.0)
|
||||
multi_json (~> 1.0)
|
||||
@@ -192,7 +193,7 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.3.3)
|
||||
colorize (0.7.2)
|
||||
colorize (0.7.3)
|
||||
columnize (0.3.6)
|
||||
comfortable_mexican_sofa (1.6.24)
|
||||
active_link_to (~> 1.0.0)
|
||||
@@ -206,6 +207,7 @@ GEM
|
||||
compass (>= 0.12.2, < 0.14)
|
||||
crack (0.4.1)
|
||||
safe_yaml (~> 0.9.0)
|
||||
dalli (2.7.2)
|
||||
database_cleaner (0.7.1)
|
||||
db2fog (0.8.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -217,7 +219,7 @@ GEM
|
||||
debugger-ruby_core_source (~> 1.2.3)
|
||||
debugger-linecache (1.2.0)
|
||||
debugger-ruby_core_source (1.2.3)
|
||||
devise (2.2.7)
|
||||
devise (2.2.8)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
@@ -300,10 +302,9 @@ GEM
|
||||
json_spec (1.1.1)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
kaminari (0.13.0)
|
||||
kaminari (0.14.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
railties (>= 3.0.0)
|
||||
kgio (2.7.4)
|
||||
launchy (2.1.2)
|
||||
addressable (~> 2.3)
|
||||
@@ -320,27 +321,27 @@ GEM
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.1)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.5.3)
|
||||
mini_portile (0.6.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
money (5.1.1)
|
||||
i18n (~> 0.6.0)
|
||||
multi_json (1.10.1)
|
||||
multi_xml (0.5.5)
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.6.8)
|
||||
newrelic_rpm (3.6.7.152)
|
||||
nokogiri (1.6.1)
|
||||
mini_portile (~> 0.5.0)
|
||||
nokogiri (1.6.2.1)
|
||||
mini_portile (= 0.6.0)
|
||||
oj (2.1.2)
|
||||
orm_adapter (0.4.0)
|
||||
orm_adapter (0.5.0)
|
||||
paperclip (2.8.0)
|
||||
activerecord (>= 2.3.0)
|
||||
activesupport (>= 2.3.2)
|
||||
cocaine (>= 0.0.2)
|
||||
mime-types
|
||||
perftools.rb (2.0.1)
|
||||
pg (0.13.2)
|
||||
poltergeist (1.5.0)
|
||||
capybara (~> 2.1)
|
||||
@@ -349,7 +350,7 @@ GEM
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyamorous (0.5.0)
|
||||
activerecord (~> 3.0)
|
||||
polyglot (0.3.4)
|
||||
polyglot (0.3.5)
|
||||
pry (0.9.12.2)
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
@@ -385,7 +386,7 @@ GEM
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.9.0)
|
||||
rake (10.3.1)
|
||||
rake (10.3.2)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -506,6 +507,7 @@ DEPENDENCIES
|
||||
comfortable_mexican_sofa
|
||||
compass-rails
|
||||
custom_error_message!
|
||||
dalli
|
||||
database_cleaner (= 0.7.1)
|
||||
db2fog
|
||||
debugger-linecache
|
||||
@@ -531,6 +533,7 @@ DEPENDENCIES
|
||||
newrelic_rpm
|
||||
oj
|
||||
paperclip
|
||||
perftools.rb
|
||||
pg
|
||||
poltergeist
|
||||
pry-debugger
|
||||
|
||||
97
INSTALL.sh
97
INSTALL.sh
@@ -1,97 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
###########################
|
||||
# Linux install script #
|
||||
# ----------------------- #
|
||||
# Tested on Debian wheezy #
|
||||
###########################
|
||||
|
||||
echo 'Checking dependencies...'
|
||||
|
||||
# Rails is installed by bundler later
|
||||
#echo -n 'Rails 3.2.. '
|
||||
#if rails -v | grep -q 'Rails 3.2'; then
|
||||
# echo 'ok'
|
||||
#else
|
||||
# echo 'not found'
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
echo -n 'Ruby 1.9.3.. '
|
||||
revision=$(ruby -v | grep -E -o '^ruby 1\.9\.([0-9]+)' | cut -d . -f 3)
|
||||
if [ "$revision" -gt 2 ]; then
|
||||
echo 'ok'
|
||||
else
|
||||
echo 'not found'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n 'PostgreSQL.. '
|
||||
if psql -? > /dev/null 2>&1; then
|
||||
echo 'ok'
|
||||
else
|
||||
echo 'not found'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
psqlCreateCommands="
|
||||
createuser -s ofn
|
||||
psql postgres -c \"ALTER USER ofn WITH ENCRYPTED PASSWORD 'f00d'\"
|
||||
createdb -O ofn open_food_network_dev
|
||||
createdb -O ofn open_food_network_test
|
||||
createdb -O ofn open_food_network_prod
|
||||
"
|
||||
PGPASSFILE=$(mktemp)
|
||||
echo ''
|
||||
echo -n 'Checking PostgreSQL database.. '
|
||||
echo 'localhost:5432:open_food_network_dev:ofn:f00d1' > $PGPASSFILE
|
||||
export PGPASSFILE
|
||||
if psql -w -U ofn open_food_network_dev -c 'select 1' > /dev/null 2>&1; then
|
||||
echo 'ok'
|
||||
else
|
||||
echo 'no access'
|
||||
echo ''
|
||||
echo 'Database needs setup. Try automatic setup with sudo? [yes]'
|
||||
read autosetup
|
||||
if [ -z "$autosetup" ] || [ "$autosetup" = "yes" ]; then
|
||||
if sudo su postgres -c "$psqlCreateCommands"; then
|
||||
echo 'User and databases created.'
|
||||
else
|
||||
echo 'Failed to create user and databases.'
|
||||
autosetup='no'
|
||||
fi
|
||||
else
|
||||
autosetup='no'
|
||||
fi
|
||||
if [ "$autosetup" = 'no' ]; then
|
||||
echo ''
|
||||
echo 'Execute the following commands as database admin user (e.g. postgres):'
|
||||
echo "$psqlCreateCommands"
|
||||
rm "$PGPASSFILE"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
rm "$PGPASSFILE"
|
||||
|
||||
echo ''
|
||||
echo 'Installing all gems. That can take a while.'
|
||||
bundle install
|
||||
|
||||
echo ''
|
||||
echo 'Seeding database..'
|
||||
bundle exec rake db:schema:load db:seed
|
||||
echo 'Skipping sample data (out of date)'
|
||||
#bundle exec rake openfoodnetwork:dev:load_sample_data
|
||||
echo 'You can run `rails server` now to start.'
|
||||
|
||||
echo ''
|
||||
echo 'Executing tests..'
|
||||
bundle exec rake db:test:load
|
||||
bundle exec rspec spec
|
||||
|
||||
if [ "$?" -eq 0 ]; then
|
||||
echo ''
|
||||
echo 'All done.'
|
||||
echo 'You can run `rails server` now.'
|
||||
fi
|
||||
BIN
app/assets/images/subtle_white_feathers.png
Normal file
BIN
app/assets/images/subtle_white_feathers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
@@ -1,3 +1,3 @@
|
||||
angular.module("ofn.admin", ["ngResource", "ngAnimate", "ofn.dropdown"]).config ($httpProvider) ->
|
||||
angular.module("ofn.admin", ["ngResource", "ngAnimate", "ofn.dropdown", "admin.products"]).config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content")
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
@@ -17,7 +17,7 @@ angular.module("ofn.admin").directive "ofnDisplayAs", (optionValueNamer) ->
|
||||
variant_unit_scale: variant_unit_scale
|
||||
variant_unit: variant_unit
|
||||
variant_unit_name: scope.product.variant_unit_name
|
||||
|
||||
|
||||
scope.placeholder_text = new optionValueNamer(variant_object).name()
|
||||
|
||||
productUnitProperties = ->
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
angular.module("admin.products")
|
||||
.controller "unitsCtrl", ($scope) ->
|
||||
.controller "unitsCtrl", ($scope, optionValueNamer) ->
|
||||
$scope.product = { master: {} }
|
||||
$scope.product.master.product = $scope.product
|
||||
$scope.placeholder_text = ""
|
||||
|
||||
$scope.$watch ->
|
||||
$scope.product.variant_unit_with_scale
|
||||
, ->
|
||||
$scope.$watchCollection '[product.variant_unit_with_scale, product.master.unit_value_with_description]', ->
|
||||
if $scope.product.variant_unit_with_scale
|
||||
match = $scope.product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/)
|
||||
if match
|
||||
@@ -16,9 +16,6 @@ angular.module("admin.products")
|
||||
else
|
||||
$scope.product.variant_unit = $scope.product.variant_unit_scale = null
|
||||
|
||||
$scope.$watch ->
|
||||
$scope.product.master.unit_value_with_description
|
||||
, ->
|
||||
if $scope.product.master.hasOwnProperty("unit_value_with_description")
|
||||
match = $scope.product.master.unit_value_with_description.match(/^([\d\.]+(?= |$)|)( |)(.*)$/)
|
||||
if match
|
||||
@@ -27,6 +24,8 @@ angular.module("admin.products")
|
||||
$scope.product.master.unit_value *= $scope.product.variant_unit_scale if $scope.product.master.unit_value && $scope.product.variant_unit_scale
|
||||
$scope.product.master.unit_description = match[3]
|
||||
|
||||
$scope.placeholder_text = new optionValueNamer($scope.product.master).name()
|
||||
|
||||
$scope.variant_unit_options = [
|
||||
["Weight (g)", "weight_1"],
|
||||
["Weight (kg)", "weight_1000"],
|
||||
@@ -42,5 +41,3 @@ angular.module("admin.products")
|
||||
|
||||
$scope.hasUnit = (product) ->
|
||||
product.variant_unit_with_scale?
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("ofn.admin").factory "optionValueNamer", ($resource) ->
|
||||
angular.module("admin.products").factory "optionValueNamer", ->
|
||||
class OptionValueNamer
|
||||
constructor: (@variant) ->
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#= require lodash.underscore.js
|
||||
#= require angular-scroll.min.js
|
||||
#= require angular-google-maps.min.js
|
||||
#= require angular-timer.min.js
|
||||
#= require ../shared/mm-foundation-tpls-0.2.2.min.js
|
||||
#= require ../shared/bindonce.min.js
|
||||
#= require ../shared/ng-infinite-scroll.min.js
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
Darkswarm.controller "HubsCtrl", ($scope, Hubs, $document, $rootScope, HashNavigation) ->
|
||||
Darkswarm.controller "HubsCtrl", ($scope, Hubs, Search, $document, $rootScope, HashNavigation, FilterSelectorsService) ->
|
||||
$scope.Hubs = Hubs
|
||||
$scope.hubs = Hubs.visible
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.query = Search.search()
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Search.search query
|
||||
|
||||
$rootScope.$on "$locationChangeSuccess", (newRoute, oldRoute) ->
|
||||
if HashNavigation.active "hubs"
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
Darkswarm.controller "ProducersCtrl", ($scope, Producers) ->
|
||||
Darkswarm.controller "ProducersCtrl", ($scope, Producers, $filter, FilterSelectorsService, Search) ->
|
||||
$scope.Producers = Producers
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.filtersActive = false
|
||||
$scope.activeTaxons = []
|
||||
$scope.query = Search.search()
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Search.search query
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
Darkswarm.controller "ProductNodeCtrl", ($scope) ->
|
||||
|
||||
$scope.price = ->
|
||||
if $scope.product.variants.length > 0
|
||||
prices = (v.price for v in $scope.product.variants)
|
||||
Math.min.apply(null, prices)
|
||||
else
|
||||
$scope.product.price
|
||||
|
||||
Darkswarm.controller "ProductNodeCtrl", ($scope, $modal) ->
|
||||
$scope.enterprise = $scope.product.supplier # For the modal, so it's consistent
|
||||
$scope.hasVariants = $scope.product.variants.length > 0
|
||||
|
||||
$scope.triggerProductModal = ->
|
||||
$modal.open(templateUrl: "product_modal.html", scope: $scope)
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) ->
|
||||
Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle, FilterSelectorsService) ->
|
||||
$scope.Product = Product
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.limit = 3
|
||||
$scope.ordering = {order: "name"}
|
||||
$scope.order_cycle = OrderCycle.order_cycle
|
||||
|
||||
@@ -5,7 +5,9 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
|
||||
'infinite-scroll',
|
||||
'angular-flash.service',
|
||||
'templates',
|
||||
'timer',
|
||||
'ngSanitize',
|
||||
'ngAnimate',
|
||||
'google-maps',
|
||||
'duScroll',
|
||||
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.directive "activeSelector", ->
|
||||
restrict: 'E'
|
||||
transclude: true
|
||||
replace: true
|
||||
templateUrl: 'active_selector.html'
|
||||
link: (scope, elem, attr)->
|
||||
scope.selector.emit = scope.emit
|
||||
elem.bind "click", ->
|
||||
scope.$apply ->
|
||||
scope.selector.active = !scope.selector.active
|
||||
scope.emit()
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
Darkswarm.directive "productModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a ng-transclude></a>"
|
||||
transclude: true
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", =>
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'product_modal.html', scope: scope)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
Darkswarm.directive "shippingTypeSelector", (FilterSelectorsService)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
templateUrl: 'shipping_type_selector.html'
|
||||
link: (scope, elem, attr)->
|
||||
scope.shippingTypes =
|
||||
pickup: false
|
||||
delivery: false
|
||||
|
||||
scope.selectors =
|
||||
delivery: FilterSelectorsService.new
|
||||
icon: "ofn-i_039-delivery"
|
||||
pickup: FilterSelectorsService.new
|
||||
icon: "ofn-i_038-takeaway"
|
||||
|
||||
scope.emit = ->
|
||||
scope.shippingTypes =
|
||||
pickup: scope.selectors.pickup.active
|
||||
delivery: scope.selectors.delivery.active
|
||||
@@ -0,0 +1,36 @@
|
||||
Darkswarm.directive "taxonSelector", (FilterSelectorsService)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
scope:
|
||||
objects: "&"
|
||||
results: "="
|
||||
templateUrl: "taxon_selector.html"
|
||||
|
||||
link: (scope, elem, attr)->
|
||||
selectors_by_id = {}
|
||||
selectors = ["foo"]
|
||||
|
||||
scope.emit = ->
|
||||
scope.results = selectors.filter (selector)->
|
||||
selector.active
|
||||
.map (selector)->
|
||||
selector.taxon.id
|
||||
|
||||
scope.selectors = ->
|
||||
taxons = {}
|
||||
selectors = []
|
||||
for object in scope.objects()
|
||||
for taxon in object.taxons
|
||||
taxons[taxon.id] = taxon
|
||||
if object.supplied_taxons
|
||||
for taxon in object.supplied_taxons
|
||||
taxons[taxon.id] = taxon
|
||||
|
||||
for id, taxon of taxons
|
||||
if selector = selectors_by_id[id]
|
||||
selectors.push selector
|
||||
else
|
||||
selector = selectors_by_id[id] = FilterSelectorsService.new
|
||||
taxon: taxon
|
||||
selectors.push selector
|
||||
selectors
|
||||
14
app/assets/javascripts/darkswarm/filters/active.js.coffee
Normal file
14
app/assets/javascripts/darkswarm/filters/active.js.coffee
Normal file
@@ -0,0 +1,14 @@
|
||||
Darkswarm.filter 'active', ()->
|
||||
(objects, options)->
|
||||
objects ||= []
|
||||
options ?= null
|
||||
|
||||
if options.open and !options.closed
|
||||
objects.filter (obj)->
|
||||
obj.active
|
||||
else if options.closed and !options.open
|
||||
objects.filter (obj)->
|
||||
!obj.active
|
||||
else
|
||||
objects
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Darkswarm.filter "byProducer", ->
|
||||
(objects, id) ->
|
||||
objects ||= []
|
||||
id ?= 0
|
||||
objects.filter (obj)->
|
||||
obj.producer.id == id
|
||||
@@ -0,0 +1,4 @@
|
||||
Darkswarm.filter "capitalize", ->
|
||||
(input, scope) ->
|
||||
input = input.toLowerCase() if input?
|
||||
input.substring(0, 1).toUpperCase() + input.substring(1)
|
||||
@@ -2,5 +2,5 @@ Darkswarm.filter 'filterProducers', (hubsFilter)->
|
||||
(producers, text) ->
|
||||
producers ||= []
|
||||
text ?= ""
|
||||
|
||||
hubsFilter(producers, text)
|
||||
|
||||
|
||||
13
app/assets/javascripts/darkswarm/filters/shipping.js.coffee
Normal file
13
app/assets/javascripts/darkswarm/filters/shipping.js.coffee
Normal file
@@ -0,0 +1,13 @@
|
||||
Darkswarm.filter 'shipping', ()->
|
||||
(objects, options)->
|
||||
objects ||= []
|
||||
options ?= null
|
||||
|
||||
if options.pickup and !options.delivery
|
||||
objects.filter (obj)->
|
||||
obj.pickup
|
||||
else if options.delivery and !options.pickup
|
||||
objects.filter (obj)->
|
||||
obj.delivery
|
||||
else
|
||||
objects
|
||||
13
app/assets/javascripts/darkswarm/filters/taxons.js.coffee
Normal file
13
app/assets/javascripts/darkswarm/filters/taxons.js.coffee
Normal file
@@ -0,0 +1,13 @@
|
||||
Darkswarm.filter 'taxons', (Matcher)->
|
||||
# Filter anything that responds to object.taxons, and/or object.primary_taxon
|
||||
(objects, ids) ->
|
||||
objects ||= []
|
||||
ids ?= []
|
||||
if ids.length == 0
|
||||
objects
|
||||
else
|
||||
objects.filter (obj)->
|
||||
taxons = obj.taxons
|
||||
taxons.concat obj.supplied_taxons if obj.supplied_taxons
|
||||
obj.primary_taxon?.id in ids || taxons.some (taxon)->
|
||||
taxon.id in ids
|
||||
@@ -1,15 +1,21 @@
|
||||
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Dereferencer)->
|
||||
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer)->
|
||||
new class Enterprises
|
||||
enterprises_by_id: {} # id/object pairs for lookup
|
||||
constructor: ->
|
||||
@enterprises = enterprises
|
||||
for enterprise in enterprises
|
||||
@enterprises_by_id[enterprise.id] = enterprise
|
||||
@dereference()
|
||||
@dereferenceEnterprises()
|
||||
@dereferenceTaxons()
|
||||
|
||||
dereference: ->
|
||||
dereferenceEnterprises: ->
|
||||
if CurrentHub.hub?.id
|
||||
CurrentHub.hub = @enterprises_by_id[CurrentHub.hub.id]
|
||||
for enterprise in @enterprises
|
||||
Dereferencer.dereference enterprise.hubs, @enterprises_by_id
|
||||
Dereferencer.dereference enterprise.producers, @enterprises_by_id
|
||||
|
||||
dereferenceTaxons: ->
|
||||
for enterprise in @enterprises
|
||||
Dereferencer.dereference enterprise.taxons, Taxons.taxons_by_id
|
||||
Dereferencer.dereference enterprise.supplied_taxons, Taxons.taxons_by_id
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
Darkswarm.factory "FilterSelectorsService", ->
|
||||
# This stores all filters so we can access in-use counts etc
|
||||
# Accessed via activeSelector Directive
|
||||
new class FilterSelectorsService
|
||||
selectors: []
|
||||
new: (obj = {})->
|
||||
obj.active = false
|
||||
@selectors.push obj
|
||||
obj
|
||||
|
||||
totalActive: =>
|
||||
@selectors.filter (selector)->
|
||||
selector.active
|
||||
.length
|
||||
|
||||
filterText: (active)=>
|
||||
total = @totalActive()
|
||||
if total == 0
|
||||
if active then "Hide filters" else "Filter by"
|
||||
else if total == 1
|
||||
"1 filter applied"
|
||||
else
|
||||
"#{@totalActive()} filters applied"
|
||||
|
||||
clearAll: =>
|
||||
for selector in @selectors
|
||||
selector.active = false
|
||||
selector.emit()
|
||||
@@ -1,5 +1,5 @@
|
||||
Darkswarm.factory 'Product', ($resource, Enterprises) ->
|
||||
new class Product
|
||||
Darkswarm.factory 'Product', ($resource, Enterprises, Dereferencer, Taxons) ->
|
||||
new class Products
|
||||
constructor: ->
|
||||
@update()
|
||||
|
||||
@@ -10,7 +10,8 @@ Darkswarm.factory 'Product', ($resource, Enterprises) ->
|
||||
|
||||
update: =>
|
||||
@loading = true
|
||||
@products = $resource("/shop/products").query =>
|
||||
@products = $resource("/shop/products").query (products)=>
|
||||
@extend()
|
||||
@dereference()
|
||||
@loading = false
|
||||
@
|
||||
@@ -18,3 +19,12 @@ Darkswarm.factory 'Product', ($resource, Enterprises) ->
|
||||
dereference: ->
|
||||
for product in @products
|
||||
product.supplier = Enterprises.enterprises_by_id[product.supplier.id]
|
||||
Dereferencer.dereference product.taxons, Taxons.taxons_by_id
|
||||
|
||||
extend: ->
|
||||
for product in @products
|
||||
if product.variants.length > 0
|
||||
prices = (v.price for v in product.variants)
|
||||
product.price = Math.min.apply(null, prices)
|
||||
|
||||
product.hasVariants = product.variants.length > 0
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.factory "Search", ($location)->
|
||||
new class Search
|
||||
search: (query = false)->
|
||||
if query
|
||||
$location.search('query', query)
|
||||
else if query == ""
|
||||
$location.search('query', null)
|
||||
else
|
||||
$location.search()['query']
|
||||
@@ -0,0 +1,8 @@
|
||||
Darkswarm.factory "Taxons", (taxons)->
|
||||
new class Taxons
|
||||
taxons: taxons
|
||||
taxons_by_id: {}
|
||||
constructor: ->
|
||||
for taxon in @taxons
|
||||
@taxons_by_id[taxon.id] = taxon
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
%li{"ng-class" => "{active: selector.active}"}
|
||||
%a{"ng-transclude" => true}
|
||||
@@ -0,0 +1,3 @@
|
||||
%active-selector{"ng-repeat" => "(name, selector) in selectors"}
|
||||
%i{"ng-class" => "selector.icon"}
|
||||
{{ name | capitalize }}
|
||||
@@ -0,0 +1,3 @@
|
||||
%active-selector{"ng-repeat" => "selector in selectors()"}
|
||||
%render-svg{path: "{{selector.taxon.icon}}"}
|
||||
%span {{ selector.taxon.name }}
|
||||
@@ -1 +0,0 @@
|
||||
Frogs
|
||||
@@ -2,17 +2,20 @@
|
||||
@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
|
||||
padding: 0.8em 0.5em
|
||||
display: block
|
||||
&:first-child
|
||||
cursor: pointer
|
||||
padding: 1rem 0
|
||||
|
||||
.active_table .active_table_node
|
||||
@include csstrans
|
||||
display: block
|
||||
border: 1px solid transparent
|
||||
|
||||
@@ -20,13 +23,12 @@
|
||||
border: 1px solid transparent
|
||||
&, & > a.row
|
||||
display: block
|
||||
|
||||
|
||||
.active_table_row.link
|
||||
border: 0
|
||||
|
||||
&.open
|
||||
.active_table_row:first-child
|
||||
@include csstrans
|
||||
border-top: 1px solid $dark-grey
|
||||
border-left: 1px solid $dark-grey
|
||||
border-right: 1px solid $dark-grey
|
||||
@@ -45,7 +47,6 @@
|
||||
background-color: rgba(255,255,255,0.2)
|
||||
|
||||
.active_table_row.link
|
||||
@include csstrans
|
||||
padding: 0
|
||||
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,0.35)
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.35)
|
||||
|
||||
@@ -1,19 +1,112 @@
|
||||
@import mixins
|
||||
@import branding
|
||||
@import big-input
|
||||
@import animations
|
||||
|
||||
// OVERRIDES
|
||||
.row .row.filter-box
|
||||
margin-left: 0
|
||||
margin-right: 0
|
||||
|
||||
.row.filter-box:first-child
|
||||
border-top: 1px solid $clr-brick
|
||||
|
||||
products .filter-box
|
||||
background: #f7f7f7
|
||||
|
||||
.filter-box
|
||||
background: rgba(245,245,245,0.6)
|
||||
|
||||
.tdhead
|
||||
padding: 0.25rem 0.5rem
|
||||
margin-top: 0.9rem
|
||||
|
||||
// OVERRIDES
|
||||
[class*="block-grid-"]
|
||||
margin: 0 0 0.5rem 0
|
||||
[class*="block-grid-"] > li
|
||||
padding-bottom: 0.5rem !important
|
||||
|
||||
|
||||
li
|
||||
@include border-radius(12px)
|
||||
padding-top: 0.5rem
|
||||
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
|
||||
// width: 100%
|
||||
// height: 2rem
|
||||
line-height: 1
|
||||
color: #444
|
||||
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
|
||||
|
||||
i.ofn-i_020-search
|
||||
position: absolute
|
||||
left: 26px
|
||||
top: 12px
|
||||
font-size: 1.6em
|
||||
z-index: 2
|
||||
color: #b2b2b2
|
||||
|
||||
position: relative
|
||||
@include placeholder(rgba(0,0,0,0.4), #777)
|
||||
input[type="text"]
|
||||
font-size: 2em
|
||||
@include csstrans
|
||||
@include big-input
|
||||
padding-left: 44px
|
||||
|
||||
@include big-input(rgba(0,0,0,0.3), #777, $clr-brick)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,58 @@
|
||||
@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
|
||||
|
||||
// ANIMATION CLASSES
|
||||
|
||||
.fade
|
||||
opacity: 0
|
||||
-webkit-transition: opacity .15s linear
|
||||
@@ -7,10 +62,10 @@
|
||||
opacity: 1
|
||||
|
||||
.reveal-modal.fade
|
||||
-webkit-transition: -webkit-transform .3s ease-out
|
||||
-moz-transition: -moz-transform .3s ease-out
|
||||
-o-transition: -o-transform .3s ease-out
|
||||
transition: transform .3s ease-out
|
||||
-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%)
|
||||
@@ -28,3 +83,77 @@
|
||||
filter: alpha(opacity = 50)
|
||||
opacity: .5
|
||||
|
||||
|
||||
.animate-repeat
|
||||
-webkit-transform: translateZ(0)
|
||||
transform: translateZ(0)
|
||||
&.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
|
||||
|
||||
|
||||
@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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
64
app/assets/stylesheets/darkswarm/big-input.sass
Normal file
64
app/assets/stylesheets/darkswarm/big-input.sass
Normal file
@@ -0,0 +1,64 @@
|
||||
@import typography
|
||||
@import branding
|
||||
@import animations
|
||||
@import mixins
|
||||
|
||||
//Big search used in active table search \\
|
||||
|
||||
@mixin big-input($input, $inputhvr, $inputactv)
|
||||
@extend .avenir
|
||||
@include csstrans
|
||||
@include border-radius(0.5rem)
|
||||
|
||||
// transition: all 0.5s ease
|
||||
background: rgba(255,255,255,0.1)
|
||||
border: 2px solid $input
|
||||
font-size: 2rem
|
||||
box-shadow: 0
|
||||
padding: 0.75rem 1rem 0.35rem 1rem
|
||||
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
|
||||
padding: 1.5rem 1rem 1rem 1rem
|
||||
letter-spacing: 0.02rem
|
||||
|
||||
@mixin big-input-static
|
||||
outline: 0
|
||||
&:active, &:focus, &.active
|
||||
padding: 0.75rem 1rem 0.35rem 1rem
|
||||
letter-spacing: 0
|
||||
|
||||
@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
|
||||
|
||||
@@ -27,7 +27,6 @@ checkout
|
||||
// Logic to turn on & off the alerts for success against each fieldset
|
||||
|
||||
label, label.alert, label.success, &.valid label.alert, &.dirty label.success
|
||||
@include csstrans
|
||||
display: none
|
||||
|
||||
&.dirty label.alert
|
||||
|
||||
@@ -8,8 +8,6 @@ footer
|
||||
.row
|
||||
&, & *
|
||||
color: white
|
||||
a, a > i
|
||||
@include csstrans
|
||||
a, a *
|
||||
color: $clr-brick-light-bright
|
||||
&:hover, &:active, &:focus
|
||||
|
||||
@@ -7,19 +7,24 @@
|
||||
background-color: black
|
||||
background-image: url("/assets/home/tagline-bg.jpg")
|
||||
@include fullbg
|
||||
height: 400px
|
||||
height: 500px
|
||||
padding: 40px 0px
|
||||
h1, h2, p
|
||||
h1, h2, span, small, timer
|
||||
color: white
|
||||
p
|
||||
color: $clr-brick-light
|
||||
h1
|
||||
margin-bottom: 1em
|
||||
margin-bottom: 3rem
|
||||
h2
|
||||
font-size: 1.6875rem
|
||||
max-width: 610px
|
||||
margin: 0 auto
|
||||
padding-bottom: 0.5rem
|
||||
|
||||
a
|
||||
color: $clr-brick-bright
|
||||
&:hover, &:active, &:focus
|
||||
color: $clr-brick-light-bright
|
||||
@include textsoftpress
|
||||
@include textsoftpress
|
||||
a.button.primary
|
||||
color: white
|
||||
@@ -2,6 +2,8 @@
|
||||
@import mixins
|
||||
|
||||
#hubs
|
||||
background: $clr-brick-ultra-light url("/assets/home/shopping-bg.jpg")
|
||||
@include fullwidthbg
|
||||
background-repeat: repeat
|
||||
background-image: url("/assets/subtle_white_feathers.png")
|
||||
// background: $clr-brick-ultra-light url("/assets/home/shopping-bg.jpg")
|
||||
// @include fullwidthbg
|
||||
@include panepadding
|
||||
|
||||
@@ -27,7 +27,6 @@ nav
|
||||
.top-bar-section ul li > a
|
||||
font-size: 0.75rem
|
||||
height: 45px
|
||||
@include csstrans
|
||||
opacity: 0.8
|
||||
&:hover, &:focus, &:active
|
||||
opacity: 1
|
||||
@@ -47,7 +46,6 @@ nav
|
||||
@include box-shadow(inset 0 0 6px 2px rgba(0,0,0,0.5))
|
||||
|
||||
.off-canvas-wrap .tab-bar .menu-icon
|
||||
@include csstrans
|
||||
@include box-shadow(none)
|
||||
|
||||
.off-canvas-wrap.move-right .tab-bar .menu-icon span
|
||||
@@ -72,4 +70,6 @@ nav
|
||||
@media screen and (max-width: 1025px)
|
||||
section.right
|
||||
.nav-branded
|
||||
padding: 0 1em
|
||||
padding: 0 1em
|
||||
|
||||
|
||||
@@ -8,56 +8,9 @@
|
||||
padding-top: 100px
|
||||
padding-bottom: 100px
|
||||
|
||||
@mixin big-input
|
||||
border: 1px solid #999
|
||||
font-size: 18px
|
||||
@extend .avenir
|
||||
box-shadow: 0
|
||||
padding: 0.75em 1em
|
||||
height: auto
|
||||
margin-bottom: 1em
|
||||
background: rgba(255,255,255,0.65)
|
||||
&:active, &:hover, &:focus
|
||||
background: rgba(255,255,255,1)
|
||||
border-color: #888
|
||||
|
||||
@mixin disabled
|
||||
color: $disabled-bright
|
||||
|
||||
@mixin csstrans
|
||||
-webkit-transition: all 100ms ease-in-out
|
||||
-moz-transition: all 100ms ease-in-out
|
||||
-ms-transition: all 100ms ease-in-out
|
||||
-o-transition: all 100ms ease-in-out
|
||||
transition: all 100ms ease-in-out
|
||||
-webkit-transform-style: preserve-3d
|
||||
|
||||
@mixin animate-in
|
||||
-webkit-animation: cssAnimation 100ms 1 ease-in
|
||||
-moz-animation: cssAnimation 100ms 1 ease-in
|
||||
-o-animation: cssAnimation 100ms 1 ease-in
|
||||
|
||||
@-webkit-keyframes cssAnimation
|
||||
from
|
||||
-webkit-transform: rotate(180deg) scale(0.25) skew(0deg) translate(0px)
|
||||
to
|
||||
-webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(0px)
|
||||
|
||||
|
||||
@-moz-keyframes cssAnimation
|
||||
from
|
||||
-moz-transform: rotate(180deg) scale(0.25) skew(0deg) translate(0px)
|
||||
to
|
||||
-moz-transform: rotate(0deg) scale(1) skew(0deg) translate(0px)
|
||||
|
||||
|
||||
@-o-keyframes cssAnimation
|
||||
from
|
||||
-o-transform: rotate(180deg) scale(0.25) skew(0deg) translate(0px)
|
||||
to
|
||||
-o-transform: rotate(0deg) scale(1) skew(0deg) translate(0px)
|
||||
|
||||
|
||||
@mixin box-shadow($box-shadow)
|
||||
-moz-box-shadow: $box-shadow
|
||||
-webkit-box-shadow: $box-shadow
|
||||
@@ -67,6 +20,18 @@
|
||||
-webkit-border-radius: $border-radius
|
||||
border-radius: $border-radius
|
||||
|
||||
@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 avenir
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
|
||||
.active_table_row
|
||||
.cta-container
|
||||
padding-bottom: 0.75rem
|
||||
// padding-bottom: 0.75rem
|
||||
background: rgba(0,0,0,0.05)
|
||||
padding-top: 0.5rem
|
||||
|
||||
// Generic styles for use
|
||||
|
||||
@@ -10,7 +10,6 @@ dialog, .reveal-modal
|
||||
background-color: rgba(0,0,0,0.65)
|
||||
|
||||
dialog .close-reveal-modal.outside, .reveal-modal .close-reveal-modal.outside
|
||||
@include csstrans
|
||||
top: -2.5rem
|
||||
right: -2.5rem
|
||||
font-size: 2rem
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
@import mixins
|
||||
@import variables
|
||||
@import branding
|
||||
@import big-input
|
||||
|
||||
|
||||
.darkswarm
|
||||
#search
|
||||
font-size: 2em
|
||||
@include big-input
|
||||
// #search
|
||||
@include placeholder(rgba(0,0,0,0.4), #777)
|
||||
|
||||
input#search
|
||||
@include big-input(rgba(0,0,0,0.3), #777, $clr-brick)
|
||||
@include big-input-static
|
||||
|
||||
color: #666
|
||||
display: block
|
||||
navigation
|
||||
@@ -98,7 +103,6 @@
|
||||
background: $clr-brick-ultra-light
|
||||
|
||||
product
|
||||
@include csstrans
|
||||
border: 1px solid #989898
|
||||
display: block
|
||||
margin-bottom: 1em !important
|
||||
@@ -111,22 +115,19 @@
|
||||
.columns
|
||||
padding-top: 1em
|
||||
padding-bottom: 1em
|
||||
line-height: 2.4em
|
||||
line-height: 1em
|
||||
|
||||
.row.summary, .row.variants
|
||||
@include csstrans
|
||||
margin-left: 0
|
||||
margin-right: 0
|
||||
background: #f7f7f7
|
||||
border-top: 1px solid #dfdfdf
|
||||
|
||||
.row.summary
|
||||
@include csstrans
|
||||
background: #fff
|
||||
line-height: 1
|
||||
|
||||
.summary-header
|
||||
@include csstrans
|
||||
font-size: 1.15rem
|
||||
|
||||
&, & *
|
||||
|
||||
@@ -20,13 +20,9 @@
|
||||
.panel
|
||||
border-color: rgba(219, 88, 61, 0.5)
|
||||
background-color: rgba(255, 255, 255, 0)
|
||||
// @include box-shadow( 0 1px 1px 0 rgba(255,255,255,1))
|
||||
|
||||
|
||||
|
||||
dl dd a
|
||||
@include avenir
|
||||
@include csstrans
|
||||
background: transparent
|
||||
text-transform: uppercase
|
||||
line-height: 50px
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
@import mixins
|
||||
|
||||
.fat-taxons
|
||||
@include csstrans
|
||||
display: inline-block
|
||||
line-height: 1
|
||||
margin-right: 0.5rem
|
||||
margin-bottom: 0.35rem
|
||||
text-transform: uppercase
|
||||
text-transform: capitalize
|
||||
font-weight: 300
|
||||
font-size: 0.875rem
|
||||
background: rgba(235,235,235,0.5)
|
||||
@@ -23,8 +22,6 @@
|
||||
&, &*
|
||||
display: inline-block
|
||||
color: #555
|
||||
// &:hover, &.hover, &:active
|
||||
// background: rgba(255,255,255,0.5)
|
||||
|
||||
.product-header
|
||||
render-svg
|
||||
@@ -40,7 +37,6 @@
|
||||
height: 24px
|
||||
|
||||
.summary-header
|
||||
@include csstrans
|
||||
render-svg
|
||||
svg
|
||||
width: 18px
|
||||
|
||||
@@ -34,6 +34,9 @@ small, .small
|
||||
margin-bottom: 0.5rem
|
||||
&, & *
|
||||
font-size: 0.875rem
|
||||
.light
|
||||
color: #999
|
||||
display: inline
|
||||
|
||||
@mixin avenir
|
||||
font-family: "AvenirBla_IE", "AvenirBla"
|
||||
|
||||
@@ -19,6 +19,17 @@ module Admin
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
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
|
||||
end
|
||||
alias_method_chain :build_resource, :address
|
||||
|
||||
|
||||
private
|
||||
|
||||
# When an enterprise user creates another enterprise, it is granted management
|
||||
|
||||
@@ -3,6 +3,10 @@ module SharedHelper
|
||||
inject_json_ams "enterprises", Enterprise.all, Api::EnterpriseSerializer, active_distributors: @active_distributors
|
||||
end
|
||||
|
||||
def inject_taxons
|
||||
inject_json_ams "taxons", Spree::Taxon.all, Api::TaxonSerializer
|
||||
end
|
||||
|
||||
def inject_json(name, partial, opts = {})
|
||||
render partial: "json/injection", locals: {name: name, partial: partial}.merge(opts)
|
||||
end
|
||||
|
||||
5
app/models/distributor_shipping_method.rb
Normal file
5
app/models/distributor_shipping_method.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class DistributorShippingMethod < ActiveRecord::Base
|
||||
self.table_name = "distributors_shipping_methods"
|
||||
belongs_to :shipping_method, class_name: Spree::ShippingMethod
|
||||
belongs_to :distributor, class_name: Enterprise, touch: true
|
||||
end
|
||||
@@ -14,8 +14,8 @@ class Enterprise < ActiveRecord::Base
|
||||
has_many :enterprise_roles, :dependent => :destroy
|
||||
has_many :users, through: :enterprise_roles
|
||||
has_and_belongs_to_many :payment_methods, join_table: 'distributors_payment_methods', class_name: 'Spree::PaymentMethod', foreign_key: 'distributor_id'
|
||||
has_and_belongs_to_many :shipping_methods, join_table: 'distributors_shipping_methods', class_name: 'Spree::ShippingMethod', foreign_key: 'distributor_id'
|
||||
|
||||
has_many :distributor_shipping_methods, foreign_key: :distributor_id
|
||||
has_many :shipping_methods, through: :distributor_shipping_methods
|
||||
|
||||
delegate :latitude, :longitude, :city, :state_name, :to => :address
|
||||
|
||||
@@ -29,7 +29,6 @@ class Enterprise < ActiveRecord::Base
|
||||
validates_presence_of :address
|
||||
validates_associated :address
|
||||
|
||||
after_initialize :initialize_country
|
||||
before_validation :set_unused_address_fields
|
||||
after_validation :geocode_address
|
||||
|
||||
@@ -159,20 +158,22 @@ class Enterprise < ActiveRecord::Base
|
||||
self.relatives.is_distributor
|
||||
end
|
||||
|
||||
def suppliers
|
||||
self.relatives.is_primary_producer
|
||||
end
|
||||
|
||||
def website
|
||||
strip_url read_attribute(:website)
|
||||
end
|
||||
|
||||
def facebook
|
||||
strip_url read_attribute(:facebook)
|
||||
end
|
||||
|
||||
def linkedin
|
||||
strip_url read_attribute(:linkedin)
|
||||
end
|
||||
|
||||
def suppliers
|
||||
self.relatives.is_primary_producer
|
||||
end
|
||||
|
||||
def distributed_variants
|
||||
Spree::Variant.joins(:product).merge(Spree::Product.in_distributor(self)).select('spree_variants.*')
|
||||
end
|
||||
@@ -192,6 +193,7 @@ class Enterprise < ActiveRecord::Base
|
||||
where('spree_products.id IN (?)', Spree::Product.in_distributor(self)).
|
||||
select('DISTINCT spree_taxons.*')
|
||||
end
|
||||
|
||||
# Return all taxons for all supplied products
|
||||
def supplied_taxons
|
||||
Spree::Taxon.
|
||||
@@ -200,17 +202,13 @@ class Enterprise < ActiveRecord::Base
|
||||
select('DISTINCT spree_taxons.*')
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def strip_url(url)
|
||||
url.andand.sub /(https?:\/\/)?(www\.)?/, ''
|
||||
end
|
||||
|
||||
def initialize_country
|
||||
self.address ||= Spree::Address.new
|
||||
self.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.address.new_record?
|
||||
end
|
||||
|
||||
def set_unused_address_fields
|
||||
address.firstname = address.lastname = address.phone = 'unused' if address.present?
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class EnterpriseRelationship < ActiveRecord::Base
|
||||
belongs_to :parent, class_name: 'Enterprise'
|
||||
belongs_to :child, class_name: 'Enterprise'
|
||||
belongs_to :parent, class_name: 'Enterprise', touch: true
|
||||
belongs_to :child, class_name: 'Enterprise', touch: true
|
||||
|
||||
validates_presence_of :parent_id, :child_id
|
||||
validates_uniqueness_of :child_id, scope: :parent_id, message: "^That relationship is already established."
|
||||
|
||||
@@ -2,6 +2,8 @@ Spree::Address.class_eval do
|
||||
has_one :enterprise
|
||||
belongs_to :country, class_name: "Spree::Country"
|
||||
|
||||
after_save :touch_enterprise
|
||||
|
||||
geocoded_by :full_address
|
||||
|
||||
delegate :name, :to => :state, :prefix => true, :allow_nil => true
|
||||
@@ -15,6 +17,10 @@ Spree::Address.class_eval do
|
||||
|
||||
private
|
||||
|
||||
def touch_enterprise
|
||||
enterprise.andand.touch
|
||||
end
|
||||
|
||||
# We have a hard-to-track-down bug around invalid addresses with all-nil fields finding
|
||||
# their way into the database. I don't know what the source of them is, so this patch
|
||||
# is designed to track them down.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
Spree::Classification.class_eval do
|
||||
belongs_to :product, :class_name => "Spree::Product", touch: true
|
||||
before_destroy :dont_destroy_if_primary_taxon
|
||||
|
||||
def dont_destroy_if_primary_taxon
|
||||
|
||||
@@ -4,7 +4,7 @@ Spree::Product.class_eval do
|
||||
# https://github.com/rails/rails/issues/7618
|
||||
has_many :option_types, :through => :product_option_types, :dependent => :destroy
|
||||
|
||||
belongs_to :supplier, :class_name => 'Enterprise'
|
||||
belongs_to :supplier, :class_name => 'Enterprise', touch: true
|
||||
belongs_to :primary_taxon, class_name: 'Spree::Taxon'
|
||||
|
||||
has_many :product_distributions, :dependent => :destroy
|
||||
@@ -12,9 +12,10 @@ Spree::Product.class_eval do
|
||||
|
||||
accepts_nested_attributes_for :product_distributions, :allow_destroy => true
|
||||
delegate_belongs_to :master, :unit_value, :unit_description
|
||||
delegate :images_attributes=, to: :master
|
||||
delegate :images_attributes=, :display_as=, to: :master
|
||||
|
||||
attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes, :images_attributes
|
||||
attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size
|
||||
attr_accessible :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes, :images_attributes, :display_as
|
||||
|
||||
validates_presence_of :supplier
|
||||
validates_presence_of :primary_taxon
|
||||
@@ -27,6 +28,7 @@ Spree::Product.class_eval do
|
||||
|
||||
after_initialize :set_available_on_to_now, :if => :new_record?
|
||||
after_save :update_units
|
||||
after_touch :touch_distributors
|
||||
before_save :add_primary_taxon_to_taxons
|
||||
|
||||
|
||||
@@ -186,8 +188,12 @@ Spree::Product.class_eval do
|
||||
end
|
||||
end
|
||||
|
||||
def touch_distributors
|
||||
Enterprise.distributing_product(self).each(&:touch)
|
||||
end
|
||||
|
||||
def add_primary_taxon_to_taxons
|
||||
taxons << primary_taxon unless taxons.find_by_id(primary_taxon)
|
||||
taxons << primary_taxon unless taxons.include? primary_taxon
|
||||
end
|
||||
|
||||
def self.all_variant_unit_option_types
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
Spree::ShippingMethod.class_eval do
|
||||
has_and_belongs_to_many :distributors, join_table: 'distributors_shipping_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id'
|
||||
has_many :distributor_shipping_methods
|
||||
has_many :distributors, through: :distributor_shipping_methods, class_name: 'Enterprise', foreign_key: 'distributor_id'
|
||||
|
||||
after_save :touch_distributors
|
||||
attr_accessible :distributor_ids, :description
|
||||
attr_accessible :require_ship_address
|
||||
|
||||
validates :distributors, presence: { message: "^At least one hub must be selected" }
|
||||
|
||||
scope :managed_by, lambda { |user|
|
||||
if user.has_spree_role?('admin')
|
||||
scoped
|
||||
@@ -41,4 +46,10 @@ Spree::ShippingMethod.class_eval do
|
||||
def adjustment_label
|
||||
'Shipping'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def touch_distributors
|
||||
distributors.each(&:touch)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,11 +51,13 @@ Spree::Variant.class_eval do
|
||||
end
|
||||
|
||||
def name_to_display
|
||||
display_name || product.name
|
||||
return product.name if display_name.blank?
|
||||
display_name
|
||||
end
|
||||
|
||||
def unit_to_display
|
||||
display_as || options_text
|
||||
return options_text if display_as.blank?
|
||||
display_as
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
%input.fullwidth{ id: 'product_unit_value_with_description', 'ng-model' => 'product.master.unit_value_with_description', :type => 'text', placeholder: "eg. 2", 'ng-disabled' => "!hasUnit(product)" }
|
||||
%input{ type: 'hidden', 'ng-value' => 'product.master.unit_value', name: 'product[unit_value]' }
|
||||
%input{ type: 'hidden', 'ng-value' => 'product.master.unit_description', name: 'product[unit_description]' }
|
||||
.three.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" }
|
||||
= f.field_container :unit_name do
|
||||
= f.label :product_variant_unit_name, :unit_name
|
||||
%input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => 'eg. bunches', :type => 'text' }
|
||||
= render 'display_as', f: f
|
||||
.three.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" }
|
||||
= f.field_container :unit_name do
|
||||
= f.label :product_variant_unit_name, t(:unit_name)
|
||||
%input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => 'eg. bunches', :type => 'text' }
|
||||
.twelve.columns.alpha
|
||||
.six.columns.alpha
|
||||
= render 'spree/admin/products/primary_taxon_form', f: f
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/ replace_contents "title"
|
||||
|
||||
= "OFN #{t(:administration)}:"
|
||||
= t(controller.controller_name, :default => controller.controller_name.titleize)
|
||||
= t(controller.controller_name, :default => controller.controller_name.titleize)
|
||||
= " - OFN #{t(:administration)}"
|
||||
@@ -1,4 +1,7 @@
|
||||
class Api::AddressSerializer < ActiveModel::Serializer
|
||||
cached
|
||||
delegate :cache_key, to: :object
|
||||
|
||||
attributes :id, :zipcode, :city, :state
|
||||
|
||||
def state
|
||||
|
||||
@@ -1,12 +1,43 @@
|
||||
class Api::EnterpriseSerializer < ActiveModel::Serializer
|
||||
def serializable_hash
|
||||
cached_serializer_hash.merge uncached_serializer_hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cached_serializer_hash
|
||||
Api::CachedEnterpriseSerializer.new(object, @options).serializable_hash
|
||||
end
|
||||
|
||||
def uncached_serializer_hash
|
||||
Api::UncachedEnterpriseSerializer.new(object, @options).serializable_hash
|
||||
end
|
||||
end
|
||||
|
||||
class Api::UncachedEnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :orders_close_at, :active
|
||||
|
||||
def orders_close_at
|
||||
OrderCycle.first_closing_for(object).andand.orders_close_at
|
||||
end
|
||||
|
||||
def active
|
||||
@options[:active_distributors].andand.include? object
|
||||
end
|
||||
end
|
||||
|
||||
class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
|
||||
cached
|
||||
delegate :cache_key, to: :object
|
||||
|
||||
attributes :name, :id, :description, :latitude, :longitude,
|
||||
:long_description, :website, :instagram, :linkedin, :twitter,
|
||||
:facebook, :is_primary_producer, :is_distributor, :phone, :visible,
|
||||
:email, :hash, :logo, :promo_image, :icon, :path,
|
||||
:pickup, :delivery, :active, :orders_close_at
|
||||
:pickup, :delivery
|
||||
|
||||
has_many :distributed_taxons, key: :taxons, serializer: Api::TaxonSerializer
|
||||
has_many :supplied_taxons, serializer: Api::TaxonSerializer
|
||||
has_many :distributed_taxons, key: :taxons, serializer: Api::IdSerializer
|
||||
has_many :supplied_taxons, serializer: Api::IdSerializer
|
||||
has_many :distributors, key: :hubs, serializer: Api::IdSerializer
|
||||
has_many :suppliers, key: :producers, serializer: Api::IdSerializer
|
||||
|
||||
@@ -20,14 +51,6 @@ class Api::EnterpriseSerializer < ActiveModel::Serializer
|
||||
object.shipping_methods.where(:require_ship_address => true).present?
|
||||
end
|
||||
|
||||
def active
|
||||
@options[:active_distributors].andand.include?(object)
|
||||
end
|
||||
|
||||
def orders_close_at
|
||||
OrderCycle.first_closing_for(object).andand.orders_close_at
|
||||
end
|
||||
|
||||
def email
|
||||
object.email.to_s.reverse
|
||||
end
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
class Api::TaxonSerializer < ActiveModel::Serializer
|
||||
cached
|
||||
delegate :cache_key, to: :object
|
||||
|
||||
attributes :id, :name, :permalink, :icon
|
||||
|
||||
def icon
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
%span{"active-table-hub-link" => "hub", change: "Change hub to", shop: "Shop at"}
|
||||
.row
|
||||
.columns.small-12
|
||||
%a.button.hub.expand{"bo-href" => "hub.path",
|
||||
%a.button.hub{"bo-href" => "hub.path",
|
||||
"ng-class" => "{primary: hub.active, secondary: !hub.active}",
|
||||
"ofn-empties-cart" => "hub"}
|
||||
%i.ofn-i_033-open-sign{"bo-if" => "hub.active"}
|
||||
|
||||
23
app/views/home/_filters.html.haml
Normal file
23
app/views/home/_filters.html.haml
Normal file
@@ -0,0 +1,23 @@
|
||||
= render partial: 'shared/components/filter_controls'
|
||||
|
||||
.row.animate-show{"ng-show" => "filtersActive"}
|
||||
.small-12.columns
|
||||
.row.filter-box
|
||||
.small-12.large-9.columns
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Type
|
||||
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-5
|
||||
%taxon-selector{objects: "hubs | hubs:query",
|
||||
results: "activeTaxons"}
|
||||
.small-12.large-3.columns
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Delivery
|
||||
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2
|
||||
%shipping-type-selector{results: "shippingTypes"}
|
||||
.row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
|
||||
.small-12.columns
|
||||
%a.button.secondary.small.expand{"ng-click" => "clearAll()"}
|
||||
%i.ofn-i_009-close
|
||||
Clear all filters
|
||||
@@ -1,27 +1,29 @@
|
||||
= inject_enterprises
|
||||
#hubs.hubs{"ng-controller" => "HubsCtrl"}
|
||||
.row
|
||||
.small-12.columns.text-center
|
||||
%h1 Ready to shop?
|
||||
%div
|
||||
Select a
|
||||
%ofn-modal{title: "food hub"}
|
||||
= render partial: "modals/food_hub"
|
||||
from the list below:
|
||||
.small-12.columns
|
||||
%h1 Find hubs in your area...
|
||||
/ %div
|
||||
/ Shop a
|
||||
/ %ofn-modal{title: "food hub"}
|
||||
/ = render partial: "modals/food_hub"
|
||||
/ from the list below:
|
||||
|
||||
#active-table-search.row.pad-top
|
||||
.small-12.columns
|
||||
%i.ofn-i_020-search
|
||||
/ %i.ofn-i_020-search
|
||||
%input{type: :text,
|
||||
"ng-model" => "query",
|
||||
placeholder: "Search postcode, suburb or hub name...",
|
||||
placeholder: "Search by Hub or Suburb name",
|
||||
"ng-debounce" => "150",
|
||||
"ofn-disable-enter" => true}
|
||||
|
||||
= render partial: "home/filters"
|
||||
|
||||
.row{bindonce: true}
|
||||
.small-12.columns
|
||||
.active_table
|
||||
%hub.active_table_node.row{"ng-repeat" => "hub in filteredHubs = (hubs | hubs:query)",
|
||||
%hub.active_table_node.row.animate-repeat{"ng-repeat" => "hub in filteredHubs = (hubs | hubs:query | taxons:activeTaxons | shipping:shippingTypes)",
|
||||
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !hub.active, 'current' : current()}",
|
||||
"scroll-after-load" => true,
|
||||
"ng-controller" => "HubNodeCtrl",
|
||||
@@ -30,6 +32,9 @@
|
||||
= render partial: 'home/skinny'
|
||||
= render partial: 'home/fat'
|
||||
|
||||
.row{"ng-show" => "filteredHubs.length == 0"}
|
||||
.columns.small-12.text-center
|
||||
No results
|
||||
.row{"ng-show" => "filteredHubs.length == 0"}
|
||||
.columns.small-12
|
||||
%p.no-results
|
||||
Sorry, no results found for
|
||||
%strong {{query}}.
|
||||
Try another search?
|
||||
|
||||
@@ -15,4 +15,7 @@
|
||||
Orders closed
|
||||
|
||||
.columns.small-1.text-right
|
||||
%i{"ng-class" => "{'ofn-i_005-caret-down' : !open(), 'ofn-i_006-caret-up' : open()}"}
|
||||
/ This forces line-height to be triggered
|
||||
%span
|
||||
%i{"ng-class" => "{'ofn-i_005-caret-down' : !open(), 'ofn-i_006-caret-up' : open()}"}
|
||||
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
.row
|
||||
.small-12.text-center.columns
|
||||
%h1= image_tag "ofn_logo_beta.png", title: "Open Food Network (beta)"
|
||||
%h2 An open marketplace that makes it easy to find, buy, sell and move sustainable local food.
|
||||
|
||||
%ofn-modal{title: "Learn more"}
|
||||
= render partial: "modals/learn_more"
|
||||
%h2 We're crowdfunding right now!
|
||||
%h5
|
||||
%timer{"end-time" => '1407679200000'}
|
||||
{{days}} days, {{hours}} hrs, {{minutes}} mins & {{seconds}} secs to go
|
||||
%p Help us make Open Food Network the best it can be:
|
||||
%a.button.primary{href: "http://startsomegood.com/openfoodnetwork", target:"_blank"} Support now
|
||||
/ %h2 An open marketplace that makes it easy to find, buy, sell and move sustainable local food.
|
||||
%br
|
||||
%ofn-modal{title: "Learn more"}
|
||||
= render partial: "modals/learn_more"
|
||||
|
||||
= render partial: "home/hubs"
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
= inject_json "currentOrder", "current_order"
|
||||
= inject_json "user", "current_user"
|
||||
= inject_json "railsFlash", "flash"
|
||||
= inject_taxons
|
||||
|
||||
.off-canvas-wrap{offcanvas: true}
|
||||
.inner-wrap
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
%h5 Shop for {{ producer.name }} products at:
|
||||
.row
|
||||
.columns.small-12
|
||||
%a.button.hub{"ng-repeat" => "hub in producer.hubs",
|
||||
%a.button.hub{"ng-repeat" => "hub in producer.hubs | orderBy:'-active'",
|
||||
"bo-href" => "hub.path", "ofn-empties-cart" => "hub",
|
||||
"bo-class" => "{primary: hub.active, secondary: !hub.active}"}
|
||||
%i.ofn-i_033-open-sign{"bo-if" => "hub.active"}
|
||||
|
||||
18
app/views/producers/_filters.html.haml
Normal file
18
app/views/producers/_filters.html.haml
Normal file
@@ -0,0 +1,18 @@
|
||||
= render partial: 'shared/components/filter_controls'
|
||||
|
||||
.row.animate-show{"ng-show" => "filtersActive"}
|
||||
.small-12.columns
|
||||
.row.filter-box
|
||||
.small-12.columns
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Type
|
||||
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-6
|
||||
%taxon-selector{objects: "Producers.visible | filterProducers:query",
|
||||
results: "activeTaxons"}
|
||||
|
||||
.row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
|
||||
.small-12.columns
|
||||
%a.button.secondary.small.expand{"ng-click" => "clearAll()"}
|
||||
%i.ofn-i_009-close
|
||||
Clear all filters
|
||||
@@ -7,4 +7,6 @@
|
||||
.columns.small-4
|
||||
{{ producer.address.state | uppercase }}
|
||||
.columns.small-1.text-right
|
||||
/ This forces line-height to be triggered
|
||||
%span
|
||||
%i{"ng-class" => "{'ofn-i_005-caret-down' : !open(), 'ofn-i_006-caret-up' : open()}"}
|
||||
@@ -1,35 +0,0 @@
|
||||
= inject_enterprises
|
||||
.producers{"ng-controller" => "ProducersCtrl"}
|
||||
.row
|
||||
.small-12.columns.text-center.pad-top
|
||||
%h1 Producers
|
||||
%div
|
||||
Select a
|
||||
%ofn-modal{title: "producer"}
|
||||
= render partial: "modals/producers"
|
||||
from the list below:
|
||||
|
||||
#active-table-search.row.pad-top
|
||||
.small-12.columns
|
||||
%i.ofn-i_020-search
|
||||
%input{type: :text,
|
||||
"ng-model" => "query",
|
||||
placeholder: "Search postcode, suburb or producer name...",
|
||||
"ng-debounce" => "150",
|
||||
"ofn-disable-enter" => true}
|
||||
|
||||
.row{bindonce: true}
|
||||
.small-12.columns
|
||||
.active_table
|
||||
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
|
||||
"scroll-after-load" => true,
|
||||
"ng-repeat" => "producer in filteredProducers = (Producers.visible | filterProducers:query)",
|
||||
"ng-controller" => "ProducerNodeCtrl",
|
||||
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",
|
||||
id: "{{producer.hash}}"}
|
||||
|
||||
.small-12.columns
|
||||
= render partial: 'producers/skinny'
|
||||
= render partial: 'producers/fat'
|
||||
|
||||
= render partial: "shared/footer"
|
||||
42
app/views/producers/index.html.haml
Normal file
42
app/views/producers/index.html.haml
Normal file
@@ -0,0 +1,42 @@
|
||||
= inject_enterprises
|
||||
.producers.pad-top{"ng-controller" => "ProducersCtrl"}
|
||||
.row
|
||||
.small-12.columns.pad-top
|
||||
%h1 Find local producers
|
||||
/ %div
|
||||
/ Find a
|
||||
/ %ofn-modal{title: "producer"}
|
||||
/ = render partial: "modals/producers"
|
||||
/ from the list below:
|
||||
|
||||
#active-table-search.row
|
||||
.small-12.columns
|
||||
%input.animate-show{type: :text,
|
||||
"ng-model" => "query",
|
||||
placeholder: "Search by Producer or Suburb name",
|
||||
"ng-debounce" => "150",
|
||||
"ofn-disable-enter" => true}
|
||||
|
||||
= render partial: "producers/filters"
|
||||
|
||||
.row{bindonce: true}
|
||||
.small-12.columns
|
||||
.active_table
|
||||
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
|
||||
"scroll-after-load" => true,
|
||||
"ng-repeat" => "producer in producers = (Producers.visible | filterProducers:query | taxons:activeTaxons)",
|
||||
"ng-controller" => "ProducerNodeCtrl",
|
||||
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",
|
||||
id: "{{producer.hash}}"}
|
||||
|
||||
.small-12.columns
|
||||
= render partial: 'producers/skinny'
|
||||
= render partial: 'producers/fat'
|
||||
|
||||
%producer.row{"ng-show" => "producers.length == 0"}
|
||||
%p.no-results
|
||||
Sorry, no results found for
|
||||
%strong {{query}}.
|
||||
Try another search?
|
||||
|
||||
= render partial: "shared/footer"
|
||||
10
app/views/shared/components/_filter_controls.html.haml
Normal file
10
app/views/shared/components/_filter_controls.html.haml
Normal file
@@ -0,0 +1,10 @@
|
||||
.row
|
||||
.small-12.columns
|
||||
%a.button.primary.tiny.filterbtn{"ng-click" => "filtersActive = !filtersActive",
|
||||
"ng-show" => "FilterSelectorsService.selectors.length > 0"}
|
||||
{{ filterText(filtersActive) }}
|
||||
%i.ofn-i_005-caret-down{"ng-show" => "!filtersActive"}
|
||||
%i.ofn-i_006-caret-up{"ng-show" => "filtersActive"}
|
||||
|
||||
%a.button.secondary.tiny.filterbtn.disabled{"ng-show" => "FilterSelectorsService.selectors.length == 0"}
|
||||
No filters
|
||||
@@ -43,7 +43,7 @@ node :variants do |product|
|
||||
end
|
||||
|
||||
child :taxons => :taxons do |taxon|
|
||||
attributes :name
|
||||
attributes :id
|
||||
end
|
||||
|
||||
child :properties => :properties do |property|
|
||||
|
||||
18
app/views/shop/products/_filters.html.haml
Normal file
18
app/views/shop/products/_filters.html.haml
Normal file
@@ -0,0 +1,18 @@
|
||||
= render partial: 'shared/components/filter_controls'
|
||||
|
||||
.row.animate-show{"ng-show" => "filtersActive"}
|
||||
.small-12.columns
|
||||
.row.filter-box
|
||||
.small-12.columns
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Type
|
||||
%ul.small-block-grid-2.medium-block-grid-3.large-block-grid-4
|
||||
%taxon-selector{objects: "Product.products | products:query",
|
||||
results: "activeTaxons"}
|
||||
|
||||
.row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
|
||||
.small-12.columns
|
||||
%a.button.secondary.small.expand{"ng-click" => "clearAll()"}
|
||||
%i.ofn-i_009-close
|
||||
Clear all filters
|
||||
@@ -1,30 +1,42 @@
|
||||
%products.small-12.columns{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null",
|
||||
"infinite-scroll" => "incrementLimit()", "infinite-scroll-distance" => "1"}
|
||||
|
||||
|
||||
= form_for :order, :url => populate_orders_path, html: {:class => "custom"} do
|
||||
.row
|
||||
.small-6.columns
|
||||
.small-12.medium-8.large-8.columns
|
||||
%input#search.text{"ng-model" => "query",
|
||||
placeholder: "Search",
|
||||
"ng-debounce" => "150",
|
||||
placeholder: "Search by product or producer",
|
||||
"ng-debounce" => "100",
|
||||
"ofn-disable-enter" => true}
|
||||
.small-6.columns
|
||||
|
||||
= render partial: "shop/products/filters"
|
||||
|
||||
.small-12.medium-4.large-4.columns
|
||||
%input.button.primary.right{type: :submit, value: "Add to Cart"}
|
||||
|
||||
%div{bindonce: true}
|
||||
|
||||
%div.pad-top{bindonce: true}
|
||||
%product.animate-repeat{"ng-controller" => "ProductNodeCtrl",
|
||||
"ng-repeat" => "product in Product.products | products:query | orderBy:ordering.order | limitTo: limit track by product.id"}
|
||||
"ng-repeat" => "product in filteredProducts = (Product.products | products:query | taxons:activeTaxons | orderBy:ordering.order) track by product.id "}
|
||||
%div
|
||||
= render partial: "shop/products/summary"
|
||||
%div{"bo-if" => "hasVariants"}
|
||||
%div{"bo-if" => "product.hasVariants"}
|
||||
= render partial: "shop/products/variants"
|
||||
.variants.row{"bo-if" => "!hasVariants"}
|
||||
.variants.row{"bo-if" => "!product.hasVariants"}
|
||||
= render partial: "shop/products/master"
|
||||
|
||||
%product{"ng-show" => "Product.loading"}
|
||||
.row.summary
|
||||
.small-12.columns.text-center
|
||||
Loading products
|
||||
|
||||
%div{"ng-show" => "filteredProducts.length == 0 && !Product.loading"}
|
||||
.row.summary
|
||||
.small-12.columns
|
||||
%p.no-results
|
||||
Sorry, no results found for
|
||||
%strong {{query}}.
|
||||
Try another search?
|
||||
.row
|
||||
.small-12.columns
|
||||
%input.button.primary.right.add_to_cart{type: :submit, value: "Add to Cart"}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
.row.summary
|
||||
.small-1.columns
|
||||
%product-modal
|
||||
%img{"bo-src" => "product.master.images[0].small_url"}
|
||||
%img{"bo-src" => "product.master.images[0].small_url", "ng-click" => "triggerProductModal()"}
|
||||
|
||||
.small-4.columns.summary-header
|
||||
%render-svg{path: "{{product.primary_taxon.icon}}"}
|
||||
%product-modal {{ product.name }}
|
||||
%a{"ng-click" => "triggerProductModal()"}{{ product.name }}
|
||||
|
||||
.small-5.columns
|
||||
%i.ofn-i_036-producers
|
||||
%producer-modal {{ enterprise.name }}
|
||||
|
||||
.small-2.columns.summary-price.text-right.price
|
||||
%span{"ng-if" => "hasVariants"}
|
||||
%span{"ng-if" => "product.hasVariants"}
|
||||
%em from
|
||||
{{ price() | currency }}
|
||||
{{ product.price | currency }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.row.variants{bindonce: true,
|
||||
"ng-repeat" => "variant in product.variants"}
|
||||
"ng-repeat" => "variant in product.variants track by variant.id"}
|
||||
|
||||
.small-1.columns
|
||||
%i.ofn-i_056-bulk{"bo-if" => "product.group_buy"}
|
||||
|
||||
4
app/views/spree/admin/products/_display_as.html.haml
Normal file
4
app/views/spree/admin/products/_display_as.html.haml
Normal file
@@ -0,0 +1,4 @@
|
||||
.three.columns.omega{ "ng-if" => "product.variant_unit_with_scale != 'items'" }
|
||||
= f.field_container :display_as do
|
||||
= f.label :product_display_as, t(:display_as)
|
||||
%input#product_display_as.fullwidth{name: "product[display_as]", placeholder: "{{ placeholder_text }}", type: "text"}
|
||||
@@ -51,13 +51,13 @@
|
||||
%li.column-list-item{ :class => "three columns alpha", 'ofn-toggle-column' => 'column', 'ng-repeat' => 'column in columns' }
|
||||
{{ column.name }}
|
||||
%hr
|
||||
%div.loading{ 'ng-show' => 'loading' }
|
||||
%div.sixteen.columns.alpha.loading{ 'ng-show' => 'loading' }
|
||||
%h4 Loading Products...
|
||||
%div{ 'ng-show' => '!loading && products.length == 0' }
|
||||
%div.sixteen.columns.alpha{ 'ng-show' => '!loading && products.length == 0' }
|
||||
%h4{ :style => 'color:red;' } No matching products found.
|
||||
%div{ 'ng-show' => 'products.length == 500' }
|
||||
%div.sixteen.columns.alpha{ 'ng-show' => '!loading && products.length == 500' }
|
||||
%h6 Search returned too many products to display (500+), please apply more search filters to reduce the number of matching products
|
||||
%div{ 'ng-hide' => 'loading || products.length == 500 || products.length == 0' }
|
||||
%div.sixteen.columns.alpha{ 'ng-hide' => 'loading || products.length == 500 || products.length == 0' }
|
||||
%div.quick_search{ :class => "five columns omega" }
|
||||
%input.search{ :class => "four columns alpha", 'ng-model' => 'query', :name => "quick_filter", :type => 'text', 'placeholder' => 'Quick Search' }
|
||||
%div.pagination{ :class => "seven columns omega" }
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
- hubs_color = @hubs.count > 0 ? "blue" : "red"
|
||||
- hubs_color = 'red' if (controller.action_name == 'create' || controller.action_name == 'update') && @object.errors.full_messages.include?("At least one hub must be selected")
|
||||
.sidebar_item.omega.four.columns#hubs
|
||||
.four.columns.alpha.header{ class: "#{hubs_color}" }
|
||||
%span.four.columns.alpha.centered Distributors
|
||||
%span.four.columns.alpha.centered Hubs
|
||||
.four.columns.alpha.list{ class: "#{hubs_color}" }
|
||||
- if @hubs.count > 0
|
||||
-# = hidden_field_tag "enterprise[hub_ids][]", []
|
||||
= f.hidden_field :distributor_ids, :multiple => true, value: nil
|
||||
- @hubs.each do |hub|
|
||||
%a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{main_app.edit_admin_enterprise_path(hub)}" }
|
||||
%span.three.columns.alpha
|
||||
|
||||
@@ -5,6 +5,7 @@ Openfoodnetwork::Application.configure do
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
config.cache_classes = false
|
||||
config.cache_store = :memory_store
|
||||
|
||||
# Log error messages when you accidentally call methods on nil.
|
||||
config.whiny_nils = true
|
||||
|
||||
@@ -37,7 +37,7 @@ Openfoodnetwork::Application.configure do
|
||||
# config.logger = SyslogLogger.new
|
||||
|
||||
# Use a different cache store in production
|
||||
# config.cache_store = :mem_cache_store
|
||||
config.cache_store = :dalli_store
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
||||
# config.action_controller.asset_host = "http://assets.example.com"
|
||||
|
||||
@@ -37,7 +37,7 @@ Openfoodnetwork::Application.configure do
|
||||
# config.logger = SyslogLogger.new
|
||||
|
||||
# Use a different cache store in production
|
||||
# config.cache_store = :mem_cache_store
|
||||
config.cache_store = :dalli_store
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
||||
# config.action_controller.asset_host = "http://assets.example.com"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
class AddFieldsToDistributorsShippingMethods < ActiveRecord::Migration
|
||||
class DistributorShippingMethod < ActiveRecord::Base
|
||||
self.table_name = "distributors_shipping_methods"
|
||||
end
|
||||
|
||||
def up
|
||||
add_column :distributors_shipping_methods, :id, :primary_key
|
||||
add_column :distributors_shipping_methods, :created_at, :datetime
|
||||
add_column :distributors_shipping_methods, :updated_at, :datetime
|
||||
|
||||
DistributorShippingMethod.reset_column_information
|
||||
DistributorShippingMethod.update_all created_at: Time.now, updated_at: Time.now
|
||||
|
||||
change_column :distributors_shipping_methods, :created_at, :datetime, null: false
|
||||
change_column :distributors_shipping_methods, :updated_at, :datetime, null: false
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :distributors_shipping_methods, :id
|
||||
remove_column :distributors_shipping_methods, :created_at
|
||||
remove_column :distributors_shipping_methods, :updated_at
|
||||
end
|
||||
end
|
||||
12
db/schema.rb
12
db/schema.rb
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20140613004344) do
|
||||
ActiveRecord::Schema.define(:version => 20140702053145) do
|
||||
|
||||
create_table "adjustment_metadata", :force => true do |t|
|
||||
t.integer "adjustment_id"
|
||||
@@ -163,9 +163,11 @@ ActiveRecord::Schema.define(:version => 20140613004344) do
|
||||
add_index "distributors_payment_methods", ["distributor_id"], :name => "index_distributors_payment_methods_on_distributor_id"
|
||||
add_index "distributors_payment_methods", ["payment_method_id"], :name => "index_distributors_payment_methods_on_payment_method_id"
|
||||
|
||||
create_table "distributors_shipping_methods", :id => false, :force => true do |t|
|
||||
t.integer "distributor_id"
|
||||
t.integer "shipping_method_id"
|
||||
create_table "distributors_shipping_methods", :force => true do |t|
|
||||
t.integer "distributor_id"
|
||||
t.integer "shipping_method_id"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "distributors_shipping_methods", ["distributor_id"], :name => "index_distributors_shipping_methods_on_distributor_id"
|
||||
@@ -560,9 +562,9 @@ ActiveRecord::Schema.define(:version => 20140613004344) do
|
||||
t.string "email"
|
||||
t.text "special_instructions"
|
||||
t.integer "distributor_id"
|
||||
t.integer "order_cycle_id"
|
||||
t.string "currency"
|
||||
t.string "last_ip_address"
|
||||
t.integer "order_cycle_id"
|
||||
t.integer "cart_id"
|
||||
end
|
||||
|
||||
|
||||
@@ -7,20 +7,31 @@
|
||||
div.dialog {
|
||||
width: 25em;
|
||||
padding: 0 4em;
|
||||
margin: 4em auto 0 auto;
|
||||
border: 1px solid #ccc;
|
||||
border-right-color: #999;
|
||||
border-bottom-color: #999;
|
||||
margin: 2em auto 0 auto;
|
||||
}
|
||||
a.go_home {
|
||||
font-size: 100%;
|
||||
color: black;
|
||||
line-height: 1.5em;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted black;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
a.go_home:hover, a.go_home:focus, a.go_home:active{
|
||||
background: #8f301d;
|
||||
color: white;
|
||||
border-bottom: none;
|
||||
}
|
||||
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- This file lives in public/404.html -->
|
||||
<div class="dialog">
|
||||
<h1>The page you were looking for doesn't exist.</h1>
|
||||
<p>You may have mistyped the address or the page may have moved.</p>
|
||||
<a href="/" ><img src="404.jpg" /></a>
|
||||
<p>It seems the page you're looking for is in a grump.
|
||||
<br><h3><a class="go_home" href="/" >Return home</a></h3>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
BIN
public/404.jpg
Normal file
BIN
public/404.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -7,20 +7,32 @@
|
||||
div.dialog {
|
||||
width: 25em;
|
||||
padding: 0 4em;
|
||||
margin: 4em auto 0 auto;
|
||||
border: 1px solid #ccc;
|
||||
border-right-color: #999;
|
||||
border-bottom-color: #999;
|
||||
margin: 2em auto 0 auto;
|
||||
}
|
||||
a.go_home {
|
||||
font-size: 100%;
|
||||
color: black;
|
||||
line-height: 1.5em;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted black;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
a.go_home:hover, a.go_home:focus, a.go_home:active{
|
||||
background: #8f301d;
|
||||
color: white;
|
||||
border-bottom: none;
|
||||
}
|
||||
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- This file lives in public/422.html -->
|
||||
<div class="dialog">
|
||||
<h1>The change you wanted was rejected.</h1>
|
||||
<p>Maybe you tried to change something you didn't have access to.</p>
|
||||
<a href="/" ><img src="422.jpg" /></a>
|
||||
<p>The change you wanted was rejected. Maybe you tried to change something you don't have access to.
|
||||
<br><h3><a class="go_home" href="/" >Return home</a></h3>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
BIN
public/422.jpg
Normal file
BIN
public/422.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
@@ -7,20 +7,39 @@
|
||||
div.dialog {
|
||||
width: 25em;
|
||||
padding: 0 4em;
|
||||
margin: 4em auto 0 auto;
|
||||
border: 1px solid #ccc;
|
||||
border-right-color: #999;
|
||||
border-bottom-color: #999;
|
||||
margin: 2em auto 0 auto;
|
||||
}
|
||||
a.go_home {
|
||||
font-size: 100%;
|
||||
color: black;
|
||||
line-height: 1.5em;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted black;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
a.go_home:hover, a.go_home:focus, a.go_home:active{
|
||||
background: #8f301d;
|
||||
color: white;
|
||||
border-bottom: none;
|
||||
}
|
||||
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- This file lives in public/500.html -->
|
||||
<div class="dialog">
|
||||
<h1>We're sorry, but something went wrong.</h1>
|
||||
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
||||
<a href="/" ><img src="500.jpg" /></a>
|
||||
<p>We're sorry, but something went wrong.
|
||||
<br>Try refreshing the page, or
|
||||
<br><h3><a class="go_home" href="/" >Return home</a></h3>
|
||||
<br>Want to let us know what went wrong? Email us at:
|
||||
<h3>
|
||||
<!-- Can we do .reverse ??
|
||||
<a class="go_home" href="mailto:hello@openfoodnetwork.org" target="_blank"></a>
|
||||
-->
|
||||
hello [at] openfoodnetwork.org
|
||||
</h3>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
BIN
public/500.jpg
Normal file
BIN
public/500.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -40,9 +40,7 @@ describe CheckoutController do
|
||||
|
||||
it "doesn't copy the previous shipping address from a pickup order" do
|
||||
old_order = create(:order, bill_address: create(:address), ship_address: create(:address))
|
||||
old_order.shipping_method.stub_chain(:andand, :require_ship_address).and_return(false)
|
||||
Spree::Order.stub_chain(:order, :where, :where, :limit, :detect).and_return(old_order)
|
||||
|
||||
controller.send(:find_last_used_addresses, "email").last.should == nil
|
||||
end
|
||||
|
||||
@@ -81,6 +79,7 @@ describe CheckoutController do
|
||||
context "via xhr" do
|
||||
before do
|
||||
controller.stub(:current_distributor).and_return(distributor)
|
||||
|
||||
controller.stub(:current_order_cycle).and_return(order_cycle)
|
||||
controller.stub(:current_order).and_return(order)
|
||||
end
|
||||
|
||||
@@ -110,16 +110,17 @@ feature %q{
|
||||
|
||||
scenario "editing an existing enterprise" do
|
||||
@enterprise = create(:enterprise)
|
||||
e2 = create(:enterprise)
|
||||
eg1 = create(:enterprise_group, name: 'eg1')
|
||||
eg2 = create(:enterprise_group, name: 'eg2')
|
||||
payment_method = create(:payment_method, distributors: [])
|
||||
shipping_method = create(:shipping_method, distributors: [])
|
||||
shipping_method = create(:shipping_method, distributors: [e2])
|
||||
enterprise_fee = create(:enterprise_fee, enterprise: @enterprise )
|
||||
|
||||
login_to_admin_section
|
||||
|
||||
click_link 'Enterprises'
|
||||
click_link 'Edit Profile'
|
||||
all("a", text:'Edit Profile').first.click
|
||||
|
||||
fill_in 'enterprise_name', :with => 'Eaterprises'
|
||||
fill_in 'enterprise_description', :with => 'Connecting farmers and eaters'
|
||||
|
||||
@@ -11,7 +11,7 @@ feature "Authentication", js: true do
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "Password", with: user.password
|
||||
click_login_button
|
||||
page.should have_content "Select a producer from the list below"
|
||||
page.should have_content "Find local producers"
|
||||
current_path.should == producers_path
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user