Merge branch 'master' into config

Conflicts:
	.gitignore
	Gemfile
This commit is contained in:
Rafael Schouten
2014-10-25 15:29:53 +11:00
235 changed files with 2388 additions and 3253 deletions

4
.gitignore vendored
View File

@@ -15,6 +15,7 @@ tmp/
.#*
*~
*.~lock.*
tags
.emacs.desktop
.DS_Store
*.sublime-project*
@@ -36,7 +37,4 @@ config/initializers/feature_toggle.rb
NERD_tree*
coverage
libpeerconnection.log
tags
# Ignore application configuration
/config/application.yml

View File

@@ -42,6 +42,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 'figaro'
gem 'foreigner'

View File

@@ -153,6 +153,7 @@ GEM
railties (>= 3.1)
sprockets
tilt
angularjs-file-upload-rails (1.1.0)
angularjs-rails (1.2.13)
ansi (1.4.2)
arel (3.0.3)
@@ -508,6 +509,7 @@ DEPENDENCIES
active_model_serializers
andand
angular-rails-templates
angularjs-file-upload-rails (~> 1.1.0)
angularjs-rails
awesome_print
aws-sdk

View File

@@ -1,3 +1,3 @@
angular.module("ofn.admin", ["ngResource", "ngAnimate", "ofn.dropdown", "admin.products", "infinite-scroll"]).config ($httpProvider) ->
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content")
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"

View File

@@ -22,6 +22,9 @@
//= require ./payment_methods/payment_methods
//= require ./products/products
//= require ./shipping_methods/shipping_methods
//= require ./utils/utils
//= require ./users/users
//= require textAngular.min.js
//= require textAngular-sanitize.min.js
//= require_tree .

View File

@@ -1,8 +1,17 @@
angular.module("admin.enterprises")
.controller "enterpriseCtrl", ($scope, Enterprise, PaymentMethods, ShippingMethods) ->
.controller "enterpriseCtrl", ($scope, longDescription, NavigationCheck, Enterprise, PaymentMethods, ShippingMethods) ->
$scope.Enterprise = Enterprise.enterprise
$scope.PaymentMethods = PaymentMethods.paymentMethods
$scope.ShippingMethods = ShippingMethods.shippingMethods
$scope.navClear = NavigationCheck.clear
# htmlVariable is used by textAngular wysiwyg for the long descrtiption.
$scope.htmlVariable = longDescription
# 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 .
$scope.enterpriseNavCallback = ->
"You are editing an enterprise!"
for payment_method in $scope.PaymentMethods
payment_method.selected = payment_method.id in $scope.Enterprise.payment_method_ids
@@ -32,4 +41,4 @@ angular.module("admin.enterprises")
$scope.ShippingMethods.reduce (count, shipping_method) ->
count++ if shipping_method.selected
count
, 0
, 0

View File

@@ -1 +1 @@
angular.module("admin.enterprises", ["admin.payment_methods", "admin.shipping_methods", "admin.users"])
angular.module("admin.enterprises", ["admin.payment_methods", "admin.utils", "admin.shipping_methods", "admin.users", "textAngular"])

View File

@@ -1,4 +1,5 @@
angular.module("admin.enterprises")
# Populate Enterprise.enterprise with enterprise json array from the page.
.factory 'Enterprise', (enterprise) ->
new class Enterprise
enterprise: enterprise
enterprise: enterprise

View File

@@ -0,0 +1,9 @@
angular.module("admin.utils").directive "navCheck", (NavigationCheck)->
restrict: 'A'
scope:
navCallback: '&'
link: (scope,element,attributes) ->
# Define navigationCallback on a controller in scope, otherwise this default will be used:
scope.navCallback ||= ->
"You will lose any unsaved work!"
NavigationCheck.register(scope.navCallback)

View File

@@ -0,0 +1,46 @@
angular.module("admin.utils")
.factory "NavigationCheck", ($window, $rootScope) ->
new class NavigationCheck
callbacks = []
constructor: ->
if $window.addEventListener
$window.addEventListener "beforeunload", @onBeforeUnloadHandler
else
$window.onbeforeunload = @onBeforeUnloadHandler
$rootScope.$on "$locationChangeStart", @locationChangeStartHandler
# Action for regular browser navigation.
onBeforeUnloadHandler: ($event) =>
message = @getMessage()
if message
($event or $window.event).preventDefault()
message
# Action for angular navigation.
locationChangeStartHandler: ($event) =>
message = @getMessage()
if message and not $window.confirm(message)
$event.stopPropagation() if $event.stopPropagation
$event.preventDefault() if $event.preventDefault
$event.cancelBubble = true
$event.returnValue = false
# Runs callback functions to retreive most recently added non-empty message.
getMessage: ->
message = null
message = callback() ? message for callback in callbacks
message
register: (callback) =>
callbacks.push callback
clear: =>
if $window.addEventListener
$window.removeEventListener "beforeunload", @onBeforeUnloadHandler
else
$window.onbeforeunload = null
$rootScope.$on "$locationChangeStart", null

View File

@@ -0,0 +1 @@
angular.module("admin.utils", [])

View File

@@ -15,6 +15,8 @@
#= require ../shared/bindonce.min.js
#= require ../shared/ng-infinite-scroll.min.js
#= require ../shared/angular-local-storage.js
#= require angularjs-file-upload
#= require angular-rails-templates
#= require_tree ../templates

View File

@@ -0,0 +1,13 @@
angular.module('Darkswarm').controller "EnterpriseImageCtrl", ($scope, EnterpriseImageService) ->
$scope.imageStep = 'logo'
$scope.imageSteps = ['logo', 'promo']
$scope.imageUploader = EnterpriseImageService.imageUploader
$scope.imageSelect = (image_step) ->
EnterpriseImageService.imageSrc = null
$scope.imageStep = image_step
$scope.imageSrc = ->
EnterpriseImageService.imageSrc

View File

@@ -1,11 +1,14 @@
Darkswarm.controller "HubsCtrl", ($scope, Hubs, Search, $document, $rootScope, HashNavigation, FilterSelectorsService) ->
$scope.Hubs = Hubs
$scope.hubs = Hubs.visible
Darkswarm.controller "EnterprisesCtrl", ($scope, Enterprises, Search, $document, $rootScope, HashNavigation, FilterSelectorsService, EnterpriseModal) ->
$scope.Enterprises = Enterprises
$scope.totalActive = FilterSelectorsService.totalActive
$scope.clearAll = FilterSelectorsService.clearAll
$scope.filterText = FilterSelectorsService.filterText
$scope.FilterSelectorsService = FilterSelectorsService
$scope.query = Search.search()
$scope.openModal = EnterpriseModal.open
$scope.activeTaxons = []
$scope.show_profiles = false
$scope.filtersActive = false
$scope.$watch "query", (query)->
Search.search query

View File

@@ -1,12 +0,0 @@
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

View File

@@ -3,7 +3,7 @@ Darkswarm.controller "RegistrationCtrl", ($scope, RegistrationService, Enterpris
$scope.enterprise = EnterpriseRegistrationService.enterprise
$scope.select = RegistrationService.select
$scope.steps = ['details','address','contact','about','images','social']
$scope.steps = ['details','contact','type','about','images','social']
$scope.countries = availableCountries

View File

@@ -12,4 +12,4 @@ Darkswarm.controller "RegistrationFormCtrl", ($scope, RegistrationService, Enter
EnterpriseRegistrationService.update(nextStep) if $scope.valid(form)
$scope.selectIfValid = (nextStep, form) ->
RegistrationService.select(nextStep) if $scope.valid(form)
RegistrationService.select(nextStep) if $scope.valid(form)

View File

@@ -1,3 +1,4 @@
Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub, Enterprises) ->
# Injecting Enterprises so CurrentHub.producers is dereferenced
Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub, Enterprises, EnterpriseModal) ->
# Injecting Enterprises so CurrentHub.producers is dereferenced.
# We should probably dereference here instead and separate out CurrentHub dereferencing from the Enterprise factory.
$scope.CurrentHub = CurrentHub

View File

@@ -1,18 +1,11 @@
Darkswarm.controller "TabsCtrl", ($scope, $rootScope, $location, OrderCycle) ->
# Return active if supplied path matches url hash path.
$scope.active = (path)->
if !OrderCycle.selected() and $location.hash() == "" and path == "about"
true
else
$location.hash() == path
$location.hash() == path
$scope.tabs = ["contact", "about", "groups", "producers"]
for tab in $scope.tabs
$scope[tab] =
path: tab
$scope.select = (tab)->
if $scope.active(tab.path)
# Toggle tab selected status by setting the url hash path.
$scope.select = (path)->
if $scope.active(path)
$location.hash ""
else
$location.hash tab.path
$location.hash path

View File

@@ -1,18 +1,19 @@
window.Darkswarm = angular.module("Darkswarm", ["ngResource",
'mm.foundation',
'angularLocalStorage',
'pasvaz.bindonce',
'infinite-scroll',
'angular-flash.service',
window.Darkswarm = angular.module("Darkswarm", ["ngResource",
'mm.foundation',
'angularLocalStorage',
'pasvaz.bindonce',
'infinite-scroll',
'angular-flash.service',
'templates',
'ngSanitize',
'ngAnimate',
'google-maps',
'duScroll',
'angularFileUpload',
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
# This allows us to trigger these two events on tooltips
@@ -20,4 +21,3 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
# We manually handle our scrolling
$anchorScrollProvider.disableAutoScrolling()

View File

@@ -1,4 +1,4 @@
Darkswarm.directive "producerModal", ($modal)->
Darkswarm.directive "enterpriseModal", ($modal)->
restrict: 'E'
replace: true
template: "<a ng-transclude></a>"
@@ -6,5 +6,4 @@ Darkswarm.directive "producerModal", ($modal)->
link: (scope, elem, attrs, ctrl)->
elem.on "click", (ev)=>
ev.stopPropagation()
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'producer_modal.html', scope: scope)
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'enterprise_modal.html', scope: scope)

View File

@@ -1,8 +0,0 @@
Darkswarm.directive "hubModal", ($modal)->
restrict: 'E'
replace: true
template: "<a>{{enterprise.name}}</a>"
link: (scope, elem, attrs, ctrl)->
elem.on "click", (ev)=>
ev.stopPropagation()
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'hub_modal.html', scope: scope)

View File

@@ -0,0 +1,7 @@
Darkswarm.directive "ofnInlineAlert", ->
restrict: 'A'
scope: true
link: (scope, elem, attrs) ->
scope.visible = true
scope.close = ->
scope.visible = false

View File

@@ -1,6 +0,0 @@
Darkswarm.directive "ofnInlineFlash", ->
restrict: 'E'
controller: ($scope) ->
$scope.visible = true
$scope.closeFlash = ->
$scope.visible = false

View File

@@ -0,0 +1,13 @@
Darkswarm.directive "ofnRegistrationLimitModal", (Navigation, $modal, Loading) ->
restrict: 'A'
link: (scope, elem, attr)->
scope.modalInstance = $modal.open
templateUrl: 'registration/limit_reached.html'
windowClass: "login-modal register-modal xlarge"
backdrop: 'static'
scope.modalInstance.result.then scope.close, scope.close
scope.close = ->
Loading.message = "Taking you back to the home page"
Navigation.go "/"

View File

@@ -1,4 +1,5 @@
Darkswarm.filter "capitalize", ->
# Convert to basic sentence case.
(input, scope) ->
input = input.toLowerCase() if input?
input = input.toLowerCase() if input?
input.substring(0, 1).toUpperCase() + input.substring(1)

View File

@@ -1,9 +0,0 @@
Darkswarm.filter 'hubs', (Matcher)->
(hubs, text) ->
hubs ||= []
text ?= ""
hubs.filter (hub)=>
Matcher.match [
hub.name, hub.address.zipcode, hub.address.city, hub.address.state
], text

View File

@@ -1,6 +0,0 @@
Darkswarm.filter 'filterProducers', (hubsFilter)->
(producers, text) ->
producers ||= []
text ?= ""
hubsFilter(producers, text)

View File

@@ -0,0 +1,15 @@
Darkswarm.filter "localizeCurrency", (currencyConfig)->
# Convert number to string currency using injected currency configuration.
(amount) ->
# Set country code (eg. "US").
currency_code = if currencyConfig.display_currency then " " + currencyConfig.currency else ""
# Set decimal points, 2 or 0 if hide_cents.
decimals = if currencyConfig.hide_cents == "true" then 0 else 2
# We need to use parseFloat before toFixed as the amount should come in as a string.
amount_fixed = parseFloat(amount).toFixed(decimals)
# Build the final price string. TODO use spree decimal point and spacer character settings.
if currencyConfig.symbol_position == 'before'
currencyConfig.symbol + amount_fixed + currency_code
else
amount_fixed + " " + currencyConfig.symbol + currency_code

View File

@@ -0,0 +1,10 @@
Darkswarm.filter 'searchEnterprises', (Matcher)->
# Search multiple fields of enterprises for matching text fragment.
(enterprises, text) ->
enterprises ||= []
text ?= ""
enterprises.filter (enterprise)=>
Matcher.match [
enterprise.name, enterprise.address.zipcode, enterprise.address.city, enterprise.address.state
], text

View File

@@ -0,0 +1,8 @@
Darkswarm.filter 'showHubProfiles', ()->
# Filter hub_profile enterprises in or out.
(enterprises, show_profiles) ->
enterprises ||= []
show_profiles ?= false
enterprises.filter (enterprise)=>
show_profiles or enterprise.is_distributor

View File

@@ -1,13 +1,16 @@
Darkswarm.filter 'taxons', (Matcher)->
# Filter anything that responds to object.taxons, and/or object.primary_taxon
Darkswarm.filter 'taxons', ()->
# Filter anything that responds to object.taxons, object.supplied_taxon or object.primary_taxon.
(objects, ids) ->
objects ||= []
ids ?= []
if ids.length == 0
# No taxons selected, pass all objects through.
objects
else
objects.filter (obj)->
taxons = obj.taxons
taxons.concat obj.supplied_taxons if obj.supplied_taxons
# Combine object taxons with supplied taxons, if they exist.
taxons = taxons.concat obj.supplied_taxons if obj.supplied_taxons
# Match primary taxon if it exists, then taxon array.
obj.primary_taxon?.id in ids || taxons.some (taxon)->
taxon.id in ids

View File

@@ -1,4 +1,4 @@
Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redirections)->
Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redirections, Loading)->
new class AuthenticationService
selectedPath: "/login"
@@ -25,4 +25,9 @@ Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redir
active: Navigation.active
close: ->
Navigation.navigate "/"
if location.pathname == "/"
Navigation.navigate "/"
else
Loading.message = "Taking you back to the home page"
location.hash = ""
location.pathname = "/"

