mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge branch 'master' into simple-order-cycles
This commit is contained in:
@@ -3,7 +3,7 @@ Darkswarm.controller "RegistrationCtrl", ($scope, RegistrationService, Enterpris
|
||||
$scope.enterprise = EnterpriseRegistrationService.enterprise
|
||||
$scope.select = RegistrationService.select
|
||||
|
||||
$scope.steps = ['details','address','contact','about','images','social']
|
||||
$scope.steps = ['details','contact','type','about','images','social']
|
||||
|
||||
$scope.countries = availableCountries
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Darkswarm.directive "ofnInlineAlert", ->
|
||||
restrict: 'A'
|
||||
scope: true
|
||||
link: (scope, elem, attrs) ->
|
||||
scope.visible = true
|
||||
scope.close = ->
|
||||
scope.visible = false
|
||||
@@ -1,6 +0,0 @@
|
||||
Darkswarm.directive "ofnInlineFlash", ->
|
||||
restrict: 'E'
|
||||
controller: ($scope) ->
|
||||
$scope.visible = true
|
||||
$scope.closeFlash = ->
|
||||
$scope.visible = false
|
||||
@@ -3,7 +3,7 @@ Darkswarm.directive "ofnRegistrationLimitModal", (Navigation, $modal, Loading) -
|
||||
link: (scope, elem, attr)->
|
||||
scope.modalInstance = $modal.open
|
||||
templateUrl: 'registration/limit_reached.html'
|
||||
windowClass: "login-modal large"
|
||||
windowClass: "login-modal register-modal xlarge"
|
||||
backdrop: 'static'
|
||||
|
||||
scope.modalInstance.result.then scope.close, scope.close
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redirections)->
|
||||
Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redirections, Loading)->
|
||||
|
||||
new class AuthenticationService
|
||||
selectedPath: "/login"
|
||||
@@ -25,4 +25,9 @@ Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redir
|
||||
active: Navigation.active
|
||||
|
||||
close: ->
|
||||
Navigation.navigate "/"
|
||||
if location.pathname == "/"
|
||||
Navigation.navigate "/"
|
||||
else
|
||||
Loading.message = "Taking you back to the home page"
|
||||
location.hash = ""
|
||||
location.pathname = "/"
|
||||
|
||||
@@ -1,44 +1,47 @@
|
||||
.container#registration-about
|
||||
.header
|
||||
%h2 Nice one!
|
||||
%h5
|
||||
Now let's flesh out the details about
|
||||
%span.brick{"ng-show" => "enterprise.is_distributor"}
|
||||
{{ enterprise.name }}
|
||||
%span.turquoise{"ng-show" => "!enterprise.is_distributor" }
|
||||
{{ enterprise.name }}
|
||||
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Nice one!
|
||||
%h5
|
||||
Now let's flesh out the details about
|
||||
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
|
||||
{{ enterprise.name }}
|
||||
|
||||
%form{ name: 'about', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('images',about)" } }
|
||||
.row
|
||||
.small-12.columns
|
||||
.alert-box.alert{"data-alert" => ""}
|
||||
{{ enterprise.name }} won't be visible on the Open Food Network until you enter a long and short description.
|
||||
%a.close{:href => "#"} ×
|
||||
|
||||
.alert-box.info{"data-alert" => ""}
|
||||
{{ enterprise.name }} has been created on the Open Food Network. If you leave at any point from here onwards, your enterprise will be saved, and you can always login to the admin section to update or continue filling out your enterprise details.
|
||||
%a.close{:href => "#"} ×
|
||||
.alert-box.info{ "ofn-inline-alert" => true, ng: { show: "visible" } }
|
||||
%h6 Success! {{ enterprise.name }} added to the Open Food Network
|
||||
%span If you exit the wizard at any stage, login and go to admin to edit or update your enterprise details.
|
||||
%a.close{ ng: { click: "close()" } } ×
|
||||
|
||||
.small-12.large-8.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_description' } Short Description:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_description', placeholder: "A short sentence describing your enterprise", ng: { model: 'enterprise.description' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_description' } Short Description:
|
||||
%input.chunky{ id: 'enterprise_description', placeholder: "A short sentence describing your enterprise", ng: { model: 'enterprise.description' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_long_desc' } Long Description:
|
||||
%textarea.chunky.small-12.columns{ id: 'enterprise_long_desc', rows: 6, placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words.", ng: { model: 'enterprise.long_description' } }
|
||||
%small {{ enterprise.long_description.length }} characters / up to 600 recommended
|
||||
.field
|
||||
%label{ for: 'enterprise_long_desc' } Long Description:
|
||||
%textarea.chunky{ id: 'enterprise_long_desc', rows: 6, placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words.", ng: { model: 'enterprise.long_description' } }
|
||||
%small {{ enterprise.long_description.length }} characters / up to 600 recommended
|
||||
.small-12.large-4.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_abn' } ABN:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_abn', placeholder: "eg. 99 123 456 789", ng: { model: 'enterprise.abn' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_abn' } ABN:
|
||||
%input.chunky{ id: 'enterprise_abn', placeholder: "eg. 99 123 456 789", ng: { model: 'enterprise.abn' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_acn' } ACN:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_acn', placeholder: "eg. 123 456 789", ng: { model: 'enterprise.acn' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_acn' } ACN:
|
||||
%input.chunky{ id: 'enterprise_acn', placeholder: "eg. 123 456 789", ng: { model: 'enterprise.acn' } }
|
||||
|
||||
.row.buttons.pad-top
|
||||
.small-12.columns
|
||||
%input.button.primary{ type: "submit", value: "Continue" }
|
||||
%input.button.primary.right{ type: "submit", value: "Continue" }
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
.container#registration-address
|
||||
.header
|
||||
%h2
|
||||
Greetings
|
||||
%span{ ng: { class: "{brick: enterprise.is_distributor, turquoise: !enterprise.is_distributor}" } }
|
||||
{{ enterprise.name }}
|
||||
|
||||
%h5 Now we need to know where you are
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
%form{ name: 'address', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('contact',address)" } }
|
||||
.row.content
|
||||
.small-12.medium-12.large-7.columns
|
||||
.row
|
||||
.small-12.columns.field
|
||||
%label{ for: 'enterprise_address' } Address:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_address', name: 'address1', required: true, placeholder: "eg. 123 Cranberry Drive", required: true, ng: { model: 'enterprise.address.address1' } }
|
||||
%span.error.small-12.columns{ ng: { show: "address.address1.$error.required && submitted" } }
|
||||
You need to enter an address.
|
||||
.row
|
||||
.small-12.large-8.columns.field
|
||||
%label{ for: 'enterprise_city' } Suburb:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_city', name: 'city', required: true, placeholder: "eg. Northcote", ng: { model: 'enterprise.address.city' } }
|
||||
%span.error.small-12.columns{ ng: { show: "address.city.$error.required && submitted" } }
|
||||
You need to enter a suburb.
|
||||
.small-12.large-4.columns.field
|
||||
%label{ for: 'enterprise_zipcode' } Postcode:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_zipcode', name: 'zipcode', required: true, placeholder: "eg. 3070", ng: { model: 'enterprise.address.zipcode' } }
|
||||
%span.error.small-12.columns{ ng: { show: "address.zipcode.$error.required && submitted" } }
|
||||
You need to enter a postcode.
|
||||
.row
|
||||
.small-12.large-8.columns.field
|
||||
%label{ for: 'enterprise_country' } Country:
|
||||
%select.chunky.small-12.columns{ id: 'enterprise_country', name: 'country', required: true, ng: { model: 'enterprise.country', options: 'c as c.name for c in countries' } }
|
||||
%span.error.small-12.columns{ ng: { show: "address.country.$error.required && submitted" } }
|
||||
You need to enter a country.
|
||||
.small-12.large-4.columns.field
|
||||
%label{ for: 'enterprise_state' } State:
|
||||
%select.chunky.small-12.columns{ id: 'enterprise_state', name: 'state', ng: { model: 'enterprise.address.state_id', options: 's.id as s.abbr for s in enterprise.country.states', show: 'countryHasStates()', required: 'countryHasStates()' } }
|
||||
%span.error.small-12.columns{ ng: { show: "address.state.$error.required && submitted" } }
|
||||
You need to enter a state.
|
||||
.small-12.medium-12.large-5.hide-for-small-only
|
||||
// This is the location area
|
||||
/ %h6
|
||||
/ Location display
|
||||
/ %i.ofn-i_013-help.has-tip{ 'data-tooltip' => true, title: "Choose how you want to display your enterprise's address on the Open Food Network. By default, full location is shown everywhere including street name and number."}
|
||||
/ .row
|
||||
/ .small-12.columns
|
||||
/ %label.indent-checkbox
|
||||
/ %input{ type: 'checkbox', id: 'enterpise_suburb_only', ng: { model: 'enterprise.suburb_only' } }
|
||||
/ Hide my street name and street number from the public (ie. only show the suburb)
|
||||
/ .small-12.columns
|
||||
/ %label.indent-checkbox
|
||||
/ %input{ type: 'checkbox', id: 'enterprise_on_map', ng: { model: 'enterprise.on_map' } }
|
||||
/ Blur my location on the map (show an approximate, not exact pin)
|
||||
|
||||
.row.buttons
|
||||
.small-12.columns
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('details')" } }
|
||||
|
||||
%input.button.primary{ type: "submit", value: "Continue" }
|
||||
@@ -1,12 +1,13 @@
|
||||
.container#registration-contact
|
||||
.header
|
||||
%h2 Last step to create your enterprise!
|
||||
%h5
|
||||
Who is responsible for managing
|
||||
%span{ ng: { class: "{brick: enterprise.is_distributor, turquoise: !enterprise.is_distributor}" } }
|
||||
{{ enterprise.name }}?
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
%form{ name: 'contact', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "create(contact)" } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Greetings!
|
||||
%h5
|
||||
Who is responsible for managing {{ enterprise.name }}?
|
||||
|
||||
%form{ name: 'contact', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('type',contact)" } }
|
||||
.row.content
|
||||
.small-12.medium-12.large-7.columns
|
||||
.row
|
||||
@@ -39,8 +40,8 @@
|
||||
/ .small-12.columns
|
||||
/ %label.indent-checkbox
|
||||
/ %input{ type: 'checkbox', id: 'contact_phone_profile', ng: { model: 'enterprise.phone_in_profile' } } Display phone in profile
|
||||
|
||||
.row.buttons
|
||||
.small-12.columns
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('address')" } }
|
||||
|
||||
%input.button.primary{ type: "submit", value: "Continue" }
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('details')" } }
|
||||
%input.button.primary.right{ type: "submit", value: "Continue" }
|
||||
|
||||
@@ -1,43 +1,77 @@
|
||||
.container#registration-details{bindonce: true}
|
||||
.header
|
||||
%h2 Let's Get Started
|
||||
%h5{ bo: { if: "enterprise.sells != 'own'" } } Woot! First we need to know what sort of enterprise you are:
|
||||
%h5{ bo: { if: "enterprise.sells == 'own'" } } Woot! First we need to know the name of your farm:
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
%form{ name: 'details', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('address',details)" } }
|
||||
.row
|
||||
.small-12.columns.field
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.sells != 'own'" } } Enterprise Name:
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.sells == 'own'" } } Farm Name:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_name', name: 'name', placeholder: "eg. Charlie's Awesome Farm", required: true, ng: { model: 'enterprise.name' } }
|
||||
%span.error.small-12.columns{ ng: { show: "details.name.$error.required && submitted" } }
|
||||
You need to enter a name for your enterprise!
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Let's Get Started
|
||||
%h5{ bo: { if: "enterprise.type != 'own'" } } Woot! First we need to know a little bit about your enterprise:
|
||||
%h5{ bo: { if: "enterprise.type == 'own'" } } Woot! First we need to know a little bit about your farm:
|
||||
|
||||
.row#enterprise-types{ 'data-equalizer' => true, bo: { if: "enterprise.sells != 'own'" } }
|
||||
.small-12.columns.field
|
||||
%form{ name: 'details', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('contact',details)" } }
|
||||
|
||||
.row
|
||||
.small-12.medium-9.large-12.columns.end
|
||||
.field
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.type != 'own'" } } Enterprise Name:
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.type == 'own'" } } Farm Name:
|
||||
%input.chunky{ id: 'enterprise_name', name: 'name', placeholder: "e.g. Charlie's Awesome Farm", required: true, ng: { model: 'enterprise.name' } }
|
||||
%span.error{ ng: { show: "details.name.$error.required && submitted" } }
|
||||
Please choose a unique name for your enterprise
|
||||
|
||||
.row
|
||||
.small-12.medium-9.large-6.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_address' } Address line 1:
|
||||
%input.chunky{ id: 'enterprise_address', name: 'address1', required: true, placeholder: "e.g. 123 Cranberry Drive", required: true, ng: { model: 'enterprise.address.address1' } }
|
||||
%span.error{ ng: { show: "details.address1.$error.required && submitted" } }
|
||||
Please enter an address
|
||||
.field
|
||||
%label{ for: 'enterprise_address2' } Address line 2:
|
||||
%input.chunky{ id: 'enterprise_address2', name: 'address2', required: false, placeholder: "", required: false, ng: { model: 'enterprise.address.address2' } }
|
||||
|
||||
.small-12.medium-9.large-6.columns.end
|
||||
.row
|
||||
.small-12.columns
|
||||
%label Choose one:
|
||||
.small-12.medium-8.large-8.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_city' } Suburb:
|
||||
%input.chunky{ id: 'enterprise_city', name: 'city', required: true, placeholder: "e.g. Northcote", ng: { model: 'enterprise.address.city' } }
|
||||
%span.error{ ng: { show: "details.city.$error.required && submitted" } }
|
||||
Please enter a suburb
|
||||
.small-12.medium-4.large-4.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_zipcode' } Postcode:
|
||||
%input.chunky{ id: 'enterprise_zipcode', name: 'zipcode', required: true, placeholder: "e.g. 3070", ng: { model: 'enterprise.address.zipcode' } }
|
||||
%span.error{ ng: { show: "details.zipcode.$error.required && submitted" } }
|
||||
Postcode required
|
||||
.row
|
||||
-# TODO redesign this to refelct the extra options available.
|
||||
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
|
||||
%a.panel#producer-panel{ href: "#", ng: { click: "enterprise.is_primary_producer = true", class: "{selected: (!enterprise.is_distributor && enterprise.is_primary_producer)}" } }
|
||||
.left
|
||||
/ %render-svg{ path: "/assets/map-icon-producer.svg" }
|
||||
%h4 I'm A Producer
|
||||
%p Producers make yummy things to eat &/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it.
|
||||
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
|
||||
%a.panel#hub-panel{ href: "#", ng: { click: "enterprise.is_distributor = true; enterprise.is_primary_producer = false", class: "{selected: (enterprise.is_distributor && !enterprise.is_primary_producer)}" } }
|
||||
.left
|
||||
/ %render-svg{ path: "/assets/map-icon-hub.svg" }
|
||||
%h4 I'm A Hub
|
||||
%p Hubs connect the producer to the eater. Hubs can be co-ops, independent retailers, buying groups, wholesalers, CSA box schemes, farm-gate stalls, etc.
|
||||
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
|
||||
%a.panel#both-panel{ href: "#", ng: { click: "enterprise.is_distributor = true; enterprise.is_primary_producer = true", class: "{selected: (enterprise.is_distributor && enterprise.is_primary_producer)}" } }
|
||||
.left
|
||||
/ %render-svg{path: "/assets/map-icon-both.svg"}
|
||||
%h4 I'm Both
|
||||
%p Hey there, Jack-of-all-trades! Not only do you produce things to eat &/or drink, you also want to sell your yummies through an Open Food Network shopfront.
|
||||
.small-12.medium-4.large-4.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_state' } State:
|
||||
%select.chunky{ id: 'enterprise_state', name: 'state', ng: { model: 'enterprise.address.state_id', options: 's.id as s.abbr for s in enterprise.country.states', show: 'countryHasStates()', required: 'countryHasStates()' } }
|
||||
%span.error{ ng: { show: "details.state.$error.required && submitted" } }
|
||||
State required
|
||||
.small-12.medium-8.large-8.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_country' } Country:
|
||||
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { model: 'enterprise.country', options: 'c as c.name for c in countries' } }
|
||||
%span.error{ ng: { show: "details.country.$error.required && submitted" } }
|
||||
Please select a country
|
||||
/ .small-12.medium-12.large-5.hide-for-small-only
|
||||
/ %h6
|
||||
/ Location display
|
||||
/ %i.ofn-i_013-help.has-tip{ 'data-tooltip' => true, title: "Choose how you want to display your enterprise's address on the Open Food Network. By default, full location is shown everywhere including street name and number."}
|
||||
/ .row
|
||||
/ .small-12.columns
|
||||
/ %label.indent-checkbox
|
||||
/ %input{ type: 'checkbox', id: 'enterpise_suburb_only', ng: { model: 'enterprise.suburb_only' } }
|
||||
/ Hide my street name and street number from the public (ie. only show the suburb)
|
||||
/ .small-12.columns
|
||||
/ %label.indent-checkbox
|
||||
/ %input{ type: 'checkbox', id: 'enterprise_on_map', ng: { model: 'enterprise.on_map' } }
|
||||
/ Blur my location on the map (show an approximate, not exact pin)
|
||||
|
||||
|
||||
.row.buttons
|
||||
.small-12.columns
|
||||
%hr
|
||||
%input.button.primary.right{ type: "submit", value: "Continue" }
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
.container#registration-finished
|
||||
.header
|
||||
%h2 Well done!
|
||||
%h5
|
||||
You have successfully completed the profile for
|
||||
%span.brick{"ng-show" => "enterprise.is_distributor"}
|
||||
{{ enterprise.name }}
|
||||
%span.turquoise{"ng-show" => "!enterprise.is_distributor" }
|
||||
{{ enterprise.name }}
|
||||
.content{ style: 'text-align: center'}
|
||||
%h3 Why not check it out on the Open Food Network?
|
||||
%a.button.primary{ type: "button", href: "/map" } Go to Map Page >
|
||||
.row
|
||||
.small-12.columns.pad-top
|
||||
%header
|
||||
%h2 Finished!
|
||||
.panel.callout
|
||||
%p
|
||||
Thanks for filling out the details for
|
||||
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
|
||||
{{ enterprise.name }}
|
||||
%p You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin.
|
||||
.row
|
||||
.small-12.columns.text-center
|
||||
%h4
|
||||
Activate
|
||||
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
|
||||
{{ enterprise.name }}
|
||||
|
||||
%br
|
||||
%br
|
||||
%p
|
||||
We've sent a confirmation email to
|
||||
%strong {{ enterprise.email }}.
|
||||
%br Please follow the instructions there to make your enterprise visible on the Open Food Network.
|
||||
|
||||
%h3 Next step - add some products:
|
||||
%a.button.primary{ type: "button", href: "/admin/products/new" } Add a Product >
|
||||
%a.button.primary{ type: "button", href: "/" } Open Food Network home >
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
.container#registration-images{ 'nv-file-drop' => true, uploader: "imageUploader", options:"{ alias: imageStep }", ng: { controller: "EnterpriseImageCtrl" } }
|
||||
.header
|
||||
%h2 Thanks!
|
||||
%h5 Let's upload some pretty pictures so your profile looks great! :)
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Thanks!
|
||||
%h5 Let's upload some pretty pictures so your profile looks great! :)
|
||||
|
||||
%form{ name: 'images', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "select('social')" } }
|
||||
.row{ ng: { repeat: 'image_step in imageSteps', show: "imageStep == image_step" } }
|
||||
%ng-include{ src: "'registration/images/'+ image_step + '.html'" }
|
||||
|
||||
.row.buttons.pad-top{ ng: { if: "imageStep == 'logo'" } }
|
||||
.small-12.columns
|
||||
%input.button.primary{ type: "button", value: "Back", ng: { click: "select('about')" } }
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('about')" } }
|
||||
|
||||
%input.button.primary{ type: "button", value: "Continue", ng: { click: "imageSelect('promo')" } }
|
||||
%input.button.primary.right{ type: "button", value: "Continue", ng: { click: "imageSelect('promo')" } }
|
||||
|
||||
.row.buttons.pad-top{ ng: { if: "imageStep == 'promo'" } }
|
||||
.small-12.columns
|
||||
%input.button.primary{ type: "button", value: "Back", ng: { click: "imageSelect('logo')" } }
|
||||
|
||||
%input.button.primary{ type: "submit", value: "Continue" }
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "imageSelect('logo')" } }
|
||||
%input.button.primary.right{ type: "submit", value: "Continue" }
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
.row.pad-top
|
||||
.small-12.columns.center
|
||||
#image-placeholder.logo
|
||||
%img{ ng: { show: "imageSrc()", src: '{{ imageSrc() }}' } }
|
||||
.message{ ng: { hide: "imageSrc()" } }
|
||||
%img{ ng: { show: "imageSrc() && !imageUploader.isUploading", src: '{{ imageSrc() }}' } }
|
||||
.message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } }
|
||||
Your logo will appear here for review once uploaded
|
||||
.loading{ ng: { hide: "!imageUploader.isUploading" } }
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%br/
|
||||
Uploading...
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
.row.pad-top
|
||||
.small-12.columns.center
|
||||
#image-placeholder.promo
|
||||
%img{ ng: { show: "imageSrc()", src: '{{ imageSrc() }}' } }
|
||||
.message{ ng: { hide: "imageSrc()" } }
|
||||
%img{ ng: { show: "imageSrc() && !imageUploader.isUploading", src: '{{ imageSrc() }}' } }
|
||||
.message{ ng: { hide: "imageSrc() || imageUploader.isUploading" } }
|
||||
Your logo will appear here for review once uploaded
|
||||
.loading{ ng: { hide: "!imageUploader.isUploading" } }
|
||||
%img.spinner{ src: "/assets/loading.gif" }
|
||||
%br/
|
||||
Uploading...
|
||||
|
||||
@@ -1,39 +1,45 @@
|
||||
%div
|
||||
.header
|
||||
%h2 Hi there!
|
||||
%h4 This wizard will step you through creating a profile
|
||||
.row
|
||||
.small-12.medium-3.large-2.columns.text-right.hide-for-small-only
|
||||
%img{:src => "/assets/potatoes.png"}
|
||||
.small-12.medium-9.large-10.columns
|
||||
%p
|
||||
Your profile gives you an online presence on the
|
||||
%strong Open Food Network,
|
||||
allowing you to easily connect with potential customers or partners. You can always choose to update your info later, as well as choose to upgrade your Profile to and Online Store, where you can sell products, track orders and receive payments. Creating a profile takes about 5-10 minutes.
|
||||
.row{ 'data-equalizer' => true }
|
||||
.small-12.medium-6.large-6.columns.pad-top{ 'data-equalizer-watch' => true }
|
||||
%h5 You'll need the following:
|
||||
%ul.check-list
|
||||
%li
|
||||
Your enterprise address and contact details
|
||||
%li
|
||||
Your logo image
|
||||
%li
|
||||
A pretty picture for your profile header
|
||||
%li
|
||||
Some 'About Us' text
|
||||
|
||||
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true}
|
||||
.highlight-box
|
||||
%h5 Your profile entitles you to:
|
||||
%ul.small-block-grid-1
|
||||
%li
|
||||
%i.ofn-i_020-search
|
||||
A searchable listing
|
||||
%li
|
||||
%i.ofn-i_040-hub
|
||||
A pin on the OFN map
|
||||
.row
|
||||
.small-12.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Hi there!
|
||||
%h4
|
||||
%small
|
||||
%i.ofn-i_040-hub
|
||||
Create your enterprise profile
|
||||
.hide-for-large-up
|
||||
%hr
|
||||
%input.button.primary{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }
|
||||
%input.button.small.primary{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }
|
||||
%hr
|
||||
|
||||
.row{ 'data-equalizer' => true }
|
||||
.small-12.medium-12.large-6.columns.pad-top{ 'data-equalizer-watch' => true }
|
||||
%h5 You'll need:
|
||||
%ul.check-list
|
||||
%li
|
||||
5-10 minutes
|
||||
%li
|
||||
Enterprise address
|
||||
%li
|
||||
Primary contact details
|
||||
%li
|
||||
Your logo image
|
||||
%li
|
||||
Landscape image for your profile
|
||||
%li
|
||||
'About Us' text
|
||||
|
||||
.small-9.medium-8.large-5.columns.pad-top.end{ 'data-equalizer-watch' => true}
|
||||
%h5
|
||||
What do I get?
|
||||
%p
|
||||
Your profile helps people
|
||||
%strong find
|
||||
and
|
||||
%strong contact
|
||||
you on the Open Food Network.
|
||||
%p Use this space to tell the story of your enterprise, to help drive connections to your social and online presence.
|
||||
|
||||
.row.show-for-large-up
|
||||
.small-12.columns
|
||||
%hr
|
||||
%input.button.primary.right{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
%div
|
||||
.header.center
|
||||
%h2 Oh no!
|
||||
%h4 You have reached the limit!
|
||||
.row
|
||||
.small-12.medium-3.large-2.columns.text-right.hide-for-small-only
|
||||
%img{:src => "/assets/potatoes.png"}
|
||||
.small-12.medium-9.large-10.columns
|
||||
%p
|
||||
You have reached the limit for the number of enterprises you are allowed to own on the
|
||||
%strong Open Food Network.
|
||||
.row
|
||||
.small-12.columns
|
||||
%hr
|
||||
%input.button.primary{ type: "button", value: "Return to the homepage", ng: { click: "close()" } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Oh no!
|
||||
%h4 You have reached the limit!
|
||||
.row
|
||||
.small-12.medium-3.large-2.columns.text-right.hide-for-small-only
|
||||
%img{:src => "/assets/potatoes.png"}
|
||||
.small-12.medium-9.large-10.columns
|
||||
%p
|
||||
You have reached the limit for the number of enterprises you are allowed to own on the
|
||||
%strong Open Food Network.
|
||||
.row
|
||||
.small-12.columns
|
||||
%hr
|
||||
%input.button.primary{ type: "button", value: "Return to the homepage", ng: { click: "close()" } }
|
||||
|
||||
@@ -1,35 +1,49 @@
|
||||
.container#registration-social
|
||||
.header
|
||||
%h2 Last step!
|
||||
%h5 How can people find {{ enterprise.name }} online?
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 Final step!
|
||||
%h5
|
||||
How can people find
|
||||
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
|
||||
{{ enterprise.name }}
|
||||
online?
|
||||
|
||||
%form{ name: 'social', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('finished',social)" } }
|
||||
.row.content
|
||||
.small-12.large-7.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_website' } Website:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_website', placeholder: "eg. openfoodnetwork.org.au", ng: { model: 'enterprise.website' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_website' } Website:
|
||||
%input.chunky{ id: 'enterprise_website', placeholder: "eg. openfoodnetwork.org.au", ng: { model: 'enterprise.website' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_facebook' } Facebook:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_facebook', placeholder: "eg. www.facebook.com/PageNameHere", ng: { model: 'enterprise.facebook' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_facebook' } Facebook:
|
||||
%input.chunky{ id: 'enterprise_facebook', placeholder: "eg. www.facebook.com/PageNameHere", ng: { model: 'enterprise.facebook' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_linkedin' } LinkedIn:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_linkedin', placeholder: "eg. www.linkedin.com/YourNameHere", ng: { model: 'enterprise.linkedin' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_linkedin' } LinkedIn:
|
||||
%input.chunky{ id: 'enterprise_linkedin', placeholder: "eg. www.linkedin.com/YourNameHere", ng: { model: 'enterprise.linkedin' } }
|
||||
.small-12.large-5.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_twitter' } Twitter:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_twitter', placeholder: "eg. @twitter_handle", ng: { model: 'enterprise.twitter' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_twitter' } Twitter:
|
||||
%input.chunky{ id: 'enterprise_twitter', placeholder: "eg. @twitter_handle", ng: { model: 'enterprise.twitter' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
%label{ for: 'enterprise_instagram' } Instagram:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_instagram', placeholder: "eg. @instagram_handle", ng: { model: 'enterprise.instagram' } }
|
||||
.field
|
||||
%label{ for: 'enterprise_instagram' } Instagram:
|
||||
%input.chunky{ id: 'enterprise_instagram', placeholder: "eg. @instagram_handle", ng: { model: 'enterprise.instagram' } }
|
||||
|
||||
.row.buttons
|
||||
.small-12.columns
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('images')" } }
|
||||
|
||||
%input.button.primary{ type: "submit", value: "Continue" }
|
||||
%input.button.primary.right{ type: "submit", value: "Continue" }
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
.row#progress-bar
|
||||
.small-12.medium-2.columns.item{ ng: { repeat: 'step in steps', class: "{active: (currentStep() == step),'show-for-medium-up': (currentStep() != step)}" } }
|
||||
{{ $index+1 + ". " + step }}
|
||||
|
||||
|
||||
46
app/assets/javascripts/templates/registration/type.html.haml
Normal file
46
app/assets/javascripts/templates/registration/type.html.haml
Normal file
@@ -0,0 +1,46 @@
|
||||
.container#registration-type{bindonce: true}
|
||||
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2
|
||||
Last step to add
|
||||
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
|
||||
{{ enterprise.name }}!
|
||||
%h4
|
||||
Are you a producer?
|
||||
|
||||
%form{ name: 'type', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "create(type)" } }
|
||||
.row#enterprise-types{ 'data-equalizer' => true, bo: { if: "enterprise.type != 'own'" } }
|
||||
.small-12.columns.field
|
||||
.row
|
||||
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true }
|
||||
%a.btnpanel#producer-panel{ href: "#", ng: { click: "enterprise.is_primary_producer = true", class: "{selected: enterprise.is_primary_producer}" } }
|
||||
%i.ofn-i_059-producer
|
||||
%h4 Yes, I'm a producer
|
||||
|
||||
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true }
|
||||
%a.btnpanel#hub-panel{ href: "#", ng: { click: "enterprise.is_primary_producer = false", class: "{selected: enterprise.is_primary_producer == false}" } }
|
||||
%i.ofn-i_063-hub
|
||||
%h4 No, I'm not a producer
|
||||
|
||||
.row
|
||||
.small-12.columns
|
||||
%input.chunky{ id: 'enterprise_is_primary_producer', name: 'is_primary_producer', hidden: true, required: true, ng: { model: 'enterprise.is_primary_producer' } }
|
||||
%span.error{ ng: { show: "type.is_primary_producer.$error.required && submitted" } }
|
||||
Please choose one. Are you are producer?
|
||||
.row
|
||||
.small-12.columns
|
||||
.panel.callout
|
||||
.left
|
||||
%i.ofn-i_013-help
|
||||
|
||||
%p Producers make yummy things to eat &/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it.
|
||||
/ %p Hubs connect the producer to the eater. Hubs can be co-ops, independent retailers, buying groups, wholesalers, CSA box schemes, farm-gate stalls, etc.
|
||||
|
||||
.row.buttons
|
||||
.small-12.columns
|
||||
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('contact')" } }
|
||||
%input.button.primary.right{ type: "submit", value: "Continue" }
|
||||
15
app/assets/stylesheets/admin/alert.css.sass
Normal file
15
app/assets/stylesheets/admin/alert.css.sass
Normal file
@@ -0,0 +1,15 @@
|
||||
.alert
|
||||
border: 3px solid #919191
|
||||
border-radius: 6px
|
||||
margin-bottom: 20px
|
||||
color: #919191
|
||||
padding: 5px 10px
|
||||
h6
|
||||
color: #919191
|
||||
.message
|
||||
font-weight: bold
|
||||
&:hover
|
||||
border-color: #DA5354
|
||||
color: #DA5354
|
||||
h6
|
||||
color: #DA5354
|
||||
@@ -2,44 +2,25 @@
|
||||
@import mixins
|
||||
|
||||
#registration-modal
|
||||
.header
|
||||
header
|
||||
text-align: center
|
||||
background-color: #efefef
|
||||
padding-bottom: 1rem
|
||||
// background-color: #efefef
|
||||
@media all and (max-width: 64em)
|
||||
text-align: left
|
||||
.container
|
||||
background-color: #ffffff
|
||||
.content
|
||||
// margin-bottom: 15px
|
||||
|
||||
i
|
||||
font-size: 150%
|
||||
|
||||
.buttons
|
||||
|
||||
ofn-inline-flash
|
||||
display: block
|
||||
padding: 15px
|
||||
position: relative
|
||||
margin-bottom: 10px
|
||||
&.brick
|
||||
background-color: $clr-brick-light
|
||||
border: 2px solid $clr-brick
|
||||
color: $clr-brick
|
||||
&.turquoise
|
||||
background-color: $clr-turquoise-light
|
||||
border: 2px solid $clr-turquoise
|
||||
color: $clr-turquoise
|
||||
.close-button
|
||||
position: absolute
|
||||
top: 0px
|
||||
right: 0px
|
||||
|
||||
.field
|
||||
margin-bottom: 15px
|
||||
margin-bottom: 1em
|
||||
|
||||
input.chunky
|
||||
.chunky
|
||||
padding: 8px
|
||||
font-size: 105%
|
||||
font-size: 1rem
|
||||
margin: 0
|
||||
width: 100%
|
||||
|
||||
label.indent-checkbox
|
||||
display: block
|
||||
@@ -51,9 +32,9 @@
|
||||
label
|
||||
margin-bottom: 3px
|
||||
|
||||
ol, ul
|
||||
// font-size: 80%
|
||||
ol, ul, p
|
||||
font-size: 0.875rem
|
||||
ol, ul
|
||||
padding: 0
|
||||
margin: 0
|
||||
ol
|
||||
@@ -62,22 +43,24 @@
|
||||
.highlight-box
|
||||
background: white
|
||||
padding: 1rem 1.2rem
|
||||
@media all and (max-width: 640px)
|
||||
@media all and (max-width: 64em)
|
||||
margin-top: 1rem
|
||||
|
||||
#progress-bar
|
||||
margin-bottom: 15px
|
||||
.item
|
||||
padding: 12px 0px
|
||||
font-size: 0.75rem
|
||||
padding: 10px 0px
|
||||
text-transform: uppercase
|
||||
text-align: center
|
||||
background-color: #333
|
||||
border: 2px solid #333
|
||||
background-color: $clr-blue
|
||||
border: 2px solid $clr-blue
|
||||
color: #fff
|
||||
.item.active
|
||||
background-color: #cccccc
|
||||
border: 2px solid #333
|
||||
color: #333
|
||||
background-color: $disabled-light
|
||||
border: 2px solid $clr-blue
|
||||
color: $clr-blue
|
||||
font-weight: 700
|
||||
@include box-shadow(inset 0 0 1px 0 #fff)
|
||||
|
||||
|
||||
@@ -110,39 +93,57 @@
|
||||
font-size: 18px
|
||||
font-weight: bold
|
||||
color: #373737
|
||||
background-color: #e1e1e1
|
||||
background-color: #f1f1f1
|
||||
text-align: center
|
||||
border: 3px dashed #494949
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
.spinner
|
||||
width: 100px
|
||||
&.logo
|
||||
.message
|
||||
padding-top: 6em
|
||||
.loading
|
||||
padding-top: 4em
|
||||
width: 306px
|
||||
height: 306px
|
||||
&.promo
|
||||
.message
|
||||
padding-top: 4em
|
||||
.loading
|
||||
padding-top: 1em
|
||||
width: 726px
|
||||
height: 166px
|
||||
|
||||
|
||||
#registration-details
|
||||
#registration-type
|
||||
#enterprise-types
|
||||
a.panel
|
||||
a.btnpanel
|
||||
display: block
|
||||
padding: 1rem
|
||||
margin-bottom: 1rem
|
||||
background-color: #efefef
|
||||
color: black
|
||||
@media all and (min-width: 768px)
|
||||
min-height: 200px
|
||||
text-align: center
|
||||
border: 1px solid transparent
|
||||
i
|
||||
font-size: 3rem
|
||||
h4
|
||||
margin-top: 1rem
|
||||
|
||||
&:hover
|
||||
background-color: #fff
|
||||
|
||||
&#producer-panel:hover
|
||||
border: 1px solid $clr-turquoise
|
||||
&, & *
|
||||
color: $clr-turquoise
|
||||
|
||||
&#hub-panel:hover, &#both-panel:hover
|
||||
border: 1px solid $clr-brick
|
||||
&, & *
|
||||
color: $clr-brick
|
||||
|
||||
&.selected
|
||||
&, & *
|
||||
color: #fff
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Devise::ConfirmationsController.class_eval do
|
||||
protected
|
||||
# Override of devise method in Devise::ConfirmationsController
|
||||
def after_confirmation_path_for(resource_name, resource)
|
||||
spree.admin_path
|
||||
end
|
||||
end
|
||||
@@ -2,17 +2,12 @@ require 'open_food_network/spree_api_key_loader'
|
||||
|
||||
class RegistrationController < BaseController
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
before_filter :load_spree_api_key, only: [:index, :store]
|
||||
before_filter :load_spree_api_key, only: [:index]
|
||||
before_filter :check_user, except: :authenticate
|
||||
layout 'registration'
|
||||
|
||||
def index
|
||||
@enterprise_attributes = { type: 'profile' }
|
||||
end
|
||||
|
||||
def store
|
||||
@enterprise_attributes = { is_distributor: true, is_primary_producer: true, type: 'single' }
|
||||
render :index
|
||||
@enterprise_attributes = { sells: 'none' }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Spree::Admin::ImageSettingsController.class_eval do
|
||||
# Spree stores attachent definitions in JSON. This converts the style name and format to
|
||||
# strings. However, when paperclip encounters these, it doesn't recognise the format.
|
||||
# Here we solve that problem by converting format and style name to symbols.
|
||||
def update_paperclip_settings_with_format_styles
|
||||
update_paperclip_settings_without_format_styles
|
||||
Spree::Image.reformat_styles
|
||||
end
|
||||
|
||||
alias_method_chain :update_paperclip_settings, :format_styles
|
||||
end
|
||||
21
app/helpers/admin/image_settings_helper.rb
Normal file
21
app/helpers/admin/image_settings_helper.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module Admin
|
||||
module ImageSettingsHelper
|
||||
def admin_image_settings_format_options
|
||||
[['Unchanged', ''], ['PNG', 'png'], ['JPEG', 'jpg']]
|
||||
end
|
||||
|
||||
def admin_image_settings_geometry_from_style(style)
|
||||
geometry, format = admin_image_settings_split_style style
|
||||
geometry
|
||||
end
|
||||
|
||||
def admin_image_settings_format_from_style(style)
|
||||
geometry, format = admin_image_settings_split_style style
|
||||
format
|
||||
end
|
||||
|
||||
def admin_image_settings_split_style(style)
|
||||
[style, nil].flatten[0..1]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,16 @@
|
||||
require 'devise/mailers/helpers'
|
||||
class EnterpriseMailer < Spree::BaseMailer
|
||||
def creation_confirmation(enterprise)
|
||||
find_enterprise(enterprise)
|
||||
subject = "#{@enterprise.name} is now on #{Spree::Config[:site_name]}"
|
||||
mail(:to => @enterprise.owner.email, :from => from_address, :subject => subject)
|
||||
include Devise::Mailers::Helpers
|
||||
|
||||
def confirmation_instructions(record, token, opts={})
|
||||
@token = token
|
||||
find_enterprise(record)
|
||||
opts = {
|
||||
subject: "Please confirm your email for #{@enterprise.name}",
|
||||
to: [ @enterprise.owner.email, @enterprise.email ].uniq,
|
||||
from: from_address,
|
||||
}
|
||||
devise_mail(record, :confirmation_instructions, opts)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Spree::UserMailer.class_eval do
|
||||
|
||||
|
||||
def signup_confirmation(user)
|
||||
@user = user
|
||||
mail(:to => user.email, :from => from_address,
|
||||
|
||||
@@ -2,11 +2,13 @@ class Enterprise < ActiveRecord::Base
|
||||
SELLS = %w(none own any)
|
||||
ENTERPRISE_SEARCH_RADIUS = 100
|
||||
|
||||
devise :confirmable, reconfirmable: true
|
||||
|
||||
self.inheritance_column = nil
|
||||
|
||||
acts_as_gmappable :process_geocoding => false
|
||||
|
||||
after_create :send_creation_email
|
||||
before_create :check_email
|
||||
|
||||
has_and_belongs_to_many :groups, class_name: 'EnterpriseGroup'
|
||||
has_many :producer_properties, foreign_key: 'producer_id'
|
||||
@@ -34,7 +36,7 @@ class Enterprise < ActiveRecord::Base
|
||||
path: 'public/images/enterprises/logos/:id/:style/:basename.:extension'
|
||||
|
||||
has_attached_file :promo_image,
|
||||
styles: { large: "1200x260#", medium: "720x156#", thumb: "100x100>" },
|
||||
styles: { large: ["1200x260#", :jpg], medium: ["720x156#", :jpg], thumb: ["100x100>", :jpg] },
|
||||
url: '/images/enterprises/promo_images/:id/:style/:basename.:extension',
|
||||
path: 'public/images/enterprises/promo_images/:id/:style/:basename.:extension'
|
||||
|
||||
@@ -59,6 +61,8 @@ class Enterprise < ActiveRecord::Base
|
||||
|
||||
scope :by_name, order('name')
|
||||
scope :visible, where(:visible => true)
|
||||
scope :confirmed, where('confirmed_at IS NOT NULL')
|
||||
scope :unconfirmed, where('confirmed_at IS NULL')
|
||||
scope :is_primary_producer, where(:is_primary_producer => true)
|
||||
scope :is_distributor, where('sells != ?', 'none')
|
||||
scope :supplying_variant_in, lambda { |variants| joins(:supplied_products => :variants_including_master).where('spree_variants.id IN (?)', variants).select('DISTINCT enterprises.*') }
|
||||
@@ -254,10 +258,16 @@ class Enterprise < ActiveRecord::Base
|
||||
select('DISTINCT spree_taxons.*')
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def devise_mailer
|
||||
EnterpriseMailer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_creation_email
|
||||
EnterpriseMailer.creation_confirmation(self).deliver
|
||||
def check_email
|
||||
skip_confirmation! if owner.enterprises.confirmed.map(&:email).include?(email)
|
||||
end
|
||||
|
||||
def strip_url(url)
|
||||
|
||||
@@ -15,7 +15,7 @@ class EnterpriseGroup < ActiveRecord::Base
|
||||
path: 'public/images/enterprise_groups/logos/:id/:style/:basename.:extension'
|
||||
|
||||
has_attached_file :promo_image,
|
||||
styles: {large: "1200x260#"},
|
||||
styles: {large: ["1200x260#", :jpg]},
|
||||
url: '/images/enterprise_groups/promo_images/:id/:style/:basename.:extension',
|
||||
path: 'public/images/enterprise_groups/promo_images/:id/:style/:basename.:extension'
|
||||
|
||||
|
||||
23
app/models/spree/image_decorator.rb
Normal file
23
app/models/spree/image_decorator.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
Spree::Image.class_eval do
|
||||
# Spree stores attachent definitions in JSON. This converts the style name and format to
|
||||
# strings. However, when paperclip encounters these, it doesn't recognise the format.
|
||||
# Here we solve that problem by converting format and style name to symbols.
|
||||
# See also: ImageSettingsController decorator.
|
||||
#
|
||||
# eg. {'mini' => ['48x48>', 'png']} is converted to {mini: ['48x48>', :png]}
|
||||
def self.format_styles(styles)
|
||||
styles_a = styles.map do |name, style|
|
||||
style[1] = style[1].to_sym if style.is_a? Array
|
||||
[name.to_sym, style]
|
||||
end
|
||||
|
||||
Hash[styles_a]
|
||||
end
|
||||
|
||||
def self.reformat_styles
|
||||
Spree::Image.attachment_definitions[:attachment][:styles] =
|
||||
format_styles(Spree::Image.attachment_definitions[:attachment][:styles])
|
||||
end
|
||||
|
||||
reformat_styles
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
/ replace_contents '#styles_list'
|
||||
|
||||
- @styles.each_with_index do |(style_name, style_value), index|
|
||||
.field.three.columns
|
||||
= label_tag "attachment_styles[#{style_name}]", style_name
|
||||
%a.destroy_style.with-tip{:alt => t(:destroy), :href => "#", :title => t(:destroy)}
|
||||
%i.icon-trash
|
||||
= text_field_tag "attachment_styles[#{style_name}][]", admin_image_settings_geometry_from_style(style_value), :class => 'fullwidth'
|
||||
%br/
|
||||
- current_format = admin_image_settings_format_from_style(style_value) || ''
|
||||
= select_tag "attachment_styles[#{style_name}][]", options_for_select(admin_image_settings_format_options, current_format), :class => 'fullwidth', :id => "attachment_styles_format_#{style_name}"
|
||||
@@ -45,6 +45,10 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
|
||||
|
||||
has_one :address, serializer: Api::AddressSerializer
|
||||
|
||||
def visible
|
||||
object.visible && object.confirmed?
|
||||
end
|
||||
|
||||
def pickup
|
||||
object.shipping_methods.where(:require_ship_address => false).present?
|
||||
end
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
class Api::StateSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :abbr
|
||||
|
||||
def abbr
|
||||
object.abbr.upcase
|
||||
end
|
||||
end
|
||||
100
app/views/enterprise_mailer/confirmation_instructions.html.haml
Normal file
100
app/views/enterprise_mailer/confirmation_instructions.html.haml
Normal file
@@ -0,0 +1,100 @@
|
||||
/ ORIGINAL & UGLY:
|
||||
/ %p= "Welcome #{@resource.contact}!"
|
||||
/ %p= "Please confirm your email address for #{@resource.name}."
|
||||
/ %p= "Click the link below to activate your enterprise:"
|
||||
/ %p= link_to 'Confirm this email address', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token)
|
||||
|
||||
|
||||
%html{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;", :xmlns => "http://www.w3.org/1999/xhtml"}
|
||||
%head{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
/ If you delete this meta tag, Half Life 3 will never be released.
|
||||
%meta{:content => "width=device-width", :name => "viewport", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}/
|
||||
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}/
|
||||
%title{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"} Open Food Network
|
||||
%link{:href => "http://rohanmitchell.com/random/template/basic-email-template/stylesheets/email.css", :rel => "stylesheet", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;", :type => "text/css"}/
|
||||
%body{:bgcolor => "#FFFFFF", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-webkit-text-size-adjust: none;height: 100%;width: 100%!important;"}
|
||||
/ HEADER
|
||||
%table.head-wrap{:bgcolor => "#333333", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 100%;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td.header.container{:style => "margin: 0 auto!important;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;display: block!important;max-width: 600px!important;clear: both!important;"}
|
||||
.content{:style => "margin: 0 auto;padding: 15px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;max-width: 600px;display: block;"}
|
||||
%table{:bgcolor => "#333333", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 100%;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%img{:src => "https://openfoodnetwork.org.au/assets/ofn_logo_beta-8e4dfc79deb25def2d107dea52dce492.png", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;max-width: 100%;", :width => "200"}/
|
||||
%td{:align => "right", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%h6.collapse{:style => "margin: 0!important;padding: 0;font-family: \"HelveticaNeue-Light\", \"Helvetica Neue Light\", \"Helvetica Neue\", Helvetica, Arial, \"Lucida Grande\", sans-serif;line-height: 1.1;margin-bottom: 15px;color: #999;font-weight: 900;font-size: 14px;text-transform: uppercase;"} Open Food Network
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
/ /HEADER
|
||||
/ BODY
|
||||
%table.body-wrap{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 100%;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td.container{:bgcolor => "#FFFFFF", :style => "margin: 0 auto!important;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;display: block!important;max-width: 600px!important;clear: both!important;"}
|
||||
.content{:style => "margin: 0 auto;padding: 15px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;max-width: 600px;display: block;"}
|
||||
%table{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 100%;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%h3{:style => "margin: 0;padding: 0;font-family: \"HelveticaNeue-Light\", \"Helvetica Neue Light\", \"Helvetica Neue\", Helvetica, Arial, \"Lucida Grande\", sans-serif;line-height: 1.1;margin-bottom: 15px;color: #000;font-weight: 500;font-size: 27px;"}= "Welcome, #{@resource.contact}!"
|
||||
%p.lead{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;margin-bottom: 10px;font-weight: normal;font-size: 17px;line-height: 1.6;"}
|
||||
= "Please confirm email address for your enterprise "
|
||||
%strong
|
||||
= "#{@resource.name}."
|
||||
%p
|
||||
/ Callout Panel
|
||||
%p.callout{:style => "margin: 0; padding: 15px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;margin-bottom: 15px;font-weight: normal;font-size: 14px;line-height: 1.6;background-color: #e1f0f5;"}
|
||||
= "Click the link below to confirm email and to activate your enterprise. This link can be used only once:"
|
||||
%br
|
||||
%strong
|
||||
= link_to 'Confirm this email address »', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token)
|
||||
/ /Callout Panel
|
||||
%p
|
||||
%p{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;margin-bottom: 10px;font-weight: normal;font-size: 14px;line-height: 1.6;"}= "We're so excited that you're joining the Open Food Network! Don't hestitate to get in touch if you have any questions."
|
||||
%p
|
||||
/ social & contact
|
||||
%table.social{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;background-color: #ebebeb;width: 100%;", :width => "100%"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
/ column 1
|
||||
%table.column{:align => "left", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 280px;float: left;min-width: 279px;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 15px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%h5{:style => "margin: 0;padding: 0;font-family: \"HelveticaNeue-Light\", \"Helvetica Neue Light\", \"Helvetica Neue\", Helvetica, Arial, \"Lucida Grande\", sans-serif;line-height: 1.1;margin-bottom: 15px;color: #000;font-weight: 900;font-size: 17px;"} Connect with Us:
|
||||
%p{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;margin-bottom: 10px;font-weight: normal;font-size: 14px;line-height: 1.6;"}
|
||||
%a.soc-btn.fb{:href => "https://www.facebook.com/OpenFoodNet", :style => "margin: 0;padding: 3px 7px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;color: #FFF;font-size: 12px;margin-bottom: 10px;text-decoration: none;font-weight: bold;display: block;text-align: center;background-color: #3B5998!important;", :target => "_blank"} Facebook
|
||||
%a.soc-btn.tw{:href => "https://twitter.com/OpenFoodNet", :style => "margin: 0;padding: 3px 7px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;color: #FFF;font-size: 12px;margin-bottom: 10px;text-decoration: none;font-weight: bold;display: block;text-align: center;background-color: #1daced!important;", :target => "_blank"} Twitter
|
||||
%a.soc-btn.li{:href => "http://www.linkedin.com/groups/Open-Food-Foundation-4743336", :style => "margin: 0;padding: 3px 7px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;color: #FFF;font-size: 12px;margin-bottom: 10px;text-decoration: none;font-weight: bold;display: block;text-align: center;background-color: #0073b2!important;", :target => "_blank"} LinkedIn
|
||||
/ /column 1
|
||||
/ column 2
|
||||
%table.column{:align => "left", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 280px;float: left;min-width: 279px;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 15px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%h5{:style => "margin: 0;padding: 0;font-family: \"HelveticaNeue-Light\", \"Helvetica Neue Light\", \"Helvetica Neue\", Helvetica, Arial, \"Lucida Grande\", sans-serif;line-height: 1.1;margin-bottom: 15px;color: #000;font-weight: 900;font-size: 17px;"} Email us:
|
||||
%p{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;margin-bottom: 10px;font-weight: normal;font-size: 14px;line-height: 1.6;"}
|
||||
%strong{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%a{:href => "hello@openfoodnetwork.org", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;color: #0096ad;"} hello@openfoodnetwork.org
|
||||
/ /column 2
|
||||
%span.clear{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;display: block;clear: both;"}
|
||||
/ /social & contact
|
||||
/ /content
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
/ /BODY
|
||||
/ FOOTER
|
||||
%table.footer-wrap{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 100%;clear: both!important;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td.container{:style => "margin: 0 auto!important;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;display: block!important;max-width: 600px!important;clear: both!important;"}
|
||||
/ content
|
||||
.content{:style => "margin: 0 auto;padding: 15px;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;max-width: 600px;display: block;"}
|
||||
%table{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;width: 100%;"}
|
||||
%tr{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%td{:align => "center", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
%p{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;margin-bottom: 10px;font-weight: normal;font-size: 14px;line-height: 1.6;"}
|
||||
%a{:href => "https://openfoodnetwork.org.au/Terms-of-service.pdf", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;color: #0096ad;", :target => "_blank"} Terms of service
|
||||
|
|
||||
%a{:href => "http://www.openfoodnetwork.org.au", :style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;color: #0096ad;", :target => "_blank"} Open Food Network
|
||||
/ | <a href="#"><unsubscribe>Unsubscribe</unsubscribe></a>
|
||||
/ /content
|
||||
%td{:style => "margin: 0;padding: 0;font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;"}
|
||||
/ /FOOTER
|
||||
@@ -1,9 +0,0 @@
|
||||
%h1
|
||||
= @enterprise.name + " has been created"
|
||||
|
||||
%h3
|
||||
Why not check it out on
|
||||
%a{ href: "#{map_url}" }
|
||||
= Spree::Config[:site_name] + "?"
|
||||
|
||||
If you have any questions, please get in touch with us at: hello@openfoodnetwork.org
|
||||
4
app/views/spree/admin/overview/_unconfirmed.html.haml
Normal file
4
app/views/spree/admin/overview/_unconfirmed.html.haml
Normal file
@@ -0,0 +1,4 @@
|
||||
- @enterprises.unconfirmed.each do |enterprise|
|
||||
.alert
|
||||
%h6= "Action Required: Please confirm the email address for #{enterprise.name}."
|
||||
%span.message= "We've sent a confirmation email to #{enterprise.email}, so please check there for further instructions. Thanks!"
|
||||
@@ -1,10 +1,17 @@
|
||||
%h1{ :style => 'margin-bottom: 30px'} Dashboard
|
||||
|
||||
- if @enterprises.unconfirmed.any?
|
||||
|
||||
= render partial: "spree/admin/overview/unconfirmed"
|
||||
|
||||
%hr
|
||||
|
||||
- if @enterprises.empty?
|
||||
|
||||
= render partial: "spree/admin/overview/enterprises"
|
||||
|
||||
- else
|
||||
|
||||
- if can? :admin, Spree::Product
|
||||
= render partial: "spree/admin/overview/products"
|
||||
|
||||
|
||||
5
config/initializers/devise.rb
Normal file
5
config/initializers/devise.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
Devise.setup do |config|
|
||||
# Add a default scope to devise, to prevent it from checking
|
||||
# whether other devise enabled models are signed into a session or not
|
||||
config.default_scope = :spree_user
|
||||
end
|
||||
@@ -27,9 +27,16 @@ module.exports = function(config) {
|
||||
'app/assets/javascripts/admin/util.js.erb'
|
||||
],
|
||||
|
||||
preprocessors: {
|
||||
'**/*.coffee': ['coffee']
|
||||
},
|
||||
|
||||
coffeePreprocessor: {
|
||||
options: {
|
||||
sourceMap: true
|
||||
},
|
||||
transformPath: function(path) {
|
||||
return path.replace(/\.coffee$/, '.js');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ Openfoodnetwork::Application.routes.draw do
|
||||
get "/map", to: "map#index", as: :map
|
||||
|
||||
get "/register", to: "registration#index", as: :registration
|
||||
get "/register/store", to: "registration#store", as: :store_registration
|
||||
get "/register/auth", to: "registration#authenticate", as: :registration_auth
|
||||
|
||||
resource :shop, controller: "shop" do
|
||||
@@ -35,6 +34,8 @@ Openfoodnetwork::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
devise_for :enterprise
|
||||
|
||||
namespace :admin do
|
||||
resources :order_cycles do
|
||||
post :bulk_update, on: :collection, as: :bulk_update
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
class EnterpriseConfigRefactor < ActiveRecord::Migration
|
||||
class Enterprise < ActiveRecord::Base
|
||||
self.inheritance_column = nil
|
||||
end
|
||||
|
||||
def up
|
||||
add_column :enterprises, :sells, :string, null: false, default: 'none'
|
||||
add_index :enterprises, :sells
|
||||
add_index :enterprises, [:is_primary_producer, :sells]
|
||||
|
||||
Enterprise.reset_column_information
|
||||
|
||||
Enterprise.all.each do |enterprise|
|
||||
enterprise.update_attributes!({:sells => sells_what?(enterprise)})
|
||||
end
|
||||
@@ -17,6 +23,8 @@ class EnterpriseConfigRefactor < ActiveRecord::Migration
|
||||
add_column :enterprises, :type, :string, null: false, default: 'profile'
|
||||
add_column :enterprises, :is_distributor, :boolean
|
||||
|
||||
Enterprise.reset_column_information
|
||||
|
||||
Enterprise.all.each do |enterprise|
|
||||
enterprise.update_attributes!({
|
||||
:type => type?(enterprise),
|
||||
|
||||
16
db/migrate/20141010043405_add_confirmable_to_enterprise.rb
Normal file
16
db/migrate/20141010043405_add_confirmable_to_enterprise.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class AddConfirmableToEnterprise < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :enterprises, :confirmation_token, :string
|
||||
add_column :enterprises, :confirmed_at, :datetime
|
||||
add_column :enterprises, :confirmation_sent_at, :datetime
|
||||
add_column :enterprises, :unconfirmed_email, :string
|
||||
add_index :enterprises, :confirmation_token, :unique => true
|
||||
|
||||
# Existing enterprises are assumed to be confirmed
|
||||
Enterprise.update_all(:confirmed_at => Time.now)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_columns :enterprises, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20140927005043) do
|
||||
ActiveRecord::Schema.define(:version => 20141010043405) do
|
||||
|
||||
create_table "adjustment_metadata", :force => true do |t|
|
||||
t.integer "adjustment_id"
|
||||
@@ -264,10 +264,15 @@ ActiveRecord::Schema.define(:version => 20140927005043) do
|
||||
t.string "instagram"
|
||||
t.string "linkedin"
|
||||
t.integer "owner_id", :null => false
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "unconfirmed_email"
|
||||
t.string "sells", :default => "none", :null => false
|
||||
end
|
||||
|
||||
add_index "enterprises", ["address_id"], :name => "index_enterprises_on_address_id"
|
||||
add_index "enterprises", ["confirmation_token"], :name => "index_enterprises_on_confirmation_token", :unique => true
|
||||
add_index "enterprises", ["is_primary_producer", "sells"], :name => "index_enterprises_on_is_primary_producer_and_sells"
|
||||
add_index "enterprises", ["owner_id"], :name => "index_enterprises_on_owner_id"
|
||||
add_index "enterprises", ["sells"], :name => "index_enterprises_on_sells"
|
||||
|
||||
15
spec/controllers/devise/confirmation_controller_spec.rb
Normal file
15
spec/controllers/devise/confirmation_controller_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Devise::ConfirmationsController do
|
||||
context "after confirmation" do
|
||||
before do
|
||||
e = create(:enterprise, confirmed_at: nil)
|
||||
@request.env["devise.mapping"] = Devise.mappings[:enterprise]
|
||||
spree_get :show, confirmation_token: e.confirmation_token
|
||||
end
|
||||
|
||||
it "should redirect to admin root" do
|
||||
expect(response).to redirect_to spree.admin_path
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,11 +7,6 @@ describe RegistrationController do
|
||||
get :index
|
||||
response.should redirect_to registration_auth_path(anchor: "signup?after_login=/register")
|
||||
end
|
||||
|
||||
it "store" do
|
||||
get :store
|
||||
response.should redirect_to registration_auth_path(anchor: "signup?after_login=/register/store")
|
||||
end
|
||||
end
|
||||
|
||||
describe "redirecting when user has reached enterprise ownership limit" do
|
||||
@@ -41,12 +36,5 @@ describe RegistrationController do
|
||||
expect(assigns(:spree_api_key)).to eq user.spree_api_key
|
||||
end
|
||||
end
|
||||
|
||||
describe "store" do
|
||||
it "loads the spree api key" do
|
||||
get :store
|
||||
expect(assigns(:spree_api_key)).to eq user.spree_api_key
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,6 +97,7 @@ FactoryGirl.define do
|
||||
long_description '<p>Hello, world!</p><p>This is a paragraph.</p>'
|
||||
email 'enterprise@example.com'
|
||||
address { FactoryGirl.create(:address) }
|
||||
confirmed_at { Time.now }
|
||||
end
|
||||
|
||||
factory :supplier_enterprise, :parent => :enterprise do
|
||||
|
||||
43
spec/features/admin/image_settings_spec.rb
Normal file
43
spec/features/admin/image_settings_spec.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
require 'spec_helper'
|
||||
|
||||
feature %q{
|
||||
As an admin
|
||||
I want to manage image formats
|
||||
} do
|
||||
include AuthenticationWorkflow
|
||||
include WebHelper
|
||||
|
||||
before(:all) do
|
||||
styles = {"mini" => "48x48>",
|
||||
"small" => "100x100>",
|
||||
"product" => "240x240>",
|
||||
"large" => "600x600>"}
|
||||
|
||||
Spree::Config[:attachment_styles] = ActiveSupport::JSON.encode(styles)
|
||||
Spree::Image.attachment_definitions[:attachment][:styles] = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles])
|
||||
Spree::Image.reformat_styles
|
||||
end
|
||||
|
||||
scenario "setting the image format for a paperclip style" do
|
||||
# When I go to the image settings page
|
||||
login_to_admin_section
|
||||
visit spree.edit_admin_image_settings_path
|
||||
|
||||
# All the styles should default to "Unchanged"
|
||||
page.should have_select 'attachment_styles_format_mini', selected: 'Unchanged'
|
||||
page.should have_select 'attachment_styles_format_small', selected: 'Unchanged'
|
||||
page.should have_select 'attachment_styles_format_product', selected: 'Unchanged'
|
||||
page.should have_select 'attachment_styles_format_large', selected: 'Unchanged'
|
||||
|
||||
# When I change a style to "PNG" and save
|
||||
select 'PNG', from: 'attachment_styles_format_mini'
|
||||
click_button 'Update'
|
||||
|
||||
# Then the change should be saved to the image formats
|
||||
page.should have_content "Image Settings successfully updated."
|
||||
page.should have_select 'attachment_styles_format_mini', selected: 'PNG'
|
||||
|
||||
styles = Spree::Image.attachment_definitions[:attachment][:styles]
|
||||
styles[:mini].should == ['48x48>', :png]
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
require "spec_helper"
|
||||
require 'spec_helper'
|
||||
|
||||
feature %q{
|
||||
As an admin
|
||||
|
||||
@@ -3,14 +3,14 @@ require 'spec_helper'
|
||||
feature %q{
|
||||
As a consumer
|
||||
I want to see a list of producers
|
||||
So that I can shop at hubs distributing their products
|
||||
So that I can shop at hubs distributing their products
|
||||
}, js: true do
|
||||
include UIComponentHelper
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
let!(:invisible_producer) { create(:supplier_enterprise, visible: false) }
|
||||
let(:taxon) { create(:taxon) }
|
||||
let!(:product) { create(:simple_product, supplier: producer, taxons: [taxon]) }
|
||||
|
||||
|
||||
before do
|
||||
visit producers_path
|
||||
end
|
||||
@@ -20,7 +20,7 @@ feature %q{
|
||||
expand_active_table_node producer.name
|
||||
page.should have_content producer.supplied_taxons.first.name.split.map(&:capitalize).join(' ')
|
||||
end
|
||||
|
||||
|
||||
it "doesn't show invisible producers" do
|
||||
page.should_not have_content invisible_producer.name
|
||||
end
|
||||
|
||||
@@ -3,8 +3,7 @@ require 'spec_helper'
|
||||
feature "Registration", js: true do
|
||||
include WebHelper
|
||||
|
||||
# TODO fix this after removal of is_distributor.
|
||||
pending "Registering a Profile" do
|
||||
describe "Registering a Profile" do
|
||||
let(:user) { create(:user, password: "password", password_confirmation: "password") }
|
||||
|
||||
it "Allows a logged in user to register a profile" do
|
||||
@@ -18,25 +17,22 @@ feature "Registration", js: true do
|
||||
# Enter Login details
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "Password", with: user.password
|
||||
click_login_and_ensure_content "This wizard will step you through creating a profile"
|
||||
click_login_and_ensure_content "Hi there!"
|
||||
|
||||
expect(URI.parse(current_url).path).to eq registration_path
|
||||
|
||||
# Done reading introduction
|
||||
click_button_and_ensure_content "Let's get started!", "Woot! First we need to know what sort of enterprise you are:"
|
||||
click_button_and_ensure_content "Let's get started!", "Woot! First we need to know a little bit about your enterprise:"
|
||||
|
||||
# Filling in details
|
||||
fill_in 'enterprise_name', with: "My Awesome Enterprise"
|
||||
click_link 'both-panel'
|
||||
|
||||
click_button_and_ensure_content "Continue", "Greetings My Awesome Enterprise"
|
||||
|
||||
# Filling in address
|
||||
fill_in 'enterprise_address', with: '123 Abc Street'
|
||||
fill_in 'enterprise_city', with: 'Northcote'
|
||||
fill_in 'enterprise_zipcode', with: '3070'
|
||||
select 'Australia', from: 'enterprise_country'
|
||||
select 'Vic', from: 'enterprise_state'
|
||||
select 'VIC', from: 'enterprise_state'
|
||||
click_button 'Continue'
|
||||
|
||||
# Filling in Contact Details
|
||||
@@ -46,6 +42,11 @@ feature "Registration", js: true do
|
||||
fill_in 'enterprise_phone', with: '12 3456 7890'
|
||||
click_button 'Continue'
|
||||
|
||||
# Choosing a type
|
||||
expect(page).to have_content 'Last step to add My Awesome Enterprise!'
|
||||
click_link 'producer-panel'
|
||||
click_button 'Continue'
|
||||
|
||||
# Enterprise should be created
|
||||
expect(page).to have_content 'Nice one!'
|
||||
e = Enterprise.find_by_name('My Awesome Enterprise')
|
||||
@@ -76,7 +77,7 @@ feature "Registration", js: true do
|
||||
click_button 'Continue'
|
||||
|
||||
# Filling in social
|
||||
expect(page).to have_content 'Last step!'
|
||||
expect(page).to have_content 'How can people find My Awesome Enterprise online?'
|
||||
fill_in 'enterprise_website', with: 'www.shop.com'
|
||||
fill_in 'enterprise_facebook', with: 'FaCeBoOk'
|
||||
fill_in 'enterprise_linkedin', with: 'LiNkEdIn'
|
||||
@@ -85,7 +86,7 @@ feature "Registration", js: true do
|
||||
click_button 'Continue'
|
||||
|
||||
# Done
|
||||
expect(page).to have_content "You have successfully completed the profile for My Awesome Enterprise"
|
||||
expect(page).to have_content "Finished!"
|
||||
e.reload
|
||||
expect(e.website).to eq "www.shop.com"
|
||||
expect(e.facebook).to eq "FaCeBoOk"
|
||||
@@ -93,31 +94,6 @@ feature "Registration", js: true do
|
||||
expect(e.twitter).to eq "@TwItTeR"
|
||||
expect(e.instagram).to eq "@InStAgRaM"
|
||||
end
|
||||
|
||||
it "Allows a logged in user to register a store" do
|
||||
visit store_registration_path
|
||||
|
||||
expect(URI.parse(current_url).path).to eq registration_auth_path
|
||||
|
||||
page.has_selector? "dd", text: "Log in"
|
||||
switch_to_login_tab
|
||||
|
||||
# Enter Login details
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "Password", with: user.password
|
||||
click_login_and_ensure_content "This wizard will step you through creating a profile"
|
||||
|
||||
expect(URI.parse(current_url).path).to eq store_registration_path
|
||||
|
||||
# Done reading introduction
|
||||
click_button_and_ensure_content "Let's get started!", "Woot! First we need to know the name of your farm:"
|
||||
|
||||
# Details Page
|
||||
expect(page).to have_content "Woot! First we need to know the name of your farm:"
|
||||
expect(page).to_not have_selector '#enterprise-types'
|
||||
|
||||
# Everything from here should be covered in 'profile' spec
|
||||
end
|
||||
end
|
||||
|
||||
def switch_to_login_tab
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe EnterpriseMailer do
|
||||
let!(:enterprise) { create(:enterprise) }
|
||||
|
||||
before do
|
||||
@enterprise = create(:enterprise)
|
||||
ActionMailer::Base.deliveries = []
|
||||
end
|
||||
|
||||
it "should send an email when given an enterprise" do
|
||||
EnterpriseMailer.creation_confirmation(@enterprise).deliver
|
||||
it "should send an email confirmation when given an enterprise" do
|
||||
EnterpriseMailer.confirmation_instructions(enterprise, 'token').deliver
|
||||
ActionMailer::Base.deliveries.count.should == 1
|
||||
mail = ActionMailer::Base.deliveries.first
|
||||
expect(mail.subject).to eq "Please confirm your email for #{enterprise.name}"
|
||||
end
|
||||
end
|
||||
@@ -3,6 +3,25 @@ require 'spec_helper'
|
||||
describe Enterprise do
|
||||
include AuthenticationWorkflow
|
||||
|
||||
describe "sending emails" do
|
||||
describe "on creation" do
|
||||
let!(:user) { create_enterprise_user( enterprise_limit: 2 ) }
|
||||
let!(:enterprise) { create(:enterprise, owner: user) }
|
||||
|
||||
it "when the email address has not already been confirmed" do
|
||||
mail_message = double "Mail::Message"
|
||||
EnterpriseMailer.should_receive(:confirmation_instructions).and_return mail_message
|
||||
mail_message.should_receive :deliver
|
||||
create(:enterprise, owner: user, email: "unknown@email.com", confirmed_at: nil )
|
||||
end
|
||||
|
||||
it "when the email address has already been confirmed" do
|
||||
EnterpriseMailer.should_not_receive(:confirmation_instructions)
|
||||
e = create(:enterprise, owner: user, email: enterprise.email, confirmed_at: nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "associations" do
|
||||
it { should belong_to(:owner) }
|
||||
it { should have_many(:supplied_products) }
|
||||
@@ -102,6 +121,7 @@ describe Enterprise do
|
||||
it { should delegate(:city).to(:address) }
|
||||
it { should delegate(:state_name).to(:address) }
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
describe 'active' do
|
||||
it 'find active enterprises' do
|
||||
@@ -111,6 +131,28 @@ describe Enterprise do
|
||||
end
|
||||
end
|
||||
|
||||
describe "confirmed" do
|
||||
it "find enterprises with a confirmed date" do
|
||||
s1 = create(:supplier_enterprise)
|
||||
d1 = create(:distributor_enterprise)
|
||||
s2 = create(:supplier_enterprise, confirmed_at: nil)
|
||||
d2 = create(:distributor_enterprise, confirmed_at: nil)
|
||||
expect(Enterprise.confirmed).to include s1, d1
|
||||
expect(Enterprise.confirmed).to_not include s2, d2
|
||||
end
|
||||
end
|
||||
|
||||
describe "unconfirmed" do
|
||||
it "find enterprises without a confirmed date" do
|
||||
s1 = create(:supplier_enterprise)
|
||||
d1 = create(:distributor_enterprise)
|
||||
s2 = create(:supplier_enterprise, confirmed_at: nil)
|
||||
d2 = create(:distributor_enterprise, confirmed_at: nil)
|
||||
expect(Enterprise.unconfirmed).to_not include s1, d1
|
||||
expect(Enterprise.unconfirmed).to include s2, d2
|
||||
end
|
||||
end
|
||||
|
||||
describe "distributors_with_active_order_cycles" do
|
||||
it "finds active distributors by order cycles" do
|
||||
s = create(:supplier_enterprise)
|
||||
@@ -504,8 +546,7 @@ describe Enterprise do
|
||||
end
|
||||
|
||||
describe "provide enterprise category" do
|
||||
|
||||
let(:producer_sell_all) { build(:enterprise, is_primary_producer: true, sells: "any") }
|
||||
let(:producer_sell_all) { build(:enterprise, is_primary_producer: true, sells: "any") }
|
||||
let(:producer_sell_own) { build(:enterprise, is_primary_producer: true, sells: "own") }
|
||||
let(:producer_sell_none) { build(:enterprise, is_primary_producer: true, sells: "none") }
|
||||
let(:non_producer_sell_all) { build(:enterprise, is_primary_producer: false, sells: "any") }
|
||||
@@ -519,7 +560,7 @@ describe Enterprise do
|
||||
producer_sell_all.category.should == :producer_hub
|
||||
producer_sell_own.category.should == :producer_shop
|
||||
producer_sell_none.category.should == :producer
|
||||
non_producer_sell_all.category.should == :hub
|
||||
non_producer_sell_all.category.should == :hub
|
||||
non_producer_sell_own.category.should == :hub
|
||||
non_producer_sell_none.category.should == :hub_profile
|
||||
end
|
||||
|
||||
18
spec/models/spree/image_spec.rb
Normal file
18
spec/models/spree/image_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
describe Image do
|
||||
describe "attachment definitions" do
|
||||
let(:name_str) { {"mini" => "48x48>"} }
|
||||
let(:formatted) { {mini: ["48x48>", "png"]} }
|
||||
|
||||
it "converts style names to symbols" do
|
||||
Image.format_styles(name_str).should == {:mini => "48x48>"}
|
||||
end
|
||||
|
||||
it "converts formats to symbols" do
|
||||
Image.format_styles(formatted).should == {:mini => ["48x48>", :png]}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,9 +13,27 @@ describe Api::EnterpriseSerializer do
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match taxon.id.to_s
|
||||
end
|
||||
|
||||
|
||||
it "will render urls" do
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match "map_005-hub.svg"
|
||||
end
|
||||
|
||||
describe "visibility" do
|
||||
before do
|
||||
enterprise.stub(:visible).and_return true
|
||||
end
|
||||
|
||||
it "is visible when confirmed" do
|
||||
enterprise.stub(:confirmed?).and_return true
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
expect(serializer.to_json).to match "\"visible\":true"
|
||||
end
|
||||
|
||||
it "is not visible when unconfirmed" do
|
||||
enterprise.stub(:confirmed?).and_return false
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
expect(serializer.to_json).to match "\"visible\":false"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user