Compare commits

..

107 Commits

Author SHA1 Message Date
Brenda Wallace
8c51d7bdd5 Merge branch 'master' into dev 2018-02-18 13:09:56 +13:00
Cesy
64e3b3b4d4 Merge pull request #1565 from Growstuff/awesomecode-style/andor-8234
Auto corrected by following Style/AndOr
2018-02-16 08:47:02 +00:00
Brenda Wallace
978523fd94 Merge branch 'dev' into awesomecode-style/andor-8234 2018-02-11 08:50:50 +13:00
Brenda Wallace
97f63d1147 Merge pull request #1583 from Growstuff/dev
Production hotfix
2018-02-11 08:42:49 +13:00
Brenda Wallace
1a9ff5eb4c Merge branch 'master' into dev 2018-02-11 08:14:44 +13:00
Brenda Wallace
72b1494db9 Merge pull request #1582 from Br3nda/hotfix-migration
Don't update flickr photos in migration
2018-02-11 08:14:00 +13:00
Brenda Wallace
83bba916a4 Don't update flickr photos in migration 2018-02-10 18:41:11 +13:00
Brenda Wallace
64179850ff Merge pull request #1563 from Growstuff/dev
Release 40
2018-02-10 09:04:55 +13:00
Brenda Wallace
9cdf2e899f Merge pull request #1569 from Br3nda/remove/paid-accounts
Removing shop, products, accounts, orders
2018-02-09 11:09:36 +13:00
Brenda Wallace
2eacf346a8 Merge remote-tracking branch 'origin/remove/paid-accounts' into remove/paid-accounts 2018-02-09 10:53:47 +13:00
Brenda Wallace
aab91e2fa9 Removed active merchant 2018-02-09 10:53:05 +13:00
Brenda Wallace
2217d87b5a Added back the member's last login 2018-02-09 10:53:05 +13:00
Brenda Wallace
44b2251896 Re-instated the member-since text on profiles 2018-02-09 10:53:05 +13:00
Brenda Wallace
f5e20cd2d2 Re-gen rubocop todo 2018-02-09 10:53:05 +13:00
Brenda Wallace
42de726405 Removing shop, products, accounts, orders 2018-02-09 10:53:05 +13:00
Brenda Wallace
65b4c7dbc1 Revert "Auto corrected by following Style/StringLiterals"
This reverts commit ab56a3c6b3.
2018-02-09 07:58:47 +13:00
Brenda Wallace
6b6ed7e31c Merge remote-tracking branch 'origin/remove/paid-accounts' into remove/paid-accounts 2018-02-09 07:47:53 +13:00
Brenda Wallace
564901f93f Merge branch 'dev' into remove/paid-accounts 2018-02-09 07:46:51 +13:00
Brenda Wallace
f8127eeec3 Revert "Auto corrected by following Style/StringLiterals"
This reverts commit ab56a3c6b3.
2018-02-09 07:44:48 +13:00
Brenda Wallace
33fb2408d6 Merge branch 'dev' into awesomecode-style/andor-8234 2018-02-07 14:25:41 +13:00
Awesome Code
ab56a3c6b3 Auto corrected by following Style/StringLiterals 2018-02-07 10:20:26 +13:00
Brenda Wallace
ef4b4d0c46 Merge branch 'dev' into awesomecode-style/andor-8234 2018-02-07 08:41:30 +13:00
Brenda Wallace
44ba29137d Merge branch 'dev' into remove/paid-accounts 2018-02-07 08:41:17 +13:00
deppbot
ed2fcc2ada Bundle Update on 2018-02-07 2018-02-07 08:40:54 +13:00
Brenda Wallace
0b5c45d08f Merge branch 'dev' into awesomecode-style/andor-8234 2018-02-05 16:13:15 +13:00
Brenda Wallace
54c880a66c Removed active merchant 2018-02-05 15:40:37 +13:00
Brenda Wallace
0699677d05 Added back the member's last login 2018-02-05 14:42:41 +13:00
Brenda Wallace
3c411f15b8 Re-instated the member-since text on profiles 2018-02-05 14:42:05 +13:00
Brenda Wallace
dcf5286275 Re-gen rubocop todo 2018-02-05 14:38:08 +13:00
Brenda Wallace
7e1e2bef91 Removing shop, products, accounts, orders 2018-02-05 14:32:59 +13:00
Brenda Wallace
5cda14f87a Don't update flickr meta data on db rollback 2018-02-05 12:52:59 +13:00
Brenda Wallace
88da0da616 Re-fetches from flickr 2018-02-05 12:52:59 +13:00
Meir Taffel
a69afd87e7 Add date_taken to photos 2018-02-05 12:52:59 +13:00
Brenda Wallace
57bfafccc7 Merge branch 'dev' into awesomecode-style/andor-8234 2018-02-05 12:28:08 +13:00
deppbot
24931381af Bundle Update on 2018-02-03 2018-02-04 08:25:59 +13:00
deppbot
742c7e30a9 Bundle Update on 2018-01-31 2018-01-31 13:12:08 +13:00
Daniel O'Connor
2f3e368ede Merge branch 'dev' into awesomecode-style/andor-8234 2018-01-29 11:45:51 +10:30
Daniel O'Connor
502a20cf10 Merge pull request #1564 from Growstuff/awesomecode-rspec/leadingsubject-8234
Auto corrected by following RSpec/LeadingSubject
2018-01-29 11:45:07 +10:30
Brenda Wallace
b2cf022522 Removed extra blank lines 2018-01-29 13:01:49 +13:00
Shiny
3d4598e4e1 style clean up 2018-01-29 12:56:41 +13:00
Awesome Code
94db28b3a9 Auto corrected by following Style/AndOr 2018-01-28 23:47:38 +00:00
Awesome Code
767477df66 Auto corrected by following RSpec/LeadingSubject 2018-01-28 23:47:27 +00:00
Brenda Wallace
7f87ee1018 Fixed default_photo for seeds - uses own photos, not the crop 2018-01-29 09:55:06 +13:00
deppbot
093a948922 Bundle Update on 2018-01-28 2018-01-29 09:54:30 +13:00
deppbot
be1553410f Bundle Update on 2018-01-24 2018-01-29 09:54:20 +13:00
Shiny
caf41e80c9 Patching paperclip gem 2018-01-24 15:07:06 +13:00
deppbot
2eff7d6716 Bundle Update on 2018-01-21 2018-01-23 09:00:34 +13:00
Shiny
df5006c61c Disable jshint
this is on by default
2018-01-23 09:00:34 +13:00
Brenda Wallace
1e0565dd9b Tell hound to ignore the bootstrap plugin file 2018-01-23 09:00:34 +13:00
Brenda Wallace
3453a648fa Latest versions of bootstrap accessibility plugin 2018-01-23 09:00:34 +13:00
Awesome Code
e8d9314cff Auto corrected by following Style/Lambda 2018-01-23 09:00:34 +13:00
Brenda Wallace
92e56cfc1e Fixed up a spec, use sign_in member instead of stubing 2018-01-23 09:00:34 +13:00
Brenda Wallace
3dc356eb29 order gardens by name on plantings form 2018-01-23 09:00:34 +13:00
Brenda Wallace
56ed61b2b3 Lock pg < 1.0.0 for now 2018-01-23 09:00:34 +13:00
Brenda Wallace
16ad5384d1 Moved gardens chart to dedicated controller 2018-01-23 09:00:34 +13:00
Brenda Wallace
cf93489af7 Fixed crops chart permissions by moving to another controller 2018-01-23 09:00:34 +13:00
Brenda Wallace
86b9a3650b Move application.js loading last again 2018-01-23 09:00:34 +13:00
Brenda Wallace
625a035f44 Scope js variables so they are not global 2018-01-23 09:00:34 +13:00
Brenda Wallace
196d37dee9 Re-instated the extra fields on crop.json 2018-01-23 09:00:34 +13:00
Shiny
6f613635d2 Update crop_detail_page_spec.rb 2018-01-23 09:00:34 +13:00
Awesome Code
46267b2a1d Auto corrected by following Style/MutableConstant 2018-01-23 09:00:34 +13:00
Awesome Code
8c8d549cb1 Auto corrected by following RSpec/NotToNot 2018-01-23 09:00:34 +13:00
Awesome Code
d9cc1dcae8 Auto corrected by following RSpec/MultipleSubjects 2018-01-23 09:00:34 +13:00
Brenda Wallace
9db4736229 Permissions (and specs) for charts json 2018-01-23 09:00:34 +13:00
pozorvlak
04a7c41f63 Only deploy from the Elasticsearch build job
Fixes #1099, or at least works around it, though a better solution would
be to rewrite our deployment system using Travis build stages or Heroku
build pipelines.

The Elasticsearch job was picked because it's the one most likely to
fail, and I can't work out how to deploy only if all three jobs pass.
2018-01-23 09:00:34 +13:00
Brenda Wallace
78b8be1fc2 Use .presence to find finished ts in timeline 2018-01-23 09:00:34 +13:00
Brenda Wallace
b6e9539127 Use predicted finish times to put current plantings on the timeline 2018-01-23 09:00:34 +13:00
Brenda Wallace
33276874a8 add google js to gardens#show 2018-01-23 09:00:34 +13:00
Brenda Wallace
9adb3d1e4e Removed d3 graph tests 2018-01-23 09:00:34 +13:00
Awesome Code
3391f6c392 Auto corrected by following Style/RescueStandardError 2018-01-23 09:00:34 +13:00
Awesome Code
a13acbe087 Auto corrected by following Style/ParallelAssignment 2018-01-23 09:00:34 +13:00
Awesome Code
0c8240d4e8 Auto corrected by following Style/OrAssignment 2018-01-23 09:00:34 +13:00
Brenda Wallace
5ea7ae8af0 Added Harvested for chart 2018-01-23 09:00:34 +13:00
Brenda Wallace
eb1b890eec Add planted_from chart 2018-01-23 09:00:34 +13:00
Brenda Wallace
4821bf3b07 Wrapped thre crops show js in a document.ready 2018-01-23 09:00:34 +13:00
Brenda Wallace
b83db1d4e7 Fix predictions, it wasn't showing nil 2018-01-23 09:00:34 +13:00
Awesome Code
dea7ce241b Auto corrected by following RSpec/EmptyLineAfterFinalLet 2018-01-23 09:00:34 +13:00
Awesome Code
8d166f1fe6 Auto corrected by following FactoryBot/DynamicAttributeDefinedStatically 2018-01-23 09:00:34 +13:00
Brenda Wallace
49253b59ee Fixing up prediction specs 2018-01-23 09:00:34 +13:00
Brenda Wallace
ca16b2c407 Removed ignore of highcharts 2018-01-23 09:00:34 +13:00
Brenda Wallace
427a0187e1 updated prediction spec 2018-01-23 09:00:34 +13:00
Brenda Wallace
b1096cd021 Moved chart includes to application.js, attempting to fix json parse error 2018-01-23 09:00:34 +13:00
Awesome Code
020d024e4b Auto corrected by following EmptyLine 2018-01-23 09:00:34 +13:00
Brenda Wallace
070a4605d0 Add a green border around predictions boxes 2018-01-23 09:00:34 +13:00
Brenda Wallace
1f8413bf3e Remove highcharts.js, we're not using it 2018-01-23 09:00:34 +13:00
Brenda Wallace
59c3edcf82 Add timeline to gardens 2018-01-23 09:00:34 +13:00
Brenda Wallace
1bf05f81ab Convert to use chartkick gem
Conflicts:
	Gemfile
	Gemfile.lock
	config/initializers/assets.rb