View File

@@ -3,7 +3,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
new class Cart
dirty: false
order: CurrentOrder.order
line_items: CurrentOrder.order?.line_items || []
line_items: CurrentOrder.order?.line_items || []
constructor: ->
for line_item in @line_items
line_item.variant.line_item = line_item
@@ -22,13 +22,13 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
# TODO what shall we do here?
data: =>
variants = {}
variants = {}
for li in @line_items_present()
variants[li.variant.id] =
variants[li.variant.id] =
quantity: li.quantity
max_quantity: li.max_quantity
{variants: variants}
saved: =>
@dirty = false
@@ -48,15 +48,15 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
total: =>
@line_items_present().map (li)->
li.variant.getPrice()
li.variant.totalPrice()
.reduce (t, price)->
t + price
, 0
register_variant: (variant)=>
exists = @line_items.some (li)-> li.variant == variant
@create_line_item(variant) unless exists
@create_line_item(variant) unless exists
create_line_item: (variant)->
variant.line_item =
variant: variant

View File

@@ -1,3 +1,4 @@
Darkswarm.factory 'CurrentHub', ($location, $filter, currentHub) ->
Darkswarm.factory 'CurrentHub', (currentHub) ->
# Populate CurrentHub.hub from json in page. This is probably redundant now.
new class CurrentHub
hub: currentHub

View File

@@ -1,3 +1,4 @@
Darkswarm.factory 'CurrentOrder', (currentOrder) ->
# Populate Currentorder.order from json in page. This is probably redundant now.
new class CurrentOrder
order: currentOrder

View File

@@ -0,0 +1,12 @@
Darkswarm.factory "EnterpriseImageService", (FileUploader, spreeApiKey) ->
new class EnterpriseImageService
imageSrc: null
imageUploader: new FileUploader
headers:
'X-Spree-Token': spreeApiKey
autoUpload: true
configure: (enterprise) =>
@imageUploader.url = "/api/enterprises/#{enterprise.id}/update_image"
@imageUploader.onSuccessItem = (image, response) => @imageSrc = response

View File

@@ -0,0 +1,8 @@
Darkswarm.factory "EnterpriseModal", ($modal, $rootScope)->
# Build a modal popup for an enterprise.
new class EnterpriseModal
open: (enterprise)->
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
scope.enterprise = enterprise
$modal.open(templateUrl: "enterprise_modal.html", scope: scope)

View File

@@ -1,4 +1,4 @@
Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService, CurrentUser, spreeApiKey, Loading, availableCountries, enterpriseAttributes) ->
Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService, EnterpriseImageService, CurrentUser, spreeApiKey, Loading, availableCountries, enterpriseAttributes) ->
new class EnterpriseRegistrationService
enterprise:
user_ids: [CurrentUser.id]
@@ -22,6 +22,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
).success((data) =>
Loading.clear()
@enterprise.id = data
EnterpriseImageService.configure(@enterprise)
RegistrationService.select('about')
).error((data) =>
Loading.clear()
@@ -54,4 +55,4 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
enterprise[key] = value
enterprise.address_attributes = @enterprise.address if @enterprise.address?
enterprise.address_attributes.country_id = @enterprise.country.id if @enterprise.country?
enterprise
enterprise

View File

@@ -1,13 +1,21 @@
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer)->
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer, visibleFilter)->
new class Enterprises
enterprises_by_id: {} # id/object pairs for lookup
enterprises_by_id: {}
constructor: ->
# Populate Enterprises.enterprises from json in page.
@enterprises = enterprises
# Map enterprises to id/object pairs for lookup.
for enterprise in enterprises
@enterprises_by_id[enterprise.id] = enterprise
# Replace enterprise and taxons ids with actual objects.
@dereferenceEnterprises()
@dereferenceTaxons()
@visible_enterprises = visibleFilter @enterprises
@producers = @visible_enterprises.filter (enterprise)->
enterprise.category in ["producer_hub", "producer_shop", "producer"]
@hubs = @visible_enterprises.filter (enterprise)->
enterprise.category in ["hub", "hub_profile", "producer_hub", "producer_shop"]
dereferenceEnterprises: ->
if CurrentHub.hub?.id
CurrentHub.hub = @enterprises_by_id[CurrentHub.hub.id]
@@ -16,6 +24,7 @@ Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer)
Dereferencer.dereference enterprise.producers, @enterprises_by_id
dereferenceTaxons: ->
for enterprise in @enterprises
for enterprise in @enterprises
Dereferencer.dereference enterprise.taxons, Taxons.taxons_by_id
Dereferencer.dereference enterprise.supplied_taxons, Taxons.taxons_by_id

View File

@@ -1,9 +0,0 @@
Darkswarm.factory 'Hubs', ($filter, Enterprises, visibleFilter) ->
new class Hubs
constructor: ->
@hubs = @order Enterprises.enterprises.filter (hub)->
hub.is_distributor && hub.has_shopfront
@visible = visibleFilter @hubs
order: (hubs)->
$filter('orderBy')(hubs, ['-active', '+orders_close_at'])

View File

@@ -1,7 +1,7 @@
Darkswarm.factory "OfnMap", (Enterprises, MapModal, visibleFilter)->
Darkswarm.factory "OfnMap", (Enterprises, EnterpriseModal, visibleFilter)->
new class OfnMap
constructor: ->
@enterprises = (@extend(enterprise) for enterprise in visibleFilter(Enterprises.enterprises))
@enterprises = (@extend(enterprise) for enterprise in visibleFilter(Enterprises.enterprises))
# Adding methods to each enterprise
@@ -14,4 +14,4 @@ Darkswarm.factory "OfnMap", (Enterprises, MapModal, visibleFilter)->
icon: enterprise.icon
id: enterprise.id
reveal: =>
MapModal.open enterprise
EnterpriseModal.open enterprise

View File

@@ -1,12 +0,0 @@
Darkswarm.factory "MapModal", ($modal, $rootScope)->
new class MapModal
open: (enterprise)->
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
scope.enterprise = enterprise
if enterprise.is_distributor
scope.hub = enterprise
$modal.open(templateUrl: "hub_modal.html", scope: scope)
else
scope.producer = enterprise
$modal.open(templateUrl: "map_modal_producer.html", scope: scope)

View File

@@ -1,6 +1,7 @@
Darkswarm.factory "Matcher", ->
new class Matcher
match: (properties, text)->
properties.some (prop)->
prop ||= ""
prop.toLowerCase().indexOf(text.toLowerCase()) != -1
# Match text fragment in an array of strings.
new class Matcher
match: (properties, text)->
properties.some (prop)->
prop ||= ""
prop.toLowerCase().indexOf(text.toLowerCase()) != -1

View File

@@ -1,7 +0,0 @@
Darkswarm.factory 'Producers', (Enterprises, visibleFilter) ->
new class Producers
constructor: ->
@producers = Enterprises.enterprises.filter (enterprise)->
enterprise.is_primary_producer
@visible = visibleFilter @producers

View File

@@ -1,4 +1,4 @@
Darkswarm.factory "RegistrationService", (Navigation, $modal, Loading)->
angular.module('Darkswarm').factory "RegistrationService", (Navigation, $modal, Loading)->
new class RegistrationService
constructor: ->
@@ -20,4 +20,4 @@ Darkswarm.factory "RegistrationService", (Navigation, $modal, Loading)->
close: ->
Loading.message = "Taking you back to the home page"
Navigation.go "/"
Navigation.go "/"

View File

@@ -1,8 +1,10 @@
Darkswarm.factory "Taxons", (taxons)->
new class Taxons
taxons: taxons
# Populate Taxons.taxons from json in page.
taxons: taxons
taxons_by_id: {}
constructor: ->
# Map taxons to id/object pairs for lookup.
for taxon in @taxons
@taxons_by_id[taxon.id] = taxon

View File

@@ -5,7 +5,8 @@ Darkswarm.factory 'Variants', ->
@variants[variant.id] ||= @extend variant
extend: (variant)->
variant.getPrice = ->
variant.price * variant.line_item.quantity
variant.basePricePercentage = Math.round(variant.base_price / variant.price * 100)
# Add totalPrice method to calculate line item total. This should be on a line item!
variant.totalPrice = ->
variant.price_with_fees * variant.line_item.quantity
variant.basePricePercentage = Math.round(variant.price / variant.price_with_fees * 100)
variant

View File

@@ -1,18 +0,0 @@
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require spin
//= require foundation
//= require_tree .
//
// Hacky fix for issue - http://foundation.zurb.com/forum/posts/2112-foundation-5100-syntax-error-in-js
Foundation.set_namespace = function() {};
$(function(){ $(document).foundation(); });

View File

