Merge branch 'laura_and_will'

Conflicts:
	app/models/spree/variant_decorator.rb
	db/schema.rb
	spec/models/spree/product_spec.rb
	spec/models/spree/variant_spec.rb
This commit is contained in:
Will Marshall
2014-06-13 12:42:14 +10:00
54 changed files with 440 additions and 232 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -8,6 +8,7 @@
#= require angular-sanitize
#= 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 ../shared/bindonce.min.js

View File

@@ -1,11 +1,13 @@
Darkswarm.controller "LoginCtrl", ($scope, $http, AuthenticationService, Redirections) ->
Darkswarm.controller "LoginCtrl", ($scope, $http, AuthenticationService, Redirections, Loading) ->
$scope.path = "/login"
$scope.submit = ->
Loading.message = "Hold on a moment, we're logging you in"
$http.post("/user/spree_user/sign_in", {spree_user: $scope.spree_user}).success (data)->
if Redirections.after_login
location.href = location.origin + Redirections.after_login
else
location.href = location.origin + location.pathname # Strips out hash fragments
.error (data) ->
Loading.clear()
$scope.errors = data.message

View File

@@ -1,4 +1,4 @@
Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, Navigation, $location, $anchorScroll, $templateCache, CurrentHub) ->
Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, Navigation, $location, $templateCache, CurrentHub) ->
$scope.toggle = ->
HashNavigation.toggle $scope.hub.hash
@@ -7,6 +7,3 @@ Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, Navigation, $locati
$scope.current = ->
$scope.hub.id is CurrentHub.id
if $scope.open()
$anchorScroll()

View File

@@ -1,7 +1,7 @@
Darkswarm.controller "HubsCtrl", ($scope, Hubs, $anchorScroll, $rootScope, HashNavigation) ->
Darkswarm.controller "HubsCtrl", ($scope, Hubs, $document, $rootScope, HashNavigation) ->
$scope.Hubs = Hubs
$scope.hubs = Hubs.hubs
$rootScope.$on "$locationChangeSuccess", (newRoute, oldRoute) ->
if HashNavigation.active "hubs"
$anchorScroll()
$document.scrollTo $("#hubs"), 100, 200

View File

@@ -1,8 +1,3 @@
Darkswarm.controller "MapCtrl", ($scope, MapConfiguration, OfnMap)->
$scope.OfnMap = OfnMap
$scope.map =
center:
latitude: -37.4713077
longitude: 144.7851531
zoom: 12
styles: MapConfiguration.options
$scope.map = MapConfiguration.options

View File

@@ -7,6 +7,7 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
'templates',
'ngSanitize',
'google-maps',
'duScroll',
'backstretch']).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')

View File

@@ -16,7 +16,7 @@ Darkswarm.directive "ofnFlash", (flash, $timeout, RailsFlashLoader)->
show = (message, type)=>
if message
$scope.flashes.push({message: message, type: typePairings[type]})
$timeout($scope.delete, 5000)
$timeout($scope.delete, 10000)
$scope.delete = ->
$scope.flashes.shift()

View File

@@ -0,0 +1,10 @@
Darkswarm.directive "loading", (Loading)->
scope: {}
restrict: 'E'
templateUrl: 'loading.html'
controller: ($scope)->
$scope.Loading = Loading
$scope.show = ->
$scope.Loading.message?
link: ($scope, element, attr)->

View File

@@ -8,10 +8,9 @@ Darkswarm.directive "ofnModal", ($modal)->
link: (scope, elem, attrs, ctrl, transclude)->
scope.title = attrs.title
contents = null
# We're using an isolate scope, which is a child of the original scope
# We have to compile the transclude against the original scope, not the isolate
transclude scope.$parent, (clone)->
contents = clone
elem.on "click", =>
# We're using an isolate scope, which is a child of the original scope
# We have to compile the transclude against the original scope, not the isolate
transclude scope.$parent, (clone)->
contents = clone
scope.modalInstance = $modal.open(controller: ctrl, template: contents, scope: scope.$parent)

View File

@@ -0,0 +1,10 @@
Darkswarm.directive "renderSvg", ()->
restrict: 'E'
priority: 99
template: "<svg-wrapper></svg-wrapper>"
link: (scope, elem, attr)->
if /.svg/.test attr.path # Only do this if we've got an svg
$.ajax
url: attr.path
success: (html)->
elem.html($(html).find("svg"))

View File

