mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge branch 'master' into working
This commit is contained in:
1
Gemfile
1
Gemfile
@@ -28,6 +28,7 @@ gem 'andand'
|
||||
gem 'truncate_html'
|
||||
gem 'representative_view'
|
||||
gem 'rabl'
|
||||
gem "active_model_serializers"
|
||||
gem 'oj'
|
||||
gem 'deface', :github => 'spree/deface', :ref => '1110a13'
|
||||
gem 'paperclip'
|
||||
|
||||
@@ -118,6 +118,8 @@ GEM
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
active_link_to (1.0.0)
|
||||
active_model_serializers (0.8.1)
|
||||
activemodel (>= 3.0)
|
||||
active_utils (2.0.2)
|
||||
activesupport (>= 2.3.11)
|
||||
i18n
|
||||
@@ -324,7 +326,7 @@ GEM
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
multi_json (1.10.0)
|
||||
multi_json (1.10.1)
|
||||
multi_xml (0.5.5)
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
@@ -492,6 +494,7 @@ PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
active_model_serializers
|
||||
andand
|
||||
angular-rails-templates
|
||||
angularjs-rails
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
#= require angular
|
||||
#= require angular-cookies
|
||||
#= require angular-sanitize
|
||||
#= require angular-animate
|
||||
#= require angular-resource
|
||||
#= require lodash.underscore.js
|
||||
#= require angular-scroll.min.js
|
||||
#= require angular-google-maps.min.js
|
||||
#= require ../shared/mm-foundation-tpls-0.2.0-SNAPSHOT
|
||||
#= require angular-timer.min.js
|
||||
#= require ../shared/mm-foundation-tpls-0.2.2.min.js
|
||||
#= require ../shared/bindonce.min.js
|
||||
#= require ../shared/ng-infinite-scroll.min.js
|
||||
#= require ../shared/angular-local-storage.js
|
||||
|
||||
@@ -2,5 +2,7 @@ Darkswarm.controller "GroupsCtrl", ($scope, Groups, $anchorScroll, $rootScope) -
|
||||
$scope.Groups = Groups
|
||||
$scope.order = 'position'
|
||||
|
||||
$rootScope.$on "$locationChangeSuccess", (newRoute, oldRoute) ->
|
||||
$anchorScroll()
|
||||
#$rootScope.$on "$locationChangeSuccess", (newRoute, oldRoute) ->
|
||||
#$anchorScroll()
|
||||
#
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Darkswarm.controller "HubsCtrl", ($scope, Hubs, $document, $rootScope, HashNavigation) ->
|
||||
$scope.Hubs = Hubs
|
||||
$scope.hubs = Hubs.hubs
|
||||
$scope.hubs = Hubs.visible
|
||||
|
||||
$rootScope.$on "$locationChangeSuccess", (newRoute, oldRoute) ->
|
||||
if HashNavigation.active "hubs"
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub) ->
|
||||
Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub, Enterprises) ->
|
||||
# Injecting Enterprises so CurrentHub.producers is dereferenced
|
||||
$scope.CurrentHub = CurrentHub
|
||||
|
||||
@@ -5,10 +5,11 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
|
||||
'infinite-scroll',
|
||||
'angular-flash.service',
|
||||
'templates',
|
||||
'timer',
|
||||
'ngSanitize',
|
||||
'google-maps',
|
||||
'duScroll',
|
||||
'backstretch']).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
|
||||
]).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'
|
||||
|
||||
@@ -6,7 +6,7 @@ Darkswarm.directive "activeTableHubLink", (CurrentHub, CurrentOrder) ->
|
||||
link: (scope, elm, attr)->
|
||||
# Swap out the text of the hub link depending on whether it'll change current hub
|
||||
# To be used with ofnEmptiesCart
|
||||
if CurrentHub.hub.id and CurrentHub.hub.id isnt scope.hub.id
|
||||
if CurrentHub.hub?.id and CurrentHub.hub.id isnt scope.hub.id
|
||||
scope.action = attr.change
|
||||
else
|
||||
scope.action = attr.shop
|
||||
|
||||
@@ -3,7 +3,7 @@ Darkswarm.directive "ofnEmptiesCart", (CurrentHub, CurrentOrder, Navigation, sto
|
||||
link: (scope, elm, attr)->
|
||||
hub = scope.$eval(attr.ofnEmptiesCart)
|
||||
# A hub is selected, we're changing to a different hub, and the cart isn't empty
|
||||
if CurrentHub.hub.id and CurrentHub.hub.id isnt hub.id
|
||||
if CurrentHub.hub?.id and CurrentHub.hub.id isnt hub.id
|
||||
unless CurrentOrder.empty()
|
||||
elm.bind 'click', (ev)->
|
||||
ev.preventDefault()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Darkswarm.directive "hubModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a>{{enterprise.name}}</a>"
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", =>
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'hub_modal.html', scope: scope)
|
||||
@@ -1,6 +0,0 @@
|
||||
Darkswarm.directive "offcanvas", ->
|
||||
restrict: "A"
|
||||
|
||||
link: (scope, el, attr) ->
|
||||
el.find(".left-off-canvas-toggle").bind 'click', ->
|
||||
el.toggleClass 'move-right'
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.directive "producerModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a ng-transclude></a>"
|
||||
transclude: true
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", =>
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'producer_modal.html', scope: scope)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.directive "productModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a ng-transclude></a>"
|
||||
transclude: true
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", =>
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'product_modal.html', scope: scope)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
Darkswarm.filter "groups", (Matcher)->
|
||||
(groups, text)->
|
||||
groups ||= []
|
||||
text ?= ""
|
||||
|
||||
groups.filter (group)=>
|
||||
Matcher.match([
|
||||
group.name, group.long_description
|
||||
], text) || group.enterprises.some (e)->
|
||||
Matcher.match [e.name], text
|
||||
@@ -0,0 +1,4 @@
|
||||
Darkswarm.filter "visible", ->
|
||||
(objects)->
|
||||
objects.filter (obj)->
|
||||
obj.visible
|
||||
@@ -0,0 +1,6 @@
|
||||
Darkswarm.factory 'Dereferencer', ->
|
||||
new class Dereferencer
|
||||
dereference: (array, data)->
|
||||
if array
|
||||
for object, i in array
|
||||
array[i] = data[object.id]
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub)->
|
||||
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Dereferencer)->
|
||||
new class Enterprises
|
||||
enterprises_by_id: {} # id/object pairs for lookup
|
||||
constructor: ->
|
||||
@@ -10,12 +10,6 @@ Darkswarm.factory 'Enterprises', (enterprises, CurrentHub)->
|
||||
dereference: ->
|
||||
if CurrentHub.hub?.id
|
||||
CurrentHub.hub = @enterprises_by_id[CurrentHub.hub.id]
|
||||
|
||||
for enterprise in @enterprises
|
||||
if enterprise.hubs
|
||||
for hub, i in enterprise.hubs
|
||||
enterprise.hubs[i] = @enterprises_by_id[hub.id]
|
||||
|
||||
if enterprise.producers
|
||||
for producer, i in enterprise.producers
|
||||
enterprise.producers[i] = @enterprises_by_id[producer.id]
|
||||
Dereferencer.dereference enterprise.hubs, @enterprises_by_id
|
||||
Dereferencer.dereference enterprise.producers, @enterprises_by_id
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
Darkswarm.factory 'Groups', (groups) ->
|
||||
Darkswarm.factory 'Groups', (groups, Enterprises, Dereferencer) ->
|
||||
new class Groups
|
||||
groups: groups
|
||||
groups_by_id: {}
|
||||
constructor: ->
|
||||
@groups = groups
|
||||
for group in @groups
|
||||
@groups_by_id[group.id] = group
|
||||
@dereference()
|
||||
dereference: ->
|
||||
for group in @groups
|
||||
Dereferencer.dereference group.enterprises, Enterprises.enterprises_by_id
|
||||
for enterprise in Enterprises.enterprises
|
||||
Dereferencer.dereference enterprise.groups, @groups_by_id
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
Darkswarm.factory 'Hubs', ($filter, Enterprises) ->
|
||||
Darkswarm.factory 'Hubs', ($filter, Enterprises, visibleFilter) ->
|
||||
new class Hubs
|
||||
constructor: ->
|
||||
@hubs = @order Enterprises.enterprises.filter (hub)->
|
||||
hub.is_distributor
|
||||
@visible = visibleFilter @hubs
|
||||
|
||||
order: (hubs)->
|
||||
$filter('orderBy')(hubs, ['-active', '+orders_close_at'])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Darkswarm.factory "OfnMap", (Enterprises, MapModal)->
|
||||
Darkswarm.factory "OfnMap", (Enterprises, MapModal, visibleFilter)->
|
||||
new class OfnMap
|
||||
constructor: ->
|
||||
@enterprises = (@extend(enterprise) for enterprise in Enterprises.enterprises)
|
||||
@enterprises = (@extend(enterprise) for enterprise in visibleFilter(Enterprises.enterprises))
|
||||
|
||||
|
||||
# Adding methods to each enterprise
|
||||
|
||||
@@ -6,7 +6,7 @@ Darkswarm.factory "MapModal", ($modal, $rootScope)->
|
||||
scope.enterprise = enterprise
|
||||
if enterprise.is_distributor
|
||||
scope.hub = enterprise
|
||||
$modal.open(templateUrl: "map_modal_hub.html", scope: scope)
|
||||
$modal.open(templateUrl: "hub_modal.html", scope: scope)
|
||||
else
|
||||
scope.producer = enterprise
|
||||
$modal.open(templateUrl: "map_modal_producer.html", scope: scope)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Navigation', ($location) ->
|
||||
Darkswarm.factory 'Navigation', ($location, $window) ->
|
||||
new class Navigation
|
||||
path: null
|
||||
|
||||
@@ -10,7 +10,6 @@ Darkswarm.factory 'Navigation', ($location) ->
|
||||
$location.path(@path)
|
||||
|
||||
toggle: (path = false)=>
|
||||
console.log "toggling"
|
||||
@path = path || @path
|
||||
if $location.path() == @path
|
||||
$location.path("/")
|
||||
@@ -18,4 +17,7 @@ Darkswarm.factory 'Navigation', ($location) ->
|
||||
@navigate(path)
|
||||
|
||||
go: (path)->
|
||||
window.location.pathname = path
|
||||
if path.match /^http/
|
||||
$window.location.href = path
|
||||
else
|
||||
$window.location.pathname = path
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
Darkswarm.factory 'Producers', (Enterprises) ->
|
||||
Darkswarm.factory 'Producers', (Enterprises, visibleFilter) ->
|
||||
new class Producers
|
||||
constructor: ->
|
||||
@producers = Enterprises.enterprises.filter (enterprise)->
|
||||
enterprise.is_primary_producer
|
||||
@visible = visibleFilter @producers
|
||||
|
||||
|
||||
9
app/assets/javascripts/shared/mm-foundation-tpls-0.2.2.min.js
vendored
Normal file
9
app/assets/javascripts/shared/mm-foundation-tpls-0.2.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
app/assets/javascripts/templates/hub_modal.html.haml
Normal file
4
app/assets/javascripts/templates/hub_modal.html.haml
Normal file
@@ -0,0 +1,4 @@
|
||||
%ng-include{src: "'partials/enterprise_header.html'"}
|
||||
%ng-include{src: "'partials/enterprise_details.html'"}
|
||||
%ng-include{src: "'partials/hub_details.html'"}
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
@@ -1,37 +1,4 @@
|
||||
.highlight
|
||||
.highlight-top
|
||||
%p.right
|
||||
{{ [enterprise.address.city, enterprise.address.state] | printArray}}
|
||||
%h3
|
||||
%i.ofn-i_036-producers
|
||||
{{ enterprise.name }}
|
||||
%img.hero-img{"ng-src" => "{{enterprise.promo_image}}"}
|
||||
|
||||
.row{bindonce: true}
|
||||
.small-12.large-8.columns
|
||||
%div{"ng-if" => "enterprise.long_description.length > 0 || enterprise.logo"}
|
||||
%h5.modal-header About
|
||||
.about-container
|
||||
%img.enterprise-logo{"bo-src" => "enterprise.logo", "bo-if" => "enterprise.logo"}
|
||||
%p.text-small{"ng-bind-html" => "enterprise.long_description"}
|
||||
.small-12.large-4.columns
|
||||
%ng-include{src: "'partials/contact.html'"}
|
||||
%ng-include{src: "'partials/follow.html'"}
|
||||
|
||||
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0"}
|
||||
.cta-container.small-12.columns
|
||||
%h5
|
||||
%i.ofn-i_029-shopping-basket
|
||||
Shop for {{enterprise.name}} products at:
|
||||
%a.button.hub{"ng-repeat" => "hub in enterprise.hubs",
|
||||
"bo-href" => "hub.path",
|
||||
"bo-class" => "{primary: hub.active, secondary: !hub.active}",
|
||||
"ofn-empties-cart" => "hub"}
|
||||
%i.ofn-i_033-open-sign{"bo-if" => "hub.active"}
|
||||
%i.ofn-i_032-closed-sign{"bo-if" => "!hub.active"}
|
||||
{{hub.name}}
|
||||
.button-address {{ hub.address.city }} , {{hub.address.state}}
|
||||
%i.ofn-i_007-caret-right
|
||||
|
||||
%a.close-reveal-modal.outside{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
%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'"}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
%a.close-reveal-modal.outside{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
@@ -5,8 +5,9 @@
|
||||
{{ enterprise.phone }}
|
||||
|
||||
%p{"ng-if" => "enterprise.email"}
|
||||
%a{"ng-href" => "mailto:{{enterprise.email | stripUrl}}", target: "_blank" }
|
||||
{{ enterprise.email | stripUrl }}
|
||||
%a{"ng-href" => "{{enterprise.email | stripUrl}}", target: "_blank", mailto: true}
|
||||
%span.email
|
||||
{{ enterprise.email | stripUrl }}
|
||||
|
||||
%p{"ng-if" => "enterprise.website"}
|
||||
%a{"ng-href" => "http://{{enterprise.website | stripUrl}}", target: "_blank" }
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
.row{bindonce: true}
|
||||
.small-12.large-8.columns
|
||||
%div{"ng-if" => "enterprise.long_description.length > 0 || enterprise.logo"}
|
||||
%h5.modal-header About
|
||||
.about-container
|
||||
%img.enterprise-logo{"bo-src" => "enterprise.logo", "bo-if" => "enterprise.logo"}
|
||||
%p.text-small{"ng-bind-html" => "enterprise.long_description"}
|
||||
.small-12.large-4.columns
|
||||
%ng-include{src: "'partials/contact.html'"}
|
||||
%ng-include{src: "'partials/follow.html'"}
|
||||
@@ -0,0 +1,9 @@
|
||||
.highlight
|
||||
.highlight-top
|
||||
%p.right
|
||||
{{ [enterprise.address.city, enterprise.address.state] | printArray}}
|
||||
%h3
|
||||
%i.ofn-i_036-producers{"ng-show" => "!enterprise.is_distributor"}
|
||||
%i.ofn-i_040-hub{"ng-show" => "enterprise.is_distributor"}
|
||||
{{ enterprise.name }}
|
||||
%img.hero-img{"ng-src" => "{{enterprise.promo_image}}"}
|
||||
@@ -0,0 +1,15 @@
|
||||
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0"}
|
||||
.cta-container.small-12.columns
|
||||
%h5
|
||||
%i.ofn-i_029-shopping-basket
|
||||
Shop for {{enterprise.name}} products at:
|
||||
%a.button.hub{"ng-repeat" => "hub in enterprise.hubs",
|
||||
"bo-href" => "hub.path",
|
||||
"bo-class" => "{primary: hub.active, secondary: !hub.active}",
|
||||
"ofn-empties-cart" => "hub"}
|
||||
%i.ofn-i_033-open-sign{"bo-if" => "hub.active"}
|
||||
%i.ofn-i_032-closed-sign{"bo-if" => "!hub.active"}
|
||||
{{hub.name}}
|
||||
.button-address {{ hub.address.city }} , {{hub.address.state}}
|
||||
%i.ofn-i_007-caret-right
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
.highlight
|
||||
.highlight-top
|
||||
%p.right
|
||||
{{ [enterprise.address.city, enterprise.address.state] | printArray}}
|
||||
%h3
|
||||
%i.ofn-i_040-hub
|
||||
{{ enterprise.name }}
|
||||
%img.hero-img{"ng-src" => "{{enterprise.promo_image}}"}
|
||||
|
||||
.row{bindonce: true}
|
||||
.small-12.large-8.columns
|
||||
%div{"ng-if" => "enterprise.long_description.length > 0 || enterprise.logo"}
|
||||
%h5.modal-header About
|
||||
.about-container
|
||||
%img.enterprise-logo{"bo-src" => "enterprise.logo", "bo-if" => "enterprise.logo"}
|
||||
%p.text-small{"ng-bind-html" => "enterprise.long_description"}
|
||||
.small-12.large-4.columns
|
||||
%ng-include{src: "'partials/contact.html'"}
|
||||
%ng-include{src: "'partials/follow.html'"}
|
||||
|
||||
.row.pad-top{bindonce: true}
|
||||
.cta-container.small-12.columns
|
||||
.row
|
||||
@@ -26,7 +6,6 @@
|
||||
%i.ofn-i_029-shopping-basket
|
||||
%span{"active-table-hub-link" => "enterprise", change: "Change hub to", shop: "Shop at"}
|
||||
.small-12.large-6.columns.right
|
||||
/ Needs logic to hide if nothing populated:
|
||||
.right{"bo-if" => "enterprise.pickup || enterprise.delivery"}
|
||||
Delivery options:
|
||||
%span{"bo-if" => "enterprise.pickup"}
|
||||
@@ -45,7 +24,3 @@
|
||||
{{enterprise.name}}
|
||||
.button-address {{ enterprise.address.city }} , {{enterprise.address.state}}
|
||||
%i.ofn-i_007-caret-right
|
||||
|
||||
%a.close-reveal-modal.outside{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
%ng-include{src: "'partials/enterprise_header.html'"}
|
||||
%ng-include{src: "'partials/enterprise_details.html'"}
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
9
app/assets/javascripts/templates/product_modal.html.haml
Normal file
9
app/assets/javascripts/templates/product_modal.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
.row
|
||||
.columns.small-12.large-6
|
||||
%img.product-img{"ng-src" => "{{product.master.images[0].large_url}}", "ng-if" => "product.master.images[0]"}
|
||||
.columns.small-12.large-6.product-header
|
||||
%h2
|
||||
%render-svg{path: "{{product.primary_taxon.icon}}"}
|
||||
{{product.name}}
|
||||
%p {{product.description}}
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
30
app/assets/stylesheets/darkswarm/animations.sass
Normal file
30
app/assets/stylesheets/darkswarm/animations.sass
Normal file
@@ -0,0 +1,30 @@
|
||||
.fade
|
||||
opacity: 0
|
||||
-webkit-transition: opacity .15s linear
|
||||
transition: opacity .15s linear
|
||||
|
||||
.fade.in
|
||||
opacity: 1
|
||||
|
||||
.reveal-modal.fade
|
||||
-webkit-transition: -webkit-transform .3s ease-out
|
||||
-moz-transition: -moz-transform .3s ease-out
|
||||
-o-transition: -o-transform .3s ease-out
|
||||
transition: transform .3s ease-out
|
||||
-webkit-transform: translate(0, -25%)
|
||||
-ms-transform: translate(0, -25%)
|
||||
transform: translate(0, -25%)
|
||||
|
||||
.reveal-modal.in
|
||||
-webkit-transform: translate(0, 0)
|
||||
-ms-transform: translate(0, 0)
|
||||
transform: translate(0, 0)
|
||||
|
||||
.reveal-modal-bg.fade
|
||||
filter: alpha(opacity = 0)
|
||||
opacity: 0
|
||||
|
||||
.reveal-modal-bg.in
|
||||
filter: alpha(opacity = 50)
|
||||
opacity: .5
|
||||
|
||||
@@ -7,19 +7,24 @@
|
||||
background-color: black
|
||||
background-image: url("/assets/home/tagline-bg.jpg")
|
||||
@include fullbg
|
||||
height: 400px
|
||||
height: 500px
|
||||
padding: 40px 0px
|
||||
h1, h2, p
|
||||
h1, h2, span, small, timer
|
||||
color: white
|
||||
p
|
||||
color: $clr-brick-light
|
||||
h1
|
||||
margin-bottom: 1em
|
||||
margin-bottom: 3rem
|
||||
h2
|
||||
font-size: 1.6875rem
|
||||
max-width: 610px
|
||||
margin: 0 auto
|
||||
padding-bottom: 0.5rem
|
||||
|
||||
a
|
||||
color: $clr-brick-bright
|
||||
&:hover, &:active, &:focus
|
||||
color: $clr-brick-light-bright
|
||||
@include textsoftpress
|
||||
@include textsoftpress
|
||||
a.button.primary
|
||||
color: white
|
||||
@@ -21,7 +21,7 @@
|
||||
.hero-img-small
|
||||
background-color: #333
|
||||
width: 100%
|
||||
min-height: 60px
|
||||
// min-height: 60px
|
||||
height: inherit
|
||||
overflow: hidden
|
||||
margin: 0 0 1rem 0 !important
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
max-height: 200px
|
||||
min-height: 20px
|
||||
margin-bottom: 0.5rem
|
||||
overflow: scroll
|
||||
overflow-y: scroll
|
||||
overflow-x: hidden
|
||||
border-bottom: 1px solid #999
|
||||
@include box-shadow(0 2px 2px -2px #999)
|
||||
|
||||
|
||||
@@ -4,4 +4,11 @@
|
||||
.producers
|
||||
@include fullwidthbg
|
||||
background-image: url("/assets/producers/producers-pg-bg.jpg")
|
||||
background-repeat: no-repeat
|
||||
background-repeat: no-repeat
|
||||
a
|
||||
color: $clr-turquoise
|
||||
&:hover, &:active, &:focus
|
||||
color: $clr-turquoise-bright
|
||||
a.button.primary
|
||||
&:hover, &:active, &:focus
|
||||
color: white
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
|
||||
ordercycle
|
||||
p.text-right
|
||||
max-width: 400px
|
||||
@media all and (max-width: 640px)
|
||||
float: left
|
||||
clear: left
|
||||
@@ -45,6 +47,8 @@
|
||||
width: 100%
|
||||
margin-top: 10px
|
||||
background: #e5e5e5
|
||||
p.text-right
|
||||
max-width: 100%
|
||||
float: right
|
||||
form.custom
|
||||
text-align: right
|
||||
|
||||
@@ -2,10 +2,27 @@
|
||||
@import mixins
|
||||
@import branding
|
||||
|
||||
// Foundation overrides
|
||||
#tabs .tabs-content > .content p
|
||||
max-width: 100% !important
|
||||
|
||||
.tabs-content > .content
|
||||
padding-top: 0 !important
|
||||
|
||||
// Tabs styling
|
||||
|
||||
#tabs
|
||||
background: url("/assets/gray_jean.png") top left repeat
|
||||
@include box-shadow(inset 0 2px 3px 0 rgba(0,0,0,0.15))
|
||||
display: block
|
||||
color: $dark-grey
|
||||
|
||||
.panel
|
||||
border-color: rgba(219, 88, 61, 0.5)
|
||||
background-color: rgba(255, 255, 255, 0)
|
||||
// @include box-shadow( 0 1px 1px 0 rgba(255,255,255,1))
|
||||
|
||||
|
||||
|
||||
dl dd a
|
||||
@include avenir
|
||||
|
||||
@@ -138,9 +138,8 @@ class CheckoutController < Spree::CheckoutController
|
||||
render :edit and return
|
||||
end
|
||||
|
||||
redirect_to(main_app.shop_paypal_payment_url(@order, :payment_method_id => payment_method.id))
|
||||
render json: {path: main_app.paypal_payment_url(@order, :payment_method_id => payment_method.id)}, status: 200
|
||||
true
|
||||
|
||||
end
|
||||
|
||||
# Overriding to customize the cancel url
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
module SharedHelper
|
||||
def inject_enterprises
|
||||
inject_json "enterprises" , "enterprises"
|
||||
inject_json_ams "enterprises", Enterprise.all, Api::EnterpriseSerializer, active_distributors: @active_distributors
|
||||
end
|
||||
|
||||
def inject_json(name, partial, opts = {})
|
||||
render partial: "json/injection", locals: {name: name, partial: partial}.merge(opts)
|
||||
end
|
||||
|
||||
def inject_json_ams(name, data, serializer, opts = {})
|
||||
json = ActiveModel::ArraySerializer.new(data, {each_serializer: serializer}.merge(opts)).to_json
|
||||
render partial: "json/injection_ams", locals: {name: name, json: json}
|
||||
end
|
||||
|
||||
def distributor_link_class(distributor)
|
||||
cart = current_order(true)
|
||||
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
|
||||
|
||||
@@ -156,7 +156,7 @@ class Enterprise < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def distributors
|
||||
self.relatives.is_distributor.visible
|
||||
self.relatives.is_distributor
|
||||
end
|
||||
|
||||
def website
|
||||
@@ -170,7 +170,7 @@ class Enterprise < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def suppliers
|
||||
self.relatives.is_primary_producer.visible
|
||||
self.relatives.is_primary_producer
|
||||
end
|
||||
|
||||
def distributed_variants
|
||||
@@ -187,15 +187,17 @@ class Enterprise < ActiveRecord::Base
|
||||
|
||||
# Return all taxons for all distributed products
|
||||
def distributed_taxons
|
||||
Spree::Product.in_distributor(self).map do |p|
|
||||
p.taxons
|
||||
end.flatten.uniq
|
||||
Spree::Taxon.
|
||||
joins(:products).
|
||||
where('spree_products.id IN (?)', Spree::Product.in_distributor(self)).
|
||||
select('DISTINCT spree_taxons.*')
|
||||
end
|
||||
# Return all taxons for all supplied products
|
||||
def supplied_taxons
|
||||
Spree::Product.in_supplier(self).map do |p|
|
||||
p.taxons
|
||||
end.flatten.uniq
|
||||
Spree::Taxon.
|
||||
joins(:products).
|
||||
where('spree_products.id IN (?)', Spree::Product.in_supplier(self)).
|
||||
select('DISTINCT spree_taxons.*')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
7
app/serializers/api/address_serializer.rb
Normal file
7
app/serializers/api/address_serializer.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class Api::AddressSerializer < ActiveModel::Serializer
|
||||
attributes :id, :zipcode, :city, :state
|
||||
|
||||
def state
|
||||
object.state.abbr
|
||||
end
|
||||
end
|
||||
62
app/serializers/api/enterprise_serializer.rb
Normal file
62
app/serializers/api/enterprise_serializer.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
class Api::EnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :description, :latitude, :longitude,
|
||||
:long_description, :website, :instagram, :linkedin, :twitter,
|
||||
:facebook, :is_primary_producer, :is_distributor, :phone, :visible,
|
||||
:email, :hash, :logo, :promo_image, :icon, :path,
|
||||
:pickup, :delivery, :active, :orders_close_at
|
||||
|
||||
has_many :distributed_taxons, key: :taxons, serializer: Api::TaxonSerializer
|
||||
has_many :supplied_taxons, serializer: Api::TaxonSerializer
|
||||
has_many :distributors, key: :hubs, serializer: Api::IdSerializer
|
||||
has_many :suppliers, key: :producers, serializer: Api::IdSerializer
|
||||
|
||||
has_one :address, serializer: Api::AddressSerializer
|
||||
|
||||
def pickup
|
||||
object.shipping_methods.where(:require_ship_address => false).present?
|
||||
end
|
||||
|
||||
def delivery
|
||||
object.shipping_methods.where(:require_ship_address => true).present?
|
||||
end
|
||||
|
||||
def active
|
||||
@options[:active_distributors].andand.include?(object)
|
||||
end
|
||||
|
||||
def orders_close_at
|
||||
OrderCycle.first_closing_for(object).andand.orders_close_at
|
||||
end
|
||||
|
||||
def email
|
||||
object.email.to_s.reverse
|
||||
end
|
||||
|
||||
def hash
|
||||
object.to_param
|
||||
end
|
||||
|
||||
def logo
|
||||
object.logo(:medium) if object.logo.exists?
|
||||
end
|
||||
|
||||
def promo_image
|
||||
object.promo_image(:large) if object.promo_image.exists?
|
||||
end
|
||||
|
||||
def icon
|
||||
if object.is_primary_producer? and object.is_distributor?
|
||||
"/assets/map-icon-both.svg"
|
||||
elsif object.is_primary_producer?
|
||||
"/assets/map-icon-producer.svg"
|
||||
else
|
||||
"/assets/map-icon-hub.svg"
|
||||
end
|
||||
end
|
||||
|
||||
# TODO when ActiveSerializers supports URL helpers
|
||||
# Then refactor. See readme https://github.com/rails-api/active_model_serializers
|
||||
def path
|
||||
"/enterprises/#{object.to_param}/shop"
|
||||
end
|
||||
end
|
||||
3
app/serializers/api/id_serializer.rb
Normal file
3
app/serializers/api/id_serializer.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
class Api::IdSerializer < ActiveModel::Serializer
|
||||
attributes :id
|
||||
end
|
||||
7
app/serializers/api/taxon_serializer.rb
Normal file
7
app/serializers/api/taxon_serializer.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class Api::TaxonSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :permalink, :icon
|
||||
|
||||
def icon
|
||||
object.icon(:original)
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
= inject_enterprises
|
||||
|
||||
:javascript
|
||||
angular.module('Darkswarm').value('groups', #{render partial: "json/groups", object: @groups})
|
||||
|
||||
@@ -19,7 +20,7 @@
|
||||
"ng-debounce" => "150",
|
||||
"ofn-disable-enter" => true}
|
||||
|
||||
.group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order",
|
||||
.group{"ng-repeat" => "group in Groups.groups | groups:query | orderBy:order",
|
||||
name: "group{{group.id}}",
|
||||
id: "group{{group.id}}"}
|
||||
.row.pad-top{bindonce: true}
|
||||
@@ -36,10 +37,12 @@
|
||||
.small-6.columns
|
||||
%p {{ group.long_description }}
|
||||
.small-6.columns
|
||||
%h5 Our hubs & producers
|
||||
%h5 Our hubs & producers
|
||||
%ul.small-block-grid-2
|
||||
%li{"ng-repeat" => "enterprise in group.enterprises"}
|
||||
%a{"bo-href" => "enterprise.path"} {{ enterprise.name }}
|
||||
%li{"ng-repeat" => "enterprise in group.enterprises", "scroll-after-load" => true}
|
||||
%hub-modal{"ng-if" => "enterprise.is_distributor"}
|
||||
%producer-modal{"ng-if" => "!enterprise.is_distributor", "show-hub-actions" => 'true'}
|
||||
{{ enterprise.name }}
|
||||
|
||||
.row.group_footer
|
||||
.small-12.columns
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
Our producers
|
||||
%ul.bullet-list
|
||||
%li{"ng-repeat" => "enterprise in hub.producers"}
|
||||
= render partial: "modals/producer"
|
||||
%producer-modal {{ enterprise.name }}
|
||||
|
||||
.row.active_table_row.link{"ng-show" => "open()", "bo-if" => "hub.active"}
|
||||
.row.active_table_row.link{"ng-show" => "open()"}
|
||||
.cta-container.columns.small-12
|
||||
.row
|
||||
.columns.small-12
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
.row
|
||||
.small-12.text-center.columns
|
||||
%h1= image_tag "ofn_logo_beta.png", title: "Open Food Network (beta)"
|
||||
%h2 An open marketplace that makes it easy to find, buy, sell and move sustainable local food.
|
||||
|
||||
%ofn-modal{title: "Learn more"}
|
||||
= render partial: "modals/learn_more"
|
||||
%h2 We're crowdfunding right now!
|
||||
%h5
|
||||
%timer{"end-time" => '1407679200000'}
|
||||
{{days}} days, {{hours}} hrs, {{minutes}} mins & {{seconds}} secs to go
|
||||
%p Help us make Open Food Network the best it can be:
|
||||
%a.button.primary{href: "http://startsomegood.com/openfoodnetwork", target:"_blank"} Support now
|
||||
/ %h2 An open marketplace that makes it easy to find, buy, sell and move sustainable local food.
|
||||
%br
|
||||
%ofn-modal{title: "Learn more"}
|
||||
= render partial: "modals/learn_more"
|
||||
|
||||
= render partial: "home/hubs"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ collection @groups
|
||||
attributes :id, :name, :position, :description, :long_description
|
||||
|
||||
child enterprises: :enterprises do
|
||||
extends 'json/enterprises'
|
||||
attributes :id
|
||||
end
|
||||
|
||||
node :logo do |group|
|
||||
|
||||
2
app/views/json/_injection_ams.html.haml
Normal file
2
app/views/json/_injection_ams.html.haml
Normal file
@@ -0,0 +1,2 @@
|
||||
:javascript
|
||||
angular.module('Darkswarm').value("#{name.to_s}", #{json})
|
||||
@@ -13,8 +13,10 @@ end
|
||||
node :delivery do |hub|
|
||||
hub.shipping_methods.where(:require_ship_address => true).present?
|
||||
end
|
||||
node :active do |hub|
|
||||
@active_distributors.include?(hub)
|
||||
if @active_distributors
|
||||
node :active do |hub|
|
||||
@active_distributors.include?(hub)
|
||||
end
|
||||
end
|
||||
node :orders_close_at do |hub|
|
||||
OrderCycle.first_closing_for(hub).andand.orders_close_at
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
%meta{name: 'viewport', content: "width=device-width,initial-scale=1.0"}/
|
||||
|
||||
%title= content_for?(:title) ? yield(:title) : 'Welcome to Open Food Network'
|
||||
= favicon_link_tag "favicon.png"
|
||||
%link{href: "http://fonts.googleapis.com/css?family=Open+Sans:400,700", rel: "stylesheet", type: "text/css"}/
|
||||
- if Rails.env.production?
|
||||
= favicon_link_tag
|
||||
- else
|
||||
= favicon_link_tag "/favicon-staging.ico"
|
||||
%link{href: "https://fonts.googleapis.com/css?family=Open+Sans:400,700", rel: "stylesheet", type: "text/css"}/
|
||||
|
||||
= yield :scripts
|
||||
%script{src: "//maps.googleapis.com/maps/api/js?sensor=false"}
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
{{ enterprise.phone }}
|
||||
|
||||
%p{"bo-if" => "enterprise.email"}
|
||||
%a{"ng-href" => "mailto:{{enterprise.email | stripUrl}}", target: "_blank" }
|
||||
{{ enterprise.email | stripUrl }}
|
||||
%a{"ng-href" => "{{enterprise.email | stripUrl}}", target: "_blank", mailto: true }
|
||||
%span.email
|
||||
{{ enterprise.email | stripUrl }}
|
||||
|
||||
%p{"bo-show" => "enterprise.website"}
|
||||
%a{"ng-href" => "http://{{enterprise.website}}", target: "_blank" }
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
%ofn-modal{title: "{{product.name}}"}
|
||||
.row
|
||||
.columns.small-12.large-6
|
||||
%img.product-img{"ng-src" => "{{product.master.images[0].large_url}}", "ng-if" => "product.master.images[0]"}
|
||||
.columns.small-12.large-6.product-header
|
||||
%h2
|
||||
%render-svg{path: "{{product.primary_taxon.icon}}"}
|
||||
{{product.name}}
|
||||
%p {{product.description}}
|
||||
%a.close-reveal-modal{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
@@ -14,16 +14,16 @@
|
||||
%i.ofn-i_020-search
|
||||
%input{type: :text,
|
||||
"ng-model" => "query",
|
||||
placeholder: "Search postcode, suburb or hub name...",
|
||||
placeholder: "Search postcode, suburb or producer name...",
|
||||
"ng-debounce" => "150",
|
||||
"ofn-disable-enter" => true}
|
||||
|
||||
.row{bindonce: true}
|
||||
.small-12.columns
|
||||
.active_table
|
||||
%producer.active_table_node.row{id: "{{producer.path}}",
|
||||
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
|
||||
"scroll-after-load" => true,
|
||||
"ng-repeat" => "producer in filteredProducers = (Producers.producers | filterProducers:query)",
|
||||
"ng-repeat" => "producer in filteredProducers = (Producers.visible | filterProducers:query)",
|
||||
"ng-controller" => "ProducerNodeCtrl",
|
||||
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",
|
||||
id: "{{producer.hash}}"}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
%input.button.primary.right{type: :submit, value: "Add to Cart"}
|
||||
|
||||
%div{bindonce: true}
|
||||
%product{"ng-controller" => "ProductNodeCtrl",
|
||||
%product.animate-repeat{"ng-controller" => "ProductNodeCtrl",
|
||||
"ng-repeat" => "product in Product.products | products:query | orderBy:ordering.order | limitTo: limit track by product.id"}
|
||||
%div
|
||||
= render partial: "shop/products/summary"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.small-1.columns
|
||||
%span.bulk{"bo-if" => "product.group_buy"} bulk
|
||||
%i.ofn-i_056-bulk{"bo-if" => "product.group_buy"}
|
||||
|
||||
|
||||
.small-4.columns
|
||||
@@ -15,7 +15,7 @@
|
||||
name: "variants[{{product.master.id}}]",
|
||||
id: "variants_{{product.master.id}}",
|
||||
"ng-model" => "product.quantity"}
|
||||
%small {{ product.master.unit_to_display }}
|
||||
%small x {{ product.master.unit_to_display }}
|
||||
|
||||
-# WITH GROUP BUY
|
||||
.small-2.columns{"bo-if" => "product.group_buy"}
|
||||
@@ -36,7 +36,7 @@
|
||||
max: "{{product.on_demand && 9999 || product.count_on_hand }}",
|
||||
name: "variant_attributes[{{product.master.id}}][max_quantity]",
|
||||
"ng-model" => "product.max_quantity"}
|
||||
{{ product.master.unit_to_display }}
|
||||
%small x {{ product.master.unit_to_display }}
|
||||
|
||||
.small-2.columns.text-right
|
||||
{{ product.price | currency }}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
.row.summary
|
||||
.small-1.columns
|
||||
%img{"bo-src" => "product.master.images[0].small_url"}
|
||||
%product-modal
|
||||
%img{"bo-src" => "product.master.images[0].small_url"}
|
||||
|
||||
.small-4.columns.summary-header
|
||||
%render-svg{path: "{{product.primary_taxon.icon}}"}
|
||||
= render partial: "modals/product"
|
||||
%product-modal {{ product.name }}
|
||||
|
||||
.small-5.columns
|
||||
%i.ofn-i_036-producers
|
||||
= render partial: "modals/producer"
|
||||
%producer-modal {{ enterprise.name }}
|
||||
|
||||
.small-2.columns.summary-price.text-right.price
|
||||
%span{"ng-if" => "hasVariants"}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"ng-repeat" => "variant in product.variants"}
|
||||
|
||||
.small-1.columns
|
||||
%span.bulk{"bo-if" => "product.group_buy"} bulk
|
||||
%i.ofn-i_056-bulk{"bo-if" => "product.group_buy"}
|
||||
|
||||
|
||||
.small-4.columns
|
||||
@@ -18,7 +18,7 @@
|
||||
max: "{{variant.on_demand && 9999 || variant.count_on_hand }}",
|
||||
name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}",
|
||||
"bo-model" => "variant.quantity"}
|
||||
%small {{ variant.unit_to_display }}
|
||||
%small x {{ variant.unit_to_display }}
|
||||
|
||||
-# WITH GROUP BUY
|
||||
.small-2.columns{"bo-if" => "product.group_buy"}
|
||||
@@ -39,7 +39,7 @@
|
||||
max: "{{variant.on_demand && 9999 || variant.count_on_hand }}",
|
||||
name: "variant_attributes[{{variant.id}}][max_quantity]",
|
||||
"ng-model" => "variant.max_quantity"}
|
||||
%small {{ variant.unit_to_display }}
|
||||
%small x {{ variant.unit_to_display }}
|
||||
|
||||
.small-2.columns.text-right.price
|
||||
{{ variant.price | currency }}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
.content#about{"ng-controller" => "AboutUsCtrl", bindonce: true}
|
||||
.row
|
||||
.small-12.large-6.columns
|
||||
%img.hero-img-small{"bo-src" => "CurrentHub.hub.promo_image"}
|
||||
%p.small-text{"bo-html" => "CurrentHub.hub.long_description"}
|
||||
.small-12.large-3.columns
|
||||
.small-12.large-8.columns.panel
|
||||
%img.hero-img-small{"bo-src" => "CurrentHub.hub.promo_image", "bo-if" => "CurrentHub.hub.promo_image"}
|
||||
%p{"bo-html" => "CurrentHub.hub.long_description"}
|
||||
.small-12.large-4.columns
|
||||
|
||||
.small-12.large-3.columns
|
||||
%img{"bo-src" => "CurrentHub.hub.logo", "bo-if" => "CurrentHub.hub.logo"}
|
||||
|
||||
@@ -4,52 +4,57 @@
|
||||
.panel
|
||||
.row
|
||||
.small-12.large-4.columns
|
||||
%h4=current_distributor.name
|
||||
%p
|
||||
= current_distributor.address.address1
|
||||
- unless current_distributor.address.address2.blank?
|
||||
%br
|
||||
= current_distributor.address.address2
|
||||
%br
|
||||
= current_distributor.address.city
|
||||
= current_distributor.address.state
|
||||
= current_distributor.address.zipcode
|
||||
- if current_distributor.address.address1 || current_distributor.address.address2 || current_distributor.address.city || current_distributor.address.state || current_distributor.address.zipcode
|
||||
%div.modal-centered
|
||||
%h5.modal-header=current_distributor.name
|
||||
%p
|
||||
= current_distributor.address.address1
|
||||
- unless current_distributor.address.address2.blank?
|
||||
%br
|
||||
= current_distributor.address.address2
|
||||
%br
|
||||
= current_distributor.address.city
|
||||
= current_distributor.address.state
|
||||
= current_distributor.address.zipcode
|
||||
|
||||
.small-12.large-8.columns
|
||||
%ul.small-block-grid-1.large-block-grid-2{bindonce: true}
|
||||
- unless current_distributor.website.blank?
|
||||
%li
|
||||
%a{href: "http://#{current_distributor.website}", target: "_blank" }
|
||||
%i.ofn-i_049-web
|
||||
= current_distributor.website
|
||||
.small-12.large-4.columns
|
||||
- if current_distributor.website || current_distributor.email
|
||||
%div.modal-centered
|
||||
%h5.modal-header Contact
|
||||
- unless current_distributor.website.blank?
|
||||
%p
|
||||
%a{href: "http://#{current_distributor.website}", target: "_blank" }
|
||||
= current_distributor.website
|
||||
- unless current_distributor.email.blank?
|
||||
%p
|
||||
%a{href: current_distributor.email.reverse, mailto: true}
|
||||
%span.email
|
||||
= current_distributor.email.reverse
|
||||
|
||||
- unless current_distributor.email.blank?
|
||||
%li
|
||||
%a{href: current_distributor.email.reverse, mailto: true }
|
||||
%i.ofn-i_050-mail-circle
|
||||
%span.email
|
||||
= current_distributor.email.reverse
|
||||
.small-12.large-4.columns
|
||||
- if current_distributor.twitter.present? || current_distributor.facebook.present? || current_distributor.linkedin.present? || current_distributor.instagram.present?
|
||||
%div.modal-centered
|
||||
%h5.modal-header Follow
|
||||
%div.follow-icons
|
||||
- unless current_distributor.twitter.blank?
|
||||
%span
|
||||
%a{href: "http://twitter.com/#{current_distributor.twitter}", target: "_blank" }
|
||||
%i.ofn-i_041-twitter
|
||||
|
||||
- unless current_distributor.twitter.blank?
|
||||
%li
|
||||
%a{href: "http://twitter.com/#{current_distributor.twitter}", target: "_blank" }
|
||||
%i.ofn-i_041-twitter
|
||||
= current_distributor.twitter
|
||||
- unless current_distributor.facebook.blank?
|
||||
%span
|
||||
%a{href: "http://#{current_distributor.facebook}", target: "_blank" }
|
||||
%i.ofn-i_044-facebook
|
||||
= current_distributor.facebook
|
||||
|
||||
- unless current_distributor.facebook.blank?
|
||||
%li
|
||||
%a{href: "http://#{current_distributor.facebook}", target: "_blank" }
|
||||
%i.ofn-i_044-facebook
|
||||
= current_distributor.facebook
|
||||
- unless current_distributor.linkedin.blank?
|
||||
%span
|
||||
%a{href: "http://#{current_distributor.linkedin}", target: "_blank" }
|
||||
%i.ofn-i_042-linkedin
|
||||
= current_distributor.linkedin
|
||||
|
||||
- unless current_distributor.linkedin.blank?
|
||||
%li
|
||||
%a{href: "http://#{current_distributor.linkedin}", target: "_blank" }
|
||||
%i.ofn-i_042-linkedin
|
||||
= current_distributor.linkedin
|
||||
|
||||
- unless current_distributor.instagram.blank?
|
||||
%li
|
||||
%a{href: "http://instagram.com.#{current_distributor.instagram}", target: "_blank" }
|
||||
%i.ofn-i_043-instagram
|
||||
= current_distributor.instagram
|
||||
- unless current_distributor.instagram.blank?
|
||||
%span
|
||||
%a{href: "http://instagram.com.#{current_distributor.instagram}", target: "_blank" }
|
||||
%i.ofn-i_043-instagram
|
||||
= current_distributor.instagram
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.content
|
||||
.row
|
||||
.small-12.columns
|
||||
%h5
|
||||
=current_distributor.name
|
||||
belongs to:
|
||||
%ul.bullet-list
|
||||
- for group in current_distributor.groups
|
||||
%li
|
||||
%a{href: main_app.groups_path(anchor: "#/#group#{group.id}")}= group.name
|
||||
.small-12.columns.panel
|
||||
- if current_distributor.groups.length > 0
|
||||
%h5
|
||||
=current_distributor.name
|
||||
is part of:
|
||||
%ul.bullet-list
|
||||
- for group in current_distributor.groups
|
||||
%li
|
||||
%a{href: main_app.groups_path + "/#/#group#{group.id}"}
|
||||
= group.name
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
angular.module('Darkswarm').value('orderCycleData', #{render "json/order_cycle"})
|
||||
|
||||
- if @order_cycles and @order_cycles.empty?
|
||||
Orders are currently closed for this hub
|
||||
%p
|
||||
Please contact your hub directly to see if they accept late orders,
|
||||
or wait until the next cycle opens.
|
||||
|
||||
= render partial: "shopping_shared/next_order_cycle"
|
||||
= render partial: "shopping_shared/last_order_cycle"
|
||||
%h4.text-right
|
||||
%i.ofn-i_032-closed-sign
|
||||
Orders are closed
|
||||
%p.text-right Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)
|
||||
.text-right
|
||||
%small
|
||||
%em
|
||||
= render partial: "shopping_shared/next_order_cycle"
|
||||
= render partial: "shopping_shared/last_order_cycle"
|
||||
|
||||
- else
|
||||
%form.custom
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.content#producers{"ng-controller" => "ProducersTabCtrl"}
|
||||
.row
|
||||
.small-12.columns
|
||||
%h5
|
||||
= "#{current_distributor.name}'s producers:"
|
||||
.small-12.columns.panel
|
||||
%h5
|
||||
{{CurrentHub.hub.name}}'s producers:
|
||||
%ul.bullet-list
|
||||
%li{"ng-repeat" => "enterprise in CurrentHub.hub.producers"}
|
||||
= render partial: "modals/producer"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
- @body_id = 'cart'
|
||||
= inject_enterprises
|
||||
|
||||
.darkswarm
|
||||
- content_for :order_cycle_form do
|
||||
%strong.avenir
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
= inject_enterprises
|
||||
|
||||
.darkswarm
|
||||
- content_for :order_cycle_form do
|
||||
%strong.avenir
|
||||
|
||||
2
config/initializers/serializers.rb
Normal file
2
config/initializers/serializers.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
ActiveModel::ArraySerializer.root = false
|
||||
ActiveModel::Serializer.root = false
|
||||
@@ -3,11 +3,7 @@ Openfoodnetwork::Application.routes.draw do
|
||||
|
||||
get "/#/login", to: "home#index", as: :spree_login
|
||||
|
||||
if Rails.env.production?
|
||||
get "/map", to: "home#index", as: :map
|
||||
else
|
||||
get "/map", to: "map#index", as: :map
|
||||
end
|
||||
get "/map", to: "map#index", as: :map
|
||||
|
||||
resource :shop, controller: "shop" do
|
||||
get :products
|
||||
@@ -20,7 +16,7 @@ Openfoodnetwork::Application.routes.draw do
|
||||
|
||||
get '/checkout', :to => 'checkout#edit' , :as => :checkout
|
||||
put '/checkout', :to => 'checkout#update' , :as => :update_checkout
|
||||
get "/checkout/paypal_payment", to: 'checkout#paypal_payment', as: :paypal_payment
|
||||
get '/checkout/paypal_payment/:order_id', to: 'checkout#paypal_payment', as: :paypal_payment
|
||||
|
||||
resources :enterprises do
|
||||
collection do
|
||||
|
||||
BIN
public/favicon-staging.ico
Normal file
BIN
public/favicon-staging.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 1.4 KiB |
@@ -1,9 +1,17 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe GroupsController do
|
||||
render_views
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
let!(:group) { create(:enterprise_group, enterprises: [enterprise], on_front_page: true) }
|
||||
it "gets all visible groups" do
|
||||
EnterpriseGroup.stub_chain :on_front_page, :by_position
|
||||
EnterpriseGroup.should_receive :on_front_page
|
||||
get :index
|
||||
end
|
||||
|
||||
it "loads all enterprises for group" do
|
||||
get :index
|
||||
response.body.should have_text enterprise.id
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,14 +14,15 @@ describe HomeController do
|
||||
assigns[:active_distributors].should == [distributor]
|
||||
end
|
||||
|
||||
it "does not show invisible hubs" do
|
||||
# Exclusion from actual rendered view handled in features/consumer/home
|
||||
it "shows JSON for invisible hubs" do
|
||||
get :index
|
||||
response.body.should_not have_content invisible_distributor.name
|
||||
response.body.should have_content invisible_distributor.name
|
||||
end
|
||||
|
||||
# This is done inside the json/hubs RABL template
|
||||
# This is done inside the json/hubs Serializer
|
||||
it "gets the next order cycle for each hub" do
|
||||
OrderCycle.should_receive(:first_closing_for).with(distributor)
|
||||
OrderCycle.should_receive(:first_closing_for).twice
|
||||
get :index
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ describe ProducersController do
|
||||
|
||||
before do
|
||||
Enterprise.stub(:distributors_with_active_order_cycles).and_return [distributor]
|
||||
Enterprise.stub(:visible).and_return [distributor]
|
||||
Enterprise.stub(:all).and_return [distributor]
|
||||
end
|
||||
|
||||
it "sets active distributors" do
|
||||
|
||||
21
spec/features/consumer/groups_spec.rb
Normal file
21
spec/features/consumer/groups_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require 'spec_helper'
|
||||
|
||||
feature 'Groups', js: true do
|
||||
include AuthenticationWorkflow
|
||||
include UIComponentHelper
|
||||
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
let!(:group) { create(:enterprise_group, enterprises: [enterprise], on_front_page: true) }
|
||||
|
||||
it "renders groups" do
|
||||
visit groups_path
|
||||
page.should have_content group.name
|
||||
end
|
||||
|
||||
it "renders enterprise modals for groups" do
|
||||
visit groups_path
|
||||
page.should have_content enterprise.name
|
||||
open_enterprise_modal enterprise
|
||||
modal_should_be_open_for enterprise
|
||||
end
|
||||
end
|
||||
@@ -5,20 +5,27 @@ feature 'Home', js: true do
|
||||
include UIComponentHelper
|
||||
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:invisible_distributor) { create(:distributor_enterprise, visible: false) }
|
||||
let(:d1) { create(:distributor_enterprise) }
|
||||
let(:d2) { create(:distributor_enterprise) }
|
||||
let!(:order_cycle) { create(:order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise)) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
let!(:er) { create(:enterprise_relationship, parent: distributor, child: producer) }
|
||||
|
||||
before do
|
||||
visit "/"
|
||||
end
|
||||
|
||||
it "shows all hubs" do
|
||||
it "shows hubs" do
|
||||
page.should have_content distributor.name
|
||||
expand_active_table_node distributor.name
|
||||
page.should have_content "Shop at #{distributor.name}"
|
||||
end
|
||||
|
||||
it "does not show invisible hubs" do
|
||||
page.should_not have_content invisible_distributor.name
|
||||
end
|
||||
|
||||
it "should grey out hubs that are not in an order cycle" do
|
||||
create(:simple_product, distributors: [d1, d2])
|
||||
visit root_path
|
||||
@@ -30,4 +37,11 @@ feature 'Home', js: true do
|
||||
follow_active_table_node distributor.name
|
||||
current_path.should == "/shop"
|
||||
end
|
||||
|
||||
it "should show hub producer modals" do
|
||||
expand_active_table_node distributor.name
|
||||
page.should have_content producer.name
|
||||
open_enterprise_modal producer
|
||||
modal_should_be_open_for producer
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ feature %q{
|
||||
}, js: true do
|
||||
include UIComponentHelper
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
let!(:invisible_producer) { create(:supplier_enterprise, visible: false) }
|
||||
|
||||
before do
|
||||
visit producers_path
|
||||
@@ -17,4 +18,8 @@ feature %q{
|
||||
expand_active_table_node producer.name
|
||||
page.should have_content producer.supplied_taxons.join(', ')
|
||||
end
|
||||
|
||||
it "doesn't show invisible producers" do
|
||||
page.should_not have_content invisible_producer.name
|
||||
end
|
||||
end
|
||||
|
||||
@@ -79,6 +79,9 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
page.should have_content product.name
|
||||
page.should have_content product.master.display_name
|
||||
page.should have_content product.master.display_as
|
||||
|
||||
open_product_modal product
|
||||
modal_should_be_open_for product
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -196,7 +199,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
context "when no order cycles are available" do
|
||||
it "tells us orders are closed" do
|
||||
visit shop_path
|
||||
page.should have_content "Orders are currently closed for this hub"
|
||||
page.should have_content "Orders are closed"
|
||||
end
|
||||
it "shows the last order cycle" do
|
||||
oc1 = create(:simple_order_cycle, distributors: [distributor], orders_close_at: 10.days.ago)
|
||||
|
||||
@@ -23,4 +23,18 @@ describe SharedHelper do
|
||||
helper.stub(:current_order) { order }
|
||||
helper.distributor_link_class(d1).should =~ /empties-cart/
|
||||
end
|
||||
|
||||
describe "Injecting json" do
|
||||
let(:enterprise) { create(:distributor_enterprise, facebook: "roger") }
|
||||
|
||||
it "Will inject via AMS" do
|
||||
helper.inject_json_ams("test", [enterprise], Api::EnterpriseSerializer).should match enterprise.name
|
||||
end
|
||||
|
||||
it "injects enterprises" do
|
||||
Enterprise.stub(:visible).and_return [enterprise]
|
||||
helper.inject_enterprises().should match enterprise.name
|
||||
helper.inject_enterprises().should match enterprise.facebook
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
describe "filtering Groups", ->
|
||||
filterGroups = null
|
||||
groups = [{
|
||||
name: "test"
|
||||
long_description: "roger"
|
||||
enterprises: [{
|
||||
name: "kittens"
|
||||
}, {
|
||||
name: "kittens"
|
||||
}]
|
||||
}, {
|
||||
name: "blankness"
|
||||
long_description: "in the sky"
|
||||
enterprises: [{
|
||||
name: "ponies"
|
||||
}, {
|
||||
name: "ponies"
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
beforeEach ->
|
||||
module 'Darkswarm'
|
||||
inject ($filter) ->
|
||||
filterGroups = $filter('groups')
|
||||
|
||||
it "filters by name", ->
|
||||
expect(filterGroups(groups, "test")[0]).toBe groups[0]
|
||||
|
||||
it "filters by description", ->
|
||||
expect(filterGroups(groups, "sky")[0]).toBe groups[1]
|
||||
|
||||
it "filters by enterprise name", ->
|
||||
expect(filterGroups(groups, "ponies")[0]).toBe groups[1]
|
||||
@@ -1,11 +0,0 @@
|
||||
describe 'Navigation service', ->
|
||||
Navigation = null
|
||||
|
||||
beforeEach ->
|
||||
module 'Darkswarm'
|
||||
inject ($injector)->
|
||||
Navigation = $injector.get("Navigation")
|
||||
|
||||
it "caches the path provided", ->
|
||||
Navigation.navigate "/foo"
|
||||
expect(Navigation.path).toEqual "/foo"
|
||||
@@ -0,0 +1,33 @@
|
||||
describe "Groups service", ->
|
||||
Groups = null
|
||||
Enterprises = null
|
||||
CurrentHubMock = {}
|
||||
groups = [{
|
||||
id: 1
|
||||
name: "Test Group"
|
||||
enterprises: [
|
||||
{id: 1},
|
||||
{id: 2}
|
||||
]
|
||||
}]
|
||||
enterprises = [
|
||||
{id: 1, name: "Test 1", groups: [{id: 1}]},
|
||||
{id: 2, name: "Test 2", groups: [{id: 1}]}
|
||||
]
|
||||
|
||||
beforeEach ->
|
||||
module 'Darkswarm'
|
||||
angular.module('Darkswarm').value('groups', groups)
|
||||
angular.module('Darkswarm').value('enterprises', enterprises)
|
||||
module ($provide)->
|
||||
$provide.value "CurrentHub", CurrentHubMock
|
||||
null
|
||||
inject (_Groups_, _Enterprises_)->
|
||||
Groups = _Groups_
|
||||
Enterprises = _Enterprises_
|
||||
|
||||
it "dereferences group enterprises", ->
|
||||
expect(Groups.groups[0].enterprises[0]).toBe enterprises[0]
|
||||
|
||||
it "dereferences enterprise groups", ->
|
||||
expect(Enterprises.enterprises[0].groups[0]).toBe groups[0]
|
||||
@@ -7,6 +7,7 @@ describe "Hubs service", ->
|
||||
active: false
|
||||
orders_close_at: new Date()
|
||||
type: "hub"
|
||||
visible: true
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
describe 'Navigation service', ->
|
||||
Navigation = null
|
||||
window =
|
||||
location:
|
||||
href: null
|
||||
pathname: null
|
||||
|
||||
beforeEach ->
|
||||
module 'Darkswarm', ($provide) ->
|
||||
$provide.value "$window", window
|
||||
null
|
||||
inject ($injector)->
|
||||
Navigation = $injector.get("Navigation")
|
||||
|
||||
|
||||
it "caches the path provided", ->
|
||||
Navigation.navigate "/foo"
|
||||
expect(Navigation.path).toEqual "/foo"
|
||||
|
||||
describe "redirecting", ->
|
||||
it "redirects to full URLs", ->
|
||||
Navigation.go "http://google.com"
|
||||
expect(window.location.href).toEqual "http://google.com"
|
||||
|
||||
it "redirects to paths", ->
|
||||
Navigation.go "/woo/yeah"
|
||||
expect(window.location.pathname).toEqual "/woo/yeah"
|
||||
|
||||
@@ -42,14 +42,12 @@ describe Enterprise do
|
||||
it "scopes relatives to visible distributors" do
|
||||
e.should_receive(:relatives).and_return(relatives = [])
|
||||
relatives.should_receive(:is_distributor).and_return relatives
|
||||
relatives.should_receive(:visible)
|
||||
e.distributors
|
||||
end
|
||||
|
||||
it "scopes relatives to visible producers" do
|
||||
e.should_receive(:relatives).and_return(relatives = [])
|
||||
relatives.should_receive(:is_primary_producer).and_return relatives
|
||||
relatives.should_receive(:visible)
|
||||
e.suppliers
|
||||
end
|
||||
end
|
||||
@@ -439,12 +437,12 @@ describe Enterprise do
|
||||
|
||||
it "gets all taxons of all distributed products" do
|
||||
Spree::Product.stub(:in_distributor).and_return [product1, product2]
|
||||
distributor.distributed_taxons.should == [taxon1, taxon2]
|
||||
distributor.distributed_taxons.sort.should == [taxon1, taxon2].sort
|
||||
end
|
||||
|
||||
it "gets all taxons of all supplied products" do
|
||||
Spree::Product.stub(:in_supplier).and_return [product1, product2]
|
||||
supplier.supplied_taxons.should == [taxon1, taxon2]
|
||||
supplier.supplied_taxons.sort.should == [taxon1, taxon2].sort
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
21
spec/serializers/enterprise_serializer.rb
Normal file
21
spec/serializers/enterprise_serializer.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
#require 'spec_helper'
|
||||
|
||||
describe Api::EnterpriseSerializer do
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
let(:taxon) { create(:taxon) }
|
||||
it "serializes an enterprise" do
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match enterprise.name
|
||||
end
|
||||
|
||||
it "includes distributed taxons" do
|
||||
enterprise.stub(:distributed_taxons).and_return [taxon]
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match taxon.name
|
||||
end
|
||||
|
||||
it "will render urls" do
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match "map-icon-hub.svg"
|
||||
end
|
||||
end
|
||||
@@ -38,6 +38,20 @@ module UIComponentHelper
|
||||
have_selector ".login-modal"
|
||||
end
|
||||
|
||||
def open_product_modal(product)
|
||||
find("a", text: product.name).click
|
||||
end
|
||||
|
||||
def open_enterprise_modal(enterprise)
|
||||
find("a", text: enterprise.name).click
|
||||
end
|
||||
|
||||
def modal_should_be_open_for(object)
|
||||
within ".reveal-modal" do
|
||||
page.should have_content object.name
|
||||
end
|
||||
end
|
||||
|
||||
def have_reset_password
|
||||
have_content "An email with instructions on resetting your password has been sent!"
|
||||
end
|
||||
|
||||
8
vendor/assets/javascripts/angular-timer.min.js
vendored
Executable file
8
vendor/assets/javascripts/angular-timer.min.js
vendored
Executable file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* angular-timer - v1.1.6 - 2014-07-01 7:37 AM
|
||||
* https://github.com/siddii/angular-timer
|
||||
*
|
||||
* Copyright (c) 2014 Siddique Hameed
|
||||
* Licensed MIT <https://github.com/siddii/angular-timer/blob/master/LICENSE.txt>
|
||||
*/
|
||||
var timerModule=angular.module("timer",[]).directive("timer",["$compile",function(a){return{restrict:"EAC",replace:!1,scope:{interval:"=interval",startTimeAttr:"=startTime",endTimeAttr:"=endTime",countdownattr:"=countdown",finishCallback:"&finishCallback",autoStart:"&autoStart",maxTimeUnit:"="},controller:["$scope","$element","$attrs","$timeout",function(b,c,d,e){function f(){b.timeoutId&&clearTimeout(b.timeoutId)}function g(){b.maxTimeUnit&&"day"!==b.maxTimeUnit?"second"===b.maxTimeUnit?(b.seconds=Math.floor(b.millis/1e3),b.minutes=0,b.hours=0,b.days=0,b.months=0,b.years=0):"minute"===b.maxTimeUnit?(b.seconds=Math.floor(b.millis/1e3%60),b.minutes=Math.floor(b.millis/6e4),b.hours=0,b.days=0,b.months=0,b.years=0):"hour"===b.maxTimeUnit?(b.seconds=Math.floor(b.millis/1e3%60),b.minutes=Math.floor(b.millis/6e4%60),b.hours=Math.floor(b.millis/36e5),b.days=0,b.months=0,b.years=0):"month"===b.maxTimeUnit?(b.seconds=Math.floor(b.millis/1e3%60),b.minutes=Math.floor(b.millis/6e4%60),b.hours=Math.floor(b.millis/36e5%24),b.days=Math.floor(b.millis/36e5/24%30),b.months=Math.floor(b.millis/36e5/24/30),b.years=0):"year"===b.maxTimeUnit&&(b.seconds=Math.floor(b.millis/1e3%60),b.minutes=Math.floor(b.millis/6e4%60),b.hours=Math.floor(b.millis/36e5%24),b.days=Math.floor(b.millis/36e5/24%30),b.months=Math.floor(b.millis/36e5/24/30%12),b.years=Math.floor(b.millis/36e5/24/365)):(b.seconds=Math.floor(b.millis/1e3%60),b.minutes=Math.floor(b.millis/6e4%60),b.hours=Math.floor(b.millis/36e5%24),b.days=Math.floor(b.millis/36e5/24),b.months=0,b.years=0),b.secondsS=1==b.seconds?"":"s",b.minutesS=1==b.minutes?"":"s",b.hoursS=1==b.hours?"":"s",b.daysS=1==b.days?"":"s",b.monthsS=1==b.months?"":"s",b.yearsS=1==b.years?"":"s",b.sseconds=b.seconds<10?"0"+b.seconds:b.seconds,b.mminutes=b.minutes<10?"0"+b.minutes:b.minutes,b.hhours=b.hours<10?"0"+b.hours:b.hours,b.ddays=b.days<10?"0"+b.days:b.days,b.mmonths=b.months<10?"0"+b.months:b.months,b.yyears=b.years<10?"0"+b.years:b.years}"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),b.autoStart=d.autoStart||d.autostart,c.append(0===c.html().trim().length?a("<span>{{millis}}</span>")(b):a(c.contents())(b)),b.startTime=null,b.endTime=null,b.timeoutId=null,b.countdown=b.countdownattr&&parseInt(b.countdownattr,10)>=0?parseInt(b.countdownattr,10):void 0,b.isRunning=!1,b.$on("timer-start",function(){b.start()}),b.$on("timer-resume",function(){b.resume()}),b.$on("timer-stop",function(){b.stop()}),b.$on("timer-clear",function(){b.clear()}),b.$on("timer-set-countdown",function(a,c){b.countdown=c}),b.start=c[0].start=function(){b.startTime=b.startTimeAttr?new Date(b.startTimeAttr):new Date,b.endTime=b.endTimeAttr?new Date(b.endTimeAttr):null,b.countdown||(b.countdown=b.countdownattr&&parseInt(b.countdownattr,10)>0?parseInt(b.countdownattr,10):void 0),f(),h(),b.isRunning=!0},b.resume=c[0].resume=function(){f(),b.countdownattr&&(b.countdown+=1),b.startTime=new Date-(b.stoppedTime-b.startTime),h(),b.isRunning=!0},b.stop=b.pause=c[0].stop=c[0].pause=function(){var a=b.timeoutId;b.clear(),b.$emit("timer-stopped",{timeoutId:a,millis:b.millis,seconds:b.seconds,minutes:b.minutes,hours:b.hours,days:b.days})},b.clear=c[0].clear=function(){b.stoppedTime=new Date,f(),b.timeoutId=null,b.isRunning=!1},c.bind("$destroy",function(){f(),b.isRunning=!1}),b.countdownattr?(b.millis=1e3*b.countdownattr,b.addCDSeconds=c[0].addCDSeconds=function(a){b.countdown+=a,b.$digest(),b.isRunning||b.start()},b.$on("timer-add-cd-seconds",function(a,c){e(function(){b.addCDSeconds(c)})}),b.$on("timer-set-countdown-seconds",function(a,c){b.isRunning||b.clear(),b.countdown=c,b.millis=1e3*c,g()})):b.millis=0,g();var h=function(){b.millis=new Date-b.startTime;var a=b.millis%1e3;return b.endTimeAttr&&(b.millis=b.endTime-new Date,a=b.interval-b.millis%1e3),b.countdownattr&&(b.millis=1e3*b.countdown),b.millis<0?(b.stop(),b.millis=0,g(),void(b.finishCallback&&b.$eval(b.finishCallback))):(g(),b.timeoutId=setTimeout(function(){h(),b.$digest()},b.interval-a),b.$emit("timer-tick",{timeoutId:b.timeoutId,millis:b.millis}),void(b.countdown>0?b.countdown--:b.countdown<=0&&(b.stop(),b.finishCallback&&b.$eval(b.finishCallback))))};(void 0===b.autoStart||b.autoStart===!0)&&b.start()}]}}]);"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports=timerModule);
|
||||
Reference in New Issue
Block a user