@@ -1,444 +0,0 @@
Gmaps = {}
Gmaps.triggerOldOnload = ->
Gmaps.oldOnload() if typeof(Gmaps.oldOnload) == 'function'
Gmaps.loadMaps = ->
#loop through all variable names.
#there should only be maps inside so it trigger their load function
for key, value of Gmaps
searchLoadIncluded = key.search(/load/)
if searchLoadIncluded == -1
load_function_name = "load_" + key
Gmaps[load_function_name]()
window.Gmaps = Gmaps
class @Gmaps4Rails
constructor: ->
#map config
@map = null #DEPRECATED: will still contain a copy of serviceObject below as transition
@serviceObject = null #contains the map we're working on
@visibleInfoWindow = null #contains the current opened infowindow
@userLocation = null #contains user's location if geolocalization was performed and successful
#empty slots
@geolocationSuccess = -> false #triggered when geolocation succeeds. Can be customized.
@geolocationFailure = -> false #triggered when geolocation fails. If customized, must be like= function(navigator_handles_geolocation){} where 'navigator_handles_geolocation' is a boolean
@callback = -> false #to let user set a custom callback function
@customClusterer = -> false #to let user set custom clusterer pictures
@infobox = -> false #to let user use custom infoboxes
@jsTemplate = false #to let user create infowindows client side
@default_map_options =
id: 'map'
draggable: true
detect_location: false # should the browser attempt to use geolocation detection features of HTML5?
center_on_user: false # centers map on the location detected through the browser
center_latitude: 0
center_longitude: 0
zoom: 7
maxZoom: null
minZoom: null
auto_adjust : true # adjust the map to the markers if set to true
auto_zoom: true # zoom given by auto-adjust
bounds: [] # adjust map to these limits. Should be [{"lat": , "lng": }]
raw: {} # raw json to pass additional options
@default_markers_conf =
#Marker config
title: ""
#MarkerImage config
picture : ""
width: 22
length: 32
draggable: false # how to modify: <%= gmaps( "markers" => { "data" => @object.to_gmaps4rails, "options" => { "draggable" => true }}) %>
#clustering config
do_clustering: false # do clustering if set to true
randomize: false # Google maps can't display two markers which have the same coordinates. This randomizer enables to prevent this situation from happening.
max_random_distance: 100 # in meters. Each marker coordinate could be altered by this distance in a random direction
list_container: null # id of the ul that will host links to all markers
offset: 0 # used when adding_markers to an existing map. Because new markers are concated with previous one, offset is here to prevent the existing from being re-created.
raw: {} # raw json to pass additional options
#Stored variables
@markers = [] # contains all markers. A marker contains the following: {"description": , "longitude": , "title":, "latitude":, "picture": "", "width": "", "length": "", "sidebar": "", "serviceObject": google_marker}
@boundsObject = null # contains current bounds from markers, polylines etc...
@polygons = [] # contains raw data, array of arrays (first element could be a hash containing options)
@polylines = [] # contains raw data, array of arrays (first element could be a hash containing options)
@circles = [] # contains raw data, array of hash
@markerClusterer = null # contains all marker clusterers
@markerImages = []
#Polyline Styling
@polylines_conf = #default style for polylines
strokeColor: "#FF0000"
strokeOpacity: 1
strokeWeight: 2
clickable: false
zIndex: null
#tnitializes the map
initialize : ->
@serviceObject = @createMap()
@map = @serviceObject #beware, soon deprecated
if (@map_options.detect_location == true or @map_options.center_on_user == true)
@findUserLocation(this)
#resets sidebar if needed
@resetSidebarContent()
findUserLocation : (map_object) ->
if (navigator.geolocation)
#try to retrieve user's position
positionSuccessful = (position) ->
map_object.userLocation = map_object.createLatLng(position.coords.latitude, position.coords.longitude)
#change map's center to focus on user's geoloc if asked
if(map_object.map_options.center_on_user == true)
map_object.centerMapOnUser()
map_object.geolocationSuccess()
positionFailure = ->
map_object.geolocationFailure(true)
navigator.geolocation.getCurrentPosition( positionSuccessful, positionFailure)
else
#failure but the navigator doesn't handle geolocation
map_object.geolocationFailure(false)
#////////////////////////////////////////////////////
#//////////////////// DIRECTIONS ////////////////////
#////////////////////////////////////////////////////
create_direction : ->
directionsDisplay = new google.maps.DirectionsRenderer()
directionsService = new google.maps.DirectionsService()
directionsDisplay.setMap(@serviceObject)
#display panel only if required
if @direction_conf.display_panel
directionsDisplay.setPanel(document.getElementById(@direction_conf.panel_id))
directionsDisplay.setOptions
suppressMarkers: false
suppressInfoWindows: false
suppressPolylines: false
request =
origin: @direction_conf.origin
destination: @direction_conf.destination
waypoints: @direction_conf.waypoints
optimizeWaypoints: @direction_conf.optimizeWaypoints
unitSystem: google.maps.DirectionsUnitSystem[@direction_conf.unitSystem]
avoidHighways: @direction_conf.avoidHighways
avoidTolls: @direction_conf.avoidTolls
region: @direction_conf.region
travelMode: google.maps.DirectionsTravelMode[@direction_conf.travelMode]
language: "en"
directionsService.route request, (response, status) ->
if (status == google.maps.DirectionsStatus.OK)
directionsDisplay.setDirections(response)
#////////////////////////////////////////////////////
#///////////////////// CIRCLES //////////////////////
#////////////////////////////////////////////////////
#Loops through all circles
#Loops through all circles and draws them
create_circles : ->
for circle in @circles
@create_circle circle
create_circle : (circle) ->
#by convention, default style configuration could be integrated in the first element
if circle == @circles[0]
@circles_conf.strokeColor = circle.strokeColor if circle.strokeColor?
@circles_conf.strokeOpacity = circle.strokeOpacity if circle.strokeOpacity?
@circles_conf.strokeWeight = circle.strokeWeight if circle.strokeWeight?
@circles_conf.fillColor = circle.fillColor if circle.fillColor?
@circles_conf.fillOpacity = circle.fillOpacity if circle.fillOpacity?
if circle.lat? and circle.lng?
# always check if a config is given, if not, use defaults
# NOTE: is there a cleaner way to do this? Maybe a hash merge of some sort?
newCircle = new google.maps.Circle
center: @createLatLng(circle.lat, circle.lng)
strokeColor: circle.strokeColor || @circles_conf.strokeColor
strokeOpacity: circle.strokeOpacity || @circles_conf.strokeOpacity
strokeWeight: circle.strokeWeight || @circles_conf.strokeWeight
fillOpacity: circle.fillOpacity || @circles_conf.fillOpacity
fillColor: circle.fillColor || @circles_conf.fillColor
clickable: circle.clickable || @circles_conf.clickable
zIndex: circle.zIndex || @circles_conf.zIndex
radius: circle.radius
circle.serviceObject = newCircle
newCircle.setMap(@serviceObject)
# clear circles
clear_circles : ->
for circle in @circles
@clear_circle circle
clear_circle : (circle) ->
circle.serviceObject.setMap(null)
hide_circles : ->
for circle in @circles
@hide_circle circle
hide_circle : (circle) ->
circle.serviceObject.setMap(null)
show_circles : ->
for circle in @circles
@show_circle @circle
show_circle : (circle) ->
circle.serviceObject.setMap(@serviceObject)
#////////////////////////////////////////////////////
#///////////////////// POLYGONS /////////////////////
#////////////////////////////////////////////////////
#polygons is an array of arrays. It loops.
create_polygons : ->
for polygon in @polygons
@create_polygon(polygon)
#creates a single polygon, triggered by create_polygons
create_polygon : (polygon) ->
polygon_coordinates = []
#Polygon points are in an Array, that's why looping is necessary
for point in polygon
latlng = @createLatLng(point.lat, point.lng)
polygon_coordinates.push(latlng)
#first element of an Array could contain specific configuration for this particular polygon. If no config given, use default
if point == polygon[0]
strokeColor = point.strokeColor || @polygons_conf.strokeColor
strokeOpacity = point.strokeOpacity || @polygons_conf.strokeOpacity
strokeWeight = point.strokeWeight || @polygons_conf.strokeWeight
fillColor = point.fillColor || @polygons_conf.fillColor
fillOpacity = point.fillOpacity || @polygons_conf.fillOpacity
clickable = point.clickable || @polygons_conf.clickable
#Construct the polygon
new_poly = new google.maps.Polygon
paths: polygon_coordinates
strokeColor: strokeColor
strokeOpacity: strokeOpacity
strokeWeight: strokeWeight
fillColor: fillColor
fillOpacity: fillOpacity
clickable: clickable
map: @serviceObject
#save polygon in list
polygon.serviceObject = new_poly
#////////////////////////////////////////////////////
#///////////////////// MARKERS //////////////////////
#////////////////////////////////////////////////////
#creates, clusterizes and adjusts map
create_markers : ->
@createServiceMarkersFromMarkers()
@clusterize()
#create google.maps Markers from data provided by user
createServiceMarkersFromMarkers : ->
for marker, index in @markers
if not @markers[index].serviceObject?
#extract options, test if value passed or use default
Lat = @markers[index].lat
Lng = @markers[index].lng
#alter coordinates if randomize is true
if @markers_conf.randomize
LatLng = @randomize(Lat, Lng)
#retrieve coordinates from the array
Lat = LatLng[0]
Lng = LatLng[1]
#save object
@markers[index].serviceObject = @createMarker
"marker_picture": if @markers[index].picture then @markers[index].picture else @markers_conf.picture
"marker_width": if @markers[index].width then @markers[index].width else @markers_conf.width
"marker_height": if @markers[index].height then @markers[index].height else @markers_conf.length
"marker_title": if @markers[index].title then @markers[index].title else null
"marker_anchor": if @markers[index].marker_anchor then @markers[index].marker_anchor else null
"shadow_anchor": if @markers[index].shadow_anchor then @markers[index].shadow_anchor else null
"shadow_picture": if @markers[index].shadow_picture then @markers[index].shadow_picture else null
"shadow_width": if @markers[index].shadow_width then @markers[index].shadow_width else null
"shadow_height": if @markers[index].shadow_height then @markers[index].shadow_height else null
"marker_draggable": if @markers[index].draggable then @markers[index].draggable else @markers_conf.draggable
"rich_marker": if @markers[index].rich_marker then @markers[index].rich_marker else null
"zindex": if @markers[index].zindex then @markers[index].zindex else null
"Lat": Lat
"Lng": Lng
"index": index
#add infowindowstuff if enabled
@createInfoWindow(@markers[index])
#create sidebar if enabled
@createSidebar(@markers[index])
@markers_conf.offset = @markers.length
#creates Image Anchor Position or return null if nothing passed
createImageAnchorPosition : (anchorLocation) ->
if (anchorLocation == null)
return null
else
return @createPoint(anchorLocation[0], anchorLocation[1])
#replace old markers with new markers on an existing map
replaceMarkers : (new_markers, adjustBounds = true) ->
@clearMarkers()
#reset previous markers
@markers = new Array
#reset current bounds
@boundsObject = @createLatLngBounds() if adjustBounds
#reset sidebar content if exists
@resetSidebarContent()
#add new markers
@markers_conf.offset = 0
@addMarkers(new_markers, adjustBounds)
#add new markers to on an existing map
addMarkers : (new_markers, adjustBounds = true) ->
#update the list of markers to take into account
@markers = @markers.concat(new_markers)
#put markers on the map
@create_markers()
@adjustMapToBounds() if adjustBounds
#////////////////////////////////////////////////////
#///////////////////// SIDEBAR //////////////////////
#////////////////////////////////////////////////////
#//creates sidebar
createSidebar : (marker_container) ->
if (@markers_conf.list_container)
ul = document.getElementById(@markers_conf.list_container)
li = document.createElement('li')
aSel = document.createElement('a')
aSel.href = 'javascript:void(0);'
html = if marker_container.sidebar? then marker_container.sidebar else "Marker"
aSel.innerHTML = html
currentMap = this
aSel.onclick = @sidebar_element_handler(currentMap, marker_container.serviceObject, 'click')
li.appendChild(aSel)
ul.appendChild(li)
#moves map to marker clicked + open infowindow
sidebar_element_handler : (currentMap, marker, eventType) ->
return () ->
currentMap.map.panTo(marker.position)
google.maps.event.trigger(marker, eventType)
resetSidebarContent : ->
if @markers_conf.list_container isnt null
ul = document.getElementById(@markers_conf.list_container)
ul.innerHTML = ""
#////////////////////////////////////////////////////
#////////////////// MISCELLANEOUS ///////////////////
#////////////////////////////////////////////////////
#to make the map fit the different LatLng points
adjustMapToBounds : ->
#FIRST_STEP: retrieve all bounds
#create the bounds object only if necessary
if @map_options.auto_adjust or @map_options.bounds isnt null
@boundsObject = @createLatLngBounds()
#if autodjust is true, must get bounds from markers polylines etc...
if @map_options.auto_adjust
#from markers
@extendBoundsWithMarkers()
#from polylines:
@updateBoundsWithPolylines()
#from polygons:
@updateBoundsWithPolygons()
#from circles
@updateBoundsWithCircles()
#in every case, I've to take into account the bounds set up by the user
@extendMapBounds()
#SECOND_STEP: ajust the map to the bounds
@adaptMapToBounds()
#////////////////////////////////////////////////////
#/////////////////// POLYLINES //////////////////////
#////////////////////////////////////////////////////
#replace old markers with new markers on an existing map
replacePolylines : (new_polylines) ->
#reset previous polylines and kill them from map
@destroy_polylines()
#set new polylines
@polylines = new_polylines
#create
@create_polylines()
#.... and adjust map boundaries
@adjustMapToBounds()
destroy_polylines : ->
for polyline in @polylines
#delete polylines from map
polyline.serviceObject.setMap(null)
#empty array
@polylines = []
#polylines is an array of arrays. It loops.
create_polylines : ->
for polyline in @polylines
@create_polyline polyline
#////////////////////////////////////////////////////
#///////////////// Basic functions //////////////////
#///////////////////tests coded//////////////////////
#//basic function to check existence of a variable
exists : (var_name) ->
return (var_name != "" and typeof var_name != "undefined")
#randomize
randomize : (Lat0, Lng0) ->
#distance in meters between 0 and max_random_distance (positive or negative)
dx = @markers_conf.max_random_distance * @random()
dy = @markers_conf.max_random_distance * @random()
Lat = parseFloat(Lat0) + (180/Math.PI)*(dy/6378137)
Lng = parseFloat(Lng0) + ( 90/Math.PI)*(dx/6378137)/Math.cos(Lat0)
return [Lat, Lng]
mergeObjectWithDefault : (object1, object2) ->
copy_object1 = {}
for key, value of object1
copy_object1[key] = value
for key, value of object2
unless copy_object1[key]?
copy_object1[key] = value
return copy_object1
mergeWithDefault : (objectName) ->
default_object = @["default_" + objectName]
object = @[objectName]
@[objectName] = @mergeObjectWithDefault(object, default_object)
return true
#gives a value between -1 and 1
random : -> return(Math.random() * 2 -1)

View File

@@ -1,174 +0,0 @@
######################################################################################################
############################################## Bing Maps ##########################################
######################################################################################################
#// http://wiki.openstreetmap.org/wiki/OpenLayers
#// http://openlayers.org/dev/examples
#//http://docs.openlayers.org/contents.html
class @Gmaps4RailsBing extends Gmaps4Rails
constructor: ->
super
@map_options =
type: "road" # aerial, auto, birdseye, collinsBart, mercator, ordnanceSurvey, road
@markers_conf =
infobox: "description" #description or htmlContent
@mergeWithDefault("map_options")
@mergeWithDefault("markers_conf")
#////////////////////////////////////////////////////
#/////////////// Basic Objects //////////////
#////////////////////////////////////////////////////
getMapType: ->
switch @map_options.type
when "road" then return Microsoft.Maps.MapTypeId.road
when "aerial" then return Microsoft.Maps.MapTypeId.aerial
when "auto" then return Microsoft.Maps.MapTypeId.auto
when "birdseye" then return Microsoft.Maps.MapTypeId.birdseye
when "collinsBart" then return Microsoft.Maps.MapTypeId.collinsBart
when "mercator" then return Microsoft.Maps.MapTypeId.mercator
when "ordnanceSurvey" then return Microsoft.Maps.MapTypeId.ordnanceSurvey
else return Microsoft.Maps.MapTypeId.auto
createPoint: (lat, lng) ->
return new Microsoft.Maps.Point(lat, lng)
createLatLng:(lat, lng) ->
return new Microsoft.Maps.Location(lat, lng)
createLatLngBounds: ->
createMap: ->
return new Microsoft.Maps.Map(document.getElementById(@map_options.id), {
credentials: @map_options.provider_key,
mapTypeId: @getMapType(),
center: @createLatLng(@map_options.center_latitude, @map_options.center_longitude),
zoom: @map_options.zoom
})
createSize: (width, height) ->
return new google.maps.Size(width, height)
#////////////////////////////////////////////////////
#////////////////////// Markers /////////////////////
#////////////////////////////////////////////////////
createMarker: (args) ->
markerLatLng = @createLatLng(args.Lat, args.Lng)
marker
#// Marker sizes are expressed as a Size of X,Y
if args.marker_picture == ""
marker = new Microsoft.Maps.Pushpin(@createLatLng(args.Lat, args.Lng), {
draggable: args.marker_draggable,
anchor: @createImageAnchorPosition(args.Lat, args.Lng),
text: args.marker_title
}
);
else
marker = new Microsoft.Maps.Pushpin(@createLatLng(args.Lat, args.Lng), {
draggable: args.marker_draggable,
anchor: @createImageAnchorPosition(args.Lat, args.Lng),
icon: args.marker_picture,
height: args.marker_height,
text: args.marker_title,
width: args.marker_width
}
);
@addToMap(marker)
return marker
#// clear markers
clearMarkers: ->
for marker in @markers
@clearMarker marker
clearMarker: (marker) ->
@removeFromMap(marker.serviceObject)
#//show and hide markers
showMarkers: ->
for marker in @markers
@showMarker marker
showMarker: (marker) ->
marker.serviceObject.setOptions({ visible: true })
hideMarkers: ->
for marker in @markers
@hideMarker marker
hideMarker: (marker) ->
marker.serviceObject.setOptions({ visible: false })
extendBoundsWithMarkers: ->
locationsArray = []
for marker in @markers
locationsArray.push(marker.serviceObject.getLocation())
@boundsObject = Microsoft.Maps.LocationRect.fromLocations(locationsArray)
#////////////////////////////////////////////////////
#/////////////////// Clusterer //////////////////////
#////////////////////////////////////////////////////
createClusterer: (markers_array) ->
clearClusterer: ->
#//creates clusters
clusterize: ->
#////////////////////////////////////////////////////
#/////////////////// INFO WINDOW ////////////////////
#////////////////////////////////////////////////////
#// creates infowindows
createInfoWindow: (marker_container) ->
if marker_container.description?
#//create the infowindow
if @markers_conf.infobox == "description"
marker_container.info_window = new Microsoft.Maps.Infobox(marker_container.serviceObject.getLocation(), { description: marker_container.description, visible: false, showCloseButton: true})
else
marker_container.info_window = new Microsoft.Maps.Infobox(marker_container.serviceObject.getLocation(), { htmlContent: marker_container.description, visible: false})
#//add the listener associated
currentMap = this
Microsoft.Maps.Events.addHandler(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.info_window))
@addToMap(marker_container.info_window)
openInfoWindow: (currentMap, infoWindow) ->
return ->
# Close the latest selected marker before opening the current one.
if currentMap.visibleInfoWindow
currentMap.visibleInfoWindow.setOptions({ visible: false })
infoWindow.setOptions({ visible:true })
currentMap.visibleInfoWindow = infoWindow
#////////////////////////////////////////////////////
#/////////////////// Other methods //////////////////
#////////////////////////////////////////////////////
fitBounds: ->
@serviceObject.setView({bounds: @boundsObject})
addToMap: (object)->
@serviceObject.entities.push(object)
removeFromMap: (object)->
@serviceObject.entities.remove(object)
centerMapOnUser: ->
@serviceObject.setView({ center: @userLocation})
updateBoundsWithPolylines: ()->
updateBoundsWithPolygons: ()->
updateBoundsWithCircles: ()->
extendMapBounds :->
adaptMapToBounds: ->
@fitBounds()