@@ -0,0 +1,10 @@
Darkswarm.directive 'scrollAfterLoad', ($timeout, $location, $document)->
restrict: "A"
link: (scope, element, attr) ->
if scope.$last is true
$(window).load ->
$timeout ->
elem = $("##{$location.hash()}")
if elem.length > 0
$document.scrollTo elem , 100, 200, (x)->
x * (2 - x)

View File

@@ -0,0 +1,5 @@
Darkswarm.factory "Loading", ->
new class Loading
message: null
clear: =>
@message = null

View File

@@ -1,5 +1,11 @@
Darkswarm.factory "MapConfiguration", ->
new class MapConfiguration
# From http://snazzymaps.com/style/15/subtle-grayscale
options: [{"featureType":"landscape","stylers":[{"saturation":-100},{"lightness":65},{"visibility":"on"}]},{"featureType":"poi","stylers":[{"saturation":-100},{"lightness":51},{"visibility":"simplified"}]},{"featureType":"road.highway","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"road.arterial","stylers":[{"saturation":-100},{"lightness":30},{"visibility":"on"}]},{"featureType":"road.local","stylers":[{"saturation":-100},{"lightness":40},{"visibility":"on"}]},{"featureType":"transit","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"administrative.province","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":-25},{"saturation":-100}]},{"featureType":"water","elementType":"geometry","stylers":[{"hue":"#ffff00"},{"lightness":-25},{"saturation":-97}]}]
options:
center:
latitude: -37.4713077
longitude: 144.7851531
zoom: 12
additional_options: {}
#mapTypeId: 'satellite'
styles: [{"featureType":"landscape","stylers":[{"saturation":-100},{"lightness":65},{"visibility":"on"}]},{"featureType":"poi","stylers":[{"saturation":-100},{"lightness":51},{"visibility":"simplified"}]},{"featureType":"road.highway","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"road.arterial","stylers":[{"saturation":-100},{"lightness":30},{"visibility":"on"}]},{"featureType":"road.local","stylers":[{"saturation":-100},{"lightness":40},{"visibility":"on"}]},{"featureType":"transit","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"administrative.province","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":-25},{"saturation":-100}]},{"featureType":"water","elementType":"geometry","stylers":[{"hue":"#ffff00"},{"lightness":-25},{"saturation":-97}]}]

View File