2018-01-23 09:00:34 +13:00
Brenda Wallace
e6e88fa0c7 Fixed up tabulation 2018-01-23 09:00:34 +13:00
Brenda Wallace
308e834713 Wrap long line 2018-01-23 09:00:34 +13:00
Brenda Wallace
121deb4f48 Fix ordering of crops' parent on form 2018-01-23 09:00:34 +13:00
Brenda Wallace
4b65f28461 Added new line at end of file 2018-01-23 09:00:34 +13:00
Brenda Wallace
87708f1765 Tabulation and jsdoc fixes 2018-01-23 09:00:34 +13:00
Brenda Wallace
2cf335a064 Removed unused variables in js 2018-01-23 09:00:34 +13:00
Brenda Wallace
b205f35399 Wrapped a long line 2018-01-23 09:00:34 +13:00
Brenda Wallace
a4c06207e3 more JSDoc 2018-01-23 09:00:34 +13:00
Brenda Wallace
580fac6aa1 removed 2 unused variable in js 2018-01-23 09:00:34 +13:00
Brenda Wallace
4a696af9ba Fix up JSDoc 2018-01-23 09:00:34 +13:00
Brenda Wallace
d2a060ad49 added JSDoc 2018-01-23 09:00:34 +13:00
Brenda Wallace
d898f926d5 added JSDoc 2018-01-23 09:00:34 +13:00
Brenda Wallace
49444edc61 contributors/commits update 2018-01-23 09:00:34 +13:00
Brenda Wallace
a4c7de381e converted variable to camel case 2018-01-23 09:00:34 +13:00
Brenda Wallace
61408d7e4e Some js cleanups 2018-01-23 09:00:34 +13:00
Brenda Wallace
9906036faf Add bootstrap js to codeclimate excludes 2018-01-23 09:00:34 +13:00
Brenda Wallace
e009d9532a Updating javascript style 2018-01-23 09:00:34 +13:00
Brenda Wallace
9f1c064900 Use the old "var" syntax, and max line 120 2018-01-23 09:00:34 +13:00
Brenda Wallace
8d3d8f3c91 Adding package lock, and eslint 2018-01-23 09:00:34 +13:00
deppbot
0feed2d359 Bundle Update on 2017-12-24 2018-01-23 09:00:34 +13:00
200 changed files with 961 additions and 4042 deletions

View File

@@ -42,3 +42,4 @@ exclude_paths:
- spec/
- public/
- app/assets/stylesheets/bootstrap-accessibility.css
- app/assets/javascripts/bootstrap*

1
.esignore Normal file
View File

@@ -0,0 +1 @@
app/assets/javascripts/bootstrap-accessibility.min.js

11
.eslintrc.json Normal file
View File

@@ -0,0 +1,11 @@
{
"extends": "google",
"env": {
"browser": true,
"node": true
},
"rules": {
"no-var": "off",
"max-len": ["error", { "code": 120, "tabWidth": 4 }]
}
}

View File

@@ -8,3 +8,6 @@ scss:
config_file: .scss-lint.yml
eslint:
config_file: .eslintrc
ignore_file: .esignore
jshint:
enabled: false

View File

@@ -46,7 +46,9 @@ PreCommit:
required_executable: 'npm'
HamlLint:
enabled: true
command: ['bundle', 'exec', 'haml-lint', 'app/views']
include:
- 'app/views/**'
command: ['bundle', 'exec', 'haml-lint']
JsonSyntax:
enabled: true
BundleOutdated:
@@ -55,13 +57,13 @@ PreCommit:
BundleAudit:
enabled: true
on_warn: warn
JsHint:
EsLint:
enabled: true
exclude:
- 'app/assets/**'
- 'spec/javascripts/support/vendor/**'
- '**/bootstrap*'
command: ['npm', 'run', 'jshint']
command: ['./node_modules/.bin/eslint']
required_executable: 'npm'
ScssLint:
enabled: true

View File