View File

@@ -1,339 +0,0 @@
#######################################################################################################
############################################## Google maps ##########################################
#######################################################################################################
class @Gmaps4RailsGoogle extends Gmaps4Rails
constructor: ->
super
#Map settings
@map_options =
disableDefaultUI: false
disableDoubleClickZoom: false
type: "ROADMAP" # HYBRID, ROADMAP, SATELLITE, TERRAIN
#markers + info styling
@markers_conf =
clusterer_gridSize: 50
clusterer_maxZoom: 5
custom_cluster_pictures: null
custom_infowindow_class: null
@mergeWithDefault("map_options")
@mergeWithDefault("markers_conf")
@kml_options =
clickable: true
preserveViewport: false
suppressInfoWindows: false
#Polygon Styling
@polygons_conf = # default style for polygons
strokeColor: "#FFAA00"
strokeOpacity: 0.8
strokeWeight: 2
fillColor: "#000000"
fillOpacity: 0.35
clickable: false
#Circle Styling
@circles_conf = #default style for circles
fillColor: "#00AAFF"
fillOpacity: 0.35
strokeColor: "#FFAA00"
strokeOpacity: 0.8
strokeWeight: 2
clickable: false
zIndex: null
#Direction Settings
@direction_conf =
panel_id: null
display_panel: false
origin: null
destination: null
waypoints: [] #[{location: "toulouse,fr", stopover: true}, {location: "Clermont-Ferrand, fr", stopover: true}]
optimizeWaypoints: false
unitSystem: "METRIC" #IMPERIAL
avoidHighways: false
avoidTolls: false
region: null
travelMode: "DRIVING" #WALKING, BICYCLING
#////////////////////////////////////////////////////
#/////////////// Basic Objects //////////////
#////////////////////////////////////////////////////
createPoint : (lat, lng) ->
return new google.maps.Point(lat, lng)
createLatLng : (lat, lng) ->
return new google.maps.LatLng(lat, lng)
createLatLngBounds : ->
return new google.maps.LatLngBounds()
createMap : ->
defaultOptions =
maxZoom: @map_options.maxZoom
minZoom: @map_options.minZoom
zoom: @map_options.zoom
center: @createLatLng(@map_options.center_latitude, @map_options.center_longitude)
mapTypeId: google.maps.MapTypeId[@map_options.type]
mapTypeControl: @map_options.mapTypeControl
disableDefaultUI: @map_options.disableDefaultUI
disableDoubleClickZoom: @map_options.disableDoubleClickZoom
draggable: @map_options.draggable
mergedOptions = @mergeObjectWithDefault @map_options.raw, defaultOptions
return new google.maps.Map document.getElementById(@map_options.id), mergedOptions
createMarkerImage : (markerPicture, markerSize, origin, anchor, scaledSize) ->
return new google.maps.MarkerImage(markerPicture, markerSize, origin, anchor, scaledSize)
createSize : (width, height) ->
return new google.maps.Size(width, height)
#////////////////////////////////////////////////////
#////////////////////// Markers /////////////////////
#////////////////////////////////////////////////////
createMarker : (args) ->
markerLatLng = @createLatLng(args.Lat, args.Lng)
#Marker sizes are expressed as a Size of X,Y
if args.marker_picture == "" and args.rich_marker == null
defaultOptions = {position: markerLatLng, map: @serviceObject, title: args.marker_title, draggable: args.marker_draggable, zIndex: args.zindex}
mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions
return new google.maps.Marker mergedOptions
if (args.rich_marker != null)
return new RichMarker({
position: markerLatLng
map: @serviceObject
draggable: args.marker_draggable
content: args.rich_marker
flat: if args.marker_anchor == null then false else args.marker_anchor[1]
anchor: if args.marker_anchor == null then 0 else args.marker_anchor[0]
zIndex: args.zindex
})
#default behavior
#calculate MarkerImage anchor location
imageAnchorPosition = @createImageAnchorPosition args.marker_anchor
shadowAnchorPosition = @createImageAnchorPosition args.shadow_anchor
#create or retrieve existing MarkerImages
markerImage = @createOrRetrieveImage(args.marker_picture, args.marker_width, args.marker_height, imageAnchorPosition)
shadowImage = @createOrRetrieveImage(args.shadow_picture, args.shadow_width, args.shadow_height, shadowAnchorPosition)
defaultOptions = {position: markerLatLng, map: @serviceObject, icon: markerImage, title: args.marker_title, draggable: args.marker_draggable, shadow: shadowImage, zIndex: args.zindex}
mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions
return new google.maps.Marker mergedOptions
#checks if obj is included in arr Array and returns the position or false
includeMarkerImage : (arr, obj) ->
for object, index in arr
return index if object.url == obj
return false
#checks if MarkerImage exists before creating a new one
#returns a MarkerImage or false if ever something wrong is passed as argument
createOrRetrieveImage : (currentMarkerPicture, markerWidth, markerHeight, imageAnchorPosition) ->
return null if (currentMarkerPicture == "" or currentMarkerPicture == null )
test_image_index = @includeMarkerImage(@markerImages, currentMarkerPicture)
switch test_image_index
when false
markerImage = @createMarkerImage(currentMarkerPicture, @createSize(markerWidth, markerHeight), null, imageAnchorPosition, null )
@markerImages.push(markerImage)
return markerImage
break
else
return @markerImages[test_image_index] if typeof test_image_index == 'number'
return false
#clear markers
clearMarkers : ->
for marker in @markers
@clearMarker marker
#show and hide markers
showMarkers : ->
for marker in @markers
@showMarker marker
hideMarkers : ->
for marker in @markers
@hideMarker marker
clearMarker : (marker) ->
marker.serviceObject.setMap(null)
showMarker : (marker) ->
marker.serviceObject.setVisible(true)
hideMarker : (marker) ->
marker.serviceObject.setVisible(false)
extendBoundsWithMarkers : ->
for marker in @markers
@boundsObject.extend(marker.serviceObject.position)
#////////////////////////////////////////////////////
#/////////////////// Clusterer //////////////////////
#////////////////////////////////////////////////////
createClusterer : (markers_array) ->
return new MarkerClusterer( @serviceObject, markers_array, { maxZoom: @markers_conf.clusterer_maxZoom, gridSize: @markers_conf.clusterer_gridSize, styles: @customClusterer() })
clearClusterer : ->
@markerClusterer.clearMarkers()
#creates clusters
clusterize : ->
if @markers_conf.do_clustering == true
#first clear the existing clusterer if any
@clearClusterer() if @markerClusterer != null
markers_array = new Array
for marker in @markers
markers_array.push(marker.serviceObject)
@markerClusterer = @createClusterer(markers_array)
#////////////////////////////////////////////////////
#/////////////////// INFO WINDOW ////////////////////
#////////////////////////////////////////////////////
#// creates infowindows
createInfoWindow : (marker_container) ->
if typeof(@jsTemplate) == "function" or marker_container.description?
marker_container.description = @jsTemplate(marker_container) if typeof(@jsTemplate) == "function"
if @markers_conf.custom_infowindow_class != null
#creating custom infowindow
boxText = document.createElement("div")
boxText.setAttribute("class", @markers_conf.custom_infowindow_class) #to customize
boxText.innerHTML = marker_container.description
marker_container.infowindow = new InfoBox(@infobox(boxText))
currentMap = this
google.maps.event.addListener(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.infowindow, marker_container.serviceObject))
else
#create default infowindow
marker_container.infowindow = new google.maps.InfoWindow({content: marker_container.description })
#add the listener associated
currentMap = this
google.maps.event.addListener(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.infowindow, marker_container.serviceObject))
openInfoWindow : (currentMap, infoWindow, marker) ->
return ->
# Close the latest selected marker before opening the current one.
currentMap.visibleInfoWindow.close() if currentMap.visibleInfoWindow != null
infoWindow.open(currentMap.serviceObject, marker)
currentMap.visibleInfoWindow = infoWindow
#////////////////////////////////////////////////////
#///////////////// KML //////////////////
#////////////////////////////////////////////////////
createKmlLayer : (kml) ->
kml_options = kml.options || {}
kml_options = @mergeObjectWithDefault(kml_options, @kml_options)
kml = new google.maps.KmlLayer( kml.url, kml_options)
kml.setMap(@serviceObject)
return kml
#////////////////////////////////////////////////////
#/////////////////// POLYLINES //////////////////////
#////////////////////////////////////////////////////
#creates a single polyline, triggered by create_polylines
create_polyline : (polyline) ->
polyline_coordinates = []
#2 cases here, either we have a coded array of LatLng or we have an Array of LatLng
for element in polyline
#if we have a coded array
if element.coded_array?
decoded_array = new google.maps.geometry.encoding.decodePath(element.coded_array)
#loop through every point in the array
for point in decoded_array
polyline_coordinates.push(point)
#or we have an array of latlng
else
#by convention, a single polyline could be customized in the first array or it uses default values
if element == polyline[0]
strokeColor = element.strokeColor || @polylines_conf.strokeColor
strokeOpacity = element.strokeOpacity || @polylines_conf.strokeOpacity
strokeWeight = element.strokeWeight || @polylines_conf.strokeWeight
clickable = element.clickable || @polylines_conf.clickable
zIndex = element.zIndex || @polylines_conf.zIndex
#add latlng if positions provided
if element.lat? && element.lng?
latlng = @createLatLng(element.lat, element.lng)
polyline_coordinates.push(latlng)
# Construct the polyline
new_poly = new google.maps.Polyline
path: polyline_coordinates
strokeColor: strokeColor
strokeOpacity: strokeOpacity
strokeWeight: strokeWeight
clickable: clickable
zIndex: zIndex
#save polyline
polyline.serviceObject = new_poly
new_poly.setMap(@serviceObject)
updateBoundsWithPolylines: ()->
for polyline in @polylines
polyline_points = polyline.serviceObject.latLngs.getArray()[0].getArray()
for point in polyline_points
@boundsObject.extend point
#////////////////////////////////////////////////////
#///////////////// KML //////////////////
#////////////////////////////////////////////////////
create_kml : ->
for kml in @kml
kml.serviceObject = @createKmlLayer kml
#////////////////////////////////////////////////////
#/////////////////// Other methods //////////////////
#////////////////////////////////////////////////////
fitBounds : ->
@serviceObject.fitBounds(@boundsObject) unless @boundsObject.isEmpty()
centerMapOnUser : ->
@serviceObject.setCenter(@userLocation)
updateBoundsWithPolygons: ()->
for polygon in @polygons
polygon_points = polygon.serviceObject.latLngs.getArray()[0].getArray()
for point in polygon_points
@boundsObject.extend point
updateBoundsWithCircles: ()->
for circle in @circles
@boundsObject.extend(circle.serviceObject.getBounds().getNorthEast())
@boundsObject.extend(circle.serviceObject.getBounds().getSouthWest())
extendMapBounds: ()->
for bound in @map_options.bounds
#create points from bounds provided
@boundsObject.extend @createLatLng(bound.lat, bound.lng)
adaptMapToBounds:()->
#if autozoom is false, take user info into account
if !@map_options.auto_zoom
map_center = @boundsObject.getCenter()
@map_options.center_latitude = map_center.lat()
@map_options.center_longitude = map_center.lng()
@serviceObject.setCenter(map_center)
else
@fitBounds()

View File

@@ -1,145 +0,0 @@
#######################################################################################################
############################################## Map Quest #############################################
#######################################################################################################
# http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/api/MQA.Poi.html
class @Gmaps4RailsMapquest extends Gmaps4Rails
constructor: ->
super
#Map settings
@map_options = {type: "map"} #map type (map, sat, hyb)
@markers_conf = {}
@mergeWithDefault "markers_conf"
@mergeWithDefault "map_options"
#////////////////////////////////////////////////////
#/////////////// Basic Objects //////////////
#////////////////////////////////////////////////////
createPoint: (lat, lng) ->
return new MQA.Poi({lat: lat, lng: lng})
createLatLng: (lat, lng) ->
return {lat: lat, lng: lng}
createLatLngBounds: ->
createMap: ->
map = new MQA.TileMap( #// Constructs an instance of MQA.TileMap
document.getElementById(@map_options.id), #//the id of the element on the page you want the map to be added into
@map_options.zoom, #//intial zoom level of the map
{lat: @map_options.center_latitude, lng: @map_options.center_longitude},
@map_options.type) #//map type (map, sat, hyb)
MQA.withModule('zoomcontrol3', (->
map.addControl(
new MQA.LargeZoomControl3(),
new MQA.MapCornerPlacement(MQA.MapCorner.TOP_LEFT)
)
))
return map
createMarkerImage: (markerPicture, markerSize, origin, anchor, scaledSize) ->
#////////////////////////////////////////////////////
#////////////////////// Markers /////////////////////
#////////////////////////////////////////////////////
createMarker: (args)->
marker = new MQA.Poi( {lat: args.Lat, lng: args.Lng} )
if args.marker_picture != ""
icon = new MQA.Icon(args.marker_picture, args.marker_height, args.marker_width)
marker.setIcon(icon)
if args.marker_anchor != null
marker.setBias({x: args.marker_anchor[0], y: args.marker_anchor[1]})
if args.shadow_picture != ""
icon = new MQA.Icon(args.shadow_picture, args.shadow_height, args.shadow_width)
marker.setShadow(icon)
if args.shadow_anchor != null
marker.setShadowOffset({x: args.shadow_anchor[0], y: args.shadow_anchor[1]})
@addToMap marker
return marker
#// clear markers
clearMarkers: ->
for marker in markers
@clearMarker marker
#//show and hide markers
showMarkers: ->
for marker in markers
@showMarker marker
hideMarkers: ->
for marker in markers
@hideMarker marker
clearMarker: (marker) ->
@removeFromMap(marker.serviceObject)
showMarker: (marker) ->
#// marker.serviceObject
hideMarker: (marker) ->
#// marker.serviceObject
extendBoundsWithMarkers: ->
if @markers.length >=2
@boundsObject = new MQA.RectLL(@markers[0].serviceObject.latLng, @markers[1].serviceObject.latLng)
for marker in @markers
@boundsObject.extend marker.serviceObject.latLng
#////////////////////////////////////////////////////
#/////////////////// Clusterer //////////////////////
#////////////////////////////////////////////////////
createClusterer: (markers_array) ->
clearClusterer: ->
#//creates clusters
clusterize: ->
#////////////////////////////////////////////////////
#/////////////////// INFO WINDOW ////////////////////
#////////////////////////////////////////////////////
#// creates infowindows
createInfoWindow: (marker_container) ->
marker_container.serviceObject.setInfoTitleHTML(marker_container.description)
#//TODO: how to disable the mouseover display when using setInfoContentHTML?
#//marker_container.serviceObject.setInfoContentHTML(marker_container.description);
#////////////////////////////////////////////////////
#/////////////////// Other methods //////////////////
#////////////////////////////////////////////////////
fitBounds: ->
@serviceObject.zoomToRect @boundsObject if @markers.length >=2
@serviceObject.setCenter @markers[0].serviceObject.latLng if @markers.length == 1
centerMapOnUser: ->
@serviceObject.setCenter @userLocation
addToMap: (object) ->
@serviceObject.addShape object
removeFromMap: (object)->
@serviceObject.removeShape object
updateBoundsWithPolylines: ()->
updateBoundsWithPolygons: ()->
updateBoundsWithCircles: ()->
extendMapBounds :->
adaptMapToBounds: ->
@fitBounds()