@@ -1,4 +1,4 @@
Darkswarm.factory 'Order', ($resource, order, $http, Navigation, storage, CurrentHub, RailsFlashLoader)->
Darkswarm.factory 'Order', ($resource, order, $http, Navigation, storage, CurrentHub, RailsFlashLoader, Loading)->
new class Order
errors: {}
secrets: {}
@@ -20,9 +20,11 @@ Darkswarm.factory 'Order', ($resource, order, $http, Navigation, storage, Curren
defaultValue: true
submit: ->
Loading.message = "Submitting your order: please wait"
$http.put('/checkout', {order: @preprocess()}).success (data, status)=>
Navigation.go data.path
.error (response, status)=>
Loading.clear()
@errors = response.errors
RailsFlashLoader.loadFlash(response.flash)

View File

@@ -0,0 +1,8 @@
#loading{"ng-show" => "show()"}
%modal-backdrop
#message
%ul.loader
%li
%li
%li
%h1 {{ Loading.message }}

View File

@@ -11,7 +11,6 @@
&:first-child
cursor: pointer
.active_table .active_table_node
@include csstrans
display: block

View File

@@ -8,7 +8,7 @@
left: 26px
top: 12px
font-size: 1.6em
z-index: 999
z-index: 2
color: #b2b2b2
input[type="text"]

View File

@@ -1,4 +1,5 @@
@import branding
@import mixins
.hubs
.active_table .active_table_node
@@ -36,7 +37,21 @@
//Open row
&.open
.fat-taxons
@include csstrans
margin-right: 0.5rem
text-transform: uppercase
font-size: 1rem
line-height: 1
color: $dark-grey
// border: 1px solid $disabled-bright
display: inline-block
padding: 0.2rem 0.5rem 0.35rem 0.35rem
object.taxon
height: 20px
// &:hover, &.hover, &:active
// background: rgba(255,255,255,0.5)
.active_table_row:first-child
border-top: 1px solid $clr-brick
border-left: 1px solid $clr-brick

View File

@@ -0,0 +1,68 @@
@import "compass/css3/user-interface"
#loading
.reveal-modal-bg
z-index: 101
background: rgba(0, 0, 0, 0.85)
#message
width: 100%
text-align: center
position: absolute
z-index: 102
margin: auto
top: 0
left: 0
bottom: 0
right: 0
@include user-select(none)
h1
color: white
position: fixed
text-align: center
left: 0
right: 0
margin: 0 auto
top: 55%
width: 100%
height: 400px
overflow: visible
.loader
position: fixed
margin: 0 auto
left: 0
right: 0
top: 50%
margin-top: -30px
width: 60px
height: 60px
list-style: none
li
background-color: #FFFFFF
width: 10px
height: 10px
float: right
margin-right: 5px
box-shadow: 0px 100px 20px rgba(0, 0, 0, 0.2)
li:first-child
-webkit-animation: loadbars 0.6s cubic-bezier(0.645, 0.045, 0.355, 1) infinite 0s
li:nth-child(2)
-webkit-animation: loadbars 0.6s ease-in-out infinite -0.2s
li:nth-child(3)
-webkit-animation: loadbars 0.6s ease-in-out infinite -0.4s
@-webkit-keyframes 'loadbars'
0%
height: 10px
margin-top: 25px
50%
height: 50px
margin-top: 0px
100%
height: 10px
margin-top: 25px

View File

@@ -1,7 +1,12 @@
// Place all the styles related to the map controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.ofn-map-container
.map-container
width: 100%
map, .angular-google-map-container, google-map, .angular-google-map
display: block
height: 100%
img // https://github.com/zurb/foundation/issues/112
max-width: none
height: auto

View File

@@ -31,35 +31,31 @@
location, location + small
display: block
#distributor_title
float: left
display: block
min-width: 350px
#distributor_title h3
margin-top: 0
@media all and (max-width: 768px)
margin-bottom: 8px
ordercycle
@media all and (max-width: 768px)
@media all and (max-width: 640px)
float: left
clear: left
padding-bottom: 12px
display: block
padding: 12px 10px
width: 100%
margin-top: 10px
background: #e5e5e5
float: right
form.custom
//width: 400px
text-align: right
margin-right: 1em
@media all and (max-width: 768px)
padding-left: 1em
padding-top: 1em
& > strong
line-height: 2.5
font-size: 1.29em
padding-right: 14px
@media all and (max-width: 768px)
font-size: 1.2em
select
select
width: inherit
display: inline-block
vackground: transparent
border-width: 1px
border-color: #999
color: #666
@@ -67,13 +63,18 @@
margin-bottom: 0
padding: 8px 20px 8px 12px
@media all and (max-width: 768px)
font-size: 1.2em
// width: 180px
font-size: 0.875em
closing
@media all and (max-width: 768px)
font-size: 1.2em
padding-bottom: 10px
color: black
font-size: 1.5em
display: block
padding-bottom: 20px
padding-bottom: 12px
span
@media all and (max-width: 768px)
font-size: 0.875em
products
display: block
@@ -101,10 +102,12 @@
input
margin: 0
width: 8em
display: inline
.columns
padding-top: 1em
padding-bottom: 1em
line-height: 2.4em
.row.summary, .row.variants
@include csstrans
@@ -116,8 +119,15 @@
.row.summary
@include csstrans
background: #fff
line-height: 1
.summary-header
@include csstrans
font-size: 1.15rem
object.taxon
height: 18px
&, & *
@include avenir
color: $clr-brick

View File

@@ -1,10 +1,10 @@
@font-face {
font-family: 'OFN';
src:url('/OFN.eot?-zgemuq');
src:url('/OFN.eot?#iefix-zgemuq') format('embedded-opentype'),
url('/OFN.woff?-zgemuq') format('woff'),
url('/OFN.ttf?-zgemuq') format('truetype'),
url('/OFN.svg?-zgemuq#OFN') format('svg');
src:url('/OFN.eot?-g90m7b');
src:url('/OFN.eot?#iefix-g90m7b') format('embedded-opentype'),
url('/OFN.woff?-g90m7b') format('woff'),
url('/OFN.ttf?-g90m7b') format('truetype'),
url('/OFN.svg?-g90m7b#OFN') format('svg');
font-weight: normal;
font-style: normal;
}
@@ -23,168 +23,174 @@
-moz-osx-font-smoothing: grayscale;
}
.ofn-i_055-point-left:before {
.ofn-i_057-expand:before {
content: "\e600";
}
.ofn-i_054-point-right:before {
.ofn-i_056-bulk:before {
content: "\e601";
}
.ofn-i_053-point-up:before {
.ofn-i_055-point-left:before {
content: "\e602";
}
.ofn-i_052-point-down:before {
.ofn-i_054-point-right:before {
content: "\e603";
}
.ofn-i_051-check-big:before {
.ofn-i_053-point-up:before {
content: "\e604";
}
.ofn-i_050-mail-circle:before {
.ofn-i_052-point-down:before {
content: "\e605";
}
.ofn-i_049-web:before {
.ofn-i_051-check-big:before {
content: "\e606";
}
.ofn-i_048-play-video:before {
.ofn-i_050-mail-circle:before {
content: "\e607";
}
.ofn-i_047-youtube:before {
.ofn-i_049-web:before {
content: "\e608";
}
.ofn-i_046-g:before {
.ofn-i_048-play-video:before {
content: "\e609";
}
.ofn-i_045-pintrest:before {
.ofn-i_047-youtube:before {
content: "\e60a";
}
.ofn-i_044-facebook:before {
.ofn-i_046-g:before {
content: "\e60b";
}
.ofn-i_043-instagram:before {
.ofn-i_045-pintrest:before {
content: "\e60c";
}
.ofn-i_042-linkedin:before {
.ofn-i_044-facebook:before {
content: "\e60d";
}
.ofn-i_041-twitter:before {
.ofn-i_043-instagram:before {
content: "\e60e";
}
.ofn-i_040-hub:before {
.ofn-i_042-linkedin:before {
content: "\e60f";
}
.ofn-i_039-delivery:before {
.ofn-i_041-twitter:before {
content: "\e610";
}
.ofn-i_038-takeaway:before {
.ofn-i_040-hub:before {
content: "\e611";
}
.ofn-i_037-map:before {
.ofn-i_039-delivery:before {
content: "\e612";
}
.ofn-i_036-producers:before {
.ofn-i_038-takeaway:before {
content: "\e613";
}
.ofn-i_035-groups:before {
.ofn-i_037-map:before {
content: "\e614";
}
.ofn-i_034-timer:before {
.ofn-i_036-producers:before {
content: "\e615";
}
.ofn-i_033-open-sign:before {
.ofn-i_035-groups:before {
content: "\e616";
}
.ofn-i_032-closed-sign:before {
.ofn-i_034-timer:before {
content: "\e617";
}
.ofn-i_031-alarm-clock:before {
.ofn-i_033-open-sign:before {
content: "\e618";
}
.ofn-i_030-money:before {
.ofn-i_032-closed-sign:before {
content: "\e619";
}
.ofn-i_029-shopping-basket:before {
.ofn-i_031-alarm-clock:before {
content: "\e61a";
}
.ofn-i_028-barcode:before {
.ofn-i_030-money:before {
content: "\e61b";
}
.ofn-i_027-shopping-cart:before {
.ofn-i_029-shopping-basket:before {
content: "\e61c";
}
.ofn-i_026-trash:before {
.ofn-i_028-barcode:before {
content: "\e61d";
}
.ofn-i_025-notepad:before {
.ofn-i_027-shopping-cart:before {
content: "\e61e";
}
.ofn-i_024-mail:before {
.ofn-i_026-trash:before {
content: "\e61f";
}
.ofn-i_023-refresh:before {
.ofn-i_025-notepad:before {
content: "\e620";
}
.ofn-i_022-cog:before {
.ofn-i_024-mail:before {
content: "\e621";
}
.ofn-i_021-tools:before {
.ofn-i_023-refresh:before {
content: "\e622";
}
.ofn-i_020-search:before {
.ofn-i_022-cog:before {
content: "\e623";
}
.ofn-i_019-map-pin:before {
.ofn-i_021-tools:before {
content: "\e624";
}
.ofn-i_018-unlocked:before {
.ofn-i_020-search:before {
content: "\e625";
}
.ofn-i_017-locked:before {
.ofn-i_019-map-pin:before {
content: "\e626";
}
.ofn-i_016-group:before {
.ofn-i_018-unlocked:before {
content: "\e627";
}
.ofn-i_015-user:before {
.ofn-i_017-locked:before {
content: "\e628";
}
.ofn-i_014-menu:before {
.ofn-i_016-group:before {
content: "\e629";
}
.ofn-i_013-help:before {
.ofn-i_015-user:before {
content: "\e62a";
}
.ofn-i_012-warning:before {
.ofn-i_014-menu:before {
content: "\e62b";
}
.ofn-i_011-spinner:before {
.ofn-i_013-help:before {
content: "\e62c";
}
.ofn-i_010-bullet:before {
.ofn-i_012-warning:before {
content: "\e62d";
}
.ofn-i_009-close:before {
.ofn-i_011-spinner:before {
content: "\e62e";
}
.ofn-i_008-caret-left:before {
.ofn-i_010-bullet:before {
content: "\e62f";
}
.ofn-i_007-caret-right:before {
.ofn-i_009-close:before {
content: "\e630";
}
.ofn-i_006-caret-up:before {
.ofn-i_008-caret-left:before {
content: "\e631";
}
.ofn-i_005-caret-down:before {
.ofn-i_007-caret-right:before {
content: "\e632";
}
.ofn-i_004-x:before {
.ofn-i_006-caret-up:before {
content: "\e633";
}
.ofn-i_003-check:before {
.ofn-i_005-caret-down:before {
content: "\e634";
}
.ofn-i_002-arrow-right:before {
.ofn-i_004-x:before {
content: "\e635";
}
.ofn-i_001-arrow-left:before {
.ofn-i_003-check:before {
content: "\e636";
}
.ofn-i_002-arrow-right:before {
content: "\e637";
}
.ofn-i_001-arrow-left:before {
content: "\e638";
}

View File

@@ -33,7 +33,7 @@
border-top: 4px solid transparent
a:after
padding-left: 8px
content: "\e632"
content: "\e634"
visibility: hidden
@include icon-font
dd:hover
@@ -48,7 +48,7 @@
a
color: $clr-brick-bright
a:after
content: "\e631"
content: "\e633"
visibility: visible
@include icon-font

View File

@@ -36,14 +36,14 @@ h1, h2, h3, h4, h5, h6, .avenir
@include avenir
padding: 0px
ul.ofn-list
ul.bullet-list
margin: 0
li
list-style: none
line-height: 1.5
height: inherit
li:before
content: "\e62d"
content: "\e62f"
font-family: "OFN"
display: inline-block
font-weight: normal

View File

@@ -40,6 +40,20 @@ Spree::Variant.class_eval do
values.to_sentence({ :words_connector => ", ", :two_words_connector => ", " })
end
def delete_unit_option_values
ovs = self.option_values.where(option_type_id: Spree::Product.all_variant_unit_option_types)
self.option_values.destroy ovs
end
def name_to_display
display_name || product.name
end
def unit_to_display
display_as || options_text
end
def update_units
delete_unit_option_values

View File

@@ -5,8 +5,7 @@
Shop for
%p.trans-sentence
%span.fat-taxons{"ng-repeat" => "taxon in hub.taxons"}
%img{"bo-src" => "taxon.icon",
name: "{{taxon.name}}", alt: "{{taxon.name}}"}
%render-svg{path: "{{taxon.icon}}"}
{{taxon.name}}
.columns.small-4
%h5 Delivery options
@@ -21,7 +20,7 @@
%h5
%i.ofn-i_036-producers
Our producers
%ul.ofn-list
%ul.bullet-list
%li{"ng-repeat" => "producer in hub.producers"}
= render partial: "modals/producer"

View File

@@ -25,6 +25,7 @@
.active_table
%hub.active_table_node.row{"ng-repeat" => "hub in filteredHubs = (hubs | hubs:query)",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !hub.active, 'current' : current()}",
"scroll-after-load" => true,
"ng-controller" => "HubNodeCtrl",
id: "{{hub.hash}}"}
.small-12.columns

View File

@@ -5,6 +5,6 @@
%h2 Map
%h5 of all our food hubs and producers
%p
%button.neutral-btn.light
%a.neutral-btn.light{href: "/map"}
%i.ofn-i_037-map
View map

View File

@@ -1,5 +1,16 @@
attributes :id, :name, :description, :long_description, :website, :instagram, :facebook, :linkedin, :twitter
node :promo_image do |producer|
producer.promo_image.url
producer.promo_image(:large)
end
node :logo do |producer|
producer.logo(:medium)
end
node :path do |producer|
producer_path(producer)
end
node :hash do |producer|
producer.to_param
end

View File

@@ -1,5 +1,5 @@
attributes :name, :id, :permalink
node :icon do |taxon|
taxon.icon.url
taxon.icon(:original)
end

View File

@@ -27,9 +27,8 @@
.inner-wrap
= render partial: "shared/menu/menu"
%ofn-flash
%section{ role: "main" }
= yield
#footer
%loading

View File

@@ -1,9 +1,7 @@
= inject_json "enterprisesForMap" , "enterprises_for_map", collection: @enterprises
.ofn-map-container{"fill-vertical" => true}
.map-container{"fill-vertical" => true}
%map{"ng-controller" => "MapCtrl"}
%google-map{center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"}
%google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"}
%markers{models: "OfnMap.enterprises", fit: "true",
coords: "'self'", icon: "'icon'", click: "'reveal'"}

View File

@@ -9,41 +9,35 @@
.row
.small-12.large-6.columns
%p{"ng-bind-html" => "producer.long_description"}
.small-12.large-6.columns
.small-8.large-4.columns
%a{"ng-href" => '/producers##{{producer.hash}}'}
Find my products
%img.producer-logo{"ng-src" => "{{producer.logo}}", "ng-if" => "producer.logo"}
%h5 Stay in touch with {{ producer.name }}
.small-4.large-2.columns
%ul.small-block-grid-1{bindonce: true}
%li{"ng-if" => "producer.website"}
%a{"ng-href" => "http://{{producer.website | stripUrl}}", target: "_blank" }
%i.ofn-i_049-web
{{ producer.website | stripUrl }}
%li{"ng-if" => "producer.email"}
%a{"ng-href" => "mailto:{{producer.email | stripUrl}}", target: "_blank" }
%i.ofn-i_050-mail-circle
{{ producer.email | stripUrl }}
%li{"ng-if" => "producer.twitter"}
%a{"ng-href" => "http://twitter.com/{{producer.twitter}}", target: "_blank"}
%i.ofn-i_041-twitter
{{ producer.twitter }}
%li{"ng-if" => "producer.facebook"}
%a{"ng-href" => "http://{{producer.facebook | stripUrl}}", target: "_blank"}
%i.ofn-i_044-facebook
{{ producer.facebook | stripUrl }}
%li{"ng-if" => "producer.linkedin"}
%a{"ng-href" => "http://{{producer.linkedin | stripUrl}}", target: "_blank"}
%i.ofn-i_042-linkedin
{{ producer.linkedin | stripUrl }}
%li{"ng-if" => "producer.instagram"}
%a{"ng-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"}
%i.ofn-i_043-instagram
{{ producer.instagram }}
%a.close-reveal-modal{"ng-click" => "$close()"}
%i.ofn-i_009-close

View File

@@ -26,6 +26,7 @@
.small-12.columns
.active_table
%producer.active_table_node.row{id: "{{producer.path}}",
"scroll-after-load" => true,
"ng-repeat" => "producer in filteredProducers = (Producers.producers | filterProducers:query)",
"ng-controller" => "ProducerNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",

View File

@@ -19,7 +19,7 @@
LinkedIn
.small-12.medium-4.columns.text-left
%h4 Getting around
%ul.ofn-list
%ul.bullet-list
%li
%a{href: "/shop"} Shop
%li

View File

@@ -38,4 +38,4 @@
%span.nav-primary.nav-branded {{ CurrentHub.name }}
%li.divider
%li.cart
= render partial: "shared/menu/cart"
= render partial: "shared/menu/cart"

View File

@@ -1,3 +1,4 @@
.fixed
= render partial: "shared/menu/large_menu"
%ofn-flash
= render partial: "shared/menu/mobile_menu"

View File

@@ -25,7 +25,7 @@ child :primary_taxon => :primary_taxon do
end
child :master => :master do
attributes :id, :is_master, :count_on_hand, :options_text, :count_on_hand, :on_demand
attributes :id, :is_master, :count_on_hand, :name_to_display, :unit_to_display, :count_on_hand, :on_demand
child :images => :images do
attributes :id, :alt
node do |img|
@@ -40,7 +40,8 @@ node :variants do |product|
{id: v.id,
is_master: v.is_master,
count_on_hand: v.count_on_hand,
options_text: v.options_text,
name_to_display: v.name_to_display,
unit_to_display: v.unit_to_display,
on_demand: v.on_demand,
price: v.price_with_fees(current_distributor, current_order_cycle),
images: v.images.map { |i| {id: i.id, alt: i.alt, small_url: i.attachment.url(:small, false)} }

View File

@@ -3,37 +3,40 @@
&nbsp;
.small-4.columns
{{ product.master.options_text }}
{{ product.master.name_to_display }}
-# WITHOUT GROUP BUY
.small-5.columns{"bo-if" => "!product.group_buy"}
%input{type: :number,
min: 0,
placeholder: "0",
"ofn-disable-scroll" => true,
max: "{{product.on_demand && 9999 || product.count_on_hand }}",
name: "variants[{{product.master.id}}]",
id: "variants_{{product.master.id}}",
"ng-model" => "product.quantity"}
{{ product.master.unit_to_display }}
-# WITH GROUP BUY
.small-2.columns{"bo-if" => "product.group_buy"}
%input{type: :number,
min: 0,
placeholder: "min",
"ofn-disable-scroll" => true,
max: "{{product.on_demand && 9999 || product.count_on_hand }}",
name: "variants[{{product.master.id}}]",
id: "variants_{{product.master.id}}",
"ng-model" => "product.quantity"}
(min)
.small-3.columns{"bo-if" => "product.group_buy"}
%input{type: :number,
min: 0,
placeholder: "max",
"ofn-disable-scroll" => true,
max: "{{product.on_demand && 9999 || product.count_on_hand }}",
name: "variant_attributes[{{product.master.id}}][max_quantity]",
"ng-model" => "product.max_quantity"}
(max)
{{ product.master.unit_to_display }}
.small-2.columns.text-right
{{ product.price | currency }}

View File

@@ -3,9 +3,7 @@
%img{"bo-src" => "product.master.images[0].small_url"}
.small-4.columns.summary-header
%img{"bo-src" => "product.primary_taxon.icon",
"ng-click" => "ordering.order = 'primary_taxon.name'",
name: "{{product.primary_taxon.name}}"}
%render-svg{path: "{{product.primary_taxon.icon}}"}
= render partial: "modals/product"
.small-5.columns

View File

@@ -6,37 +6,40 @@
&nbsp;
.small-4.columns
{{ variant.options_text }}
{{ variant.name_to_display }}
-# WITHOUT GROUP BUY
.small-5.columns{"bo-if" => "!product.group_buy"}
%input{type: :number,
value: nil,
min: 0,
placeholder: "0",
"ofn-disable-scroll" => true,
max: "{{variant.on_demand && 9999 || variant.count_on_hand }}",
name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}",
"bo-model" => "variant.quantity"}
{{ variant.unit_to_display }}
-# WITH GROUP BUY
.small-2.columns{"bo-if" => "product.group_buy"}
%input{type: :number,
value: nil,
min: 0,
placeholder: "min",
"ofn-disable-scroll" => true,
max: "{{variant.on_demand && 9999 || variant.count_on_hand }}",
name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}",
"bo-model" => "variant.quantity"}
(min)
.small-3.columns{"bo-if" => "product.group_buy"}
%input{type: :number,
min: 0,
placeholder: "max",
"ofn-disable-scroll" => true,
max: "{{variant.on_demand && 9999 || variant.count_on_hand }}",
name: "variant_attributes[{{variant.id}}][max_quantity]",
"ng-model" => "variant.max_quantity"}
(max)
{{ variant.unit_to_display }}
.small-2.columns.text-right.price
{{ variant.price | currency }}

View File

@@ -1,13 +1,14 @@
%navigation
%distributor.details.row
#distributor_title
- if current_distributor.logo.exists?
%img.left{src: current_distributor.logo.url(:thumb)}
%h3
= current_distributor.name
%location= current_distributor.address.city
/ Will this needs to be a drop-down to choose either pick-up point or delivery once shipping methods are implemented
= render partial: "shopping_shared/order_cycles"
.small-12.medium-6.large-6.columns
#distributor_title
- if current_distributor.logo.exists?
%img.left{src: current_distributor.logo.url(:thumb)}
%h3
= current_distributor.name
%location= current_distributor.address.city
/ Will this needs to be a drop-down to choose either pick-up point or delivery once shipping methods are implemented
.small-12.medium-6.large-6.columns
= render partial: "shopping_shared/order_cycles"
= render partial: "shopping_shared/tabs"

View File

@@ -4,7 +4,7 @@
%h5
=current_distributor.name
belongs to:
%ul.ofn-list
%ul.bullet-list
- for group in current_distributor.groups
%li
%a{href: main_app.groups_path(anchor: "#/#group#{group.id}")}= group.name

View File

@@ -3,6 +3,6 @@
.small-12.columns
%h5
= "#{current_distributor.name}'s producers:"
%ul.ofn-list
%ul.bullet-list
%li{"ng-repeat" => "producer in CurrentHub.producers"}
= render partial: "modals/producer"

View File

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

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20140612020206) do
ActiveRecord::Schema.define(:version => 20140604051248) do
create_table "adjustment_metadata", :force => true do |t|
t.integer "adjustment_id"
@@ -547,9 +547,9 @@ ActiveRecord::Schema.define(:version => 20140612020206) do
t.string "email"
t.text "special_instructions"
t.integer "distributor_id"
t.integer "order_cycle_id"
t.string "currency"
t.string "last_ip_address"
t.integer "order_cycle_id"
t.integer "cart_id"
end

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -36,6 +36,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
exchange.variants << product.master
visit shop_path
save_screenshot "/users/willmarshall/Desktop/wtsvg.png"
find("#tab_producers a").click
page.should have_content supplier.name
end
@@ -64,6 +65,8 @@ feature "As a consumer I want to shop with a distributor", js: true do
end
it "shows products after selecting an order cycle" do
product.master.update_attribute(:display_name, "kitten")
product.master.update_attribute(:display_as, "rabbit")
exchange1.variants << product.master ## add product to exchange
visit shop_path
page.should_not have_content product.name
@@ -74,6 +77,9 @@ feature "As a consumer I want to shop with a distributor", js: true do
page.should have_content "Next order closing in 2 days"
Spree::Order.last.order_cycle.should == oc1
page.should have_content product.name
save_screenshot "/Users/willmarshall/Desktop/shop.png"
page.should have_content product.master.display_name
page.should have_content product.master.display_as
end
end
end

View File

@@ -124,6 +124,31 @@ module Spree
end
describe "unit value/description" do
describe "getting name for display" do
it "returns display_name if present" do
v = create(:variant, display_name: "foo")
v.name_to_display.should == "foo"
end
it "returns product name if display_name is empty" do
v = create(:variant, product: create(:product))
v.name_to_display.should == v.product.name
end
end
describe "getting unit for display" do
it "returns display_as if present" do
v = create(:variant, display_as: "foo")
v.unit_to_display.should == "foo"
end
it "returns options_text if display_as is empty" do
v = create(:variant)
v.stub(:options_text).and_return "ponies"
v.unit_to_display.should == "ponies"
end
end
describe "setting the variant's weight from the unit value" do
it "sets the variant's weight when unit is weight" do
p = create(:simple_product, variant_unit: nil, variant_unit_scale: nil)
@@ -209,6 +234,25 @@ module Spree
end
end
end
context "when the variant already has a value set (and all required option values exist)" do
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v0) { create(:variant, product: p0, unit_value: 10, unit_description: 'foo') }
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v) { create(:variant, product: p, unit_value: 5, unit_description: 'bar') }
it "removes the old option value and assigns the new one" do
ov_orig = v.option_values.last
ov_new = v0.option_values.last
expect {
v.update_attributes!(unit_value: 10, unit_description: 'foo')
}.to change(Spree::OptionValue, :count).by(0)
v.option_values.should_not include ov_orig
v.option_values.should include ov_new
end
end
context "when the variant already has a value set (and all required option values exist)" do
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
@@ -246,7 +290,7 @@ module Spree
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v) { create(:variant, product: p, unit_value: 5, unit_description: 'bar', display_as: 'FOOS!') }
it "requests the name of the new option_value from OptionValueName" do
it "does not request the name of the new option_value from OptionValueName" do
OpenFoodNetwork::OptionValueNamer.any_instance.should_not_receive(:name)
v.update_attributes!(unit_value: 10, unit_description: 'foo')
ov = v.option_values.last
@@ -264,37 +308,20 @@ module Spree
it "removes option value associations for unit option types" do
expect {
@v.send(:delete_unit_option_values)
@v.delete_unit_option_values
}.to change(@v.option_values, :count).by(-1)
end
it "does not delete option values" do
expect {
@v.send(:delete_unit_option_values)
@v.delete_unit_option_values
}.to change(Spree::OptionValue, :count).by(0)
end
end
end
describe "deletion" do
let(:v) { create(:variant) }
let(:e) { create(:exchange, variants: [v]) }
it "marks the variant as deleted" do
v.deleted_at.should be_nil
v.delete
v.deleted_at.should_not be_nil
end
it "removes the variant from all order cycles" do
e
v.delete
e.variants(true).should be_empty
end
end
describe "destruction" do
it "removes the variant from all order cycles" do
it "destroys exchange variants" do
v = create(:variant)
e = create(:exchange, variants: [v])

File diff suppressed because one or more lines are too long