@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --no-offense-counts`
# on 2017-12-06 11:20:15 +1300 using RuboCop version 0.49.1.
# on 2018-02-05 14:37:22 +1300 using RuboCop version 0.49.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -39,7 +39,6 @@ Rails/SkipsModelValidations:
# SupportedStyles: strict, flexible
Rails/TimeZone:
Exclude:
- 'spec/controllers/accounts_controller_spec.rb'
- 'spec/factories/member.rb'
- 'spec/factories/post.rb'
- 'spec/models/post_spec.rb'
@@ -60,7 +59,6 @@ Style/AsciiComments:
# SupportedStyles: nested, compact
Style/ClassAndModuleChildren:
Exclude:
- 'app/controllers/admin/orders_controller.rb'
- 'lib/actions/oauth_signup_action.rb'
- 'lib/haml/filters/escaped_markdown.rb'
@@ -68,24 +66,11 @@ Style/IdenticalConditionalBranches:
Exclude:
- 'app/controllers/follows_controller.rb'
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'spec/controllers/member_controller_spec.rb'
- 'spec/models/photo_spec.rb'
# Cop supports --auto-correct.
Style/MultilineIfModifier:
Exclude:
- 'spec/rails_helper.rb'
# Cop supports --auto-correct.
Style/MutableConstant:
Exclude:
- 'app/models/planting.rb'
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
# SupportedStyles: predicate, comparison
@@ -96,11 +81,6 @@ Style/NumericPredicate:
- 'app/helpers/plantings_helper.rb'
- 'lib/tasks/growstuff.rake'
# Cop supports --auto-correct.
Style/ParallelAssignment:
Exclude:
- 'app/mailers/notifier.rb'
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed

View File

@@ -56,6 +56,7 @@ deploy:
secure: "WrQxf0fEKkCdXrjcejurobOnNNz3he4dDwjBbToXbQTQNDObPp7NetJrLsfM8FiUFEeOuvhIHHiDQtMvY720zGGAGxDptvgFS+0QHCUqoTRZA/yFfUmHlG2jROXTzk5uVK0AE4k6Ion5kX8+mM0EnMT/7u+MTFiukrJctSiEXfg="
on:
repo: Growstuff/growstuff
condition: "$RSPEC_TAG = elasticsearch"
app:
dev: growstuff-staging
master: growstuff-prod

View File

@@ -8,14 +8,15 @@ submit the change with your pull request.
## Committers
- Alex Bayley / [Skud](https://github.com/Skud)
- Cesy / [cesy](https://github.com/cesy)
- Miles Gould / [pozorvlak](https://github.com/pozorvlak)
- Taylor Griffin / [tygriffin](https://github.com/tygriffin)
- Mackenzie Morgan / [maco](https://github.com/maco)
- Brenda Wallace / [br3nda](https://github.com/br3nda)
## Contributors
- Alex Bayley / [Skud](https://github.com/Skud)
- Taylor Griffin / [tygriffin](https://github.com/tygriffin)
- Joseph Caudle / [jcaudle](https://github.com/jcaudle)
- Ricky Amianym / [amianym](https://github.com/amianym)
- Juliet Kemp / [julietk](https://github.com/julietk)
@@ -73,7 +74,6 @@ submit the change with your pull request.
- Lucas Nogueira / [lucasnogueira](https://github.com/lucasnogueira)
- Charley Lewittes / [ctlewitt](https://github.com/ctlewitt)
- Kristine Nicole Polvoriza / [polveenomials](https://github.com/polveenomials)
- Brenda Wallace / [br3nda](https://github.com/br3nda)
- Jim Stallings / [jestallin](https://github.com/jestallin)
- Alyssa Ransbury / [alran](https://github.com/alran)
- Thomas Countz / [thomascountz](https://github.com/thomascountz)
@@ -82,6 +82,7 @@ submit the change with your pull request.
- Harry Brodsky / [hbrodsk1](https://github.com/hbrodsk1)
- Jeff Kingswood / [ancyentmariner](https://github.com/ancyentmariner)
- Logan Gingerich / [logangingerich](https://github.com/logangingerich)
- Mark Taffman / [mftaff](https://github.com/mftaff)
## Bots

View File

@@ -38,7 +38,7 @@ gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
gem 'leaflet-rails'
gem 'rails-assets-leaflet.markercluster', source: 'https://rails-assets.org'
gem 'pg'
gem 'pg', '< 1.0.0' # Upstream bug, see https://github.com/Growstuff/growstuff/pull/1539
gem 'ruby-units' # for unit conversion
gem 'unicorn' # http server
@@ -48,7 +48,6 @@ gem 'bootstrap-kaminari-views' # bootstrap views for kaminari
gem 'kaminari' # pagination
gem 'active_utils'
gem 'activemerchant'
gem 'sidekiq'
# Markdown formatting for updates etc
@@ -78,8 +77,7 @@ gem 'omniauth-facebook'
gem 'omniauth-flickr', '>= 0.0.15'
gem 'omniauth-twitter'
# For charting data
gem 'd3-rails', '~> 3.5' # 4.* produces Error: <spyOn> : could not find an object to spy upon for linear() - see https://travis-ci.org/Growstuff/growstuff/jobs/204461482
gem "chartkick"
# client for Elasticsearch. Elasticsearch is a flexible
# and powerful, distributed, real-time search and analytics engine.
@@ -126,7 +124,6 @@ group :development do
end
group :development, :test do
gem "active_merchant-paypal-bogus-gateway"
gem 'bullet' # performance tuning by finding unnecesary queries
gem 'byebug' # debugging
gem 'capybara' # integration tests

View File

@@ -26,19 +26,12 @@ GEM
addressable
active_median (0.1.4)
activerecord
active_merchant-paypal-bogus-gateway (0.1.0)
activemerchant
active_utils (3.3.9)
activesupport (>= 3.2, < 5.2.0)
i18n
activejob (4.2.10)
activesupport (= 4.2.10)
globalid (>= 0.3.0)
activemerchant (1.75.0)
activesupport (>= 3.2.14, < 6.x)
builder (>= 2.1.2, < 4.0.0)
i18n (>= 0.6.9)
nokogiri (~> 1.4)
activemodel (4.2.10)
activesupport (= 4.2.10)
builder (~> 3.1)
@@ -57,15 +50,15 @@ GEM
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
arel (6.0.4)
ast (2.3.0)
autoprefixer-rails (7.2.3)
ast (2.4.0)
autoprefixer-rails (7.2.5)
execjs
bcrypt (3.1.11)
better_errors (2.2.0)
coderay (>= 1.0.0)
erubis (>= 2.6.6)
rack (>= 0.9.0)
binding_of_caller (0.7.3)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
bluecloth (2.2.0)
bonsai-elasticsearch-rails (0.2.0)
@@ -81,24 +74,25 @@ GEM
sass (>= 3.3.4)
bootstrap_form (2.7.0)
builder (3.2.3)
bullet (5.7.0)
bullet (5.7.2)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.10.0)
byebug (9.1.0)
cancancan (2.1.2)
capybara (2.16.1)
uniform_notifier (~> 1.11.0)
byebug (10.0.0)
cancancan (2.1.3)
capybara (2.17.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
xpath (>= 2.0, < 4.0)
capybara-email (2.5.0)
capybara (~> 2.4)
mail
capybara-screenshot (1.0.18)
capybara (>= 1.0, < 3)
launchy
chartkick (2.2.5)
childprocess (0.8.0)
ffi (~> 1.0, >= 1.0.11)
climate_control (0.2.0)
@@ -143,12 +137,10 @@ GEM
crass (1.0.3)
csv_shaper (1.3.0)
activesupport (>= 3.0.0)
d3-rails (3.5.17)
railties (>= 3.1)
dalli (2.7.6)
database_cleaner (1.6.2)
debug_inspector (0.0.3)
devise (4.3.0)
devise (4.4.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.2)
@@ -156,8 +148,7 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.3)
docile (1.1.5)
easy_translate (0.5.0)
json
easy_translate (0.5.1)
thread
thread_safe
elasticsearch (2.0.2)
@@ -181,11 +172,11 @@ GEM
factory_bot_rails (4.8.2)
factory_bot (~> 4.8.2)
railties (>= 3.0.0)
faker (1.8.5)
i18n (~> 0.9.1)
faker (1.8.7)
i18n (>= 0.7)
faraday (0.12.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.18)
ffi (1.9.21)
figaro (1.1.1)
thor (~> 0.14)
flickraw (0.9.9)
@@ -203,10 +194,10 @@ GEM
gravatar-ultimate (2.0.0)
activesupport (>= 2.3.14)
rack
guard (2.14.1)
guard (2.14.2)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
lumberjack (~> 1.0)
lumberjack (>= 1.0.12, < 2.0)
nenv (~> 0.1)
notiffany (~> 0.0)
pry (>= 0.9.12)
@@ -238,7 +229,7 @@ GEM
rake (>= 10, < 13)
rubocop (>= 0.49.0)
sysexits (~> 1.1)
hashie (3.5.6)
hashie (3.5.7)
heroics (0.0.24)
erubis (~> 2.0)
excon
@@ -252,7 +243,7 @@ GEM
ruby_parser (~> 3.5)
httparty (0.15.6)
multi_xml (>= 0.5.2)
i18n (0.9.1)
i18n (0.9.3)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.12)
activesupport (>= 4.0.2)
@@ -264,19 +255,19 @@ GEM
parser (>= 2.2.3.0)
term-ansicolor (>= 1.3.2)
terminal-table (>= 1.5.1)
jasmine (2.8.0)
jasmine-core (>= 2.8.0, < 3.0.0)
jasmine (2.9.0)
jasmine-core (>= 2.9.0, < 3.0.0)
phantomjs
rack (>= 1.2.1)
rake
jasmine-core (2.8.0)
jasmine-core (2.99.0)
jquery-rails (4.3.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
js-routes (1.4.2)
js-routes (1.4.3)
railties (>= 3.2)
sprockets-rails
json (2.1.0)
@@ -297,13 +288,13 @@ GEM
activerecord
kaminari-core (= 1.1.1)
kaminari-core (1.1.1)
kgio (2.11.1)
kgio (2.11.2)
kramdown (1.16.2)
launchy (2.4.3)
addressable (~> 2.3)
leaflet-rails (1.2.0)
leaflet-rails (1.3.1)
rails (>= 4.2.0)
letter_opener (1.4.1)
letter_opener (1.6.0)
launchy (~> 2.2)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
@@ -323,14 +314,14 @@ GEM
mimemagic (0.3.2)
mini_mime (1.0.0)
mini_portile2 (2.3.0)
minitest (5.10.3)
minitest (5.11.3)
moneta (0.8.1)
multi_json (1.11.3)
multi_xml (0.6.0)
multipart-post (2.0.0)
nenv (0.3.0)
newrelic_rpm (4.6.0.338)
nokogiri (1.8.1)
newrelic_rpm (4.8.0.341)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
notiffany (0.1.1)
nenv (~> 0.1)
@@ -342,7 +333,7 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.7.1)
omniauth (1.8.1)
hashie (>= 3.4.6, < 3.6.0)
rack (>= 1.6.2, < 3)
omniauth-facebook (4.0.0)
@@ -360,7 +351,7 @@ GEM
omniauth-oauth (~> 1.1)
rack
orm_adapter (0.5.0)
paperclip (5.1.0)
paperclip (5.2.1)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
cocaine (~> 0.5.5)
@@ -403,13 +394,13 @@ GEM
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.10)
sprockets-rails
rails-assets-leaflet (1.2.0)
rails-assets-leaflet.markercluster (1.2.0)
rails-assets-leaflet (1.3.1)
rails-assets-leaflet.markercluster (1.3.0)
rails-assets-leaflet (>= 1.0.3)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.8)
activesupport (>= 4.2.0.beta, < 5.0)
rails-dom-testing (1.0.9)
activesupport (>= 4.2.0, < 5.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
@@ -445,7 +436,7 @@ GEM
activemodel (>= 3.0)
activesupport (>= 3.0)
rspec-mocks (>= 2.99, < 4.0)
rspec-core (3.7.0)
rspec-core (3.7.1)
rspec-support (~> 3.7.0)
rspec-expectations (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
@@ -461,7 +452,7 @@ GEM
rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.7.0)
rspec-support (~> 3.7.0)
rspec-support (3.7.0)
rspec-support (3.7.1)
rubocop (0.49.1)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
@@ -475,7 +466,7 @@ GEM
ruby_parser (3.10.1)
sexp_processor (~> 4.9)
rubyzip (1.2.1)
sass (3.5.4)
sass (3.5.5)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
@@ -486,12 +477,12 @@ GEM
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (3.8.0)
selenium-webdriver (3.9.0)
childprocess (~> 0.5)
rubyzip (~> 1.0)
rubyzip (~> 1.2)
sexp_processor (4.10.0)
shellany (0.0.1)
sidekiq (5.0.5)
sidekiq (5.1.0)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
rack-protection (>= 1.5.0)
@@ -523,15 +514,15 @@ GEM
timecop (0.9.1)
tins (1.16.3)
trollop (1.16.2)
tzinfo (1.2.4)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uglifier (4.0.2)
uglifier (4.1.5)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.3.0)
unicorn (5.3.1)
unicorn (5.4.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.10.0)
uniform_notifier (1.11.0)
warden (1.2.7)
rack (>= 1.0)
webrat (0.7.3)
@@ -543,17 +534,15 @@ GEM
websocket-extensions (0.1.3)
will_paginate (3.1.6)
xmlrpc (0.3.0)
xpath (2.1.0)
nokogiri (~> 1.3)
xpath (3.0.0)
nokogiri (~> 1.8)
PLATFORMS
ruby
DEPENDENCIES
active_median
active_merchant-paypal-bogus-gateway
active_utils
activemerchant
acts_as_paranoid (~> 0.5.0)
better_errors (~> 2.2.0)
binding_of_caller
@@ -569,12 +558,12 @@ DEPENDENCIES
capybara
capybara-email
capybara-screenshot
chartkick
codeclimate-test-reporter
coffee-rails
comfortable_mexican_sofa
coveralls
csv_shaper
d3-rails (~> 3.5)
dalli
database_cleaner
devise
@@ -612,7 +601,7 @@ DEPENDENCIES
omniauth-facebook
omniauth-flickr (>= 0.0.15)
omniauth-twitter
pg
pg (< 1.0.0)
platform-api
poltergeist
pry
@@ -638,9 +627,8 @@ DEPENDENCIES
will_paginate
xmlrpc
RUBY VERSION
ruby 2.4.1p111
BUNDLED WITH
1.16.0
1.16.1

View File

@@ -10,12 +10,12 @@
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require leaflet
//= require leaflet.markercluster
//= require js-routes
//= require jquery
//= require jquery_ujs
//= require jquery-ui/autocomplete
//= require bootstrap-sprockets
//= require bootstrap-datepicker
//= require_tree .
// = require leaflet
// = require leaflet.markercluster
// = require js-routes
// = require jquery
// = require jquery_ujs
// = require jquery-ui/autocomplete
// = require bootstrap-sprockets
// = require bootstrap-datepicker
// = require_tree .

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
// = require Chart.bundle
// = require chartkick

View File

@@ -1,37 +1,27 @@
//= require graphs/horizontal_bar_graph
if (document.getElementById("cropmap") !== null) {
mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
mapbox_access_token = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_access_token %>";
mapbox_base_url = "http://a.tiles.mapbox.com/v4/" + mapbox_map_id + "/{z}/{x}/{y}.png?access_token=" + mapbox_access_token;
L.Icon.Default.imagePath = '/assets'
cropmap = L.map('cropmap').setView([0.0, -0.0], 2);
showCropMap(cropmap);
}
function showCropMap(cropmap) {
var mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
var mapbox_access_token = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_access_token %>";
var mapbox_base_url = "http://a.tiles.mapbox.com/v4/" + mapbox_map_id + "/{z}/{x}/{y}.png?access_token=" + mapbox_access_token;
L.tileLayer(mapbox_base_url, {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors under <a href="http://www.openstreetmap.org/copyright">ODbL</a> | Map imagery &copy; <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18
}).addTo(cropmap);
markers = new L.MarkerClusterGroup({showCoverageOnHover: false, maxClusterRadius: 20 });
var markers = new L.MarkerClusterGroup({showCoverageOnHover: false, maxClusterRadius: 20 });
things_to_map = location.pathname + '.json';
var things_to_map = location.pathname + '.json';
$.getJSON(things_to_map, function(crop) {
$.each(crop.plantings, function(i, planting) {
owner = planting.owner;
var owner = planting.owner;
if (owner.latitude && owner.longitude) {
marker = new L.Marker(new L.LatLng(owner.latitude, owner.longitude));
var marker = new L.Marker(new L.LatLng(owner.latitude, owner.longitude));
planting_url = "/plantings/" + planting.id;
planting_link = "<a href='" + planting_url + "'>" + owner.login_name + "'s " + crop.name + "</a>";
var planting_url = "/plantings/" + planting.id;
var planting_link = "<a href='" + planting_url + "'>" + owner.login_name + "'s " + crop.name + "</a>";
where = "<p><i>" + owner.location + "</i></p>";
var where = "<p><i>" + owner.location + "</i></p>";
details = "<p>";
var details = "<p>";
if (planting.quantity) {
details = details + "Quantity: " + planting.quantity + "<br/>";
}
@@ -51,41 +41,17 @@ function showCropMap(cropmap) {
cropmap.addLayer(markers);
}
function plantingStats(crop) {
var sunniness_counts = { 'empty': 0, 'sun': 0, 'semi-shade': 0, 'shade': 0 };
$.each(crop.plantings, function(i, planting) {
if (planting.sunniness) {
sunniness_counts[planting.sunniness]++;
} else {
sunniness_counts['Empty']++;
}
$(document).ready(function() {
if (document.getElementById("cropmap") !== null) {
L.Icon.Default.imagePath = '/assets';
var cropmap = L.map('cropmap').setView([0.0, -0.0], 2);
showCropMap(cropmap);
}
$('.btn.toggle.crop-hierarchy').click(function () {
$('.toggle.crop-hierarchy').toggleClass('hide');
});
return [
{name: 'Empty', value: sunniness_counts['empty']},
{name: 'Sun', value: sunniness_counts['sun']},
{name: 'Semi-shade', value: sunniness_counts['semi-shade']},
{name: 'Shade', value: sunniness_counts['shade']}
];
}
if ($("#sunchart")[0] !== null) {
var HorizontalBarGraph = growstuff.HorizontalBarGraph;
$.getJSON(location.pathname + '.json', function (crop) {
data = {
bars: plantingStats(crop),
bar_color: 'steelblue',
width: {size: 300, scale: 'linear'},
height: {size: 100, scale: 'ordinal'},
//left is used to shift the bars over so that there is
//room for the labels
margin: {top: 0, right: 0, bottom: 0, left: 100}
};
var graph = new HorizontalBarGraph(data);
graph.render(d3.select($('#sunchart')[0]));
});
}
$('.btn.toggle.crop-hierarchy').click(function () {
$('.toggle.crop-hierarchy').toggleClass('hide');
});
});

View File

@@ -1,50 +0,0 @@
//= require graphs/width_scale
//= require graphs/height_scale
(function(){
'use strict';
/*
This represents bars for a bar graph.
Currently these are used for HorizontalBarGraph.
*/
var growstuff = (window.growstuff = window.growstuff || {});
var WidthScale = growstuff.WidthScale;
var HeightScale = growstuff.HeightScale;
function BarGroup(data) {
this._data = data;
}
BarGroup.prototype.render = function(root){
var data = this._data;
var bars = this._data.bars;
var widthScale = new WidthScale(data).render();
var heightScale = new HeightScale(data).render();
return root.append('g')
.attr("class", "bar")
.selectAll("rect")
.data(bars.map(function(bar) { return bar.value; }))
.enter()
.append("rect")
.attr("y", function(d, i){
return heightScale(i);
})
.attr("height", heightScale.rangeBand())
.attr("fill", data.bar_color)
.attr("width", function(d){
return widthScale(d);
})
.append("title")
.text(function(d){
return 'This value is ' + d + '.';
});
};
growstuff.BarGroup = BarGroup;
}());

View File

@@ -1,40 +0,0 @@
(function() {
'use strict';
/*
This file draws the labels to the left of each bar.
*/
var growstuff = (window.growstuff = window.growstuff || {});
function BarLabelGroup(data) {
this._data = data;
}
BarLabelGroup.prototype.render = function(d3){
var bars = this._data.bars;
//vvcopy pasta from spike vv -- this is a good candidate for refactor
var barHeight = 40;
return d3.append('g')
.attr("class", "bar-label")
.selectAll("text")
.data(bars.map(function(bar){ return bar.name;}))
.enter()
.append("text")
.attr('x', -80)
.attr('y', function(d, i){
//shrink the margin between each label to give them an even spread with
//bars
var barLabelSpread = 2/3;
//move them downward to line up with bars
var barLabelTopEdge = 17;
return i * barHeight * (barLabelSpread) + barLabelTopEdge;
})
.text(function(d){return d;});
};
growstuff.BarLabelGroup = BarLabelGroup;
}());

View File

@@ -1,29 +0,0 @@
//=require d3
/*
Height Scale is used to map the number of bars to the display size of
the svg
*/
(function(){
'use strict';
var growstuff = (window.growstuff = window.growstuff || {});
function HeightScale(data){
this._data = data;
}
HeightScale.prototype.render = function(){
var data = this._data;
var scaleType = data.height.scale;
var axisSize = data.height.size;
return d3.scale[scaleType]()
.domain(d3.range(data.bars.length))
.rangeRoundBands([0, data.height.size], 0.05, 0);
};
growstuff.HeightScale = HeightScale;
}());

View File

@@ -1,51 +0,0 @@
//= require d3
//= require graphs/bar_group
//= require graphs/bar_label_group
/*
Horizontal Bar Graph represents sum total of the graph including all of the parts:
Bars
Bar Labels
The main dimensions of the graph are rendered here.
*/
(function() {
'use strict';
var growstuff = (window.growstuff = window.growstuff || {});
var BarGroup = growstuff.BarGroup;
var BarLabelGroup = growstuff.BarLabelGroup;
function HorizontalBarGraph(data) {
this._data = data;
this._d3 = d3;
}
HorizontalBarGraph.prototype.render = function(root) {
var bars = this._data.bars;
var width = this._data.width;
var height = this._data.height;
var barLabelGroup = new BarLabelGroup(this._data);
var margin = this._data.margin;
var barGroup = new BarGroup(this._data);
var svg = root
.append("svg")
.attr("width", width.size + margin.left + margin.right)
.attr("height", height.size + margin.top + margin.bottom)
.append("g")
.attr("class","bar-graph")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
barGroup.render(svg);
barLabelGroup.render(svg);
return svg;
};
growstuff.HorizontalBarGraph = HorizontalBarGraph;
}());

View File

@@ -1,33 +0,0 @@
//=require d3
/*
Width scale is used to map the value for the length of each bar
to the display size of the svg
*/
(function(){
'use strict';
var growstuff = (window.growstuff = window.growstuff || {});
function WidthScale (data){
this._data = data;
}
WidthScale.prototype.render = function() {
var data = this._data;
var scaleType = data.width.scale;
var axisSize = data.width.size;
return d3.scale[scaleType]()
.domain([0, this.getMaxValue()])
.range([0, axisSize]);
};
WidthScale.prototype.getMaxValue = function(){
return d3.max(this._data.bars.map(function(bar) { return bar.value; }));
};
growstuff.WidthScale = WidthScale;
}());

View File

@@ -1,25 +1,24 @@
if (document.getElementById("membermap") !== null) {
mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
mapbox_access_token = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_access_token %>";
mapbox_base_url = "http://a.tiles.mapbox.com/v4/" + mapbox_map_id + "/{z}/{x}/{y}.png?access_token=" + mapbox_access_token;
L.Icon.Default.imagePath = '/assets'
var mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
var mapbox_access_token = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_access_token %>";
var mapbox_base_url = "http://a.tiles.mapbox.com/v4/" + mapbox_map_id + "/{z}/{x}/{y}.png?access_token=" + mapbox_access_token;
L.Icon.Default.imagePath = '/assets';
$.getJSON(location.pathname + '.json', function(member) {
if (member.latitude && member.longitude) {
membermap = L.map('membermap').setView([member.latitude, member.longitude], 4);
var membermap = L.map('membermap').setView([member.latitude, member.longitude], 4);
L.tileLayer(mapbox_base_url, {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors under <a href="http://www.openstreetmap.org/copyright">ODbL</a> | Map imagery &copy; <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18
}).addTo(membermap);
marker = new L.Marker(new L.LatLng(member.latitude, member.longitude));
var marker = new L.Marker(new L.LatLng(member.latitude, member.longitude));
member_url = "/members/" + member.slug;
member_link = "<a href='" + member_url + "'>" + member.login_name + "</a>";
var member_url = "/members/" + member.slug;
var member_link = "<a href='" + member_url + "'>" + member.login_name + "</a>";
where = "<p><i>" + member.location + "</i></p>";
var where = "<p><i>" + member.location + "</i></p>";
marker.bindPopup(member_link + where).openPopup();
marker.addTo(membermap);

View File

@@ -1,18 +1,18 @@
$(document).ready(function () {
$(document).ready(function() {
$('.post-like').show();
$('.post-like').on('ajax:success', function(event, data) {
var like_control = $('#post-' + data.id + ' .post-like');
var likeControl = $('#post-' + data.id + ' .post-like');
$('#post-' + data.id + ' .like-count').text(data.description);
if (data.liked_by_member) {
like_control.data("method", "delete");
like_control.attr("href", data.url);
like_control.text("Unlike");
likeControl.data('method', 'delete');
likeControl.attr('href', data.url);
likeControl.text('Unlike');
} else {
like_control.data("method", "post");
like_control.attr("href", '/likes.json?post_id=' + data.id);
like_control.text("Like");
likeControl.data('method', 'post');
likeControl.attr('href', '/likes.json?post_id=' + data.id);
likeControl.text('Like');
}
});
});
});

View File

@@ -5,3 +5,4 @@
@import 'custom_bootstrap/custom_bootstrap'
@import 'overrides'
@import 'graphs'
@import 'predictions'

View File

@@ -1 +1 @@
.btn:focus{outline:dotted 2px #000}div.active:focus{outline:dotted 1px #000}a:focus{outline:dotted 1px #000}.close:hover,.close:focus{outline:dotted 1px #000}.nav>li>a:hover,.nav>li>a:focus{outline:dotted 1px #000}.carousel-inner>.item{position:absolute;top:-999999em;display:block;-moz-transition:ease-in-out 0.6s left;-o-transition:ease-in-out 0.6s left;-webkit-transition:ease-in-out 0.6s left;transition:ease-in-out 0.6s left}.carousel-inner>.active{top:0}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{position:relative}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.alert-success{color:#2d4821}.alert-info{color:#214c62}.alert-warning{color:#6c4a00;background-color:#f9f1c6}.alert-danger{color:#d2322d}.alert-danger:hover{color:#a82824}
.btn:focus{outline:dotted 2px #000}div.active:focus{outline:dotted 1px #000}a:focus{outline:dotted 1px #000}.close:hover,.close:focus{outline:dotted 1px #000}.nav>li>a:hover,.nav>li>a:focus{outline:dotted 1px #000}.carousel-indicators li,.carousel-indicators li.active{height:18px;width:18px;border-width:2px;position:relative;box-shadow:0px 0px 0px 1px #808080}.carousel-indicators.active li{background-color:rgba(100,149,253,0.6)}.carousel-indicators.active li.active{background-color:white}.carousel-tablist-highlight{display:block;position:absolute;outline:2px solid transparent;background-color:transparent;box-shadow:0px 0px 0px 1px transparent}.carousel-tablist-highlight.focus{outline:2px solid #6495ED;background-color:rgba(0,0,0,0.4)}a.carousel-control:focus{outline:2px solid #6495ED;background-image:linear-gradient(to right, transparent 0px, rgba(0,0,0,0.5) 100%);box-shadow:0px 0px 0px 1px #000000}.carousel-pause-button{position:absolute;top:-30em;left:-300em;display:block}.carousel-pause-button.focus{top:0.5em;left:0.5em}.carousel:hover .carousel-caption,.carousel.contrast .carousel-caption{background-color:rgba(0,0,0,0.5);z-index:10}.alert-success{color:#2d4821}.alert-info{color:#214c62}.alert-warning{color:#6c4a00;background-color:#f9f1c6}.alert-danger{color:#d2322d}.alert-danger:hover{color:#a82824}

View File

@@ -13,6 +13,7 @@ $blue: #2f4365
$red: #8e4d43
$orange: #ffa500
$yellow: #b2935c
$white: #ffffff
$body-bg: $beige
$text-color: $brown

View File

@@ -3,37 +3,18 @@
@import "custom_bootstrap/variables"
// this padding needs to be done before the responsive stuff is imported
body
// modifying this for our promotional banner. can be replaced after if
// needed.
// padding-top: $navbar-height + 15px
padding-top: $navbar-height
//@import "bootstrap/responsive"
// Font Awesome
@import "font-awesome-sprockets"
@import "font-awesome"
// Glyphicons
//@import "bootstrap/glyphicons"
.list-inline > li.first
padding-left: 0px
h2
font-size: 150%
//#subtitle
// color: lighten($brown, 30%)
// font-style: italic
// font-weight: normal
// margin-top: 0px
// padding-left: 1em
// padding-top: 0px
h3
font-size: 120%

View File

@@ -0,0 +1,11 @@
.predictions
.metric
height: 180px
border: 1px solid lighten($green, 20%)
background: $white
margin: 4px
strong
font-size: 250%
font-align: center
h3

View File

@@ -1,53 +0,0 @@
class AccountTypesController < ApplicationController
before_action :authenticate_member!
load_and_authorize_resource
respond_to :html
# GET /account_types
def index
@account_types = AccountType.all.order(:name)
respond_with(@account_types)
end
# GET /account_types/1
def show
respond_with(@account_types)
end
# GET /account_types/new
def new
@account_type = AccountType.new
respond_with(@account_type)
end
# GET /account_types/1/edit
def edit
respond_with(@account_type)
end
# POST /account_types
def create
@account_type = AccountType.new(account_type_params)
flash[:notice] = I18n.t('account_types.created') if @account_type.save
respond_with(@account_type)
end
# PUT /account_types/1
def update
flash[:notice] = I18n.t('account_types.updated') if @account_type.update(account_type_params)
respond_with(@account_type)
end
# DELETE /account_types/1
def destroy
@account_type.destroy
flash[:notice] = I18n.t('account_types.deleted')
respond_with(@account_type)
end
private
def account_type_params
params.require(:account_type).permit(:is_paid, :is_permanent_paid, :name)
end
end

View File

@@ -1,31 +0,0 @@
class AccountsController < ApplicationController
before_action :authenticate_member!
load_and_authorize_resource
respond_to :html
# GET /accounts
def index
@accounts = Account.all.order(created_at: :desc)
respond_with(@accounts)
end
# GET /accounts/1
def show
respond_with(@account)
end
# GET /accounts/1/edit
def edit; end
# PUT /accounts/1
def update
flash[:notice] = I18n.t('account.update') if @account.update(params[:account])
respond_with(@account)
end
private
def account_params
params.require(:account).permit(:account_type_id, :member_id, :paid_until)
end
end

View File

@@ -1,23 +0,0 @@
module Admin
class OrdersController < ApplicationController
def index
authorize! :manage, :all
respond_to do |format|
format.html # index.html.haml
end
end
def search
authorize! :manage, :all
@orders = Order.search(by: params[:search_by], for: params[:search_text])
if @orders.empty?
flash[:alert] = "Couldn't find order with #{params[:search_by]} = #{params[:search_text]}"
end
respond_to do |format|
format.html # index.html.haml
end
end
end
end

View File

@@ -0,0 +1,30 @@
module Charts
class CropsController < ApplicationController
respond_to :json
def sunniness
pie_chart_query 'sunniness'
end
def planted_from
pie_chart_query 'planted_from'
end
def harvested_for
@crop = Crop.find(params[:crop_id])
render json: Harvest.joins(:plant_part)
.where(crop: @crop)
.group("plant_parts.name").count(:id)
end
private
def pie_chart_query(field)
@crop = Crop.find(params[:crop_id])
render json: Planting.where(crop: @crop)
.where.not(field.to_sym => nil)
.where.not(field.to_sym => '')
.group(field.to_sym).count(:id)
end
end
end

View File

@@ -0,0 +1,16 @@
module Charts
class GardensController < ApplicationController
respond_to :json
def timeline
@data = []
@garden = Garden.find(params[:garden_id])
@garden.plantings.where.not(planted_at: nil)
.order(finished_at: :desc).each do |p|
# use finished_at if we have it, otherwise use predictions
finish = p.finished_at.presence || p.finish_predicted_at
@data << [p.crop.name, p.planted_at, finish] if finish.present?
end
render json: @data
end
end
end

View File

@@ -51,9 +51,9 @@ class CropsController < ApplicationController
def show
@crop = Crop.includes(:scientific_names, plantings: :photos).find(params[:id])
@posts = @crop.posts.order(created_at: :desc).paginate(page: params[:page])
# respond_with(@crop)
respond_to do |format|
format.html # show.html.haml
format.html
format.json { render json: @crop.to_json(crop_json_fields) }
end
end

View File

@@ -1,36 +0,0 @@
class OrderItemsController < ApplicationController
before_action :authenticate_member!
load_and_authorize_resource
respond_to :html
responders :flash
# POST /order_items
def create
if params[:order_item][:price]
params[:order_item][:price] = params[:order_item][:price].to_f * 100 # convert to cents
end
@order_item = OrderItem.new(order_item_params)
@order_item.order = current_member.current_order || Order.create(member_id: current_member.id)
if @order_item.save
redirect_to @order_item.order, notice: 'Added item to your order.'
else
redirect_to shop_path, alert: errors
end
end
private
def errors
if @order_item.errors.empty?
"There was a problem with your order."
else
@order_item.errors.full_messages.to_sentence
end
end
def order_item_params
params.require(:order_item).permit(:order_id, :price, :product_id, :quantity)
end
end

View File

@@ -1,90 +0,0 @@
class OrdersController < ApplicationController
before_action :authenticate_member!
load_and_authorize_resource
# GET /orders
def index
@orders = Order.by_member(current_member)
respond_to do |format|
format.html # index.html.erb
end
end
# GET /orders/1
def show
respond_to do |format|
format.html # show.html.erb
end
end
# GET /orders/new
def new
@order = Order.new
respond_to do |format|
format.html # new.html.erb
end
end
# checkout with PayPal
def checkout
respond_to do |format|
if @order.update_attributes(referral_code: params[:referral_code])
response = EXPRESS_GATEWAY.setup_purchase(
@order.total,
items: @order.activemerchant_items,
currency: Growstuff::Application.config.currency,
no_shipping: true,
ip: request.remote_ip,
return_url: complete_order_url,
cancel_return_url: shop_url
)
format.html { redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token) }
else
format.html { render action: "show" }
end
end
end
def complete
if params[:token] && params['PayerID']
purchase = EXPRESS_GATEWAY.purchase(
@order.total,
currency: Growstuff::Application.config.currency,
ip: request.remote_ip,
payer_id: params['PayerID'],
token: params[:token]
)
if purchase.success?
@order.completed_at = Time.zone.now
@order.record_paypal_details(params[:token])
else
flash[:alert] = "Could not complete your order. Please notify support."
end
else
flash[:alert] = "PayPal didn't return a token or payer_id for your order. Please notify support."
end
@order.update_account # apply paid account benefits, etc.
respond_to do |format|
format.html # new.html.erb
end
end
def cancel
respond_to do |format|
format.html { redirect_to shop_url, notice: 'Order was cancelled.' }
end
end
# DELETE /orders/1
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to shop_url, notice: 'Order was deleted.' }
end
end
end

View File

@@ -88,7 +88,7 @@ class PhotosController < ApplicationController
photo = Photo.find_by(flickr_photo_id: flickr_photo_id_param)
photo ||= Photo.new(photo_params)
photo.owner_id = current_member.id
photo.set_flickr_metadata
photo.set_flickr_metadata!
photo
end

View File

@@ -31,7 +31,7 @@ class PlantingsController < ApplicationController
@planting = Planting.includes(:owner, :crop, :garden, :photos)
.friendly
.find(params[:id])
@photos = @planting.photos.order(created_at: :desc).includes(:owner).paginate(page: params[:page])
@photos = @planting.photos.order(date_taken: :desc).includes(:owner).paginate(page: params[:page])
respond_with @planting
end

View File

@@ -1,46 +0,0 @@
class ProductsController < ApplicationController
before_action :authenticate_member!
load_and_authorize_resource
respond_to :html
responders :flash
def index
@products = Product.all.order(:name)
respond_with @products
end
def show
respond_with @product
end
def new
@product = Product.new
respond_with @product
end
def edit
respond_with @product
end
def create
@product = Product.create(product_params)
respond_with @product
end
def update
@product.update(product_params)
respond_with @product
end
def destroy
@product.destroy
respond_with @product
end
private
def product_params
params.require(:product).permit(:description, :min_price, :recommended_price, :name,
:account_type_id, :paid_months)
end
end

View File

@@ -1,19 +0,0 @@
class ShopController < ApplicationController
respond_to :html
def index
@products = Product.all
@order_item = OrderItem.new
# this is (hopefully) part of a short-term hack to prevent people from
# ordering multiple subscriptions, which would be very confusing to deal
# with. We check whether they have an order already in progress, and if
# so, point that out to them and encourage them to checkout, rather than
# letting them add more stuff to their order.
@order = nil
@most_recent_item = nil
return unless current_member
@order = current_member.current_order
@most_recent_item = @order.order_items.first if @order
end
end

View File

@@ -37,17 +37,20 @@ class Notifier < ActionMailer::Base
end
def new_crop_request(member, request)
@member, @request = member, request
@member = member
@request = request
mail(to: @member.email, subject: "#{@request.requester.login_name} has requested #{@request.name} as a new crop")
end
def crop_request_approved(member, crop)
@member, @crop = member, crop
@member = member
@crop = crop
mail(to: @member.email, subject: "#{crop.name.capitalize} has been approved")
end
def crop_request_rejected(member, crop)
@member, @crop = member, crop
@member = member
@crop = crop
mail(to: @member.email, subject: "#{crop.name.capitalize} has been rejected")
end
end

View File

@@ -15,17 +15,18 @@ class Ability
can :view_follows, Member
can :view_followers, Member
# Everyone can see the charts
can :timeline, Garden
can :sunniness, Crop
can :planted_from, Crop
can :harvested_for, Crop
# except these, which don't make sense if you're not logged in
cannot :read, Notification
cannot :read, Authentication
cannot :read, Order
cannot :read, OrderItem
# and nobody should be able to view this except admins
cannot :read, Role
cannot :read, Product
cannot :read, Account
cannot :read, AccountType
# nobody should be able to view unapproved crops unless they
# are wranglers or admins
@@ -114,20 +115,6 @@ class Ability
can :update, Seed, owner_id: member.id
can :destroy, Seed, owner_id: member.id
# orders/shop/etc
can :create, Order
can :read, Order, member_id: member.id
can :complete, Order, member_id: member.id, completed_at: nil
can :checkout, Order, member_id: member.id, completed_at: nil
can :cancel, Order, member_id: member.id, completed_at: nil
can :destroy, Order, member_id: member.id, completed_at: nil
can :create, OrderItem
# for now, let's not let people mess with individual order items
cannot :read, OrderItem, order: { member_id: member.id }
cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil }
cannot :destroy, OrderItem, order: { member_id: member.id, completed_at: nil }
# following/unfollowing permissions
can :create, Follow
cannot :create, Follow, followed_id: member.id # can't follow yourself
@@ -142,12 +129,6 @@ class Ability
can :read, :all
can :manage, :all
# can't change order history, because it's *history*
cannot :create, Order
cannot :complete, Order
cannot :destroy, Order
cannot :manage, OrderItem
# can't delete plant parts if they have harvests associated with them
cannot :destroy, PlantPart
can :destroy, PlantPart do |pp|

View File

@@ -1,23 +0,0 @@
class Account < ActiveRecord::Base
belongs_to :member
belongs_to :account_type
validates :member_id, uniqueness: {
message: 'already has account details associated with it'
}
before_create do |account|
unless account.account_type
account.account_type = AccountType.find_or_create_by(name:
Growstuff::Application.config.default_account_type)
end
end
def paid_until_string
if account_type.is_permanent_paid
"forever"
elsif account_type.is_paid
paid_until.to_s
end
end
end

View File

@@ -1,13 +0,0 @@
class AccountType < ActiveRecord::Base
#
# Relationships
has_many :products
#
# Validations
validates :name, presence: true, uniqueness: true
def to_s
name
end
end

View File

@@ -46,7 +46,7 @@ class CsvImporter
names_to_add.each do |name|
sciname = ScientificName.find_by(name: name, crop: @crop)
sciname = ScientificName.create!(name: name, crop: @crop, creator: cropbot) unless sciname
sciname ||= ScientificName.create!(name: name, crop: @crop, creator: cropbot)
@crop.scientific_names << sciname
end
end
@@ -56,15 +56,15 @@ class CsvImporter
return if alternate_names.blank?
alternate_names.split(/,\s*/).each do |name|
altname = AlternateName.find_by(name: name, crop: @crop)
altname = AlternateName.create! name: name, crop: @crop, creator: cropbot unless altname
altname ||= AlternateName.create! name: name, crop: @crop, creator: cropbot
@crop.alternate_names << altname
end
end
def cropbot
@cropbot = Member.find_by!(login_name: 'cropbot') unless @cropbot
@cropbot ||= Member.find_by!(login_name: 'cropbot')
@cropbot
rescue
rescue StandardError
raise "cropbot account not found: run rake db:seed"
end
end

View File

@@ -7,7 +7,7 @@ class Member < ActiveRecord::Base
friendly_id :login_name, use: %i(slugged finders)
#
# Relationshops
# Relationships
has_many :posts, foreign_key: 'author_id'
has_many :comments, foreign_key: 'author_id'
has_many :forums, foreign_key: 'owner_id'
@@ -19,9 +19,6 @@ class Member < ActiveRecord::Base
has_many :notifications, foreign_key: 'recipient_id'
has_many :sent_notifications, foreign_key: 'sender_id'
has_many :authentications
has_many :orders
has_one :account
has_one :account_type, through: :account
has_many :photos
has_many :requested_crops, class_name: Crop, foreign_key: 'requester_id'
has_many :likes, dependent: :destroy
@@ -79,11 +76,9 @@ class Member < ActiveRecord::Base
after_save :update_newsletter_subscription
# Give each new member a default garden
# and an account record (for paid accounts etc)
# we use find_or_create to avoid accidentally creating a second one,
# which can happen sometimes especially with FactoryBot associations
after_create { |member| Garden.create(name: "Garden", owner_id: member.id) }
after_create { |member| Account.find_or_create_by(member_id: member.id) }
# allow login via either login_name or email address
def self.find_first_by_auth_conditions(warden_conditions)
@@ -101,34 +96,6 @@ class Member < ActiveRecord::Base
roles.any? { |r| r.name.gsub(/\s+/, "_").underscore.to_sym == role_sym }
end
def current_order
orders.find_by(completed_at: nil)
end
# when purchasing a product that gives you a paid account, this method
# does all the messing around to actually make sure the account is
# updated correctly -- account type, paid until, etc. Usually this is
# called by order.update_account, which loops through all order items
# and does this for each one.
def update_account_after_purchase(product)
account.account_type = product.account_type if product.account_type
if product.paid_months
start_date = account.paid_until || Time.zone.now
account.paid_until = start_date + product.paid_months.months
end
account.save
end
def paid?
if account.account_type.is_permanent_paid
true
elsif account.account_type.is_paid && account.paid_until >= Time.zone.now
true
else
false
end
end
def auth(provider)
authentications.find_by(provider: provider)
end

View File

@@ -1,90 +0,0 @@
class Order < ActiveRecord::Base
#
# Relationships
belongs_to :member, with_deleted: true
has_many :order_items, dependent: :destroy
#
# Validations
validates :referral_code, format: {
with: /\A[a-zA-Z0-9 ]*\z/,
message: "may only include letters and numbers"
}
#
# Teiggers
before_save :standardize_referral_code
#
# Scopes
scope :by_member, ->(member) { where(member: member) }
# total price of an order
def total
sum = 0
order_items.each do |i|
subtotal = i.price * i.quantity
sum += subtotal
end
sum
end
# return items in the format ActiveMerchant/PayPal want them
def activemerchant_items
items = []
order_items.each do |i|
items.push(name: i.product.name,
quantity: i.quantity,
amount: i.price)
end
items
end
# record the paypal details for reference
def record_paypal_details(token)
self.paypal_express_token = token
details = EXPRESS_GATEWAY.details_for(token)
self.paypal_express_payer_id = details.payer_id
save
end
# when an order is completed, we update the member's account to mark
# them as paid, or whatever, based on what products they ordered
def update_account
order_items.each do |i|
member.update_account_after_purchase(i.product)
end
end
# removes whitespace and forces to uppercase (we're somewhat liberal
# in what we accept, but we clean it up anyway.)
def standardize_referral_code
self.referral_code = referral_code.upcase.gsub(/\s/, '') if referral_code
end
# search orders (used by admin/orders)
# usage: Order.search({ :by => 'member', :for => 'Skud' })
# can search by: member, order_id, paypal_token, paypal_payer_id,
def self.search(args = {})
if args[:for]
case args[:by]
when "member"
member = Member.with_deleted.find_by(login_name: args[:for])
return member.orders if member
when "order_id"
order = Order.find_by(id: args[:for])
return [order] if order
when "paypal_token"
order = Order.find_by(paypal_express_token: args[:for])
return [order] if order
when "paypal_payer_id"
order = Order.find_by(paypal_express_payer_id: args[:for])
return [order] if order
when "referral_code"
# coerce to uppercase
return Order.where(referral_code: args[:for].upcase)
end
end
[]
end
end

View File

@@ -1,12 +0,0 @@
class OrderItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
validate :price_must_be_greater_than_minimum
validates :order_id, uniqueness: { message: "may only have one item." }
def price_must_be_greater_than_minimum
@product = Product.find(product_id)
errors.add(:price, "must be greater than the product's minimum value") if price < @product.min_price
end
end

View File

@@ -27,7 +27,8 @@ class Photo < ActiveRecord::Base
license_url: license.url,
thumbnail_url: FlickRaw.url_q(info),
fullsize_url: FlickRaw.url_z(info),
link_url: FlickRaw.url_photopage(info)
link_url: FlickRaw.url_photopage(info),
date_taken: info.dates.taken
}
end
@@ -49,7 +50,11 @@ class Photo < ActiveRecord::Base
end
end
def set_flickr_metadata
def set_flickr_metadata!
update_attributes(flickr_metadata)
end
def to_s
"#{title} by #{owner.login_name}"
end
end

View File

@@ -4,12 +4,12 @@ class Planting < ActiveRecord::Base
friendly_id :planting_slug, use: %i(slugged finders)
# Constants
SUNNINESS_VALUES = %w(sun semi-shade shade)
SUNNINESS_VALUES = %w(sun semi-shade shade).freeze
PLANTED_FROM_VALUES = [
'seed', 'seedling', 'cutting', 'root division', 'runner',
'bulb', 'root/tuber', 'bare root plant', 'advanced plant',
'graft', 'layering'
]
].freeze
##
## Triggers

View File

@@ -1,15 +0,0 @@
class Product < ActiveRecord::Base
#
# Relationships
belongs_to :account_type
has_and_belongs_to_many :orders # rubocop:disable Rails/HasAndBelongsToMany
#
# Validations
validates :paid_months, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
validates :min_price, presence: true
def to_s
name
end
end

View File

@@ -16,8 +16,6 @@ class Seed < ActiveRecord::Base
#
# Validations
validates :crop, approved: true
delegate :name, to: :crop
delegate :default_photo, to: :crop
validates :crop, presence: { message: "must be present and exist in our database" }
validates :quantity, allow_nil: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
@@ -38,6 +36,10 @@ class Seed < ActiveRecord::Base
inclusion: { in: HEIRLOOM_VALUES, message: "You must say whether the seeds"\
"are heirloom, hybrid, or unknown" }
#
# Delegations
delegate :name, to: :crop
#
# Scopes
default_scope { joins(:owner) } # Ensure owner exists
@@ -45,6 +47,10 @@ class Seed < ActiveRecord::Base
scope :interesting, -> { tradable.has_location }
scope :has_location, -> { joins(:owner).where.not("members.location": nil) }
def default_photo
photos.order(created_at: :desc).first
end
def tradable?
tradable_to != 'nowhere'
end

View File

@@ -1,21 +0,0 @@
= form_for @account_type do |f|
- if @account_type.errors.any?
#error_explanation
%h2
= pluralize(@account_type.errors.size, "error")
prohibited this account_type from being saved:
%ul
- @account_type.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name
.field
= f.label :is_paid
= f.check_box :is_paid
.field
= f.label :is_permanent_paid
= f.check_box :is_permanent_paid
.actions
= f.submit 'Save'

View File

@@ -1,7 +0,0 @@
- content_for :title, "Editing account type"
= render 'form'
= link_to 'Show', @account_type
\|
= link_to 'Back', account_types_path

View File

@@ -1,23 +0,0 @@
- content_for :title, "Listing account types"
%table
%tr
%th Name
%th Is paid
%th Is permanent paid
%th
%th
%th
- @account_types.each do |account_type|
%tr
%td= account_type.name
%td= account_type.is_paid
%td= account_type.is_permanent_paid
%td= link_to 'Show', account_type
%td= link_to 'Edit', edit_account_type_path(account_type)
%td= link_to 'Destroy', account_type, method: :delete, data: { confirm: 'Are you sure?' }
%br
= link_to 'New Account type', new_account_type_path

View File

@@ -1,5 +0,0 @@
- content_for :title, "New account type"
= render 'form'
= link_to 'Back', account_types_path

View File

@@ -1,17 +0,0 @@
%p#notice= notice
%p
%b Name:
= @account_type.name
%p
%b Is paid:
= @account_type.is_paid
%p
%b Is permanent paid:
= @account_type.is_permanent_paid
= link_to 'Edit', edit_account_type_path(@account_type)
\|
= link_to 'Delete', @account_type, method: :delete, data: { confirm: 'Are you sure?' }
\|
= link_to 'Back', account_types_path

View File

@@ -1,21 +0,0 @@
= form_for @account do |f|
- if @account.errors.any?
#error_explanation
%h2
= pluralize(@account.errors.size, "error")
prohibited this account from being saved:
%ul
- @account.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :member_id
= f.number_field :member_id
.field
= f.label :account_type
= f.text_field :account_type
.field
= f.label :paid_until
= f.datetime_select :paid_until
.actions
= f.submit 'Save'

View File

@@ -1,7 +0,0 @@
- content_for :title, "Editing account"
= render 'form'
= link_to 'Show', @account
\|
= link_to 'Back', accounts_path

View File

@@ -1,23 +0,0 @@
- content_for :title, "Listing accounts"
%table
%tr
%th Member
%th Account type
%th Paid until
%th
%th
%th
- @accounts.each do |account|
%tr
%td= account.member_id
%td= account.account_type
%td= account.paid_until
%td= link_to 'Show', account
%td= link_to 'Edit', edit_account_path(account)
%td= link_to 'Destroy', account, method: :delete, data: { confirm: 'Are you sure?' }
%br
= link_to 'New Account detail', new_account_path

View File

@@ -1,5 +0,0 @@
- content_for :title, "New account"
= render 'form'
= link_to 'Back', accounts_path

View File

@@ -1,15 +0,0 @@
%p#notice= notice
%p
%b Member:
= @account.member_id
%p
%b Account type:
= @account.account_type.name
%p
%b Paid until:
= @account.paid_until
= link_to 'Edit', edit_account_path(@account)
\|
= link_to 'Back', accounts_path

View File

@@ -6,8 +6,6 @@
.col-md-4
%h2 Site admin
%ul#site_admin
%li= link_to "Account types", account_types_path
%li= link_to "Products", products_path
%li= link_to "Roles", roles_path
%li= link_to "Forums", forums_path
%li= link_to "CMS", comfy_admin_cms_path
@@ -22,8 +20,3 @@
%ul
%li= link_to "Newsletter subscribers", admin_newsletter_path
%li= link_to "Members", admin_members_path
.row
.col-md-12
%h2 Orders
= render "admin/orders/searchform"

View File

@@ -1,8 +0,0 @@
= form_tag(url_for(controller: 'admin/orders', action: 'search'), method: :get, class: 'form-inline') do
= label_tag :distance, "Search orders:", class: 'control-label'
= text_field_tag :search_text
= select_tag :search_by,
options_for_select('Member': 'member', 'Referral code': 'referral_code',
'Order ID': 'order_id', 'Paypal Token': 'paypal_token',
'Paypal Payer ID': 'paypal_payer_id')
= submit_tag "Search", class: 'btn btn-primary'

View File

@@ -1,3 +0,0 @@
- content_for :title, 'Admin Orders'
= render "admin/orders/searchform"

View File

@@ -1,41 +0,0 @@
- content_for :title, 'Search Orders'
= render "admin/orders/searchform"
- unless @orders.empty?
%h2
Found
= pluralize(@orders.size, "result")
%table.table.table-striped
%tr
%th Member
%th Order number
%th Date completed
%th Referral code
%th Items
%th
- @orders.each do |order|
%tr
%td
= link_to order.member.login_name, order.member
= "(deleted)" if order.member.deleted_at
%td= order.id
%td
- if order.completed_at
= order.completed_at.to_s
- else
In progress
%td
= order.referral_code
%td
- unless order.order_items.empty?
- order.order_items.each do |o|
= o.quantity
x
= o.product.name
@
= price_with_currency(o.price)
%br/
%td= link_to 'Details', order, class: 'btn btn-default btn-xs'

View File

@@ -51,7 +51,8 @@
.form-group
= f.label :parent_id, 'Parent crop', class: 'control-label col-md-2'
.col-md-8
= collection_select(:crop, :parent_id, Crop.all, :id, :name, { include_blank: true }, class: 'form-control')
= collection_select(:crop, :parent_id, Crop.all.order(:name), :id, :name,
{ include_blank: true }, class: 'form-control')
%span.help-block Optional. For setting up crop hierarchies for varieties etc.

View File

@@ -1,29 +1,35 @@
- unless crop.perennial.nil?
%p
#{crop.name} is
- if crop.perennial == true
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
a perennial crop
(living more than two years)
- elsif crop.perennial == false
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
an annual crop
(living and reproducing in a single year or less)
.predictions
- unless crop.perennial.nil?
.row
.col-md-12
%p
#{crop.name} is
- if crop.perennial == true
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
a perennial crop
(living more than two years)
- elsif crop.perennial == false
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
an annual crop
(living and reproducing in a single year or less)
- if crop.annual? && crop.median_lifespan.present?
%p
Median lifespan of #{crop.name} plants is
%strong= crop.median_lifespan
days
.row
- if crop.annual? && crop.median_lifespan.present?
.metric.col-md-3.col-xs-5
%h3 Median lifespan
%strong= crop.median_lifespan
%span days
- if crop.median_days_to_first_harvest.present?
%p
First harvest expected
%strong= crop.median_days_to_first_harvest
days after planting
- if crop.median_days_to_first_harvest.present?
.metric.col-md-3.col-xs-5
%h3 First harvest expected
%strong= crop.median_days_to_first_harvest
%span days
after planting
- if crop.annual? && crop.median_days_to_last_harvest.present?
%p
Last harvest expected
%strong= crop.median_days_to_last_harvest
days after planting
- if crop.annual? && crop.median_days_to_last_harvest.present?
.metric.col-md-3.col-xs-5
%h3 Last harvest expected
%strong= crop.median_days_to_last_harvest
%span days
after planting

View File

@@ -8,6 +8,9 @@
= tag("meta", property: "og:url", content: request.original_url)
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
- content_for :scripts do
= javascript_include_tag "charts"
= render partial: 'approval_status_message', locals: { crop: @crop }
- if @crop.approved?
@@ -23,37 +26,51 @@
.row
.col-md-9
- if member_signed_in?
= display_seed_availability(@current_member, @crop)
= link_to "View your seeds", seeds_by_owner_path(owner: current_member.slug)
.row
.col-md-12
- if member_signed_in?
= display_seed_availability(@current_member, @crop)
= link_to "View your seeds", seeds_by_owner_path(owner: current_member.slug)
%h2 Predictions
= render 'predictions', crop: @crop
%h2
- if !@crop.plantings.empty?
= @crop.name.titleize
has been planted
= pluralize(@crop.plantings.size, "time")
by #{ENV['GROWSTUFF_SITE_NAME']} members.
- else
Nobody is growing this yet. You could be the first!
%p= render 'crops/photos', crop: @crop
%h2
- if !@crop.plantings.empty?
= @crop.name.titleize
has been planted
= pluralize(@crop.plantings.size, "time")
by #{ENV['GROWSTUFF_SITE_NAME']} members.
- else
Nobody is growing this yet. You could be the first!
.row
.col-md-12
%h2 Predictions
= render 'predictions', crop: @crop
%h2
Sunniness Chart
.row
.col-md-12
%h2 Photos
%p= render 'crops/photos', crop: @crop
.row
.col-md-3
%h2 Sunniness
= pie_chart crop_sunniness_path(@crop), legend: "bottom"
#sunchart
.col-md-3
%h2 Planted from
= pie_chart crop_planted_from_path(@crop), legend: "bottom"
.col-md-3
%h2 Harvested for
= pie_chart crop_harvested_for_path(@crop), legend: "bottom"
%h2
Crop Map
%p
Only plantings by members who have set their locations are shown on this map.
- if current_member && current_member.location.blank?
= link_to "Set your location.", edit_member_registration_path
#cropmap
.row
.col-md-12
%h2 Crop Map
%p
Only plantings by members who have set their locations are shown on this map.
- if current_member && current_member.location.blank?
= link_to "Set your location.", edit_member_registration_path
#cropmap
%a{ name: 'posts' }
%h2 What people are saying about #{@crop.name.pluralize}

View File

@@ -9,6 +9,11 @@
= tag("meta", property: "og:type", content: "website")
= tag("meta", property: "og:url", content: request.original_url)
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
- content_for :scripts do
= javascript_include_tag "charts"
= javascript_include_tag "https://www.gstatic.com/charts/loader.js"
.row
.col-md-9
%p.btn-group= render 'gardens/actions', garden: @garden
@@ -32,7 +37,11 @@
Why not
= link_to 'tell us more.', edit_garden_path(@garden)
%h3 What's planted here?
%h3 Garden timeline
.row
= timeline garden_timeline_path(@garden), adapter: "google"
%h3 Current plantings in garden
.row
- if @current_plantings.size.positive?
- @current_plantings.each do |planting|

View File

@@ -47,7 +47,6 @@
%li= link_to t('.browse_members'), members_path
%li= link_to t('.posts'), posts_path
%li= link_to t('.forums'), forums_path
%li= link_to t('.support_growstuff'), shop_path
- if member_signed_in?
%li.dropdown<
@@ -64,7 +63,6 @@
%li= link_to t('.harvest'), harvests_by_owner_path(owner: current_member.slug)
%li= link_to t('.seeds'), seeds_by_owner_path(owner: current_member.slug)
%li= link_to t('.posts'), posts_by_author_path(author: current_member.slug)
%li= link_to t('.account'), orders_path
%li
- if current_member.notifications.unread_count.positive?
= link_to(t('.inbox_unread', unread_count: current_member.notifications.unread_count),

View File

@@ -1,5 +1,6 @@
!!! 5
%html{ lang: "en", prefix: "og: http://ogp.me/ns#" }
= yield :scripts
= render partial: "layouts/meta"
%body
= render partial: "layouts/header"
@@ -27,5 +28,4 @@
\==================================================
/ Placed at the end of the document so the pages load faster
= javascript_include_tag "application"
!= Growstuff::Application.config.analytics_code

View File

@@ -1,24 +0,0 @@
%h3 Account details
%p
%strong Member since:
= member.created_at.to_s(:date)
%p
%strong Account type:
= member.account_type
account
%p
%strong Last Login:
= member.last_sign_in_at
%p
%strong Member Roles:
%br
- if member.role? :admin
Administrator
- if member.role? :crop_wrangler
Crop Wrangler
- else
Member

View File

@@ -0,0 +1,9 @@
%p
%strong Member Roles:
%br
- if member.role? :admin
Administrator
- if member.role? :crop_wrangler
Crop Wrangler
- unless (member.role?(:admin) || member.role?(:crop_wrangler))
Member

View File

@@ -1,3 +1,10 @@
%p
%strong Member since:
= member.created_at.to_s(:date)
%p
%strong Last Login:
= member.last_sign_in_at
%h3 Activity
%ul.list-inline
@@ -33,4 +40,3 @@
= link_to pluralize(member.followers.size, "follower"), member_followers_path(member)
- else
0 followers

View File

@@ -10,8 +10,6 @@
- content_for :buttonbar do
- if can? :update, @member
= link_to 'Edit profile', edit_member_registration_path, class: 'btn btn-default'
- if @member == current_member && !@member.paid?
= link_to "Upgrade account", shop_path, class: 'btn btn-default'
- if can?(:create, Notification) && current_member != @member
= link_to 'Send message', new_notification_path(recipient_id: @member.id), class: 'btn btn-default'
@@ -33,7 +31,7 @@
= render partial: "gardens", locals: { member: @member, gardens: @gardens }
.col-md-3
= render partial: "avatar", locals: { member: @member }
= render partial: "account", locals: { member: @member }
= render partial: "roles", locals: { member: @member }
= render partial: "stats", locals: { member: @member }
= render partial: "contact", locals: { member: @member,
twitter_auth: @twitter_auth,

View File

@@ -1,45 +0,0 @@
- content_for :title, "Completed order"
%p Thank you for your order.
%p
%strong Completed at:
= @order.completed_at
%p
%strong Order number:
= @order.id
= render "shared/account_status"
%h2 Order items
%table.table.table-striped
%tr
%th Product
%th Price
%th Quantity
%th Subtotal
- total = 0
- @order.order_items.each do |i|
%tr
%td= i.product.name
%td
= price_with_currency(i.price)
%td= i.quantity
%td
- subtotal = i.price * i.quantity
- total += subtotal
= price_with_currency(subtotal)
%tr
%td
%td
%td
%strong Total:
%td
%strong
= price_with_currency(total)
%p
= link_to "View other orders/order history", orders_path

View File

@@ -1,44 +0,0 @@
- content_for :title, "Your Account"
= render "shared/account_status"
%h2 Orders
- if current_member.orders.present?
%p
Your order history shows what you have bought via our
= succeed "." do
= link_to "shop", shop_path
%table.table.table-striped
%tr
%th Order number
%th Date completed
%th Items
%th
- @orders.each do |order|
%tr
%td= order.id
%td
- if order.completed_at
= order.completed_at.to_s
- else
In progress
%td
- unless order.order_items.empty?
- order.order_items.each do |o|
= o.quantity
x
= o.product.name
@
= price_with_currency(o.price)
%br/
%td= link_to 'Details', order, class: 'btn btn-default btn-xs'
- else
%p
You have not made any orders. You can place an order via our
= succeed "." do
= link_to "shop", shop_path

View File

@@ -1,84 +0,0 @@
- content_for :title, @order.completed_at ? "Order details (##{@order.id})" : "Current order"
%p
%strong Order number:
= @order.id
%p
%strong Ordered by:
= link_to @order.member, @order.member
%p
%strong Date begun:
= @order.created_at.to_s
- if @order.completed_at
%p
%strong Date completed:
= @order.completed_at.to_s
- if @order.referral_code
%p
%strong Referral code:
= @order.referral_code
- if current_member.role? :admin
%p
%strong Paypal Express token:
= @order.paypal_express_token
%p
%strong Paypal Express payer ID:
= @order.paypal_express_payer_id
%h2 Order items
%table.table.table-striped
%tr
%th Product
%th Price
%th Quantity
%th Subtotal
- @order.order_items.each do |i|
%tr
%td= i.product.name
%td
= price_with_currency(i.price)
%td= i.quantity
%td
- subtotal = i.price * i.quantity
= price_with_currency(subtotal)
%tr
%td
%td
%td
%strong Total:
%td
%strong
= price_with_currency(@order.total)
= forex_link(@order.total)
- if @order.errors.any?
.alert
#error_explanation
%h3
= pluralize(@order.errors.size, "error")
stopped you from checking out:
%ul
- @order.errors.full_messages.each do |msg|
%li= msg
- if can?(:complete, @order) || can?(:destroy, @order)
= form_tag(checkout_order_path(@order), method: :get, class: 'form-inline') do
%p
- if can? :complete, @order
= label_tag :referral_code, "Do you have a referral code?"
= text_field_tag :referral_code, @order.referral_code, class: 'input-medium'
= submit_tag "Checkout with PayPal", class: 'btn btn-primary'
- if can? :destroy, @order
= link_to 'Delete this order', @order, method: :delete,
data: { confirm: 'Are you sure?' },
class: 'btn btn-default'
= link_to "View other orders/order history", orders_path, class: 'btn btn-default'
%p

View File

@@ -21,7 +21,7 @@
= f.label :garden_id, 'Where did you plant it?', class: 'control-label col-md-2'
.col-md-8
= collection_select(:planting, :garden_id,
Garden.active.where(owner_id: current_member),
current_member.gardens.active.order("lower(gardens.name)"),
:id, :name,
selected: @planting.garden_id || @garden.id,
class: 'form-control')

View File

@@ -1,32 +0,0 @@
= form_for @product do |f|
- if @product.errors.any?
#error_explanation
%h2
= pluralize(@product.errors.size, "error")
prohibited this product from being saved:
%ul
- @product.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name, class: 'form-control'
.field
= f.label :description
= f.text_area :description, class: 'form-control'
.field
= f.label :min_price, "Minimum price (in cents)"
= f.text_field :min_price
.field
= f.label :recommended_price, "Recommended price (in cents)"
= f.text_field :recommended_price
.field
= f.label :account_type
= collection_select(:product, :account_type_id, AccountType.all, :id,
:name, selected: @product.account_type_id)
.field
= f.label :paid_months
= f.text_field :paid_months
.form-group
.actions
= f.submit 'Save'

View File

@@ -1,7 +0,0 @@
- content_for :title, "Editing product"
= render 'form'
= link_to 'Show', @product
\|
= link_to 'Back', products_path

View File

@@ -1,29 +0,0 @@
- content_for :title, "Listing products"
%table
%tr
%th Name
%th Description
%th Min price
%th Recommended price
%th Account type
%th Paid months
%th
%th
%th
- @products.each do |product|
%tr
%td= product.name
%td= product.description
%td= product.min_price
%td= product.recommended_price
%td= product.account_type ? product.account_type.name : ""
%td= product.paid_months
%td= link_to 'Show', product
%td= link_to 'Edit', edit_product_path(product)
%td= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' }
%br
= link_to 'New Product', new_product_path

View File

@@ -1,5 +0,0 @@
- content_for :title, "New product"
= render 'form'
= link_to 'Back', products_path

View File

@@ -1,25 +0,0 @@
%p#notice= notice
%p
%b Name:
= @product.name
%p
%b Description:
:growstuff_markdown
#{strip_tags(@product.description)}
%p
%b Min price:
= @product.min_price
%p
%b Recommended price:
= @product.recommended_price
%p
%b Account type:
= @product.account_type.name
%p
%b Paid months:
= @product.paid_months
= link_to 'Edit', edit_product_path(@product)
\|
= link_to 'Back', products_path

View File

@@ -1,13 +0,0 @@
%h2 Your current account status
%p
%strong Account type:
= current_member.account_type.name
- if current_member.account.paid_until_string
%p
%strong Paid until:
= current_member.account.paid_until_string
- unless current_member.paid?
= link_to "Upgrade and support #{ENV['GROWSTUFF_SITE_NAME']}", shop_path, class: 'btn btn-primary'

View File

@@ -1,83 +0,0 @@
- content_for :title, t('.title')
%p
Growstuff relies on your support to build and run this open source
platform for food growers. We do not have outside investment, and do
not accept ads. Instead, we offer paid memberships, which give you
access to premium features, and ensure that we focus our efforts on
keeping you, our members, happy.
%p
We are currently developing a number of advanced features for paid
members. We will announce our progress on these in our
= link_to "Feedback and Support forum", "http://www.growstuff.org/forums/growstuff-feedback-support"
as well as via other channels.
%p
All our accounts are priced on a sliding scale. You can choose how
much you want to pay. Remember, your subscription supports an open
source, open data platform supporting home food growers and promoting
sustainable food systems!
- if current_member && current_member.paid?
%h2 Thank you for supporting Growstuff
%p You currently have a paid membership, and can't buy another one at this time.
= render "shared/account_status"
- elsif @order && !@order.order_items.empty?
%h2 Your current order
%p
You currently have the following item in your cart:
%strong
= @most_recent_item.product
@
= price_with_currency(@most_recent_item.price)
%p
= link_to "View order and checkout", order_path(@order)
or
= succeed "." do
= link_to 'delete this order', @order, method: :delete,
data: { confirm: 'Are you sure?' }
- else
- @products.each do |p|
%h2= p.name
%div
:growstuff_markdown
#{ strip_tags p.description }
%p
Pay what you want, starting at
= succeed "." do
= price_with_currency(p.min_price)
= forex_link(p.min_price)
- if p.recommended_price
Recommended price:
= succeed "." do
= price_with_currency(p.recommended_price)
= forex_link(p.recommended_price)
%div
- if can? :create, Order
= form_for @order_item do |f|
.field
= f.text_field :price, value: price_in_dollars(p.recommended_price || p.min_price)
.field
= f.hidden_field :product_id, value: p.id
.field
= f.hidden_field :quantity, value: 1
.actions
= f.submit 'Buy', class: 'btn btn-primary'
- else
Please
= link_to "sign in", new_member_session_path
or
= link_to "sign up", new_member_registration_path
to purchase.

View File

@@ -44,9 +44,6 @@ module Growstuff
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure a default account type
config.default_account_type = "Free"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]

View File

@@ -57,11 +57,6 @@ GROWSTUFF_TWITTER_SECRET: ""
GROWSTUFF_FLICKR_KEY: ""
GROWSTUFF_FLICKR_SECRET: ""
# Paypal is used for payments, obviously.
GROWSTUFF_PAYPAL_USERNAME: "dummy"
GROWSTUFF_PAYPAL_PASSWORD: "dummy"
GROWSTUFF_PAYPAL_SIGNATURE: "dummy"
# https://developers.facebook.com/
GROWSTUFF_FACEBOOK_KEY: ""
GROWSTUFF_FACEBOOK_SECRET: ""

View File

@@ -63,17 +63,6 @@ Growstuff::Application.configure do
config.mapbox_map_id = 'growstuff.i3n2il6a'
config.mapbox_access_token = 'pk.eyJ1IjoiZ3Jvd3N0dWZmIiwiYSI6IkdxMkx4alUifQ.n0igaBsw97s14zMa0lwKCA'
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
login: ENV['GROWSTUFF_PAYPAL_USERNAME'] || 'dummy',
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'] || 'dummy',
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE'] || 'dummy'
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
config.action_controller.action_on_unpermitted_parameters = :raise
config.active_job.queue_adapter = :sidekiq

View File

@@ -91,16 +91,5 @@ Growstuff::Application.configure do
config.mapbox_map_id = 'growstuff.i3n2c4ie'
config.mapbox_access_token = 'pk.eyJ1IjoiZ3Jvd3N0dWZmIiwiYSI6IkdxMkx4alUifQ.n0igaBsw97s14zMa0lwKCA'
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :production
paypal_options = {
login: ENV['GROWSTUFF_PAYPAL_USERNAME'],
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'],
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE']
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
config.active_job.queue_adapter = :sidekiq
end

View File

@@ -89,16 +89,5 @@ Growstuff::Application.configure do
config.mapbox_map_id = 'growstuff.i3n2hao7'
config.mapbox_access_token = 'pk.eyJ1IjoiZ3Jvd3N0dWZmIiwiYSI6IkdxMkx4alUifQ.n0igaBsw97s14zMa0lwKCA'
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
login: ENV['GROWSTUFF_PAYPAL_USERNAME'],
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'],
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE']
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
config.active_job.queue_adapter = :sidekiq
end

View File

@@ -51,13 +51,6 @@ Growstuff::Application.configure do
config.analytics_code = ''
config.currency = 'AUD'
end
config.after_initialize do
require "active_merchant/ext/paypal_bogus_gateway"
ActiveMerchant::Billing::Base.mode = :test
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalBogusGateway.new
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalBogusGateway.new
end
end
Geocoder.configure(lookup: :test)

View File

@@ -0,0 +1,15 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add Yarn node_modules folder to the asset load path.
Rails.application.config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
Rails.application.config.assets.precompile += %w(charts.js)

View File

@@ -1,11 +1,5 @@
---
en:
account:
update: Account detail was successfully updated.
account_types:
created: Account type was successfully created.
deleted: Account type was successfully deleted.
updated: Account type was successfully updated.
activerecord:
models:
comment:
@@ -99,7 +93,6 @@ en:
open:
ad_free_linktext: ad-free
api_docs_linktext: API documentation
buy_account_linktext: buying a paid account
creative_commons_linktext: Creative Commons license
get_involved_body_html: >
We believe in collaboration, and work closely with our members and the wider food-growing community.
@@ -213,9 +206,6 @@ en:
default: Everyone's seeds
owner_seeds: "%{owner} seeds"
string: "%{crop} seeds belonging to %{owner}"
shop:
index:
title: Shop
unauthorized:
create:
all: Please sign in or sign up to create a %{subject}.

View File

@@ -27,7 +27,9 @@ Growstuff::Application.routes.draw do
get '/plantings/owner/:owner' => 'plantings#index', as: 'plantings_by_owner'
get '/plantings/crop/:crop' => 'plantings#index', as: 'plantings_by_crop'
resources :gardens
resources :gardens do
get 'timeline' => 'charts/gardens#timeline'
end
get '/gardens/owner/:owner' => 'gardens#index', as: 'gardens_by_owner'
resources :seeds
@@ -50,6 +52,9 @@ Growstuff::Application.routes.draw do
get 'crops/search' => 'crops#search', as: 'crops_search'
resources :crops do
get 'photos' => 'photos#index'
get 'sunniness' => 'charts/crops#sunniness'
get 'planted_from' => 'charts/crops#planted_from'
get 'harvested_for' => 'charts/crops#harvested_for'
end
resources :comments
@@ -67,17 +72,6 @@ Growstuff::Application.routes.draw do
get '/places/search' => 'places#search', as: 'search_places'
get '/places/:place' => 'places#show', as: 'place'
# everything for paid accounts etc
resources :account_types
resources :accounts
resources :orders
get 'orders/:id/checkout' => 'orders#checkout', as: 'checkout_order'
get 'orders/:id/complete' => 'orders#complete', as: 'complete_order'
get 'orders/:id/cancel' => 'orders#cancel', as: 'cancel_order'
resources :order_items
resources :products
resources :likes, only: %i(create destroy)
get "home/index"
@@ -86,15 +80,11 @@ Growstuff::Application.routes.draw do
get 'auth/:provider/callback' => 'authentications#create'
get 'members/auth/:provider/callback' => 'authentications#create'
get '/shop' => 'shop#index'
get '/shop/:action' => 'shop#:action'
comfy_route :cms_admin, path: '/admin/cms'
namespace :admin do
resources :members
end
get '/admin/orders' => 'admin/orders#index'
get '/admin/orders/:action' => 'admin/orders#:action'
get '/admin' => 'admin#index'
get '/admin/newsletter' => 'admin#newsletter', as: :admin_newsletter
get '/admin/:action' => 'admin#:action'

View File

@@ -0,0 +1,5 @@
class AddDatetakenToPhotos < ActiveRecord::Migration
def change
add_column :photos, :date_taken, :datetime
end
end

View File

@@ -0,0 +1,9 @@
class RemoveShop < ActiveRecord::Migration
def up
drop_table :order_items
drop_table :orders
drop_table :products
drop_table :account_types
drop_table :accounts
end
end

View File

@@ -11,27 +11,11 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20171129041341) do
ActiveRecord::Schema.define(version: 20180205000612) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "account_types", force: :cascade do |t|
t.string "name", null: false
t.boolean "is_paid"
t.boolean "is_permanent_paid"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "accounts", force: :cascade do |t|
t.integer "member_id", null: false
t.integer "account_type_id"
t.datetime "paid_until"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "alternate_names", force: :cascade do |t|
t.string "name", null: false
t.integer "crop_id", null: false
@@ -359,25 +343,6 @@ ActiveRecord::Schema.define(version: 20171129041341) do
t.datetime "updated_at"
end
create_table "order_items", force: :cascade do |t|
t.integer "order_id"
t.integer "product_id"
t.integer "price"
t.integer "quantity"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "orders", force: :cascade do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "completed_at"
t.integer "member_id"
t.string "paypal_express_token"
t.string "paypal_express_payer_id"
t.string "referral_code"
end
create_table "orders_products", id: false, force: :cascade do |t|
t.integer "order_id"
t.integer "product_id"
@@ -405,6 +370,7 @@ ActiveRecord::Schema.define(version: 20171129041341) do
t.string "license_url"
t.string "link_url", null: false
t.string "flickr_photo_id"
t.datetime "date_taken"
end
create_table "photos_plantings", id: false, force: :cascade do |t|
@@ -460,17 +426,6 @@ ActiveRecord::Schema.define(version: 20171129041341) do
add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree
add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true, using: :btree
create_table "products", force: :cascade do |t|
t.string "name", null: false
t.text "description", null: false
t.integer "min_price", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "account_type_id"
t.integer "paid_months"
t.integer "recommended_price"
end
create_table "roles", force: :cascade do |t|
t.string "name", null: false
t.text "description"

View File

@@ -7,12 +7,9 @@ def load_data
Crop.transaction do
# for all Growstuff sites, including production ones
load_roles
load_basic_account_types
create_cropbot
load_crops
load_plant_parts
load_paid_account_types
load_products
# We don't load these in an environment except development to
# prevent creating users in the wild - especially admins - with
@@ -44,20 +41,6 @@ def load_roles
@wrangler = Role.create(name: 'Crop Wrangler')
end
def load_basic_account_types
puts "Adding 'free' and 'staff' account types..."
AccountType.create!(
name: "Free",
is_paid: false,
is_permanent_paid: false
)
AccountType.create!(
name: "Staff",
is_paid: true,
is_permanent_paid: true
)
end
def load_test_users # rubocop:disable Metrics/AbcSize
puts "Loading test users..."
@@ -65,7 +48,7 @@ def load_test_users # rubocop:disable Metrics/AbcSize
source_path = Rails.root.join('db', 'seeds')
begin
suburb_file = File.open("#{source_path}/suburbs.csv")
rescue
rescue StandardError
puts "Warning: unable to open suburbs.csv"
end
@@ -141,39 +124,6 @@ def create_cropbot
@cropbot_user.skip_confirmation!
@cropbot_user.roles << @wrangler
@cropbot_user.save!
@cropbot_user.account.account_type = AccountType.find_by(name: "Staff")
@cropbot_user.account.save
end
def load_paid_account_types
puts "Adding 'paid' and 'seed' account types..."
@paid_account = AccountType.create!(
name: "Paid",
is_paid: true,
is_permanent_paid: false
)
@seed_account = AccountType.create!(
name: "Seed",
is_paid: true,
is_permanent_paid: true
)
end
def load_products
puts "Adding products..."
Product.create!(
name: "Annual subscription",
description: "Paid account, 1 year",
min_price: 3000,
account_type_id: @paid_account.id,
paid_months: 12
)
Product.create!(
name: "Seed account",
description: "Paid account, in perpetuity",
min_price: 15_000,
account_type_id: @seed_account.id
)
end
def load_plant_parts

View File

@@ -51,7 +51,7 @@ namespace :growstuff do
send_on_day = 3 # wednesday
every_n_weeks = 2 # send fortnightly
if Time.zone.today.cwday == send_on_day and Time.zone.today.cweek % every_n_weeks == 0
if (Time.zone.today.cwday == send_on_day) && (Time.zone.today.cweek % every_n_weeks == 0)
Member.confirmed.find_each do |m|
Notifier.planting_reminder(m).deliver_now!
end
@@ -62,7 +62,7 @@ namespace :growstuff do
# this fixes up anyone who has erroneously wound up with a 0,0 lat/long
task depopulate_null_island: :environment do
Member.find_each do |m|
if m.location and (m.latitude.nil? and m.longitude.nil?)
if m.location && (m.latitude.nil? && m.longitude.nil?)
m.geocode
m.save
end
@@ -88,84 +88,13 @@ namespace :growstuff do
# site is small and there aren't many of them, so it shouldn't matter
# for this one-off script.
Garden.all.each do |g|
if g.name.nil? or g.name =~ /^\s*$/
if g.name.nil? || g.name =~ /^\s*$/
g.name = "Garden"
g.save
end
end
end
desc "June 2013: create account types and products."
task setup_shop: :environment do
puts "Adding account types..."
AccountType.find_or_create_by(
name: "Free",
is_paid: false,
is_permanent_paid: false
)
@paid_account = AccountType.find_or_create_by(
name: "Paid",
is_paid: true,
is_permanent_paid: false
)
@seed_account = AccountType.find_or_create_by(
name: "Seed",
is_paid: true,
is_permanent_paid: true
)
@staff_account = AccountType.find_or_create_by(
name: "Staff",
is_paid: true,
is_permanent_paid: true
)
puts "Adding products..."
Product.find_or_create_by(
name: "Annual subscription",
description: "An annual subscription gives you access "\
"to paid account features for one year. Does not auto-renew.",
min_price: 3000,
account_type_id: @paid_account.id,
paid_months: 12
)
Product.find_or_create_by(
name: "Seed account",
description: "A seed account helps Growstuff grow in its "\
"early days. It gives you all the features of "\
"a paid account, in perpetuity. This account "\
"type never expires.",
min_price: 15_000,
account_type_id: @seed_account.id
)
puts "Giving each member an account record..."
Member.all.each do |m|
Account.create(member_id: m.id) unless m.account
end
puts "Making Skud a staff account..."
@skud = Member.find_by(login_name: 'Skud')
if @skud
@skud.account.account_type = @staff_account
@skud.account.save
end
puts "Done setting up shop."
end
desc "June 2013: replace nil account_types with free accounts"
task nil_account_type: :environment do
free = AccountType.find_by(name: "Free")
raise "Free account type not found: run rake growstuff:oneoff:setup_shop"\
unless free
Account.all.each do |a|
unless a.account_type
a.account_type = free
a.save
end
end
end
desc "July 2013: replace nil seed.tradable_to with nowhere"
task tradable_to_nowhere: :environment do
Seed.all.each do |s|
@@ -187,8 +116,6 @@ namespace :growstuff do
task set_default_crop_creator: :environment do
cropbot = Member.find_by(login_name: "cropbot")
raise "cropbot not found: create cropbot member on site or run rake db:seed" unless cropbot
cropbot.account.account_type = AccountType.find_by(name: "Staff") # set this just because it's nice
cropbot.account.save
Crop.find_each do |crop|
unless crop.creator
crop.creator = cropbot

814
package-lock.json generated
View File

File diff suppressed because it is too large Load Diff

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