View File

@@ -1,261 +0,0 @@
#######################################################################################################
############################################## Open Layers ##########################################
#######################################################################################################
#// http://wiki.openstreetmap.org/wiki/OpenLayers
#// http://openlayers.org/dev/examples
#//http://docs.openlayers.org/contents.html
class @Gmaps4RailsOpenlayers extends Gmaps4Rails
constructor: ->
super
@map_options = {}
@mergeWithDefault "map_options"
@markers_conf = {}
@mergeWithDefault "markers_conf"
@openMarkers = null
@markersLayer = null
@markersControl = null
@polylinesLayer = null
#////////////////////////////////////////////////////
#/////////////// Basic Objects ////////////////////
#////////////////////////////////////////////////////
createPoint: (lat, lng)->
createLatLng: (lat, lng)->
return new OpenLayers.LonLat(lng, lat).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")) # transform from WGS 1984 to Spherical Mercator Projection
createAnchor: (offset)->
return null if offset == null
return new OpenLayers.Pixel(offset[0], offset[1])
createSize: (width, height)->
return new OpenLayers.Size(width, height)
createLatLngBounds: ->
return new OpenLayers.Bounds()
createMap: ->
#//todo add customization: kind of map and other map options
map = new OpenLayers.Map(@map_options.id)
map.addLayer(new OpenLayers.Layer.OSM())
map.setCenter(@createLatLng(@map_options.center_latitude, @map_options.center_longitude), #// Center of the map
@map_options.zoom) #// Zoom level
return map
#////////////////////////////////////////////////////
#////////////////////// Markers /////////////////////
#////////////////////////////////////////////////////
#//http://openlayers.org/dev/examples/marker-shadow.html
createMarker: (args) ->
style_mark = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default'])
style_mark.fillOpacity = 1
#//creating markers' dedicated layer
if (@markersLayer == null)
@markersLayer = new OpenLayers.Layer.Vector("Markers", null)
@serviceObject.addLayer(@markersLayer)
#//TODO move?
@markersLayer.events.register("featureselected", @markersLayer, @onFeatureSelect)
@markersLayer.events.register("featureunselected", @markersLayer, @onFeatureUnselect)
@markersControl = new OpenLayers.Control.SelectFeature(@markersLayer)
@serviceObject.addControl(@markersControl)
@markersControl.activate()
#//showing default pic if none available
if args.marker_picture == ""
#style_mark.graphicWidth = 24
style_mark.graphicHeight = 30
style_mark.externalGraphic = "http://openlayers.org/dev/img/marker-blue.png"
#//creating custom pic
else
style_mark.graphicWidth = args.marker_width
style_mark.graphicHeight = args.marker_height
style_mark.externalGraphic = args.marker_picture
#//adding anchor if any
if args.marker_anchor != null
style_mark.graphicXOffset = args.marker_anchor[0]
style_mark.graphicYOffset = args.marker_anchor[1]
#//adding shadow if any
if args.shadow_picture != ""
style_mark.backgroundGraphic = args.shadow_picture
style_mark.backgroundWidth = args.shadow_width
style_mark.backgroundHeight = args.shadow_height
#//adding shadow's anchor if any
if args.shadow_anchor != null
style_mark.backgroundXOffset = args.shadow_anchor[0]
style_mark.backgroundYOffset = args.shadow_anchor[1]
style_mark.graphicTitle = args.marker_title
marker = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(args.Lng, args.Lat),
null,
style_mark)
#//changing coordinates so that it actually appears on the map!
marker.geometry.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"))
#//adding layer to the map
@markersLayer.addFeatures([marker])
return marker
#//clear markers
clearMarkers: ->
@clearMarkersLayerIfExists()
@markersLayer = null
@boundsObject = new OpenLayers.Bounds()
clearMarkersLayerIfExists: ->
@serviceObject.removeLayer(@markersLayer) if @markersLayer != null and @serviceObject.getLayer(@markersLayer.id) != null
extendBoundsWithMarkers: ->
console.log "here"
for marker in @markers
@boundsObject.extend(@createLatLng(marker.lat,marker.lng))
#////////////////////////////////////////////////////
#/////////////////// Clusterer //////////////////////
#////////////////////////////////////////////////////
#//too ugly to be considered valid :(
createClusterer: (markers_array)->
options =
pointRadius: "${radius}"
fillColor: "#ffcc66"
fillOpacity: 0.8
strokeColor: "#cc6633"
strokeWidth: "${width}"
strokeOpacity: 0.8
funcs =
context:
width: (feature) ->
return (feature.cluster) ? 2 : 1
radius: (feature) ->
pix = 2
pix = Math.min(feature.attributes.count, 7) + 2 if feature.cluster
return pix
style = new OpenLayers.Style options, funcs
strategy = new OpenLayers.Strategy.Cluster()
clusters = new OpenLayers.Layer.Vector "Clusters",
strategies: [strategy]
styleMap: new OpenLayers.StyleMap
"default": style
"select":
fillColor: "#8aeeef"
strokeColor: "#32a8a9"
@clearMarkersLayerIfExists()
@serviceObject.addLayer(clusters)
clusters.addFeatures(markers_array)
return clusters
clusterize: ->
if @markers_conf.do_clustering == true
#//first clear the existing clusterer if any
if @markerClusterer != null
@clearClusterer()
markers_array = new Array
for marker in @markers
markers_array.push(marker.serviceObject)
@markerClusterer = @createClusterer markers_array
clearClusterer: ->
@serviceObject.removeLayer @markerClusterer
#////////////////////////////////////////////////////
#/////////////////// INFO WINDOW ////////////////////
#////////////////////////////////////////////////////
#// creates infowindows
createInfoWindow: (marker_container) ->
marker_container.serviceObject.infoWindow = marker_container.description if marker_container.description?
onPopupClose: (evt) ->
#// 'this' is the popup.
@markersControl.unselect @feature
onFeatureSelect: (evt) ->
feature = evt.feature
popup = new OpenLayers.Popup.FramedCloud("featurePopup",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(300,200),
feature.infoWindow,
null, true, @onPopupClose)
feature.popup = popup
popup.feature = feature
@map.addPopup popup
onFeatureUnselect: (evt) ->
feature = evt.feature
if feature.popup
#//popup.feature = null;
@map.removePopup feature.popup
feature.popup.destroy()
feature.popup = null
#////////////////////////////////////////////////////
#/////////////////// POLYLINES //////////////////////
#////////////////////////////////////////////////////
create_polyline : (polyline) ->
if(@polylinesLayer == null)
@polylinesLayer = new OpenLayers.Layer.Vector("Polylines", null)
@serviceObject.addLayer(@polylinesLayer)
@polylinesLayer.events.register("featureselected", @polylinesLayer, @onFeatureSelect)
@polylinesLayer.events.register("featureunselected", @polylinesLayer, @onFeatureUnselect)
@polylinesControl = new OpenLayers.Control.DrawFeature(@polylinesLayer, OpenLayers.Handler.Path)
@serviceObject.addControl(@polylinesControl)
polyline_coordinates = []
for element in polyline
#by convention, a single polyline could be customized in the first array or it uses default values
if element == polyline[0]
strokeColor = element.strokeColor || @polylines_conf.strokeColor
strokeOpacity = element.strokeOpacity || @polylines_conf.strokeOpacity
strokeWeight = element.strokeWeight || @polylines_conf.strokeWeight
clickable = element.clickable || @polylines_conf.clickable
zIndex = element.zIndex || @polylines_conf.zIndex
#add latlng if positions provided
if element.lat? && element.lng?
latlng = new OpenLayers.Geometry.Point(element.lng, element.lat)
polyline_coordinates.push(latlng)
line_points = new OpenLayers.Geometry.LineString(polyline_coordinates);
line_style = { strokeColor: strokeColor, strokeOpacity: strokeOpacity, strokeWidth: strokeWeight };
polyline = new OpenLayers.Feature.Vector(line_points, null, line_style);
polyline.geometry.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"))
@polylinesLayer.addFeatures([polyline])
return polyline
updateBoundsWithPolylines: ()->
updateBoundsWithPolygons: ()->
updateBoundsWithCircles: ()->
# #////////////////////////////////////////////////////
# #/////////////////// Other methods //////////////////
# #////////////////////////////////////////////////////
fitBounds: ->
@serviceObject.zoomToExtent(@boundsObject, true)
centerMapOnUser: ->
@serviceObject.setCenter @userLocation
extendMapBounds :->
adaptMapToBounds: ->
@fitBounds()

View File

@@ -1,4 +0,0 @@
/*! Backstretch - v2.0.4 - 2013-06-19
* http://srobbin.com/jquery-plugins/backstretch/
* Copyright (c) 2013 Scott Robbin; Licensed MIT */
(function(a,d,p){a.fn.backstretch=function(c,b){(c===p||0===c.length)&&a.error("No images were supplied for Backstretch");0===a(d).scrollTop()&&d.scrollTo(0,0);return this.each(function(){var d=a(this),g=d.data("backstretch");if(g){if("string"==typeof c&&"function"==typeof g[c]){g[c](b);return}b=a.extend(g.options,b);g.destroy(!0)}g=new q(this,c,b);d.data("backstretch",g)})};a.backstretch=function(c,b){return a("body").backstretch(c,b).data("backstretch")};a.expr[":"].backstretch=function(c){return a(c).data("backstretch")!==p};a.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5E3,fade:0};var r={left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},s={position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"auto",maxHeight:"none",maxWidth:"none",zIndex:-999999},q=function(c,b,e){this.options=a.extend({},a.fn.backstretch.defaults,e||{});this.images=a.isArray(b)?b:[b];a.each(this.images,function(){a("<img />")[0].src=this});this.isBody=c===document.body;this.$container=a(c);this.$root=this.isBody?l?a(d):a(document):this.$container;c=this.$container.children(".backstretch").first();this.$wrap=c.length?c:a('<div class="backstretch"></div>').css(r).appendTo(this.$container);this.isBody||(c=this.$container.css("position"),b=this.$container.css("zIndex"),this.$container.css({position:"static"===c?"relative":c,zIndex:"auto"===b?0:b,background:"none"}),this.$wrap.css({zIndex:-999998}));this.$wrap.css({position:this.isBody&&l?"fixed":"absolute"});this.index=0;this.show(this.index);a(d).on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===d.pageYOffset&&(d.scrollTo(0,1),this.resize())},this))};q.prototype={resize:function(){try{var a={left:0,top:0},b=this.isBody?this.$root.width():this.$root.innerWidth(),e=b,g=this.isBody?d.innerHeight?d.innerHeight:this.$root.height():this.$root.innerHeight(),j=e/this.$img.data("ratio"),f;j>=g?(f=(j-g)/2,this.options.centeredY&&(a.top="-"+f+"px")):(j=g,e=j*this.$img.data("ratio"),f=(e-b)/2,this.options.centeredX&&(a.left="-"+f+"px"));this.$wrap.css({width:b,height:g}).find("img:not(.deleteable)").css({width:e,height:j}).css(a)}catch(h){}return this},show:function(c){if(!(Math.abs(c)>this.images.length-1)){var b=this,e=b.$wrap.find("img").addClass("deleteable"),d={relatedTarget:b.$container[0]};b.$container.trigger(a.Event("backstretch.before",d),[b,c]);this.index=c;clearInterval(b.interval);b.$img=a("<img />").css(s).bind("load",function(f){var h=this.width||a(f.target).width();f=this.height||a(f.target).height();a(this).data("ratio",h/f);a(this).fadeIn(b.options.speed||b.options.fade,function(){e.remove();b.paused||b.cycle();a(["after","show"]).each(function(){b.$container.trigger(a.Event("backstretch."+this,d),[b,c])})});b.resize()}).appendTo(b.$wrap);b.$img.attr("src",b.images[c]);return b}},next:function(){return this.show(this.index<this.images.length-1?this.index+1:0)},prev:function(){return this.show(0===this.index?this.images.length-1:this.index-1)},pause:function(){this.paused=!0;return this},resume:function(){this.paused=!1;this.next();return this},cycle:function(){1<this.images.length&&(clearInterval(this.interval),this.interval=setInterval(a.proxy(function(){this.paused||this.next()},this),this.options.duration));return this},destroy:function(c){a(d).off("resize.backstretch orientationchange.backstretch");clearInterval(this.interval);c||this.$wrap.remove();this.$container.removeData("backstretch")}};var l,f=navigator.userAgent,m=navigator.platform,e=f.match(/AppleWebKit\/([0-9]+)/),e=!!e&&e[1],h=f.match(/Fennec\/([0-9]+)/),h=!!h&&h[1],n=f.match(/Opera Mobi\/([0-9]+)/),t=!!n&&n[1],k=f.match(/MSIE ([0-9]+)/),k=!!k&&k[1];l=!((-1<m.indexOf("iPhone")||-1<m.indexOf("iPad")||-1<m.indexOf("iPod"))&&e&&534>e||d.operamini&&"[object OperaMini]"==={}.toString.call(d.operamini)||n&&7458>t||-1<f.indexOf("Android")&&e&&533>e||h&&6>h||"palmGetResource"in d&&e&&534>e||-1<f.indexOf("MeeGo")&&-1<f.indexOf("NokiaBrowser/8.5.0")||k&&6>=k)})(jQuery,window);

View File

@@ -1,62 +0,0 @@
//;(function (window, document, $) {
// alert($("#sidebarButton").html());
//}(this, document, jQuery));
//;(function (window, document, $) {
// // Set the negative margin on the top menu for slide-menu pages
// var $selector1 = $('#topMenu'),
// events = 'click.fndtn';
// if ($selector1.length > 0) $selector1.css("margin-top", $selector1.height() * -1);
//
// // Watch for clicks to show the sidebar
// var $selector2 = $('#sidebarButton');
// if ($selector2.length > 0) {
// $('#sidebarButton').on(events, function (e) {
// console.log("testing one two three");
// e.preventDefault();
// $('body').toggleClass('active');
// });
// }
// else {
// console.log("not supposed to be there");
// }
//
// // Watch for clicks to show the menu for slide-menu pages
// var $selector3 = $('#menuButton');
// if ($selector3.length > 0) {
// $('#menuButton').on(events, function (e) {
// e.preventDefault();
// $('body').toggleClass('active-menu');
// });
// }
//
// // // Adjust sidebars and sizes when resized
// // $(window).resize(function() {
// // // if (!navigator.userAgent.match(/Android/i)) $('body').removeClass('active');
// // var $selector4 = $('#topMenu');
// // if ($selector4.length > 0) $selector4.css("margin-top", $selector4.height() * -1);
// // });
//
// // Switch panels for the paneled nav on mobile
// var $selector5 = $('#switchPanels');
// if ($selector5.length > 0) {
// $('#switchPanels dd').on(events, function (e) {
// e.preventDefault();
// var switchToPanel = $(this).children('a').attr('href'),
// switchToIndex = $(switchToPanel).index();
// $(this).toggleClass('active').siblings().removeClass('active');
// $(switchToPanel).parent().css("left", (switchToIndex * (-100) + '%'));
// });
// }
//
// $('#nav li a').on(events, function (e) {
// alert("test");
// e.preventDefault();
// var href = $(this).attr('href'),
// $target = $(href);
// $('html, body').animate({scrollTop : $target.offset().top}, 300);
// });
//}(this, document, jQuery));

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -9,7 +9,5 @@
//= require store/spree_core
//= require store/spree_auth
//= require store/spree_promo
//= require angular
//= require angular-resource
//= require_tree .

View File

@@ -1,8 +0,0 @@
$(document).ready ->
$('#cart_adjustments').hide()
$('th.cart-adjustment-header').html('<a href="#">Distribution...</a>')
$('th.cart-adjustment-header a').click ->
$('#cart_adjustments').toggle()
$('th.cart-adjustment-header a').html('Distribution')
false

View File

@@ -1,20 +0,0 @@
'use strict'
angular.module('store', ['ngResource']).
controller('CartCtrl', ['$scope', '$window', 'CartFactory', ($scope, $window, CartFactory) ->
$scope.state = 'Empty'
$scope.loadCart = (cart_id) ->
if cart_id?
CartFactory.load cart_id, (cart) ->
$scope.cart = cart
if $scope.cart?.orders?.length > 0
$scope.state = "There's something there...."
$scope.addVariant = (variant, quantity) ->
])
.config(['$httpProvider', ($httpProvider) ->
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
])

View File

@@ -1,11 +0,0 @@
'use strict'
angular.module('store').
factory('CartFactory', ['$resource', '$window', '$http', ($resource, $window, $http) ->
Cart = $resource '/open_food_network/cart/:cart_id.json', {},
{ 'show': { method: 'GET'} }
load: (id, callback) ->
Cart.show {cart_id: id}, (cart) ->
callback(cart)
])

View File

@@ -1,47 +0,0 @@
/**
* Update the price on the product details page in real time when the variant or the quantity are changed.
**/
$(document).ready(function() {
// Product page with variant choice
$("#product-variants input[type='radio']").change(products_update_price_with_variant);
$("#quantity").change(products_update_price_with_variant);
$("#quantity").change();
// Product page with master price only
$(".add-to-cart input.title:not(#quantity):not(.max_quantity)").change(products_update_price_without_variant).change();
// Product page other
$("#distributor_id").change(function() {
var distributor_html = distributors[$(this).val()];
if(!distributor_html) {
distributor_html = 'When you select a distributor for your order, their address and pickup times will be displayed here.';
}
$("#product-distributor-details .distributor-details").html(distributor_html);
});
});
function products_update_price_with_variant() {
var variant_price = $("#product-variants input[type='radio']:checked").parent().find("span.price").html().trim();
variant_price = variant_price.substr(2, variant_price.length-3);
var quantity = $("#quantity").val();
$("#product-price span.price").html("$"+(parseFloat(variant_price) * parseInt(quantity)).toFixed(2));
}
function products_update_price_without_variant() {
var master_price = $("#product-price span.price").data('master-price');
if(master_price == null) {
// Store off the master price
master_price = $("#product-price span.price").html();
master_price = master_price.substring(1);
$("#product-price span.price").data('master-price', master_price);
}
var quantity = $(this).val();
$("#product-price span.price").html("$"+(parseFloat(master_price)*parseInt(quantity)).toFixed(2));
}

View File

@@ -1,4 +0,0 @@
$(document).ready ->
$("#order_order_cycle_id").change -> $("#order_cycle_select").submit()
$("#reset_order_cycle").click -> return false unless confirm "Changing your collection date will clear your cart."
$(".shop-distributor.empties-cart").click -> return false unless confirm "Changing your location will clear your cart."

View File

@@ -1,4 +0,0 @@
%ng-include{src: "'partials/enterprise_header.html'"}
%ng-include{src: "'partials/enterprise_details.html'"}
%ng-include{src: "'partials/hub_actions.html'"}
%ng-include{src: "'partials/close.html'"}

View File

@@ -1,12 +1,13 @@
.highlight
.highlight-top
%p.right
{{ [enterprise.address.city, enterprise.address.state_name] | printArray}}
%h3{"ng-if" => "enterprise.is_distributor"}
%a{"bo-href" => "enterprise.path", "ofn-empties-cart" => "enterprise", bindonce: true}
%i.ofn-i_040-hub
.highlight{"ng-class" => "{'is_distributor' : enterprise.is_distributor}"}
.highlight-top.row
.small-12.medium-7.large-8.columns
%h3{"ng-if" => "enterprise.is_distributor"}
%a{"bo-href" => "enterprise.path", "ofn-empties-cart" => "enterprise", bindonce: true}
%i{"ng-class" => "enterprise.icon_font"}
%span {{ enterprise.name }}
%h3{"ng-if" => "!enterprise.is_distributor", "ng-class" => "{'is_producer' : enterprise.is_primary_producer}"}
%i{"ng-class" => "enterprise.icon_font"}
%span {{ enterprise.name }}
%h3{"ng-if" => "!enterprise.is_distributor"}
%i.ofn-i_036-producers
%span {{ enterprise.name }}
.small-12.medium-5.large-4.columns.text-right.small-only-text-left
%p {{ [enterprise.address.city, enterprise.address.state_name] | printArray}}
%img.hero-img{"ng-src" => "{{enterprise.promo_image}}"}

View File

@@ -1,4 +1,4 @@
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0 && enterprise.has_shopfront"}
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0 && enterprise.is_distributor"}
.cta-container.small-12.columns
%label
Shop for

View File

@@ -1,4 +1,4 @@
.row.pad-top{bindonce: true, ng: { if: 'enterprise.has_shopfront' } }
.row.pad-top{bindonce: true, ng: { if: 'enterprise.is_distributor' } }
.cta-container.small-12.columns
.row
.small-4.columns

View File

@@ -10,26 +10,26 @@
.expanded{"ng-show" => "expanded"}
%ul
%li.cost
.right {{ variant.base_price | currency }}
.right {{ variant.price | localizeCurrency }}
Item cost
%li{"bo-if" => "variant.fees.admin"}
.right {{ variant.fees.admin | currency }}
.right {{ variant.fees.admin | localizeCurrency }}
Admin fee
%li{"bo-if" => "variant.fees.sales"}
.right {{ variant.fees.sales | currency }}
.right {{ variant.fees.sales | localizeCurrency }}
Sales fee
%li{"bo-if" => "variant.fees.packing"}
.right {{ variant.fees.packing | currency }}
.right {{ variant.fees.packing | localizeCurrency }}
Packing fee
%li{"bo-if" => "variant.fees.transport"}
.right {{ variant.fees.transport | currency }}
.right {{ variant.fees.transport | localizeCurrency }}
Transport fee
%li{"bo-if" => "variant.fees.fundraising"}
.right {{ variant.fees.fundraising | currency }}
.right {{ variant.fees.fundraising | localizeCurrency }}
Fundraising fee
%li
%strong
.right = {{ variant.price | currency }}
.right = {{ variant.price_with_fees | localizeCurrency }}
&nbsp;
%a{"ng-click" => "expanded = !expanded"}

View File

@@ -1,3 +0,0 @@
%ng-include{src: "'partials/enterprise_header.html'"}
%ng-include{src: "'partials/enterprise_details.html'"}
%ng-include{src: "'partials/close.html'"}

View File

@@ -1,44 +1,47 @@
.container#registration-about
.header
%h2 Nice one!
%h5
Now let's flesh out the details about
%span.brick{"ng-show" => "enterprise.is_distributor"}
{{ enterprise.name }}
%span.turquoise{"ng-show" => "!enterprise.is_distributor" }
{{ enterprise.name }}
%ng-include{ src: "'registration/steps.html'" }
%form{ name: 'about', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('social',about)" } }
.row
.small-12.columns
%header
%h2 Nice one!
%h5
Now let's flesh out the details about
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
%form{ name: 'about', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('images',about)" } }
.row
.small-12.columns
.alert-box.alert{"data-alert" => ""}
{{ enterprise.name }} won't be visible on the Open Food Network until you enter a long and short description.
%a.close{:href => "#"} &times;
.alert-box.info{"data-alert" => ""}
{{ enterprise.name }} has been created on the Open Food Network. If you leave at any point from here onwards, your enterprise will be saved, and you can always login to the admin section to update or continue filling out your enterprise details.
%a.close{:href => "#"} &times;
.alert-box.info{ "ofn-inline-alert" => true, ng: { show: "visible" } }
%h6 Success! {{ enterprise.name }} added to the Open Food Network
%span If you exit the wizard at any stage, login and go to admin to edit or update your enterprise details.
%a.close{ ng: { click: "close()" } } &times;
.small-12.large-8.columns
.row
.small-12.columns
%label{ for: 'enterprise_description' } Short Description:
%input.chunky.small-12.columns{ id: 'enterprise_description', placeholder: "A short sentence describing your enterprise", ng: { model: 'enterprise.description' } }
.field
%label{ for: 'enterprise_description' } Short Description:
%input.chunky{ id: 'enterprise_description', placeholder: "A short sentence describing your enterprise", ng: { model: 'enterprise.description' } }
.row
.small-12.columns
%label{ for: 'enterprise_long_desc' } Long Description:
%textarea.chunky.small-12.columns{ id: 'enterprise_long_desc', placeholder: "We recommend keeping your description to under 600 characters or 150 words. Why? Cus people are lazy, and don't like to read too much text online. ;)", ng: { model: 'enterprise.long_description' } }
%small {{ enterprise.long_description.length }} characters used
.field
%label{ for: 'enterprise_long_desc' } Long Description:
%textarea.chunky{ id: 'enterprise_long_desc', rows: 6, placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words.", ng: { model: 'enterprise.long_description' } }
%small {{ enterprise.long_description.length }} characters / up to 600 recommended
.small-12.large-4.columns
.row
.small-12.columns
%label{ for: 'enterprise_abn' } ABN:
%input.chunky.small-12.columns{ id: 'enterprise_abn', placeholder: "eg. 99 123 456 789", ng: { model: 'enterprise.abn' } }
.field
%label{ for: 'enterprise_abn' } ABN:
%input.chunky{ id: 'enterprise_abn', placeholder: "eg. 99 123 456 789", ng: { model: 'enterprise.abn' } }
.row
.small-12.columns
%label{ for: 'enterprise_acn' } ACN:
%input.chunky.small-12.columns{ id: 'enterprise_acn', placeholder: "eg. 123 456 789", ng: { model: 'enterprise.acn' } }
.field
%label{ for: 'enterprise_acn' } ACN:
%input.chunky{ id: 'enterprise_acn', placeholder: "eg. 123 456 789", ng: { model: 'enterprise.acn' } }
.row.buttons.pad-top
.small-12.columns
%input.button.primary{ type: "submit", value: "Continue" }
%input.button.primary.right{ type: "submit", value: "Continue" }

View File

@@ -1,60 +0,0 @@
.container#registration-address
.header
%h2
Greetings
%span{ ng: { class: "{brick: enterprise.is_distributor, turquoise: !enterprise.is_distributor}" } }
{{ enterprise.name }}
%h5 Now we need to know where you are
%ng-include{ src: "'registration/steps.html'" }
%form{ name: 'address', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('contact',address)" } }
.row.content
.small-12.medium-12.large-7.columns
.row
.small-12.columns.field
%label{ for: 'enterprise_address' } Address:
%input.chunky.small-12.columns{ id: 'enterprise_address', name: 'address1', required: true, placeholder: "eg. 123 Cranberry Drive", required: true, ng: { model: 'enterprise.address.address1' } }
%span.error.small-12.columns{ ng: { show: "address.address1.$error.required && submitted" } }
You need to enter an address.
.row
.small-12.large-8.columns.field
%label{ for: 'enterprise_city' } Suburb:
%input.chunky.small-12.columns{ id: 'enterprise_city', name: 'city', required: true, placeholder: "eg. Northcote", ng: { model: 'enterprise.address.city' } }
%span.error.small-12.columns{ ng: { show: "address.city.$error.required && submitted" } }
You need to enter a suburb.
.small-12.large-4.columns.field
%label{ for: 'enterprise_zipcode' } Postcode:
%input.chunky.small-12.columns{ id: 'enterprise_zipcode', name: 'zipcode', required: true, placeholder: "eg. 3070", ng: { model: 'enterprise.address.zipcode' } }
%span.error.small-12.columns{ ng: { show: "address.zipcode.$error.required && submitted" } }
You need to enter a postcode.
.row
.small-12.large-8.columns.field
%label{ for: 'enterprise_country' } Country:
%select.chunky.small-12.columns{ id: 'enterprise_country', name: 'country', required: true, ng: { model: 'enterprise.country', options: 'c as c.name for c in countries' } }
%span.error.small-12.columns{ ng: { show: "address.country.$error.required && submitted" } }
You need to enter a country.
.small-12.large-4.columns.field
%label{ for: 'enterprise_state' } State:
%select.chunky.small-12.columns{ id: 'enterprise_state', name: 'state', ng: { model: 'enterprise.address.state_id', options: 's.id as s.abbr for s in enterprise.country.states', show: 'countryHasStates()', required: 'countryHasStates()' } }
%span.error.small-12.columns{ ng: { show: "address.state.$error.required && submitted" } }
You need to enter a state.
.small-12.medium-12.large-5.hide-for-small-only
// This is the location area
/ %h6
/ Location display
/ %i.ofn-i_013-help.has-tip{ 'data-tooltip' => true, title: "Choose how you want to display your enterprise's address on the Open Food Network. By default, full location is shown everywhere including street name and number."}
/ .row
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'enterpise_suburb_only', ng: { model: 'enterprise.suburb_only' } }
/ Hide my street name and street number from the public (ie. only show the suburb)
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'enterprise_on_map', ng: { model: 'enterprise.on_map' } }
/ Blur my location on the map (show an approximate, not exact pin)
.row.buttons
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('details')" } }
&nbsp;
%input.button.primary{ type: "submit", value: "Continue" }

View File

@@ -1,12 +1,13 @@
.container#registration-contact
.header
%h2 Last step to create your enterprise!
%h5
Who is responsible for managing
%span{ ng: { class: "{brick: enterprise.is_distributor, turquoise: !enterprise.is_distributor}" } }
{{ enterprise.name }}?
%ng-include{ src: "'registration/steps.html'" }
%form{ name: 'contact', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "create(contact)" } }
.row
.small-12.columns
%header
%h2 Greetings!
%h5
Who is responsible for managing {{ enterprise.name }}?
%form{ name: 'contact', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('type',contact)" } }
.row.content
.small-12.medium-12.large-7.columns
.row
@@ -39,8 +40,8 @@
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'contact_phone_profile', ng: { model: 'enterprise.phone_in_profile' } } &nbsp; Display phone in profile
.row.buttons
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('address')" } }
&nbsp;
%input.button.primary{ type: "submit", value: "Continue" }
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('details')" } }
%input.button.primary.right{ type: "submit", value: "Continue" }

View File

@@ -1,42 +1,77 @@
.container#registration-details{bindonce: true}
.header
%h2 Let's Get Started
%h5{ bo: { if: "enterprise.type != 'single'" } } Woot! First we need to know what sort of enterprise you are:
%h5{ bo: { if: "enterprise.type == 'single'" } } Woot! First we need to know the name of your farm:
%ng-include{ src: "'registration/steps.html'" }
%form{ name: 'details', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('address',details)" } }
.row
.small-12.columns.field
%label{ for: 'enterprise_name', bo: { if: "enterprise.type != 'single'" } } Enterprise Name:
%label{ for: 'enterprise_name', bo: { if: "enterprise.type == 'single'" } } Farm Name:
%input.chunky.small-12.columns{ id: 'enterprise_name', name: 'name', placeholder: "eg. Charlie's Awesome Farm", required: true, ng: { model: 'enterprise.name' } }
%span.error.small-12.columns{ ng: { show: "details.name.$error.required && submitted" } }
You need to enter a name for your enterprise!
.row
.small-12.columns
%header
%h2 Let's Get Started
%h5{ bo: { if: "enterprise.type != 'own'" } } Woot! First we need to know a little bit about your enterprise:
%h5{ bo: { if: "enterprise.type == 'own'" } } Woot! First we need to know a little bit about your farm:
.row#enterprise-types{ 'data-equalizer' => true, bo: { if: "enterprise.type != 'single'" } }
.small-12.columns.field
%form{ name: 'details', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('contact',details)" } }
.row
.small-12.medium-9.large-12.columns.end
.field
%label{ for: 'enterprise_name', bo: { if: "enterprise.type != 'own'" } } Enterprise Name:
%label{ for: 'enterprise_name', bo: { if: "enterprise.type == 'own'" } } Farm Name:
%input.chunky{ id: 'enterprise_name', name: 'name', placeholder: "e.g. Charlie's Awesome Farm", required: true, ng: { model: 'enterprise.name' } }
%span.error{ ng: { show: "details.name.$error.required && submitted" } }
Please choose a unique name for your enterprise
.row
.small-12.medium-9.large-6.columns
.field
%label{ for: 'enterprise_address' } Address line 1:
%input.chunky{ id: 'enterprise_address', name: 'address1', required: true, placeholder: "e.g. 123 Cranberry Drive", required: true, ng: { model: 'enterprise.address.address1' } }
%span.error{ ng: { show: "details.address1.$error.required && submitted" } }
Please enter an address
.field
%label{ for: 'enterprise_address2' } Address line 2:
%input.chunky{ id: 'enterprise_address2', name: 'address2', required: false, placeholder: "", required: false, ng: { model: 'enterprise.address.address2' } }
.small-12.medium-9.large-6.columns.end
.row
.small-12.columns
%label Choose one:
.small-12.medium-8.large-8.columns
.field
%label{ for: 'enterprise_city' } Suburb:
%input.chunky{ id: 'enterprise_city', name: 'city', required: true, placeholder: "e.g. Northcote", ng: { model: 'enterprise.address.city' } }
%span.error{ ng: { show: "details.city.$error.required && submitted" } }
Please enter a suburb
.small-12.medium-4.large-4.columns
.field
%label{ for: 'enterprise_zipcode' } Postcode:
%input.chunky{ id: 'enterprise_zipcode', name: 'zipcode', required: true, placeholder: "e.g. 3070", ng: { model: 'enterprise.address.zipcode' } }
%span.error{ ng: { show: "details.zipcode.$error.required && submitted" } }
Postcode required
.row
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
%a.panel#producer-panel{ href: "#", ng: { click: "enterprise.is_distributor = false; enterprise.is_primary_producer = true", class: "{selected: (!enterprise.is_distributor && enterprise.is_primary_producer)}" } }
.left
/ %render-svg{ path: "/assets/map-icon-producer.svg" }
%h4 I'm A Producer
%p Producers make yummy things to eat &amp;/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it.
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
%a.panel#hub-panel{ href: "#", ng: { click: "enterprise.is_distributor = true; enterprise.is_primary_producer = false", class: "{selected: (enterprise.is_distributor && !enterprise.is_primary_producer)}" } }
.left
/ %render-svg{ path: "/assets/map-icon-hub.svg" }
%h4 I'm A Hub
%p Hubs connect the producer to the eater. Hubs can be co-ops, independent retailers, buying groups, wholesalers, CSA box schemes, farm-gate stalls, etc.
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
%a.panel#both-panel{ href: "#", ng: { click: "enterprise.is_distributor = true; enterprise.is_primary_producer = true", class: "{selected: (enterprise.is_distributor && enterprise.is_primary_producer)}" } }
.left
/ %render-svg{path: "/assets/map-icon-both.svg"}
%h4 I'm Both
%p Hey there, Jack-of-all-trades! Not only do you produce things to eat &amp;/or drink, you also want to sell your yummies through an Open Food Network shopfront.
.small-12.medium-4.large-4.columns
.field
%label{ for: 'enterprise_state' } State:
%select.chunky{ id: 'enterprise_state', name: 'state', ng: { model: 'enterprise.address.state_id', options: 's.id as s.abbr for s in enterprise.country.states', show: 'countryHasStates()', required: 'countryHasStates()' } }
%span.error{ ng: { show: "details.state.$error.required && submitted" } }
State required
.small-12.medium-8.large-8.columns
.field
%label{ for: 'enterprise_country' } Country:
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { model: 'enterprise.country', options: 'c as c.name for c in countries' } }
%span.error{ ng: { show: "details.country.$error.required && submitted" } }
Please select a country
/ .small-12.medium-12.large-5.hide-for-small-only
/ %h6
/ Location display
/ %i.ofn-i_013-help.has-tip{ 'data-tooltip' => true, title: "Choose how you want to display your enterprise's address on the Open Food Network. By default, full location is shown everywhere including street name and number."}
/ .row
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'enterpise_suburb_only', ng: { model: 'enterprise.suburb_only' } }
/ Hide my street name and street number from the public (ie. only show the suburb)
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'enterprise_on_map', ng: { model: 'enterprise.on_map' } }
/ Blur my location on the map (show an approximate, not exact pin)
.row.buttons
.small-12.columns
%hr
%input.button.primary.right{ type: "submit", value: "Continue" }

View File

@@ -1,18 +1,24 @@
.container#registration-finished
.header
%h2 Well done!
%h5
You have successfully completed the profile for
%span.brick{"ng-show" => "enterprise.is_distributor"}
{{ enterprise.name }}
%span.turquoise{"ng-show" => "!enterprise.is_distributor" }
{{ enterprise.name }}
.content{ style: 'text-align: center'}
%h3 Why not check it out on the Open Food Network?
%a.button.primary{ type: "button", href: "/map" } Go to Map Page &gt;
.row
.small-12.columns.pad-top
%header
%h2 Finished!
.panel.callout
%p
Thanks for filling out the details for
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
%p You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin.
.row
.small-12.columns.text-center
%h4
Activate
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
%br
%br
%p
We've sent a confirmation email to
%strong {{ enterprise.email }}.
%br Please follow the instructions there to make your enterprise visible on the Open Food Network.
%h3 Next step - add some products:
%a.button.primary{ type: "button", href: "/admin/products/new" } Add a Product &gt;
%a.button.primary{ type: "button", href: "/" } Open Food Network home &gt;

View File

@@ -1,14 +1,22 @@
.container#registration-images
.header
%h2 Thanks!
%h5 Let's upload some pretty pictures so your profile looks great! :)
.container#registration-images{ 'nv-file-drop' => true, uploader: "imageUploader", options:"{ alias: imageStep }", ng: { controller: "EnterpriseImageCtrl" } }
%ng-include{ src: "'registration/steps.html'" }
.row.content
.row.buttons
.row
.small-12.columns
%input.button.primary.left{ type: "button", value: "Back", ng: { click: "select('about')" } }
&nbsp;
%input.button.primary.right{ type: "button", value: "Continue", ng: { click: "select('social')" } }
%header
%h2 Thanks!
%h5 Let's upload some pretty pictures so your profile looks great! :)
%form{ name: 'images', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "select('social')" } }
.row{ ng: { repeat: 'image_step in imageSteps', show: "imageStep == image_step" } }
%ng-include{ src: "'registration/images/'+ image_step + '.html'" }
.row.buttons.pad-top{ ng: { if: "imageStep == 'logo'" } }
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('about')" } }
&nbsp;
%input.button.primary.right{ type: "button", value: "Continue", ng: { click: "imageSelect('promo')" } }
.row.buttons.pad-top{ ng: { if: "imageStep == 'promo'" } }
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "imageSelect('logo')" } }
%input.button.primary.right{ type: "submit", value: "Continue" }

View File

@@ -0,0 +1,45 @@
.small-12.medium-12.large-6.columns
.row
.small-12.columns.center
.row
.small-12.columns.center
%h4
Step 1. Select Logo Image
.row
.small-12.columns.center
%span.small
Tip: Square images will work best, preferably at least 300&times;300px
.row.pad-top
.small-12.columns
.image-select.small-12.columns
%label.small-12.columns.button{ for: 'image-select' } Choose a logo image
%input#image-select{ type: 'file', hidden: true, 'nv-file-select' => true, uploader: "imageUploader", options: '{ alias: imageStep }' }
.row.show-for-large-up
.large-12.columns
%span#or.large-12.columns
OR
.row.show-for-large-up
.large-12.columns
#image-over{ 'nv-file-over' => true, uploader: "imageUploader" }
Drag and drop your logo here
.small-12.medium-12.large-6.columns
.row
.small-12.columns.center
.row
.small-12.columns.center
%h4
Step 2. Review Your Logo
.row
.small-12.columns.center
%span.small
Tip: for best results, your logo should fill the available space
.row.pad-top
.small-12.columns.center
#image-placeholder.logo
%img{ ng: { show: "imageSrc() && !imageUploader.isUploading", src: '{{ imageSrc() }}' } }
.message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } }
Your logo will appear here for review once uploaded
.loading{ ng: { hide: "!imageUploader.isUploading" } }
%img.spinner{ src: "/assets/loading.gif" }
%br/
Uploading...

View File

@@ -0,0 +1,43 @@
.small-12.medium-12.large-12.columns
.row
.small-12.columns.center
%h4
Step 3. Select Promo Image
.row
.small-12.medium-12.large-5.columns.center
.row
.small-12.columns.center
%span.small
Tip: Shown as a banner, preferred size is 1200&times;260px
.row.pad-top
.small-12.columns
.image-select.small-12.columns
%label.small-12.columns.button{ for: 'image-select' } Choose a promo image
%input#image-select{ type: 'file', hidden: true, 'nv-file-select' => true, uploader: "imageUploader", options: '{ alias: imageStep }' }
.large-2.columns
%span#or.horizontal.large-12.columns
OR
.large-5.columns
#image-over{ 'nv-file-over' => true, uploader: "imageUploader" }
Drag and drop your promo here
.small-12.medium-12.large-12.columns.pad-top
.row
.small-12.columns.center
%h4
Step 4. Review Your Promo Banner
.row
.small-12.columns.center
.row
.small-12.columns.center
%span.small
Tip: for best results, your promo image should fill the available space
.row.pad-top
.small-12.columns.center
#image-placeholder.promo
%img{ ng: { show: "imageSrc() && !imageUploader.isUploading", src: '{{ imageSrc() }}' } }
.message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } }
Your logo will appear here for review once uploaded
.loading{ ng: { hide: "!imageUploader.isUploading" } }
%img.spinner{ src: "/assets/loading.gif" }
%br/
Uploading...

View File

@@ -1,40 +1,45 @@
%div
.header
%h2 Hi there!
%h4 This wizard will step you through creating a profile
.row
.small-12.medium-3.large-2.columns.text-right.hide-for-small-only
%img{:src => "/assets/potatoes.png"}
.small-12.medium-9.large-10.columns
%p
Your profile gives you an online presence on the
%strong Open Food Network,
allowing you to easily connect with potential customers or partners. You can always choose to update your info later, as well as choose to upgrade your Profile to and Online Store, where you can sell products, track orders and receive payments. Creating a profile takes about 5-10 minutes.
.row{ 'data-equalizer' => true }
.small-12.medium-6.large-6.columns.pad-top{ 'data-equalizer-watch' => true }
%h5 You'll need the following:
%ul.check-list
%li
Your enterprise address and contact details
%li
Your logo image
%li
A pretty picture for your profile header
%li
Some 'About Us' text
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true}
.highlight-box
%h5 Your profile entitles you to:
%ul.small-block-grid-1
%li
%i.ofn-i_020-search
A searchable listing
%li
%i.ofn-i_040-hub
A pin on the OFN map
.row
.small-12.columns
.row
.small-12.columns
%header
%h2 Hi there!
%h4
%small
%i.ofn-i_040-hub
Create your enterprise profile
.hide-for-large-up
%hr
%input.button.primary{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }
%input.button.small.primary{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }
%hr
.row{ 'data-equalizer' => true }
.small-12.medium-12.large-6.columns.pad-top{ 'data-equalizer-watch' => true }
%h5 You'll need:
%ul.check-list
%li
5-10 minutes
%li
Enterprise address
%li
Primary contact details
%li
Your logo image
%li
Landscape image for your profile
%li
'About Us' text
.small-9.medium-8.large-5.columns.pad-top.end{ 'data-equalizer-watch' => true}
%h5
What do I get?
%p
Your profile helps people
%strong find
and
%strong contact
you on the Open Food Network.
%p Use this space to tell the story of your enterprise, to help drive connections to your social and online presence.
.row.show-for-large-up
.small-12.columns
%hr
%input.button.primary.right{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }

View File

@@ -0,0 +1,16 @@
.row
.small-12.columns
%header
%h2 Oh no!
%h4 You have reached the limit!
.row
.small-12.medium-3.large-2.columns.text-right.hide-for-small-only
%img{:src => "/assets/potatoes.png"}
.small-12.medium-9.large-10.columns
%p
You have reached the limit for the number of enterprises you are allowed to own on the
%strong Open Food Network.
.row
.small-12.columns
%hr
%input.button.primary{ type: "button", value: "Return to the homepage", ng: { click: "close()" } }

View File

@@ -1,35 +1,49 @@
.container#registration-social
.header
%h2 Last step!
%h5 How can people find {{ enterprise.name }} online?
%ng-include{ src: "'registration/steps.html'" }
.row
.small-12.columns
%header
%h2 Final step!
%h5
How can people find
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
online?
%form{ name: 'social', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('finished',social)" } }
.row.content
.small-12.large-7.columns
.row
.small-12.columns
%label{ for: 'enterprise_website' } Website:
%input.chunky.small-12.columns{ id: 'enterprise_website', placeholder: "eg. openfoodnetwork.org.au", ng: { model: 'enterprise.website' } }
.field
%label{ for: 'enterprise_website' } Website:
%input.chunky{ id: 'enterprise_website', placeholder: "eg. openfoodnetwork.org.au", ng: { model: 'enterprise.website' } }
.row
.small-12.columns
%label{ for: 'enterprise_facebook' } Facebook:
%input.chunky.small-12.columns{ id: 'enterprise_facebook', placeholder: "eg. www.facebook.com/PageNameHere", ng: { model: 'enterprise.facebook' } }
.field
%label{ for: 'enterprise_facebook' } Facebook:
%input.chunky{ id: 'enterprise_facebook', placeholder: "eg. www.facebook.com/PageNameHere", ng: { model: 'enterprise.facebook' } }
.row
.small-12.columns
%label{ for: 'enterprise_linkedin' } LinkedIn:
%input.chunky.small-12.columns{ id: 'enterprise_linkedin', placeholder: "eg. www.linkedin.com/YourNameHere", ng: { model: 'enterprise.linkedin' } }
.field
%label{ for: 'enterprise_linkedin' } LinkedIn:
%input.chunky{ id: 'enterprise_linkedin', placeholder: "eg. www.linkedin.com/YourNameHere", ng: { model: 'enterprise.linkedin' } }
.small-12.large-5.columns
.row
.small-12.columns
%label{ for: 'enterprise_twitter' } Twitter:
%input.chunky.small-12.columns{ id: 'enterprise_twitter', placeholder: "eg. @twitter_handle", ng: { model: 'enterprise.twitter' } }
.field
%label{ for: 'enterprise_twitter' } Twitter:
%input.chunky{ id: 'enterprise_twitter', placeholder: "eg. @twitter_handle", ng: { model: 'enterprise.twitter' } }
.row
.small-12.columns
%label{ for: 'enterprise_instagram' } Instagram:
%input.chunky.small-12.columns{ id: 'enterprise_instagram', placeholder: "eg. @instagram_handle", ng: { model: 'enterprise.instagram' } }
.field
%label{ for: 'enterprise_instagram' } Instagram:
%input.chunky{ id: 'enterprise_instagram', placeholder: "eg. @instagram_handle", ng: { model: 'enterprise.instagram' } }
.row.buttons
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('about')" } }
&nbsp;
%input.button.primary{ type: "submit", value: "Continue" }
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('images')" } }
%input.button.primary.right{ type: "submit", value: "Continue" }

View File

@@ -1,5 +1,3 @@
.row#progress-bar
.small-12.medium-2.columns.item{ ng: { repeat: 'step in steps', class: "{active: (currentStep() == step),'show-for-medium-up': (currentStep() != step)}" } }
{{ $index+1 + ". " + step }}

View File

@@ -0,0 +1,46 @@
.container#registration-type{bindonce: true}
%ng-include{ src: "'registration/steps.html'" }
.row
.small-12.columns
%header
%h2
Last step to add
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}!
%h4
Are you a producer?
%form{ name: 'type', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "create(type)" } }
.row#enterprise-types{ 'data-equalizer' => true, bo: { if: "enterprise.type != 'own'" } }
.small-12.columns.field
.row
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true }
%a.btnpanel#producer-panel{ href: "#", ng: { click: "enterprise.is_primary_producer = true", class: "{selected: enterprise.is_primary_producer}" } }
%i.ofn-i_059-producer
%h4 Yes, I'm a producer
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true }
%a.btnpanel#hub-panel{ href: "#", ng: { click: "enterprise.is_primary_producer = false", class: "{selected: enterprise.is_primary_producer == false}" } }
%i.ofn-i_063-hub
%h4 No, I'm not a producer
.row
.small-12.columns
%input.chunky{ id: 'enterprise_is_primary_producer', name: 'is_primary_producer', hidden: true, required: true, ng: { model: 'enterprise.is_primary_producer' } }
%span.error{ ng: { show: "type.is_primary_producer.$error.required && submitted" } }
Please choose one. Are you are producer?
.row
.small-12.columns
.panel.callout
.left
%i.ofn-i_013-help
&nbsp;
%p Producers make yummy things to eat &amp;/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it.
/ %p Hubs connect the producer to the eater. Hubs can be co-ops, independent retailers, buying groups, wholesalers, CSA box schemes, farm-gate stalls, etc.
.row.buttons
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('contact')" } }
%input.button.primary.right{ type: "submit", value: "Continue" }

View File

@@ -48,7 +48,7 @@
.small-4.medium-2.large-2.columns.variant-price
.table-cell.price
%i.ofn-i_009-close
{{ variant.price | currency }}
{{ variant.price_with_fees | localizeCurrency }}
-# Now in a template in app/assets/javascripts/templates !
%price-breakdown{"price-breakdown" => "_", variant: "variant",
@@ -59,4 +59,4 @@
.small-12.medium-2.large-2.columns.total-price.text-right
.table-cell
%strong
{{ variant.getPrice() | currency }}
{{ variant.totalPrice() | localizeCurrency }}

View File

@@ -0,0 +1,15 @@
.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

View File

@@ -9,6 +9,7 @@
*= require admin/spree_promo
*= require shared/jquery-ui-timepicker-addon
*= require shared/textAngular.min
*= require_self
*= require_tree .

View File

@@ -156,4 +156,4 @@ div.dashboard_item
background-color: #9fc820
&.bottom
border-radius: 0px 0px 6px 6px
padding: 15px 15px
padding: 15px 15px

View File

@@ -210,3 +210,24 @@ table#listing_enterprise_groups {
color: #575757;
}
.field_with_errors > input {
border-color: red;
}
// textAngular wysiwyg
text-angular {
.ta-scroll-window > .ta-bind {
max-height: 400px;
min-height: 100px;
}
.ta-scroll-window.form-control {
min-height: 100px;
}
.btn-group {
display: inline;
margin-right: 8px;
button {
padding: 5px 10px;
}
}
}

View File

@@ -33,6 +33,9 @@ div.sidebar_item
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
@@ -40,7 +43,6 @@ div.sidebar_item
margin-left: -1px
padding: 10px 2px 10px 5%
overflow: hidden
max-width: 160px
text-overflow: ellipsis
span.omega
padding: 8px 18px 8px 0px
@@ -72,4 +74,4 @@ div.sidebar_item
background-color: #DA5354
&:hover
background-color: #9fc820

View File

@@ -17,7 +17,9 @@ $clr-blue-bright: #14b6cc
$disabled-light: #e5e5e5
$disabled-bright: #ccc
$disabled-med: #b3b3b3
$disabled-dark: #999
$disabled-v-dark: #808080
$med-grey: #666
$dark-grey: #333
$black: #000

View File

@@ -87,6 +87,8 @@
&.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
@@ -126,3 +128,13 @@
.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

View File

@@ -11,12 +11,16 @@
@include box-shadow(0 1px 2px 1px rgba(0,0,0,0.25))
.hero-img
border-bottom: 1px solid $disabled-bright
outline: 1px solid $disabled-bright
border-color: transparent
@include box-shadow(none)
width: 100%
min-height: 56px
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

View File

@@ -16,6 +16,20 @@
-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

View File

@@ -25,23 +25,39 @@
position: relative
.highlight-top
padding: 0.75rem 0.9375rem
width: 100%
overflow: hidden
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
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

View File

@@ -1,6 +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
background: #fff
padding-top: 10px

View File

@@ -4,8 +4,14 @@
dialog, .reveal-modal
border: none
outline: none
padding: 1rem
padding: 30px 20px 0 20px
border-bottom: 30px solid white
overflow-y: scroll
overflow-x: hidden
// 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)
@@ -25,14 +31,18 @@ dialog, .reveal-modal
max-height: 80%
.reveal-modal-bg
background-color: rgba(0,0,0,0.65)
background-color: rgba(0,0,0,0.85)
dialog .close-reveal-modal, .reveal-modal .close-reveal-modal
right: 0.4rem
background-color: rgba(235,235,235,0.85)
right: 0.25rem
top: 0.25rem
background-color: rgba(205,205,205,0.65)
text-shadow: none
padding: 0.3rem
font-size: 2rem
padding: 0.45rem
color: #666
z-index: 9999999
@include border-radius(999999rem)
&:hover, &:active, &:focus
background-color: rgba(235,235,235,1)
background-color: rgba(205,205,205,1)
color: #333

View File

@@ -32,6 +32,11 @@
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
@@ -51,9 +56,11 @@
.fat-taxons
background-color: $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

View File

@@ -2,44 +2,25 @@
@import mixins
#registration-modal
.header
header
text-align: center
background-color: #efefef
padding-bottom: 1rem
// background-color: #efefef
@media all and (max-width: 64em)
text-align: left
.container
background-color: #ffffff
.content
// margin-bottom: 15px
i
font-size: 150%
.buttons
ofn-inline-flash
display: block
padding: 15px
position: relative
margin-bottom: 10px
&.brick
background-color: $clr-brick-light
border: 2px solid $clr-brick
color: $clr-brick
&.turquoise
background-color: $clr-turquoise-light
border: 2px solid $clr-turquoise
color: $clr-turquoise
.close-button
position: absolute
top: 0px
right: 0px
.field
margin-bottom: 15px
margin-bottom: 1em
input.chunky
.chunky
padding: 8px
font-size: 105%
font-size: 1rem
margin: 0
width: 100%
label.indent-checkbox
display: block
@@ -51,9 +32,9 @@
label
margin-bottom: 3px
ol, ul
// font-size: 80%
ol, ul, p
font-size: 0.875rem
ol, ul
padding: 0
margin: 0
ol
@@ -62,40 +43,107 @@
.highlight-box
background: white
padding: 1rem 1.2rem
@media all and (max-width: 640px)
@media all and (max-width: 64em)
margin-top: 1rem
#progress-bar
margin-bottom: 15px
.item
padding: 12px 0px
font-size: 0.75rem
padding: 10px 0px
text-transform: uppercase
text-align: center
background-color: #333
border: 2px solid #333
background-color: $clr-blue
border: 2px solid $clr-blue
color: #fff
.item.active
background-color: #cccccc
border: 2px solid #333
color: #333
background-color: $disabled-light
border: 2px solid $clr-blue
color: $clr-blue
font-weight: 700
@include box-shadow(inset 0 0 1px 0 #fff)
#registration-details
.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.panel
a.btnpanel
display: block
padding: 1rem
margin-bottom: 1rem
background-color: #efefef
color: black
@media all and (min-width: 768px)
min-height: 200px
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
@@ -112,4 +160,3 @@
p
clear: both
font-size: 0.875rem

View File

@@ -74,8 +74,10 @@ button.success, .button.success
.profile-checkbox
display: inline-block
input[type="checkbox"] + label
label
margin: 0 0.2rem
float: right
// Responsive
@media screen and (min-width: 768px)

Some files were not shown because too many files have changed in this diff Show More