@@ -1,7 +1,7 @@
|
||||
engines:
|
||||
rubocop:
|
||||
enabled: true
|
||||
channel: "rubocop-0-70"
|
||||
channel: "rubocop-0-71"
|
||||
scss-lint:
|
||||
enabled: true
|
||||
shellcheck:
|
||||
@@ -44,3 +44,4 @@ exclude_paths:
|
||||
- public/
|
||||
- app/assets/stylesheets/bootstrap-accessibility.css
|
||||
- app/assets/javascripts/bootstrap*
|
||||
- app/assets/stylesheets/leaflet_overrides.scss
|
||||
|
||||
1
.gitignore
vendored
@@ -28,3 +28,4 @@ config/database.yml
|
||||
cc-test-reporter
|
||||
elasticsearch-*.deb
|
||||
elasticsearch-*.deb.sha512
|
||||
|
||||
|
||||
13
.hound.yml
@@ -1,13 +0,0 @@
|
||||
---
|
||||
fail_on_violations: true
|
||||
ruby:
|
||||
config_file: .rubocop.yml
|
||||
haml:
|
||||
config_file: .haml-lint.yml
|
||||
scss:
|
||||
config_file: .scss-lint.yml
|
||||
eslint:
|
||||
config_file: .eslintrc
|
||||
ignore_file: .esignore
|
||||
jshint:
|
||||
enabled: false
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"userBlacklist": ["tygriffin","oshiho3"]
|
||||
}
|
||||
@@ -22,7 +22,7 @@ PreCommit:
|
||||
problem_on_unmodified_line: warn
|
||||
RuboCop:
|
||||
enabled: true
|
||||
command: ['bundle', 'exec', 'rubocop', '-D', '--rails']
|
||||
command: ['bundle', 'exec', 'rubocop', '-D']
|
||||
TrailingWhitespace:
|
||||
enabled: true
|
||||
exclude:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
inherit_from: .rubocop_todo.yml
|
||||
require: rubocop-rails
|
||||
AllCops:
|
||||
Exclude:
|
||||
- 'db/schema.rb'
|
||||
@@ -56,7 +57,7 @@ Metrics/BlockLength:
|
||||
- 'config/**/*.rb'
|
||||
|
||||
Metrics/LineLength:
|
||||
Max: 120
|
||||
Max: 140
|
||||
|
||||
# Remove the following once the code style matches
|
||||
Metrics/MethodLength:
|
||||
@@ -75,4 +76,4 @@ Metrics/PerceivedComplexity:
|
||||
Rails/SkipsModelValidations:
|
||||
Exclude:
|
||||
- 'db/migrate/20190317023129_finished_boolean.rb'
|
||||
- 'db/seeds.rb'
|
||||
- 'db/seeds.rb'
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.6.0
|
||||
2.6.3
|
||||
|
||||
23
.travis.yml
@@ -3,21 +3,26 @@ language: ruby
|
||||
cache:
|
||||
bundler: true
|
||||
directories:
|
||||
- travis_phantomjs
|
||||
- tmp/cache/assets/test/sprockets
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- chromium-chromedriver
|
||||
- google-chrome-stable
|
||||
code_climate:
|
||||
repo_token:
|
||||
secure: "PfhLGBKRgNqhKuYCJsK+VPhdAzcgWFGeeOyxC/eS8gtlvIISVdgyZE+r30uIei0DFI6zEiN62eW4d+xtT4j7/e2ZcAcx7U52mza/SnQNuu3nCGQDJB8VOvV5NbnwXfi8vfr4e889Mt7k3ocd2c4gqB4UtRqrzhygj7HN+B/GfEk="
|
||||
env:
|
||||
matrix:
|
||||
- GROWSTUFF_ELASTICSEARCH=true RSPEC_TAG=elasticsearch COVERAGE=true PERCY_CHECKS=true
|
||||
- GROWSTUFF_ELASTICSEARCH=true RSPEC_TAG=elasticsearch COVERAGE=true
|
||||
- GROWSTUFF_ELASTICSEARCH=false RSPEC_TAG=~elasticsearch COVERAGE=false
|
||||
- STATIC_CHECKS=true
|
||||
- STATIC_CHECKS=true PERCY_CHECKS=true
|
||||
global:
|
||||
- secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4="
|
||||
- GROWSTUFF_EMAIL="noreply@test.growstuff.org"
|
||||
- GROWSTUFF_SITE_NAME="Growstuff (travis)"
|
||||
- RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
before_install:
|
||||
- ./script/install_phantomjs.sh
|
||||
- export PATH=$PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH
|
||||
- ./script/install_codeclimate.sh
|
||||
- ./script/install_linters.sh
|
||||
- VERSION="6.2.3" ./script/install_elasticsearch.sh
|
||||
@@ -33,9 +38,9 @@ script:
|
||||
./script/check_static.rb
|
||||
else
|
||||
set +e;
|
||||
RAILS_ENV=test bundle exec rake db:create db:migrate search:create;
|
||||
RAILS_ENV=test bundle exec rake db:create db:migrate search:reindex;
|
||||
bundle exec rake assets:precompile;
|
||||
bundle exec rspec --tag $RSPEC_TAG spec/;
|
||||
bundle exec rspec -fd --tag $RSPEC_TAG spec/;
|
||||
fi;
|
||||
- set +e
|
||||
after_script:
|
||||
@@ -67,7 +72,3 @@ deploy:
|
||||
- restart
|
||||
after_deploy:
|
||||
- bundle exec script/heroku_maintenance.rb off
|
||||
addons:
|
||||
code_climate:
|
||||
repo_token:
|
||||
secure: "PfhLGBKRgNqhKuYCJsK+VPhdAzcgWFGeeOyxC/eS8gtlvIISVdgyZE+r30uIei0DFI6zEiN62eW4d+xtT4j7/e2ZcAcx7U52mza/SnQNuu3nCGQDJB8VOvV5NbnwXfi8vfr4e889Mt7k3ocd2c4gqB4UtRqrzhygj7HN+B/GfEk="
|
||||
|
||||
33
Gemfile
@@ -2,7 +2,7 @@
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
ruby '2.6.0'
|
||||
ruby '2.6.3'
|
||||
|
||||
gem 'rails', '5.2.2.1'
|
||||
|
||||
@@ -16,7 +16,13 @@ gem 'sass-rails'
|
||||
gem 'jsonapi-resources'
|
||||
|
||||
# CSS framework
|
||||
gem 'bootstrap-sass'
|
||||
gem "bootstrap", ">= 4.3.1"
|
||||
gem 'material-sass', '4.1.1'
|
||||
|
||||
# Icons used by bootstrap/material-sass
|
||||
gem 'material_icons'
|
||||
|
||||
# icons
|
||||
gem 'font-awesome-sass'
|
||||
|
||||
gem 'uglifier' # JavaScript compressor
|
||||
@@ -26,15 +32,13 @@ gem 'oj' # Speeds up json
|
||||
# planting and harvest predictions
|
||||
# based on median values for the crop
|
||||
gem 'active_median', '0.1.4' # needs postgresql update https://github.com/Growstuff/growstuff/issues/1757
|
||||
gem 'active_record_union'
|
||||
|
||||
gem 'flickraw'
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-ui-rails'
|
||||
gem 'js-routes' # provides access to Rails routes in Javascript
|
||||
|
||||
# Boostrap friendly layout for photo galleries
|
||||
gem 'isotope-rails'
|
||||
|
||||
gem 'cancancan' # for checking member privileges
|
||||
gem 'csv_shaper' # CSV export
|
||||
gem 'figaro' # for handling config via ENV variables
|
||||
@@ -61,6 +65,7 @@ gem 'bluecloth'
|
||||
|
||||
# Pagination
|
||||
gem 'will_paginate'
|
||||
gem 'will_paginate-bootstrap4'
|
||||
|
||||
# user signup/login/etc
|
||||
gem 'devise'
|
||||
@@ -77,6 +82,9 @@ gem 'geocoder', '1.4.9' # TODO: Fails on version 1.5.0. Needs investigation
|
||||
# For easy calendar selection
|
||||
gem 'bootstrap-datepicker-rails'
|
||||
|
||||
# DRY-er easier bootstrap 4 forms
|
||||
gem "bootstrap_form", ">= 4.2.0"
|
||||
|
||||
# For connecting to other services (eg Twitter)
|
||||
gem 'omniauth', '~> 1.3'
|
||||
gem 'omniauth-facebook'
|
||||
@@ -87,6 +95,7 @@ gem 'omniauth-twitter'
|
||||
gem "chartkick"
|
||||
|
||||
# clever elastic search
|
||||
gem 'elasticsearch', '< 7.0.0'
|
||||
gem 'searchkick'
|
||||
|
||||
gem "hashie", ">= 3.5.3"
|
||||
@@ -103,6 +112,9 @@ gem 'xmlrpc' # fixes rake error - can be removed if not needed later
|
||||
|
||||
gem 'puma'
|
||||
|
||||
gem 'loofah', '>= 2.2.1'
|
||||
gem 'rack-protection', '>= 2.0.1'
|
||||
|
||||
group :production do
|
||||
gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku
|
||||
gem 'dalli'
|
||||
@@ -132,13 +144,12 @@ group :development, :test do
|
||||
gem 'haml-i18n-extractor'
|
||||
gem 'haml-rails' # HTML templating language
|
||||
gem 'haml_lint', '>= 0.25.1' # Checks haml files for goodness
|
||||
gem 'i18n-tasks' # adds tests for finding missing and unused translations
|
||||
gem 'poltergeist' # for headless JS testing
|
||||
gem 'i18n-tasks' # adds tests for finding missing and unused translations
|
||||
gem 'rspec-activemodel-mocks'
|
||||
gem 'rspec-rails' # unit testing framework
|
||||
gem 'rubocop', '~> 0.70'
|
||||
gem 'rubocop', '~> 0.71'
|
||||
gem 'rubocop-rails'
|
||||
gem 'rubocop-rspec'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'webrat' # provides HTML matchers for view tests
|
||||
end
|
||||
|
||||
@@ -146,11 +157,11 @@ group :test do
|
||||
gem 'codeclimate-test-reporter', require: false
|
||||
gem 'percy-capybara', '~> 4.0.0'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'timecop'
|
||||
gem 'webdrivers'
|
||||
end
|
||||
|
||||
group :travis do
|
||||
gem 'platform-api'
|
||||
end
|
||||
gem 'loofah', '>= 2.2.1'
|
||||
gem 'rack-protection', '>= 2.0.1'
|
||||
|
||||
178
Gemfile.lock
@@ -30,6 +30,8 @@ GEM
|
||||
addressable
|
||||
active_median (0.1.4)
|
||||
activerecord
|
||||
active_record_union (1.3.0)
|
||||
activerecord (>= 4.0)
|
||||
active_utils (3.3.16)
|
||||
activesupport (>= 4.2)
|
||||
i18n
|
||||
@@ -55,9 +57,9 @@ GEM
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
arel (9.0.0)
|
||||
ast (2.4.0)
|
||||
autoprefixer-rails (9.4.7)
|
||||
autoprefixer-rails (9.6.0)
|
||||
execjs
|
||||
bcrypt (3.1.12)
|
||||
bcrypt (3.1.13)
|
||||
better_errors (2.5.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubi (>= 1.0.0)
|
||||
@@ -66,21 +68,25 @@ GEM
|
||||
bonsai-elasticsearch-rails (7.0.1)
|
||||
elasticsearch-model (< 8)
|
||||
elasticsearch-rails (< 8)
|
||||
bootstrap (4.3.1)
|
||||
autoprefixer-rails (>= 9.1.0)
|
||||
popper_js (>= 1.14.3, < 2)
|
||||
sassc-rails (>= 2.0.0)
|
||||
bootstrap-datepicker-rails (1.8.0.1)
|
||||
railties (>= 3.0)
|
||||
bootstrap-kaminari-views (0.0.5)
|
||||
kaminari (>= 0.13)
|
||||
rails (>= 3.1)
|
||||
bootstrap-sass (3.4.1)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sassc (>= 2.0.0)
|
||||
bootstrap_form (4.2.0)
|
||||
actionpack (>= 5.0)
|
||||
activemodel (>= 5.0)
|
||||
builder (3.2.3)
|
||||
bullet (6.0.0)
|
||||
bullet (6.0.1)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
byebug (11.0.1)
|
||||
cancancan (3.0.1)
|
||||
capybara (3.24.0)
|
||||
capybara (3.25.0)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
@@ -97,7 +103,6 @@ GEM
|
||||
chartkick (3.2.0)
|
||||
childprocess (1.0.1)
|
||||
rake (< 13.0)
|
||||
cliver (0.3.2)
|
||||
codeclimate-test-reporter (1.0.9)
|
||||
simplecov (<= 0.13)
|
||||
coderay (1.1.2)
|
||||
@@ -123,12 +128,12 @@ GEM
|
||||
rails (>= 5.0.0)
|
||||
concurrent-ruby (1.1.5)
|
||||
connection_pool (2.2.2)
|
||||
coveralls (0.8.19)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov (~> 0.12.0)
|
||||
term-ansicolor (~> 1.3)
|
||||
thor (~> 0.19.1)
|
||||
tins (~> 1.6)
|
||||
coveralls (0.7.1)
|
||||
multi_json (~> 1.3)
|
||||
rest-client
|
||||
simplecov (>= 0.7)
|
||||
term-ansicolor
|
||||
thor
|
||||
crass (1.0.4)
|
||||
csv_shaper (1.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -142,33 +147,35 @@ GEM
|
||||
warden (~> 1.2.3)
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
elasticsearch (7.1.0)
|
||||
elasticsearch-api (= 7.1.0)
|
||||
elasticsearch-transport (= 7.1.0)
|
||||
elasticsearch-api (7.1.0)
|
||||
domain_name (0.5.20180417)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
elasticsearch (6.8.0)
|
||||
elasticsearch-api (= 6.8.0)
|
||||
elasticsearch-transport (= 6.8.0)
|
||||
elasticsearch-api (6.8.0)
|
||||
multi_json
|
||||
elasticsearch-model (6.0.0)
|
||||
activesupport (> 3)
|
||||
elasticsearch (> 1)
|
||||
hashie
|
||||
elasticsearch-rails (6.0.0)
|
||||
elasticsearch-transport (7.1.0)
|
||||
elasticsearch-transport (6.8.0)
|
||||
faraday
|
||||
multi_json
|
||||
erubi (1.8.0)
|
||||
erubis (2.7.0)
|
||||
excon (0.62.0)
|
||||
excon (0.64.0)
|
||||
execjs (2.7.0)
|
||||
factory_bot (4.11.1)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_bot_rails (4.11.1)
|
||||
factory_bot (~> 4.11.1)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.9.3)
|
||||
factory_bot (5.0.2)
|
||||
activesupport (>= 4.2.0)
|
||||
factory_bot_rails (5.0.2)
|
||||
factory_bot (~> 5.0.2)
|
||||
railties (>= 4.2.0)
|
||||
faker (1.9.5)
|
||||
i18n (>= 0.7)
|
||||
faraday (0.15.4)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.10.0)
|
||||
ffi (1.11.1)
|
||||
figaro (1.1.1)
|
||||
thor (~> 0.14)
|
||||
flickraw (0.9.10)
|
||||
@@ -212,13 +219,15 @@ GEM
|
||||
excon
|
||||
moneta
|
||||
multi_json (>= 1.9.2)
|
||||
highline (2.0.1)
|
||||
highline (2.0.2)
|
||||
html2haml (2.2.0)
|
||||
erubis (~> 2.7.0)
|
||||
haml (>= 4.0, < 6)
|
||||
nokogiri (>= 1.6.0)
|
||||
ruby_parser (~> 3.5)
|
||||
httparty (0.16.3)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httparty (0.17.0)
|
||||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.6.0)
|
||||
@@ -233,25 +242,22 @@ GEM
|
||||
rails-i18n
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
terminal-table (>= 1.5.1)
|
||||
isotope-rails (2.2.2)
|
||||
jquery-rails
|
||||
rails (>= 4.0)
|
||||
jaro_winkler (1.5.2)
|
||||
jaro_winkler (1.5.3)
|
||||
jquery-rails (4.3.5)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-ui-rails (6.0.1)
|
||||
railties (>= 3.2.16)
|
||||
js-routes (1.4.6)
|
||||
js-routes (1.4.7)
|
||||
railties (>= 4)
|
||||
sprockets-rails
|
||||
json (2.1.0)
|
||||
jsonapi-resources (0.9.8)
|
||||
json (2.2.0)
|
||||
jsonapi-resources (0.9.9)
|
||||
activerecord (>= 4.1)
|
||||
concurrent-ruby
|
||||
railties (>= 4.1)
|
||||
jwt (2.1.0)
|
||||
jwt (2.2.1)
|
||||
kaminari (1.1.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.1.1)
|
||||
@@ -268,7 +274,7 @@ GEM
|
||||
kramdown (2.1.0)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
leaflet-rails (1.4.0)
|
||||
leaflet-rails (1.5.1)
|
||||
rails (>= 4.2.0)
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
@@ -283,11 +289,16 @@ GEM
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (0.3.3)
|
||||
mimemagic (~> 0.3.2)
|
||||
material-sass (4.1.1)
|
||||
autoprefixer-rails (>= 6.0.3)
|
||||
sass (>= 3.5.2)
|
||||
material_icons (2.2.1)
|
||||
railties (>= 3.2)
|
||||
memcachier (0.0.2)
|
||||
method_source (0.9.2)
|
||||
mime-types (3.2.2)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2018.0812)
|
||||
mime-types-data (3.2019.0331)
|
||||
mimemagic (0.3.3)
|
||||
mini_magick (4.9.3)
|
||||
mini_mime (1.0.1)
|
||||
@@ -297,7 +308,8 @@ GEM
|
||||
multi_json (1.11.3)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
newrelic_rpm (6.4.0.356)
|
||||
netrc (0.11.0)
|
||||
newrelic_rpm (6.5.0.357)
|
||||
nio4r (2.3.1)
|
||||
nokogiri (1.10.3)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
@@ -337,12 +349,10 @@ GEM
|
||||
platform-api (2.2.0)
|
||||
heroics (~> 0.0.25)
|
||||
moneta (~> 1.0.0)
|
||||
poltergeist (1.18.1)
|
||||
capybara (>= 2.1, < 4)
|
||||
cliver (~> 0.3.1)
|
||||
websocket-driver (>= 0.2.0)
|
||||
public_suffix (3.1.0)
|
||||
puma (3.12.1)
|
||||
popper_js (1.14.5)
|
||||
public_suffix (3.1.1)
|
||||
puma (4.0.0)
|
||||
nio4r (~> 2.0)
|
||||
rack (2.0.7)
|
||||
rack-protection (2.0.5)
|
||||
rack
|
||||
@@ -361,7 +371,7 @@ GEM
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.2.2.1)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-assets-leaflet (1.3.4)
|
||||
rails-assets-leaflet (1.5.1)
|
||||
rails-assets-leaflet.markercluster (1.4.1)
|
||||
rails-assets-leaflet (>= 1.3.1)
|
||||
rails-controller-testing (1.0.4)
|
||||
@@ -393,21 +403,25 @@ GEM
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.0)
|
||||
ffi (~> 1.0)
|
||||
redis (4.1.0)
|
||||
redis (4.1.2)
|
||||
regexp_parser (1.5.1)
|
||||
responders (2.4.1)
|
||||
actionpack (>= 4.2.0, < 6.0)
|
||||
railties (>= 4.2.0, < 6.0)
|
||||
responders (3.0.0)
|
||||
actionpack (>= 5.0)
|
||||
railties (>= 5.0)
|
||||
rest-client (2.0.2)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
rspec-activemodel-mocks (1.1.0)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
rspec-mocks (>= 2.99, < 4.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-core (3.8.1)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.2)
|
||||
rspec-expectations (3.8.4)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
rspec-mocks (3.8.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.2)
|
||||
@@ -418,14 +432,17 @@ GEM
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.0)
|
||||
rubocop (0.71.0)
|
||||
rspec-support (3.8.2)
|
||||
rubocop (0.72.0)
|
||||
jaro_winkler (~> 1.5.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.6)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 1.7)
|
||||
rubocop-rails (2.1.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 0.72.0)
|
||||
rubocop-rspec (1.33.0)
|
||||
rubocop (>= 0.60.0)
|
||||
ruby-progressbar (1.10.1)
|
||||
@@ -433,8 +450,8 @@ GEM
|
||||
ruby_dep (1.5.0)
|
||||
ruby_parser (3.13.1)
|
||||
sexp_processor (~> 4.9)
|
||||
rubyzip (1.2.2)
|
||||
sass (3.7.3)
|
||||
rubyzip (1.2.3)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
@@ -448,13 +465,13 @@ GEM
|
||||
sassc (2.0.1)
|
||||
ffi (~> 1.9)
|
||||
rake
|
||||
sassc-rails (2.1.0)
|
||||
sassc-rails (2.1.2)
|
||||
railties (>= 4.0.0)
|
||||
sassc (>= 2.0)
|
||||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
scout_apm (2.4.24)
|
||||
scout_apm (2.5.1)
|
||||
searchkick (4.0.2)
|
||||
activemodel (>= 5)
|
||||
elasticsearch (>= 6)
|
||||
@@ -462,13 +479,13 @@ GEM
|
||||
selenium-webdriver (3.142.3)
|
||||
childprocess (>= 0.5, < 2.0)
|
||||
rubyzip (~> 1.2, >= 1.2.2)
|
||||
sexp_processor (4.12.0)
|
||||
sexp_processor (4.12.1)
|
||||
sidekiq (5.2.7)
|
||||
connection_pool (~> 2.2, >= 2.2.2)
|
||||
rack (>= 1.5.0)
|
||||
rack-protection (>= 1.5.0)
|
||||
redis (>= 3.3.5, < 5)
|
||||
simplecov (0.12.0)
|
||||
simplecov (0.13.0)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
@@ -482,20 +499,23 @@ GEM
|
||||
sprockets (>= 3.0.0)
|
||||
sysexits (1.2.0)
|
||||
temple (0.8.1)
|
||||
term-ansicolor (1.7.0)
|
||||
term-ansicolor (1.7.1)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thor (0.19.4)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.9)
|
||||
timecop (0.9.1)
|
||||
tins (1.20.2)
|
||||
tins (1.20.3)
|
||||
trollop (1.16.2)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (4.1.20)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.6)
|
||||
unicode-display_width (1.6.0)
|
||||
unicorn (5.5.1)
|
||||
kgio (~> 2.6)
|
||||
@@ -503,14 +523,20 @@ GEM
|
||||
uniform_notifier (1.12.1)
|
||||
warden (1.2.8)
|
||||
rack (>= 2.0.6)
|
||||
webdrivers (4.1.0)
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (~> 1.0)
|
||||
selenium-webdriver (>= 3.0, < 4.0)
|
||||
webrat (0.7.3)
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
websocket-driver (0.7.0)
|
||||
websocket-driver (0.7.1)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
websocket-extensions (0.1.4)
|
||||
will_paginate (3.1.7)
|
||||
will_paginate-bootstrap4 (0.2.2)
|
||||
will_paginate (~> 3.0, >= 3.0.0)
|
||||
xmlrpc (0.3.0)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
@@ -520,13 +546,15 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
active_median (= 0.1.4)
|
||||
active_record_union
|
||||
active_utils
|
||||
better_errors
|
||||
bluecloth
|
||||
bonsai-elasticsearch-rails
|
||||
bootstrap (>= 4.3.1)
|
||||
bootstrap-datepicker-rails
|
||||
bootstrap-kaminari-views
|
||||
bootstrap-sass
|
||||
bootstrap_form (>= 4.2.0)
|
||||
bullet
|
||||
bundler (>= 1.1.5)
|
||||
byebug
|
||||
@@ -543,6 +571,7 @@ DEPENDENCIES
|
||||
dalli
|
||||
database_cleaner
|
||||
devise
|
||||
elasticsearch (< 7.0.0)
|
||||
factory_bot_rails
|
||||
faker
|
||||
figaro
|
||||
@@ -558,7 +587,6 @@ DEPENDENCIES
|
||||
haml_lint (>= 0.25.1)
|
||||
hashie (>= 3.5.3)
|
||||
i18n-tasks
|
||||
isotope-rails
|
||||
jquery-rails
|
||||
jquery-ui-rails
|
||||
js-routes
|
||||
@@ -568,6 +596,8 @@ DEPENDENCIES
|
||||
letter_opener
|
||||
listen
|
||||
loofah (>= 2.2.1)
|
||||
material-sass (= 4.1.1)
|
||||
material_icons
|
||||
memcachier
|
||||
newrelic_rpm
|
||||
oj
|
||||
@@ -579,7 +609,6 @@ DEPENDENCIES
|
||||
percy-capybara (~> 4.0.0)
|
||||
pg (< 1.0.0)
|
||||
platform-api
|
||||
poltergeist
|
||||
puma
|
||||
rack-protection (>= 2.0.1)
|
||||
rails (= 5.2.2.1)
|
||||
@@ -590,7 +619,8 @@ DEPENDENCIES
|
||||
responders
|
||||
rspec-activemodel-mocks
|
||||
rspec-rails
|
||||
rubocop (~> 0.70)
|
||||
rubocop (~> 0.71)
|
||||
rubocop-rails
|
||||
rubocop-rspec
|
||||
ruby-units
|
||||
sass-rails
|
||||
@@ -601,12 +631,14 @@ DEPENDENCIES
|
||||
timecop
|
||||
uglifier
|
||||
unicorn
|
||||
webdrivers
|
||||
webrat
|
||||
will_paginate
|
||||
will_paginate-bootstrap4
|
||||
xmlrpc
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.6.0p0
|
||||
ruby 2.6.3p62
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.2
|
||||
1.17.3
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
Welcome to the Growstuff project.
|
||||
|
||||
You can find our app at https://www.growstuff.org
|
||||
|
||||
Growstuff is an open source/open data project to create a website for
|
||||
food gardeners. We crowdsource information on what our members are
|
||||
growing and harvesting, aggregate it, and make it available as open data
|
||||
|
||||
2
app.json
@@ -3,7 +3,7 @@
|
||||
"stack": "heroku-18",
|
||||
"description": "Open data project for small-scale food growers",
|
||||
"scripts": {
|
||||
"postdeploy": "bundle exec rails db:migrate db:seed"
|
||||
"postdeploy": "bundle exec rails db:seed"
|
||||
},
|
||||
"env": {
|
||||
"GROWSTUFF_ELASTICSEARCH": {
|
||||
|
||||
11
app/assets/images/icons/delete.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48" version="1.1" width="96px" height="96px">
|
||||
<g id="surface1">
|
||||
<path style=" fill:#9FA8DA;" d="M 12 13 L 12 38 C 12 40.210938 13.789063 42 16 42 L 32 42 C 34.210938 42 36 40.210938 36 38 L 36 13 Z "/>
|
||||
<path style=" fill:#7986CB;" d="M 23 15 L 25 15 L 25 38 L 23 38 Z "/>
|
||||
<path style=" fill:#7986CB;" d="M 29 15 L 31 15 L 31 38 L 29 38 Z "/>
|
||||
<path style=" fill:#7986CB;" d="M 17 15 L 19 15 L 19 38 L 17 38 Z "/>
|
||||
<path style=" fill:#5C6BC0;" d="M 10 11 L 38 11 L 38 15 L 10 15 Z "/>
|
||||
<path style=" fill:#5C6BC0;" d="M 21.800781 13.027344 C 21.308594 12.492188 21 11.785156 21 11 C 21 9.34375 22.34375 8 24 8 C 25.65625 8 27 9.34375 27 11 C 27 11.785156 26.691406 12.492188 26.199219 13.027344 L 28.5625 13.027344 C 28.839844 12.40625 29 11.722656 29 11 C 29 8.238281 26.761719 6 24 6 C 21.238281 6 19 8.238281 19 11 C 19 11.722656 19.160156 12.40625 19.4375 13.027344 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1022 B |
23
app/assets/images/icons/finished.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48" version="1.1" width="96px" height="96px">
|
||||
<g id="surface1">
|
||||
<path style=" fill:#CFD8DC;" d="M 5 38 L 5 14 L 43 14 L 43 38 C 43 40.199219 41.199219 42 39 42 L 9 42 C 6.800781 42 5 40.199219 5 38 Z "/>
|
||||
<path style=" fill:#F44336;" d="M 43 10 L 43 16 L 5 16 L 5 10 C 5 7.800781 6.800781 6 9 6 L 39 6 C 41.199219 6 43 7.800781 43 10 Z "/>
|
||||
<path style=" fill:#B71C1C;" d="M 36 10 C 36 11.65625 34.65625 13 33 13 C 31.34375 13 30 11.65625 30 10 C 30 8.34375 31.34375 7 33 7 C 34.65625 7 36 8.34375 36 10 Z "/>
|
||||
<path style=" fill:#B71C1C;" d="M 18 10 C 18 11.65625 16.65625 13 15 13 C 13.34375 13 12 11.65625 12 10 C 12 8.34375 13.34375 7 15 7 C 16.65625 7 18 8.34375 18 10 Z "/>
|
||||
<path style=" fill:#B0BEC5;" d="M 33 3 C 31.898438 3 31 3.898438 31 5 L 31 10 C 31 11.101563 31.898438 12 33 12 C 34.101563 12 35 11.101563 35 10 L 35 5 C 35 3.898438 34.101563 3 33 3 Z "/>
|
||||
<path style=" fill:#B0BEC5;" d="M 15 3 C 13.898438 3 13 3.898438 13 5 L 13 10 C 13 11.101563 13.898438 12 15 12 C 16.101563 12 17 11.101563 17 10 L 17 5 C 17 3.898438 16.101563 3 15 3 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 13 20 L 17 20 L 17 24 L 13 24 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 19 20 L 23 20 L 23 24 L 19 24 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 25 20 L 29 20 L 29 24 L 25 24 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 31 20 L 35 20 L 35 24 L 31 24 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 13 26 L 17 26 L 17 30 L 13 30 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 19 26 L 23 26 L 23 30 L 19 30 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 25 26 L 29 26 L 29 30 L 25 30 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 31 26 L 35 26 L 35 30 L 31 30 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 13 32 L 17 32 L 17 36 L 13 36 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 19 32 L 23 32 L 23 36 L 19 36 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 25 32 L 29 32 L 29 36 L 25 36 Z "/>
|
||||
<path style=" fill:#90A4AE;" d="M 31 32 L 35 32 L 35 36 L 31 36 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
26
app/assets/images/icons/garden.svg
Normal file
@@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" fill:#2E7D32;" d="M 30 11.5 C 30 14.539063 27.539063 17 24.5 17 C 21.460938 17 19 14.539063 19 11.5 C 19 8.460938 21.460938 6 24.5 6 C 27.539063 6 30 8.460938 30 11.5 Z "/>
|
||||
<path style=" fill:#2E7D32;" d="M 41 16.5 C 41 18.984375 38.984375 21 36.5 21 C 34.015625 21 32 18.984375 32 16.5 C 32 14.015625 34.015625 12 36.5 12 C 38.984375 12 41 14.015625 41 16.5 Z "/>
|
||||
<path style=" fill:#388E3C;" d="M 22 14 C 22 16.761719 19.761719 19 17 19 C 14.238281 19 12 16.761719 12 14 C 12 11.238281 14.238281 9 17 9 C 19.761719 9 22 11.238281 22 14 Z "/>
|
||||
<path style=" fill:#388E3C;" d="M 12 19.5 C 12 21.433594 10.433594 23 8.5 23 C 6.566406 23 5 21.433594 5 19.5 C 5 17.566406 6.566406 16 8.5 16 C 10.433594 16 12 17.566406 12 19.5 Z "/>
|
||||
<path style=" fill:#388E3C;" d="M 43 19.5 C 43 21.433594 41.433594 23 39.5 23 C 37.566406 23 36 21.433594 36 19.5 C 36 17.566406 37.566406 16 39.5 16 C 41.433594 16 43 17.566406 43 19.5 Z "/>
|
||||
<path style=" fill:#388E3C;" d="M 35 14 C 35 16.761719 32.761719 19 30 19 C 27.238281 19 25 16.761719 25 14 C 25 11.238281 27.238281 9 30 9 C 32.761719 9 35 11.238281 35 14 Z "/>
|
||||
<path style=" fill:#4CAF50;" d="M 26 19 C 26 21.761719 23.761719 24 21 24 C 18.238281 24 16 21.761719 16 19 C 16 16.238281 18.238281 14 21 14 C 23.761719 14 26 16.238281 26 19 Z "/>
|
||||
<path style=" fill:#4CAF50;" d="M 18 17 C 18 19.761719 15.761719 22 13 22 C 10.238281 22 8 19.761719 8 17 C 8 14.238281 10.238281 12 13 12 C 15.761719 12 18 14.238281 18 17 Z "/>
|
||||
<path style=" fill:#4CAF50;" d="M 38 20 C 38 22.210938 36.210938 24 34 24 C 31.789063 24 30 22.210938 30 20 C 30 17.789063 31.789063 16 34 16 C 36.210938 16 38 17.789063 38 20 Z "/>
|
||||
<path style=" fill:#9CCC65;" d="M 31 19.5 C 31 21.433594 29.433594 23 27.5 23 C 25.566406 23 24 21.433594 24 19.5 C 24 17.566406 25.566406 16 27.5 16 C 29.433594 16 31 17.566406 31 19.5 Z "/>
|
||||
<path style=" fill:#9CCC65;" d="M 18 18.5 C 18 19.878906 16.878906 21 15.5 21 C 14.121094 21 13 19.878906 13 18.5 C 13 17.121094 14.121094 16 15.5 16 C 16.878906 16 18 17.121094 18 18.5 Z "/>
|
||||
<path style=" fill:#795548;" d="M 5 20 L 43 20 L 43 42 L 5 42 Z "/>
|
||||
<path style=" fill:#4E342E;" d="M 5 26 L 43 26 L 43 28 L 5 28 Z "/>
|
||||
<path style=" fill:#4E342E;" d="M 5 34 L 43 34 L 43 36 L 5 36 Z "/>
|
||||
<path style=" fill:#8D6E63;" d="M 9 20 L 13 20 L 13 42 L 9 42 Z "/>
|
||||
<path style=" fill:#8D6E63;" d="M 35 20 L 39 20 L 39 42 L 35 42 Z "/>
|
||||
<path style=" fill:#6D4C41;" d="M 7 20 L 9 20 L 9 42 L 7 42 Z "/>
|
||||
<path style=" fill:#6D4C41;" d="M 33 20 L 35 20 L 35 42 L 33 42 Z "/>
|
||||
<path style=" fill:#3E2723;" d="M 7 26 L 9 26 L 9 28 L 7 28 Z "/>
|
||||
<path style=" fill:#3E2723;" d="M 7 34 L 9 34 L 9 36 L 7 36 Z "/>
|
||||
<path style=" fill:#3E2723;" d="M 33 26 L 35 26 L 35 28 L 33 28 Z "/>
|
||||
<path style=" fill:#3E2723;" d="M 33 34 L 35 34 L 35 36 L 33 36 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
5
app/assets/images/icons/harvest.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" " d="M 7.304688 4 L 4.664063 11.042969 L 6.804688 11.042969 L 8.695313 6 L 23.308594 6 L 25.199219 11.042969 L 27.332031 11.042969 L 24.691406 4 Z M 2 12 L 2 18 L 3.257813 18 L 6.257813 28 L 25.746094 28 L 28.746094 18 L 30 18 L 30 12 Z M 4 14 L 28 14 L 28 16 L 27.253906 16 L 24.253906 26 L 7.742188 26 L 4.742188 16 L 4 16 Z M 11 17 L 11 24 L 13 24 L 13 17 Z M 15 17 L 15 24 L 17 24 L 17 17 Z M 19 17 L 19 24 L 21 24 L 21 17 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 633 B |
5
app/assets/images/icons/home.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" " d="M 16 2.59375 L 15.28125 3.28125 L 2.28125 16.28125 L 3.71875 17.71875 L 5 16.4375 L 5 28 L 14 28 L 14 18 L 18 18 L 18 28 L 27 28 L 27 16.4375 L 28.28125 17.71875 L 29.71875 16.28125 L 16.71875 3.28125 Z M 16 5.4375 L 25 14.4375 L 25 26 L 20 26 L 20 16 L 12 16 L 12 26 L 7 26 L 7 14.4375 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 498 B |
3
app/assets/images/icons/plant-seeds.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="100" height="100" fill="000000">
|
||||
<path d="M 12.457031 4 C 12.303766 4.0054531 12.180109 4.0547969 12.099609 4.1542969 C 11.777609 4.5522969 12.255016 5.5897031 13.166016 6.4707031 C 14.077016 7.3517031 15.076437 7.7427031 15.398438 7.3457031 C 15.720438 6.9477031 15.243031 5.9102969 14.332031 5.0292969 C 13.648781 4.3685469 12.916828 3.9836406 12.457031 4 z M 18.273438 7.0078125 C 17.745498 7.0965566 17.100062 7.9065781 16.742188 8.9863281 C 16.333187 10.220328 16.453766 11.339375 17.009766 11.484375 C 17.565766 11.629375 18.348813 10.745719 18.757812 9.5117188 C 19.166812 8.2777187 19.046234 7.160625 18.490234 7.015625 C 18.420734 6.9975 18.348857 6.9951348 18.273438 7.0078125 z M 10.966797 9.0019531 C 10.493797 8.9824531 10.145656 9.0859531 10.035156 9.3144531 C 9.8141562 9.7714531 10.626609 10.561125 11.849609 11.078125 C 13.072609 11.595125 14.243844 11.643547 14.464844 11.185547 C 14.685844 10.728547 13.873391 9.938875 12.650391 9.421875 C 12.038891 9.163375 11.439797 9.0214531 10.966797 9.0019531 z M 3 14 L 3 16 L 9.203125 16 C 9.709475 19.363146 12.49988 22 16 22 C 19.50012 22 22.290525 19.363146 22.796875 16 L 29 16 L 29 14 L 21 14 L 21 15 C 21 17.773666 18.773666 20 16 20 C 13.226334 20 11 17.773666 11 15 L 11 14 L 3 14 z M 15.830078 14.001953 A 2.5 0.99900001 0.361 0 0 13.5 14.984375 A 2.5 0.99900001 0.361 0 0 15.994141 15.998047 A 2.5 0.99900001 0.361 0 0 18.5 15.015625 A 2.5 0.99900001 0.361 0 0 16.005859 14.001953 A 2.5 0.99900001 0.361 0 0 15.830078 14.001953 z M 7 17 A 1 1 0 0 0 6 18 A 1 1 0 0 0 7 19 A 1 1 0 0 0 8 18 A 1 1 0 0 0 7 17 z M 25 17 A 1 1 0 0 0 24 18 A 1 1 0 0 0 25 19 A 1 1 0 0 0 26 18 A 1 1 0 0 0 25 17 z M 4 20 A 1 1 0 0 0 3 21 A 1 1 0 0 0 4 22 A 1 1 0 0 0 5 21 A 1 1 0 0 0 4 20 z M 10 20 A 1 1 0 0 0 9 21 A 1 1 0 0 0 10 22 A 1 1 0 0 0 11 21 A 1 1 0 0 0 10 20 z M 22 20 A 1 1 0 0 0 21 21 A 1 1 0 0 0 22 22 A 1 1 0 0 0 23 21 A 1 1 0 0 0 22 20 z M 28 20 A 1 1 0 0 0 27 21 A 1 1 0 0 0 28 22 A 1 1 0 0 0 29 21 A 1 1 0 0 0 28 20 z M 7 23 A 1 1 0 0 0 6 24 A 1 1 0 0 0 7 25 A 1 1 0 0 0 8 24 A 1 1 0 0 0 7 23 z M 13 23 A 1 1 0 0 0 12 24 A 1 1 0 0 0 13 25 A 1 1 0 0 0 14 24 A 1 1 0 0 0 13 23 z M 19 23 A 1 1 0 0 0 18 24 A 1 1 0 0 0 19 25 A 1 1 0 0 0 20 24 A 1 1 0 0 0 19 23 z M 25 23 A 1 1 0 0 0 24 24 A 1 1 0 0 0 25 25 A 1 1 0 0 0 26 24 A 1 1 0 0 0 25 23 z M 4 26 A 1 1 0 0 0 3 27 A 1 1 0 0 0 4 28 A 1 1 0 0 0 5 27 A 1 1 0 0 0 4 26 z M 10 26 A 1 1 0 0 0 9 27 A 1 1 0 0 0 10 28 A 1 1 0 0 0 11 27 A 1 1 0 0 0 10 26 z M 16 26 A 1 1 0 0 0 15 27 A 1 1 0 0 0 16 28 A 1 1 0 0 0 17 27 A 1 1 0 0 0 16 26 z M 22 26 A 1 1 0 0 0 21 27 A 1 1 0 0 0 22 28 A 1 1 0 0 0 23 27 A 1 1 0 0 0 22 26 z M 28 26 A 1 1 0 0 0 27 27 A 1 1 0 0 0 28 28 A 1 1 0 0 0 29 27 A 1 1 0 0 0 28 26 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
5
app/assets/images/icons/planting.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" " d="M 23.398438 14.023438 C 23.058594 14.042969 22.835938 13.933594 22.808594 13.914063 L 21.121094 14.992188 C 21.492188 15.574219 22.257813 15.96875 23.117188 16.019531 C 23.183594 16.023438 23.25 16.023438 23.316406 16.023438 C 24.445313 16.023438 25.554688 15.453125 26.394531 14.4375 C 27.828125 12.695313 28.835938 10.847656 28.878906 10.769531 L 29.332031 9.929688 L 28.515625 9.4375 C 23.984375 6.714844 21.394531 8.007813 20.492188 8.691406 C 19.328125 9.574219 18.796875 11.019531 19.089844 12.429688 C 18.160156 13.023438 17.234375 13.773438 16.496094 14.6875 C 16.070313 13.691406 15.40625 12.796875 14.632813 12.007813 C 14.703125 11.824219 14.75 11.644531 14.78125 11.511719 C 14.796875 11.441406 14.8125 11.375 14.832031 11.316406 C 15.34375 9.601563 14.640625 7.601563 13.082031 6.34375 C 11.972656 5.449219 8.820313 3.683594 3.519531 6.605469 L 2.835938 6.980469 L 3.03125 7.730469 C 3.070313 7.882813 4.015625 11.445313 5.894531 13.53125 C 6.707031 14.433594 7.726563 14.941406 8.847656 14.996094 C 8.917969 15 8.988281 15 9.054688 15 C 10.3125 15 11.390625 14.441406 11.828125 14.042969 L 10.484375 12.5625 C 10.46875 12.574219 8.789063 13.753906 7.382813 12.191406 C 6.292969 10.984375 5.550781 9.046875 5.199219 7.984375 C 8.984375 6.160156 11.078125 7.296875 11.824219 7.898438 C 12.699219 8.605469 13.132813 9.648438 12.953125 10.554688 C 10.800781 8.960938 8.558594 8.070313 8.378906 8.003906 L 7.65625 9.867188 C 9.699219 10.65625 15 13.484375 15 17 L 15 20.144531 C 14.238281 20.34375 13.542969 20.753906 13.019531 21.34375 C 12.550781 21.117188 12.035156 21 11.5 21 C 10.070313 21 8.839844 21.859375 8.296875 23.09375 C 8.035156 23.03125 7.769531 23 7.5 23 C 5.570313 23 4 24.570313 4 26.5 L 4 27 L 6 27 L 6 26.5 C 6 25.671875 6.671875 25 7.5 25 C 7.902344 25 8.210938 25.167969 8.398438 25.308594 L 10 24.511719 L 10 24.496094 C 10.003906 23.671875 10.675781 23 11.5 23 C 11.902344 23 12.28125 23.160156 12.566406 23.449219 L 14.1875 23.167969 C 14.515625 22.457031 15.226563 22 16 22 C 16.726563 22 17.398438 22.40625 17.75 23.0625 L 19.328125 23.304688 C 19.527344 23.109375 19.792969 23 20.070313 23 C 20.65625 23 21.136719 23.480469 21.136719 24.066406 C 21.136719 24.183594 21.113281 24.300781 21.066406 24.429688 L 22.671875 25.519531 C 22.9375 25.28125 23.382813 25 24 25 C 25.101563 25 26 25.898438 26 27 L 28 27 C 28 24.792969 26.207031 23 24 23 C 23.65625 23 23.316406 23.046875 22.992188 23.132813 C 22.59375 21.894531 21.433594 21 20.070313 21 C 19.652344 21 19.253906 21.082031 18.878906 21.238281 C 18.367188 20.703125 17.714844 20.332031 17 20.144531 L 17 19 L 17.003906 19 L 17.003906 18.671875 C 17.003906 14.519531 23.535156 12.53125 23.601563 12.511719 L 23.039063 10.59375 C 22.9375 10.621094 22.121094 10.871094 21.046875 11.363281 C 21.125 10.949219 21.339844 10.5625 21.703125 10.289063 C 22.761719 9.484375 24.558594 9.636719 26.617188 10.675781 C 26.214844 11.332031 25.589844 12.273438 24.851563 13.167969 C 24.300781 13.835938 23.757813 14.003906 23.398438 14.023438 Z M 13.484375 10.820313 L 13.496094 10.976563 C 13.445313 10.9375 13.390625 10.898438 13.339844 10.855469 C 13.386719 10.84375 13.429688 10.824219 13.484375 10.820313 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
6
app/assets/images/icons/post.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" version="1.1" width="96px" height="96px">
|
||||
<g id="surface1">
|
||||
<path style=" " d="M 2 5 L 2 21 L 6 21 L 6 26.09375 L 7.625 24.78125 L 12.34375 21 L 22 21 L 22 5 Z M 4 7 L 20 7 L 20 19 L 11.65625 19 L 11.375 19.21875 L 8 21.90625 L 8 19 L 4 19 Z M 24 9 L 24 11 L 28 11 L 28 23 L 24 23 L 24 25.90625 L 20.34375 23 L 12.84375 23 L 10.34375 25 L 19.65625 25 L 26 30.09375 L 26 25 L 30 25 L 30 9 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 548 B |
18
app/assets/images/icons/seeds-colour.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" fill:#E0AC6E;" d="M 36 20 L 16 6 L 4 23 L 25 37 L 31 37 L 38.070313 25.394531 Z "/>
|
||||
<path style=" fill:#5D4037;" d="M 36.484375 35.726563 C 37.742188 36.925781 39.226563 37.355469 39.78125 36.679688 C 40.34375 36 39.773438 34.476563 38.515625 33.273438 C 37.253906 32.074219 35.777344 31.644531 35.214844 32.320313 C 34.652344 32.996094 35.226563 34.523438 36.484375 35.726563 Z "/>
|
||||
<path style=" fill:#5D4037;" d="M 30.359375 38.433594 C 31.976563 39.203125 33.578125 39.183594 33.929688 38.390625 C 34.285156 37.597656 33.257813 36.328125 31.640625 35.5625 C 30.023438 34.796875 28.421875 34.8125 28.070313 35.605469 C 27.714844 36.398438 28.742188 37.664063 30.359375 38.433594 Z "/>
|
||||
<path style=" fill:#5D4037;" d="M 29.484375 31.726563 C 30.742188 32.925781 32.226563 33.355469 32.78125 32.679688 C 33.34375 32 32.773438 30.476563 31.515625 29.273438 C 30.253906 28.074219 28.777344 27.644531 28.214844 28.320313 C 27.652344 28.996094 28.226563 30.523438 29.484375 31.726563 Z "/>
|
||||
<path style=" fill:#5D4037;" d="M 43 41.5 C 43 40.671875 41.65625 40 40 40 C 38.34375 40 37 40.671875 37 41.5 C 37 42.328125 38.34375 43 40 43 C 41.65625 43 43 42.328125 43 41.5 Z "/>
|
||||
<path style=" fill:#FFCC80;" d="M 16 6 L 18.214844 11.652344 L 10 23 L 4 23 L 25 37 L 36 20 Z "/>
|
||||
<path style=" fill:#558B2F;" d="M 28 23 C 28 26.316406 25.316406 29 22 29 C 18.683594 29 16 26.316406 16 23 C 16 19.683594 18.683594 17 22 17 C 25.316406 17 28 19.683594 28 23 "/>
|
||||
<path style=" fill:#FFFFFF;" d="M 20.535156 19.941406 C 20.535156 19.113281 21.191406 18.445313 22 18.445313 C 22.808594 18.445313 23.464844 19.113281 23.464844 19.941406 C 23.464844 20.773438 22 22.945313 22 22.945313 C 22 22.945313 20.535156 20.773438 20.535156 19.941406 "/>
|
||||
<path style=" fill:#FFFFFF;" d="M 23.464844 25.945313 C 23.464844 26.777344 22.808594 27.445313 22 27.445313 C 21.191406 27.445313 20.535156 26.777344 20.535156 25.945313 C 20.535156 25.113281 22 22.945313 22 22.945313 C 22 22.945313 23.464844 25.113281 23.464844 25.945313 "/>
|
||||
<path style=" fill:#FFFFFF;" d="M 18.730469 22.742188 C 18.03125 22.328125 17.792969 21.414063 18.195313 20.695313 C 18.597656 19.976563 19.496094 19.730469 20.195313 20.148438 C 20.894531 20.5625 22 22.945313 22 22.945313 C 22 22.945313 19.433594 23.15625 18.730469 22.742188 "/>
|
||||
<path style=" fill:#FFFFFF;" d="M 25.269531 23.144531 C 25.96875 23.5625 26.207031 24.476563 25.804688 25.195313 C 25.402344 25.914063 24.503906 26.160156 23.804688 25.742188 C 23.101563 25.328125 22 22.945313 22 22.945313 C 22 22.945313 24.566406 22.730469 25.269531 23.144531 "/>
|
||||
<path style=" fill:#FFFFFF;" d="M 25.269531 22.742188 C 25.96875 22.328125 26.207031 21.414063 25.804688 20.695313 C 25.402344 19.976563 24.503906 19.730469 23.804688 20.148438 C 23.101563 20.5625 22 22.945313 22 22.945313 C 22 22.945313 24.566406 23.15625 25.269531 22.742188 "/>
|
||||
<path style=" fill:#FFFFFF;" d="M 18.730469 23.144531 C 18.03125 23.5625 17.792969 24.476563 18.195313 25.195313 C 18.597656 25.914063 19.496094 26.160156 20.195313 25.742188 C 20.894531 25.328125 22 22.945313 22 22.945313 C 22 22.945313 19.433594 22.730469 18.730469 23.144531 "/>
|
||||
<path style=" fill:#FFC107;" d="M 23.5 23 C 23.5 23.828125 22.828125 24.5 22 24.5 C 21.171875 24.5 20.5 23.828125 20.5 23 C 20.5 22.171875 21.171875 21.5 22 21.5 C 22.828125 21.5 23.5 22.171875 23.5 23 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
5
app/assets/images/icons/seeds.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" " d="M 10.84375 2 L 10.28125 2.8125 L 2.53125 14.46875 L 1.96875 15.3125 L 2.8125 15.84375 L 8.84375 19.875 L 13.5 22.9375 L 15.03125 22.25 C 15.148438 21.535156 15.746094 21 16.5 21 C 16.777344 21 17.265625 21.195313 17.5 21.375 L 19.09375 20.5625 C 19.09375 19.667969 19.691406 19 20.5 19 C 20.832031 19 21.117188 19.121094 21.375 19.3125 L 22.8125 19.0625 L 24.46875 16.59375 L 26.5 13.5625 L 27.03125 12.71875 L 26.21875 12.15625 L 11.6875 2.53125 Z M 11.40625 4.78125 L 24.25 13.28125 L 22.8125 15.46875 L 21.5625 17.34375 C 21.207031 17.21875 20.898438 17 20.5 17 C 19 17 17.820313 18.003906 17.34375 19.3125 C 17.046875 19.230469 16.828125 19 16.5 19 C 15.285156 19 14.375 19.738281 13.75 20.6875 L 9.96875 18.1875 L 4.75 14.75 Z M 13.9375 9 C 13.242188 9.007813 12.566406 9.378906 12.21875 10.125 L 12.03125 10.53125 L 11.625 10.59375 C 10.03125 10.855469 9.421875 12.863281 10.59375 14 L 10.90625 14.28125 L 10.84375 14.6875 C 10.59375 16.316406 12.269531 17.539063 13.6875 16.75 L 14.0625 16.5625 L 14.40625 16.75 C 15.84375 17.496094 17.515625 16.214844 17.21875 14.59375 L 17.125 14.1875 L 17.4375 13.90625 C 18.578125 12.738281 17.910156 10.746094 16.3125 10.53125 L 15.90625 10.46875 L 15.71875 10.09375 C 15.351563 9.359375 14.632813 8.992188 13.9375 9 Z M 14 12 C 14.550781 12 15 12.449219 15 13 C 14.996094 13.554688 14.550781 14 14 14 C 13.449219 14 13 13.554688 13 13 C 13 12.449219 13.445313 11.996094 14 12 Z M 22.1875 21.78125 C 22.039063 21.777344 21.925781 21.820313 21.84375 21.90625 C 21.515625 22.242188 21.9375 23.179688 22.78125 24 C 23.625 24.820313 24.546875 25.210938 24.875 24.875 C 25.203125 24.539063 24.8125 23.601563 23.96875 22.78125 C 23.335938 22.167969 22.632813 21.789063 22.1875 21.78125 Z M 27.25 22.9375 C 26.855469 23.078125 26.445313 23.859375 26.3125 24.84375 C 26.160156 25.96875 26.425781 26.9375 26.875 27 C 27.324219 27.0625 27.816406 26.1875 27.96875 25.0625 C 28.121094 23.9375 27.855469 23 27.40625 22.9375 C 27.351563 22.929688 27.304688 22.917969 27.25 22.9375 Z M 22.09375 26 C 21.703125 26.003906 21.402344 26.125 21.3125 26.34375 C 21.132813 26.777344 21.804688 27.457031 22.8125 27.875 C 23.820313 28.292969 24.789063 28.277344 24.96875 27.84375 C 25.148438 27.410156 24.476563 26.730469 23.46875 26.3125 C 22.964844 26.105469 22.484375 25.996094 22.09375 26 Z M 27.875 28.3125 C 26.699219 28.3125 25.75 28.6875 25.75 29.15625 C 25.75 29.625 26.699219 30 27.875 30 C 29.050781 30 30 29.625 30 29.15625 C 30 28.6875 29.050781 28.3125 27.875 28.3125 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
5
app/assets/images/icons/trade.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" version="1.1" width="100" height="100" fill="000000">
|
||||
<g id="surface1">
|
||||
<path style=" " d="M 16 4 C 9.382813 4 4 9.382813 4 16 C 4 19.070313 5.15625 21.875 7.0625 24 L 5 24 L 5 26 L 11 26 L 11 20 L 9 20 L 9 23.125 C 7.15625 21.3125 6 18.792969 6 16 C 6 10.464844 10.464844 6 16 6 Z M 18.25 4.21875 L 17.6875 6.15625 C 18.347656 6.269531 19.003906 6.445313 19.625 6.6875 L 20.15625 4.75 C 19.53125 4.519531 18.90625 4.34375 18.25 4.21875 Z M 21 6 L 21 12 L 23 12 L 23 8.875 C 24.847656 10.683594 26 13.199219 26 16 C 26 21.535156 21.535156 26 16 26 L 16 28 C 22.617188 28 28 22.617188 28 16 C 28 12.921875 26.820313 10.121094 24.90625 8 L 27 8 L 27 6 Z M 12.375 25.3125 L 11.84375 27.25 C 12.46875 27.480469 13.09375 27.65625 13.75 27.78125 L 14.3125 25.84375 C 13.652344 25.730469 12.996094 25.554688 12.375 25.3125 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 936 B |
@@ -13,10 +13,12 @@
|
||||
// = require leaflet
|
||||
// = require leaflet.markercluster
|
||||
// = require js-routes
|
||||
// = require popper
|
||||
// = require jquery
|
||||
// = require jquery_ujs
|
||||
// = require jquery-ui/widgets/autocomplete
|
||||
// = require bootstrap-sprockets
|
||||
// = require bootstrap-datepicker
|
||||
// = require isotope
|
||||
// = require bootstrap
|
||||
// = require material
|
||||
// = require_tree .
|
||||
|
||||
@@ -31,7 +31,7 @@ jQuery ->
|
||||
|
||||
if el.data( 'uiAutocomplete' )
|
||||
el.data( 'uiAutocomplete' )._renderItem = ( ul, item ) ->
|
||||
$( '<li></li>' )
|
||||
$( '<li class="list-group-item"></li>' )
|
||||
.data( 'item.autocomplete', item )
|
||||
.append( "<a>#{item.name}</a>" )
|
||||
.appendTo( ul )
|
||||
|
||||
1
app/assets/javascripts/nav.js
Normal file
@@ -0,0 +1 @@
|
||||
$('.dropdown-toggle').dropdown();
|
||||
@@ -1,8 +0,0 @@
|
||||
$('.planting-facts').isotope({
|
||||
layoutMode: 'fitRows',
|
||||
percentPosition: true,
|
||||
itemSelector: '.fact',
|
||||
fitRows: {
|
||||
gutter: 10,
|
||||
},
|
||||
});
|
||||
21
app/assets/stylesheets/_crops.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
.planting {
|
||||
.crop-card {
|
||||
height: 100%;
|
||||
margin: .1em;
|
||||
min-height: 300px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.img-thumbnail {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.crop-photos {
|
||||
margin-left: 3em;
|
||||
}
|
||||
|
||||
.crops-search-form {
|
||||
background-color: $white;
|
||||
padding: 1em;
|
||||
}
|
||||
0
app/assets/stylesheets/_harvests.scss
Normal file
76
app/assets/stylesheets/_homepage.scss
Normal file
@@ -0,0 +1,76 @@
|
||||
// signup widget on homepage
|
||||
.jumbotron .signup {
|
||||
background-color: lighten($green, 40%);
|
||||
border: 1px solid lighten($green, 20%);
|
||||
border-radius: 6px;
|
||||
line-height: 200%;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.homepage-cards {
|
||||
display: flex;
|
||||
flex: none;
|
||||
flex-wrap: wrap;
|
||||
margin: .5em;
|
||||
// left: -.5em;
|
||||
|
||||
.card {
|
||||
left: -.5em;
|
||||
margin: .5em;
|
||||
min-height: 100px;
|
||||
padding: 0;
|
||||
|
||||
%h3.crop-name {
|
||||
font-size: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.crop-card {
|
||||
min-height: 80px;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
margin: .5em;
|
||||
}
|
||||
|
||||
.img-card {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.member-cards {
|
||||
display: flex;
|
||||
flex: none;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.card {
|
||||
margin: 1em;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.homepage-cards {
|
||||
.seed-card {
|
||||
min-height: 80px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.member-card {
|
||||
min-height: 80px;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
.homepage-cards {
|
||||
.card {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
app/assets/stylesheets/_members.scss
Normal file
@@ -0,0 +1,17 @@
|
||||
.member-thumbnail {
|
||||
border-radius: 12px;
|
||||
height: 200px;
|
||||
margin: 1em;
|
||||
padding: .25em;
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 5em;
|
||||
}
|
||||
}
|
||||
|
||||
.member-thumbnail div ~ div {
|
||||
padding-left: 1em;
|
||||
width: 15em;
|
||||
}
|
||||
56
app/assets/stylesheets/_photos.scss
Normal file
@@ -0,0 +1,56 @@
|
||||
.photo-grid {
|
||||
background: $beige;
|
||||
}
|
||||
|
||||
// clear fix
|
||||
.photo-grid:after {
|
||||
clear: both;
|
||||
content: "";
|
||||
display: block;
|
||||
}
|
||||
|
||||
.photo-grid-item {
|
||||
float: left;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-photo {
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.photo-thumbnail {
|
||||
margin-bottom: 1em;
|
||||
margin-right: 1em;
|
||||
max-width: 150px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text {
|
||||
bottom: 0;
|
||||
color: $black;
|
||||
display: none;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $white;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.text {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
104
app/assets/stylesheets/_plantings.scss
Executable file
@@ -0,0 +1,104 @@
|
||||
.planting {
|
||||
|
||||
.planting-badges {
|
||||
font-size: 1em;
|
||||
position: absolute;
|
||||
top: 3em;
|
||||
.badge-super-late {
|
||||
background-color: $red;
|
||||
}
|
||||
.badge-harvest {
|
||||
background-color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
.planting-thumbnail {
|
||||
padding: 0;
|
||||
width: 150px;
|
||||
|
||||
.badge {
|
||||
font-size: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.planting-full-badges {
|
||||
.badge {
|
||||
font-size: 200%;
|
||||
}
|
||||
}
|
||||
.progress {
|
||||
.progress-bar {
|
||||
border-bottom-color: $green;
|
||||
}
|
||||
.progress-bar:after {
|
||||
background-color: $beige;
|
||||
}
|
||||
}
|
||||
|
||||
.planting-name {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.planting-quick-actions {
|
||||
background-color: $white;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.planting-thumbnail-photo {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
dl.planting-attributes {
|
||||
dt {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.planting-facts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: none;
|
||||
|
||||
.planting-fact-card {
|
||||
background: $white;
|
||||
background: $white;
|
||||
border-radius: 5%;
|
||||
border: 1px solid lighten($green, 20%);
|
||||
margin: 1em;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
|
||||
strong {
|
||||
font-align: center;
|
||||
font-size: 4em;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h3 {
|
||||
// padding-top: 1em;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
app/assets/stylesheets/_predictions.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
.predictions {
|
||||
.predictions-card {
|
||||
background: $white;
|
||||
border-radius: 5%;
|
||||
border: 1px solid lighten($green, 20%);
|
||||
margin: 1em;
|
||||
max-width: 250px;
|
||||
text-align: center;
|
||||
|
||||
strong {
|
||||
font-align: center;
|
||||
font-size: 4em;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
app/assets/stylesheets/_seeds.scss
Normal file
55
app/assets/stylesheets/_variables.scss
Normal file
@@ -0,0 +1,55 @@
|
||||
//$screen-md-min: 1028px
|
||||
|
||||
// Base colours
|
||||
$beige: #f3f1ee;
|
||||
$brown: #413f3b;
|
||||
|
||||
$green: #5f8e43;
|
||||
$blue: #2f4365;
|
||||
$red: #ff4d43;
|
||||
$orange: #ffa500;
|
||||
$yellow: #b2935c;
|
||||
$white: #fff;
|
||||
|
||||
|
||||
$body-bg: $beige;
|
||||
$text-color: $brown;
|
||||
$link-color: $green;
|
||||
$graph-hover: $orange;
|
||||
|
||||
$primary: (
|
||||
color: $green,
|
||||
dark: darken($green, 20%),
|
||||
light: lighten($green, 20%)
|
||||
);
|
||||
$secondary: (
|
||||
color: $blue,
|
||||
dark: darken($blue, 20%),
|
||||
light: lighten($blue, 20%)
|
||||
);
|
||||
$success: (
|
||||
color: $green,
|
||||
dark: darken($green, 20%),
|
||||
light: lighten($green, 20%)
|
||||
);
|
||||
$danger: (
|
||||
color: $red,
|
||||
dark: darken($red, 20%),
|
||||
light: lighten($red, 20%)
|
||||
);
|
||||
$dark: (
|
||||
color: $brown,
|
||||
dark: darken($brown, 20%),
|
||||
light: lighten($brown, 20%)
|
||||
);
|
||||
|
||||
// Nav bar
|
||||
$navbar-default-bg: $brown;
|
||||
$navbar-default-bg-highlight: $brown;
|
||||
$navbar-default-color: $beige;
|
||||
$navbar-default-link-color: darken($beige, 20%);
|
||||
$navbar-default-link-hover-color: $beige;
|
||||
$navbar-default-link-active-color: darken($beige, 80%);
|
||||
$navbar-default-brand-color: lighten($green, 20%);
|
||||
|
||||
$highest-level: 1070;
|
||||
@@ -1,10 +0,0 @@
|
||||
@import 'jquery-ui/autocomplete'
|
||||
@import 'bootstrap-datepicker'
|
||||
@import 'leaflet'
|
||||
@import 'leaflet.markercluster'
|
||||
@import 'custom_bootstrap/custom_bootstrap'
|
||||
@import 'overrides'
|
||||
@import 'graphs'
|
||||
@import 'predictions'
|
||||
@import 'plantings'
|
||||
@import 'photos'
|
||||
27
app/assets/stylesheets/application.scss
Normal file
@@ -0,0 +1,27 @@
|
||||
// Import original variables so they can be used in overrides
|
||||
|
||||
@import 'variables';
|
||||
@import 'material';
|
||||
|
||||
@import 'jquery-ui/autocomplete';
|
||||
@import 'bootstrap-datepicker';
|
||||
@import 'leaflet';
|
||||
@import 'leaflet.markercluster';
|
||||
|
||||
@import 'predictions';
|
||||
@import 'plantings';
|
||||
@import 'members';
|
||||
@import 'harvests';
|
||||
@import 'seeds';
|
||||
@import 'crops';
|
||||
|
||||
@import 'homepage';
|
||||
@import 'photos';
|
||||
|
||||
// Font Awesome
|
||||
@import 'font-awesome-sprockets';
|
||||
@import 'font-awesome';
|
||||
@import 'material_icons';
|
||||
@import 'rails_bootstrap_forms';
|
||||
|
||||
@import 'overrides';
|
||||
@@ -1,82 +0,0 @@
|
||||
.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;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!! AUTOMATICALLY GENERATED FILE. DO NOT MODIFY !!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// Core variables and mixins
|
||||
@import "bootstrap-sprockets"
|
||||
@import "bootstrap/variables"
|
||||
// Modify this for custom colors, font-sizes, etc
|
||||
@import "custom_bootstrap/variables"
|
||||
@import "bootstrap/mixins"
|
||||
// Modify this for custom mixins
|
||||
@import "custom_bootstrap/mixins"
|
||||
|
||||
// Reset and dependencies
|
||||
@import "bootstrap/normalize"
|
||||
@import "bootstrap/print"
|
||||
@import "bootstrap/glyphicons"
|
||||
|
||||
// Core CSS
|
||||
@import "bootstrap/scaffolding"
|
||||
@import "bootstrap/type"
|
||||
@import "bootstrap/code"
|
||||
@import "bootstrap/grid"
|
||||
@import "bootstrap/tables"
|
||||
@import "bootstrap/forms"
|
||||
@import "bootstrap/buttons"
|
||||
|
||||
// Components
|
||||
@import "bootstrap/component-animations"
|
||||
@import "bootstrap/dropdowns"
|
||||
@import "bootstrap/button-groups"
|
||||
@import "bootstrap/input-groups"
|
||||
@import "bootstrap/navs"
|
||||
@import "bootstrap/navbar"
|
||||
@import "bootstrap/breadcrumbs"
|
||||
@import "bootstrap/pagination"
|
||||
@import "bootstrap/pager"
|
||||
@import "bootstrap/labels"
|
||||
@import "bootstrap/badges"
|
||||
@import "bootstrap/jumbotron"
|
||||
@import "bootstrap/thumbnails"
|
||||
@import "bootstrap/alerts"
|
||||
@import "bootstrap/progress-bars"
|
||||
@import "bootstrap/media"
|
||||
@import "bootstrap/list-group"
|
||||
@import "bootstrap/panels"
|
||||
@import "bootstrap/responsive-embed"
|
||||
@import "bootstrap/wells"
|
||||
@import "bootstrap/close"
|
||||
|
||||
// Components w/ JavaScript
|
||||
@import "bootstrap/modals"
|
||||
@import "bootstrap/tooltip"
|
||||
@import "bootstrap/popovers"
|
||||
@import "bootstrap/carousel"
|
||||
|
||||
// Utility classes
|
||||
@import "bootstrap/utilities"
|
||||
@import "bootstrap/responsive-utilities"
|
||||
@@ -1 +0,0 @@
|
||||
// Use this file to override Twitter Bootstrap mixins or define own mixins.
|
||||
@@ -1,56 +0,0 @@
|
||||
// Use this file to override Twitter Bootstrap variables or define own variables.
|
||||
|
||||
// Import original variables so they can be used in overrides
|
||||
@import 'bootstrap/variables.scss'
|
||||
|
||||
// Base colours
|
||||
|
||||
$beige: #f3f1ee
|
||||
$brown: #413f3b
|
||||
|
||||
$green: #5f8e43
|
||||
$blue: #2f4365
|
||||
$red: #ff4d43
|
||||
$orange: #ffa500
|
||||
$yellow: #b2935c
|
||||
$white: #ffffff
|
||||
|
||||
$body-bg: $beige
|
||||
$text-color: $brown
|
||||
$link-color: $green
|
||||
$graph-hover: $orange
|
||||
|
||||
$brand-primary: $green
|
||||
|
||||
$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
$font-family-serif: Georgia, "Times New Roman", Times, serif
|
||||
$font-family-mono: Monaco, Menlo, Consolas, "Courier New", monospace
|
||||
|
||||
$font-size-base: 14px
|
||||
$font-family-base: $font-family-sans-serif
|
||||
$line-height-base: 1.5
|
||||
$alt-font-family: $font-family-serif
|
||||
|
||||
$headings-font-family: $font-family-sans-serif
|
||||
$headings-font-weight: bold // instead of browser default, bold
|
||||
$headings-color: inherit // empty to use BS default, $textColor
|
||||
|
||||
// Hero unit
|
||||
$jumbotron-bg: darken($body-bg, 10%)
|
||||
|
||||
// Nav bar
|
||||
$navbar-default-bg: $brown
|
||||
$navbar-default-bg-highlight: $brown
|
||||
$navbar-default-color: $beige
|
||||
$navbar-default-link-color: darken($beige, 20%)
|
||||
$navbar-default-link-hover-color: $beige
|
||||
$navbar-default-link-active-color: darken($beige,80%)
|
||||
$navbar-default-brand-color: lighten($green, 20%)
|
||||
|
||||
// Top nav collapse threshold
|
||||
$grid-float-breakpoint: $screen-md-min
|
||||
|
||||
$dropdown-bg: lighten($beige, 10%)
|
||||
$dropdown-link-color: $brown
|
||||
$dropdown-link-hover-color: $brown
|
||||
$dropdown-link-hover-bg: lighten($green, 50%)
|
||||
@@ -1,2 +0,0 @@
|
||||
.bar rect:hover
|
||||
fill: $graph-hover
|
||||
@@ -1,10 +0,0 @@
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip
|
||||
border: none
|
||||
|
||||
.thumbnail
|
||||
background: #fff !important
|
||||
border: solid 1px whitesmoke
|
||||
|
||||
.thumbnail .crop-thumbnail .cropinfo
|
||||
padding-top: 14px
|
||||
13
app/assets/stylesheets/leaflet_overrides.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
background: #fff !important;
|
||||
border: solid 1px whitesmoke;
|
||||
}
|
||||
|
||||
.thumbnail .crop-thumbnail .cropinfo {
|
||||
padding-top: 14px;
|
||||
}
|
||||
@@ -1,371 +0,0 @@
|
||||
@import "bootstrap-sprockets"
|
||||
@import "bootstrap"
|
||||
@import "custom_bootstrap/variables"
|
||||
// this padding needs to be done before the responsive stuff is imported
|
||||
body
|
||||
padding-top: $navbar-height
|
||||
|
||||
// Font Awesome
|
||||
@import "font-awesome-sprockets"
|
||||
@import "font-awesome"
|
||||
|
||||
.list-inline > li.first
|
||||
padding-left: 0px
|
||||
|
||||
.activity-list
|
||||
list-style-type: none
|
||||
padding: 0
|
||||
|
||||
h2
|
||||
font-size: 150%
|
||||
|
||||
h3
|
||||
font-size: 120%
|
||||
|
||||
.main
|
||||
padding-right: 1em
|
||||
|
||||
.navbar .navbar-form
|
||||
padding-top: 0
|
||||
padding-bottom: 0
|
||||
margin-right: 0
|
||||
margin-left: 15px
|
||||
border: 0
|
||||
-webkit-box-shadow: none
|
||||
box-shadow: none
|
||||
|
||||
.img-responsive
|
||||
max-width: 100%
|
||||
height: auto
|
||||
|
||||
.avatar
|
||||
border-radius: 50%
|
||||
z-index: 2
|
||||
position: relative
|
||||
|
||||
.profile-sidebar
|
||||
margin-top: -5rem
|
||||
|
||||
.profile-activity
|
||||
background: white
|
||||
padding: 2em
|
||||
margin-top: 2em
|
||||
.container
|
||||
width: 100%
|
||||
|
||||
.sidebar
|
||||
border-left: 1px solid darken($beige, 10%)
|
||||
margin-left: -1px
|
||||
padding-left: 1em
|
||||
|
||||
// this is used for eg. crops and members index pages
|
||||
.six-across:nth-child(6n+1)
|
||||
margin-left: 0px
|
||||
|
||||
.three-across:nth-child(3n+1)
|
||||
margin-left: 0px
|
||||
clear: both
|
||||
|
||||
// let's condense the hero unit a little
|
||||
.jumbotron
|
||||
padding-top: 30px
|
||||
padding-bottom: 30px
|
||||
|
||||
// info under the main heading on homepage
|
||||
.jumbotron .info
|
||||
padding-top: 15px
|
||||
|
||||
// signup widget on homepage
|
||||
.jumbotron .signup
|
||||
background-color: lighten($green, 40%)
|
||||
border: 1px solid lighten($green, 20%)
|
||||
border-radius: 6px
|
||||
line-height: 200%
|
||||
padding: 15px
|
||||
text-align: center
|
||||
|
||||
// stats shown on homepage. eg. "999 members..."
|
||||
p.stats
|
||||
font-weight: bold
|
||||
|
||||
.member-cards
|
||||
display: flex
|
||||
flex: none
|
||||
flex-wrap: wrap
|
||||
|
||||
.card-row
|
||||
display: grid
|
||||
grid-template-columns: 50% 50%
|
||||
grid-gap: 25px
|
||||
grid-row-gap: 5px
|
||||
|
||||
.member-thumbnail
|
||||
padding: .25em
|
||||
margin: 1em
|
||||
|
||||
div
|
||||
width: 5em
|
||||
display: inline-block
|
||||
vertical-align: top
|
||||
|
||||
.member-thumbnail div~div
|
||||
padding-left: 1em
|
||||
width: 15em
|
||||
|
||||
.progress
|
||||
border-radius: 0
|
||||
.progress-bar-text
|
||||
text-align: center
|
||||
|
||||
.layout-actions
|
||||
width: 100%
|
||||
|
||||
#placesmap, #cropmap
|
||||
height: 500px
|
||||
|
||||
#membermap
|
||||
height: 250px
|
||||
z-index: 0
|
||||
|
||||
.location-not-set
|
||||
height: 250px
|
||||
width: 100%
|
||||
background-image: image-url('location-not-set.en.png')
|
||||
background-repeat: no-repeat
|
||||
background-position: center
|
||||
|
||||
.member-location
|
||||
font-size: small
|
||||
font-style: italic
|
||||
|
||||
|
||||
.member-location a
|
||||
color: $brown
|
||||
|
||||
|
||||
.photo-thumbnail
|
||||
padding: 0
|
||||
position: relative
|
||||
|
||||
img
|
||||
width: 100%
|
||||
|
||||
.text
|
||||
display: none
|
||||
color: #000
|
||||
position: absolute
|
||||
bottom: 0
|
||||
background: rgba(0, 0, 0, 0.8)
|
||||
width: 100%
|
||||
margin: 0
|
||||
|
||||
p
|
||||
padding: 5px
|
||||
margin: 0
|
||||
color: #fff
|
||||
|
||||
&:hover
|
||||
.text
|
||||
display: block
|
||||
|
||||
.thumbnail
|
||||
border: none
|
||||
text-align: center
|
||||
margin-bottom: 1.5em
|
||||
max-width: 160px
|
||||
max-height: 200px
|
||||
|
||||
.member-thumbnail
|
||||
text-align: left
|
||||
img
|
||||
height: 85px
|
||||
width: 85px
|
||||
max-width: 85px
|
||||
|
||||
.crop-thumbnail
|
||||
height: 220px
|
||||
.cropinfo
|
||||
display: inline-block
|
||||
max-width: 100%
|
||||
white-space: nowrap
|
||||
line-height: 1em
|
||||
padding-bottom: 2px
|
||||
|
||||
.cropname
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
.scientificname
|
||||
font-size: small
|
||||
font-style: italic
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
.plantingcount
|
||||
font-size: small
|
||||
|
||||
.crop-name a
|
||||
padding-top: 2px
|
||||
|
||||
.scientific-name small
|
||||
margin-bottom: -2px
|
||||
|
||||
li.crop-hierarchy
|
||||
list-style-type: disc
|
||||
|
||||
.navbar-brand
|
||||
margin: 0px
|
||||
padding: 0px
|
||||
|
||||
.navbar-bottom
|
||||
margin: 40px 0px 0px 0px !important
|
||||
|
||||
.post-actions
|
||||
margin-bottom: 1rem
|
||||
|
||||
// footer
|
||||
footer
|
||||
#footer1, #footer2, #footer3
|
||||
text-align: left
|
||||
padding-top: 1em
|
||||
padding-bottom: 2em
|
||||
ul
|
||||
list-style-type: none
|
||||
list-style-position: outside
|
||||
padding-left: 0px
|
||||
margin-left: 0px
|
||||
|
||||
a
|
||||
color: $navbar-default-link-color
|
||||
text-decoration: none
|
||||
|
||||
a:hover
|
||||
color: $navbar-default-link-hover-color
|
||||
|
||||
a:active
|
||||
color: $navbar-default-link-active-color
|
||||
|
||||
.navbar-bottom.navbar
|
||||
border-radius: 0
|
||||
|
||||
// ensure footer is pushed to bottom of browser window
|
||||
|
||||
#maincontainer
|
||||
min-height: 80%
|
||||
padding: 50px
|
||||
|
||||
html, body
|
||||
height: 100%
|
||||
|
||||
.crop-image, .member-image
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
// Autosuggest
|
||||
|
||||
.ui-autocomplete
|
||||
background: white
|
||||
z-index: $zindex-tooltip
|
||||
|
||||
.alert
|
||||
a
|
||||
font-weight: 800
|
||||
|
||||
|
||||
/* override "info" alert boxes to be green, not blue, on Growstuff */
|
||||
$state-info-text: darken($green, 10%)
|
||||
$state-info-bg: lighten($green, 50%)
|
||||
|
||||
/* and set "success" to be the same, as it was just very slightly
|
||||
* different because the default bootstrap green is slightly different
|
||||
* from ours */
|
||||
$state-success-text: darken($green, 10%)
|
||||
$state-success-bg: lighten($green, 50%)
|
||||
|
||||
.hide
|
||||
display: none
|
||||
|
||||
#add-sci_name-row, #remove-sci_name-row, #add-alt_name-row, #remove-alt_name-row
|
||||
display: none
|
||||
|
||||
.panel-footer
|
||||
height: 6em
|
||||
|
||||
.panel
|
||||
.dl-horizontal
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
.form-group.required .control-label:before
|
||||
content: "* "
|
||||
color: red
|
||||
|
||||
.margin-bottom
|
||||
margin-bottom: 1em
|
||||
|
||||
.red
|
||||
color: red
|
||||
|
||||
.truncate
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
|
||||
ul.plantings
|
||||
list-style-type: none
|
||||
|
||||
ul.thumbnail-buttons
|
||||
list-style-type: none
|
||||
text-align: right
|
||||
|
||||
|
||||
.hover-wrapper .text
|
||||
position: absolute
|
||||
visibility: hidden
|
||||
|
||||
.hover-wrapper:hover .text
|
||||
visibility: visible
|
||||
|
||||
.homepage-listing
|
||||
padding-bottom: 6px
|
||||
|
||||
@media (min-width: $screen-md-min)
|
||||
.planting-thumbnail
|
||||
dl.planting-attributes
|
||||
width: 100%
|
||||
|
||||
dt
|
||||
text-align: left
|
||||
width: 120px
|
||||
dd
|
||||
padding-left: 120px
|
||||
margin-left: auto
|
||||
|
||||
.navbar .navbar-form
|
||||
width: 250px
|
||||
|
||||
// Overrides applying only to mobile view. This must be at the end of the overrides file.
|
||||
@media only screen and (max-width: 767px)
|
||||
.sidebar
|
||||
margin-left: 0
|
||||
border-left: none
|
||||
padding-left: 0
|
||||
|
||||
#map
|
||||
height: 300px
|
||||
|
||||
.navbar .nav > li
|
||||
display: block
|
||||
|
||||
.navbar .navbar-form
|
||||
width: 185px
|
||||
padding-left: 0
|
||||
padding-right: 0
|
||||
.homepage
|
||||
.thumbnail
|
||||
height: 180px
|
||||
.seed-thumbnail
|
||||
height: 220px
|
||||
|
||||
#maincontainer
|
||||
padding: 10px
|
||||
454
app/assets/stylesheets/overrides.scss
Executable file
@@ -0,0 +1,454 @@
|
||||
body {
|
||||
background-color: $beige;
|
||||
font-family: $font-family-sans-serif;
|
||||
}
|
||||
|
||||
section {
|
||||
padding-top: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: $brown;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card a:hover {
|
||||
background-color: $beige;
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
span.badge {
|
||||
background-color: $brown;
|
||||
|
||||
a {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.list-inline > li.first {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.activity-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
#navbar-search {
|
||||
.input-group {
|
||||
input {
|
||||
background-color: $white;
|
||||
color: $black;
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
color: $navbar-default-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.index-cards {
|
||||
display: flex;
|
||||
flex: none;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.card {
|
||||
margin: 1em 1em 1em 0;
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
img.img-icon {
|
||||
width: 1.2em;
|
||||
}
|
||||
|
||||
.img-square {
|
||||
height: 150px;
|
||||
object-fit: cover;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.img-card {
|
||||
height: 180px;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.img-responsive {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
border-radius: 50%;
|
||||
padding: 1em;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.profile-sidebar {
|
||||
margin-top: -5rem;
|
||||
}
|
||||
|
||||
.profile-activity {
|
||||
background: $white;
|
||||
margin-top: 2em;
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
border-left: 1px solid darken($beige, 10%);
|
||||
margin-left: -1px;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
// this is used for eg. crops and members index pages
|
||||
.six-across:nth-child(6n+1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.three-across:nth-child(3n+1) {
|
||||
clear: both;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
// let's condense the hero unit a little
|
||||
.jumbotron {
|
||||
background-color: darken($beige, 10%);
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
// signup widget on homepage
|
||||
.signup {
|
||||
background-color: lighten($green, 40%);
|
||||
border-radius: 6px;
|
||||
border: 1px solid lighten($green, 20%);
|
||||
line-height: 200%;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// info under the main heading on homepage
|
||||
.jumbotron .info {
|
||||
//padding-top: 15px
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
// stats shown on homepage. eg. "999 members..."
|
||||
p.stats {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-row {
|
||||
display: grid;
|
||||
grid-gap: 25px;
|
||||
grid-row-gap: 5px;
|
||||
grid-template-columns: 50% 50%;
|
||||
}
|
||||
.card {
|
||||
margin-bottom: 1em
|
||||
}
|
||||
|
||||
.progress {
|
||||
border-radius: 0;
|
||||
|
||||
.progress-bar-text {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
#placesmap,
|
||||
#cropmap {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
#membermap {
|
||||
height: 250px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.location-not-set {
|
||||
background-image: image-url('location-not-set.en.png');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
height: 250px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.member-location {
|
||||
font-size: small;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.member-location a {
|
||||
color: $brown;
|
||||
}
|
||||
|
||||
.associations {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
|
||||
li.crop-hierarchy {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar-bottom {
|
||||
margin: 40px 0 0 !important;
|
||||
}
|
||||
|
||||
.post-actions {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
// footer
|
||||
footer {
|
||||
#footer1,
|
||||
#footer2,
|
||||
#footer3 {
|
||||
padding-bottom: 2em;
|
||||
padding-top: 1em;
|
||||
text-align: left;
|
||||
|
||||
ul {
|
||||
list-style-position: outside;
|
||||
list-style-type: none;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $navbar-default-link-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: $navbar-default-link-hover-color;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: $navbar-default-link-active-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure footer is pushed to bottom of browser window
|
||||
|
||||
#maincontainer {
|
||||
min-height: 80%;
|
||||
}
|
||||
|
||||
#global-actions {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.member-image {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
// Autosuggest
|
||||
.ui-autocomplete {
|
||||
background: $white;
|
||||
z-index: $highest-level;
|
||||
}
|
||||
|
||||
.alert {
|
||||
a {
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
||||
|
||||
/* override "info" alert boxes to be green, not blue, on Growstuff */
|
||||
$state-info-text: darken($green, 10%);
|
||||
$state-info-bg: lighten($green, 50%);
|
||||
|
||||
/* and set "success" to be the same, as it was just very slightly
|
||||
* different because the default bootstrap green is slightly different
|
||||
* from ours */
|
||||
$state-success-text: darken($green, 10%);
|
||||
$state-success-bg: lighten($green, 50%);
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#add-sci_name-row,
|
||||
#remove-sci_name-row,
|
||||
#add-alt_name-row,
|
||||
#remove-alt_name-row {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
height: 6em;
|
||||
}
|
||||
|
||||
.panel {
|
||||
.dl-horizontal {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
label.required:after {
|
||||
color: red;
|
||||
content:" *";
|
||||
}
|
||||
|
||||
.margin-bottom {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
ul.plantings {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
ul.thumbnail-buttons {
|
||||
list-style-type: none;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.hover-wrapper .text {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.hover-wrapper:hover .text {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.homepage-listing {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1500px;
|
||||
}
|
||||
|
||||
// Small devices (landscape phones, less than 768px)
|
||||
@include media-breakpoint-down(md) {
|
||||
.planting-thumbnail {
|
||||
dl.planting-attributes {
|
||||
width: 100%;
|
||||
|
||||
dt {
|
||||
text-align: left;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: auto;
|
||||
padding-left: 120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.form-page {
|
||||
text-align: center;
|
||||
|
||||
.form-card {
|
||||
display: inline-block;
|
||||
margin-top: 0.5em;
|
||||
max-width: 800px;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.crop-card {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
// Overrides applying only to mobile view. This must be at the end of the overrides file.
|
||||
// Extra small devices (portrait phones, less than 576px)
|
||||
@include media-breakpoint-down(xs) {
|
||||
#maincontainer {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
margin-left: 0;
|
||||
border-left: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#map {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.navbar .nav > li {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.navbar .navbar-form {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
.navbar-search {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
#maincontainer {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.homepage-cards {
|
||||
.crop-card {
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.index-cards {
|
||||
.card {
|
||||
width: 100%;
|
||||
margin: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
.photo-grid
|
||||
background: #DDD
|
||||
|
||||
.photo-grid-item
|
||||
//background: #e6e5e4
|
||||
//border: 2px solid #b6b5b4
|
||||
//height: 100px
|
||||
|
||||
|
||||
/* clear fix */
|
||||
.photo-grid:after
|
||||
content: ''
|
||||
display: block
|
||||
clear: both
|
||||
|
||||
/* ---- .photo-grid-item ---- */
|
||||
|
||||
.photo-grid-sizer,
|
||||
.photo-grid-item
|
||||
//width: 33.333%
|
||||
|
||||
.photo-grid-item
|
||||
float: left
|
||||
|
||||
.photo-grid-item img
|
||||
display: block
|
||||
max-width: 100%
|
||||
@@ -1,61 +0,0 @@
|
||||
.planting
|
||||
.planting-badges
|
||||
font-size: 100%
|
||||
position: absolute
|
||||
top: 3em
|
||||
.badge-super-late
|
||||
background-color: $red
|
||||
.badge-harvest
|
||||
background-color: $blue
|
||||
.planting-super-late
|
||||
.planting-late
|
||||
background-color: $beige
|
||||
|
||||
.planting-thumbnail
|
||||
width: 150px
|
||||
padding: 0em
|
||||
margin-bottom: 0.5em
|
||||
margin-top: 0.5em
|
||||
border: 1px solid darken($beige, 10%)
|
||||
border-radius: 4px
|
||||
.badge
|
||||
font-size: 100%
|
||||
.planting-full-badges
|
||||
.badge
|
||||
font-size: 200%
|
||||
|
||||
.planting-name
|
||||
position: relative
|
||||
text-align: center
|
||||
font-size: 150%
|
||||
top: -0.5em
|
||||
.planting-quick-actions
|
||||
position: absolute
|
||||
left: 142px
|
||||
top: 6px
|
||||
.planting-thumbnail-photo
|
||||
height: 150px
|
||||
|
||||
dl.planting-attributes
|
||||
dt
|
||||
text-align: left
|
||||
dd
|
||||
margin-left: auto
|
||||
|
||||
.fact
|
||||
text-align: center
|
||||
height: 180px
|
||||
width: 160px
|
||||
border: 1px solid lighten($green, 20%)
|
||||
border-radius: 5%
|
||||
background: $white
|
||||
padding: 1em
|
||||
margin: 0.3em
|
||||
strong
|
||||
font-size: 3em
|
||||
font-align: center
|
||||
h3
|
||||
span
|
||||
display: block
|
||||
img
|
||||
height: 50%
|
||||
@@ -1,14 +0,0 @@
|
||||
.predictions
|
||||
.prediction-metric
|
||||
text-align: center
|
||||
height: 180px
|
||||
border: 1px solid lighten($green, 20%)
|
||||
border-radius: 5%
|
||||
background: $white
|
||||
margin: 4px
|
||||
strong
|
||||
font-size: 4em
|
||||
font-align: center
|
||||
h3
|
||||
span
|
||||
display: block
|
||||
@@ -197,7 +197,8 @@ class CropsController < ApplicationController
|
||||
def crops
|
||||
q = Crop.approved.includes(:scientific_names, plantings: :photos)
|
||||
q = q.popular unless @sort == 'alpha'
|
||||
q.order("LOWER(crops.name)").includes(:photos).paginate(page: params[:page])
|
||||
q.order(Arel.sql("LOWER(crops.name)"))
|
||||
.includes(:photos).paginate(page: params[:page])
|
||||
end
|
||||
|
||||
def requested_crops
|
||||
|
||||
@@ -18,8 +18,17 @@ class MembersController < ApplicationController
|
||||
@flickr_auth = @member.auth('flickr')
|
||||
@facebook_auth = @member.auth('facebook')
|
||||
@posts = @member.posts
|
||||
@gardens = @member.gardens.active.order(:name)
|
||||
@harvests = @member.harvests
|
||||
|
||||
# TODO: Consider shifting all of these onto a member activity model?
|
||||
@activity = plantings_for_show
|
||||
.union_all(harvests_for_show)
|
||||
.union_all(posts_for_show)
|
||||
.union_all(comments_for_show)
|
||||
.union_all(photos_for_show)
|
||||
.union_all(seeds_for_show)
|
||||
.where(owner_id: @member.id)
|
||||
.order(event_at: :desc)
|
||||
.limit(30)
|
||||
|
||||
# The garden form partial is called from the "New Garden" tab;
|
||||
# it requires a garden to be passed in @garden.
|
||||
@@ -91,4 +100,71 @@ class MembersController < ApplicationController
|
||||
Member.order(:login_name)
|
||||
end.confirmed.paginate(page: params[:page])
|
||||
end
|
||||
|
||||
# Queries for the show view/action
|
||||
def plantings_for_show
|
||||
Planting.select(
|
||||
:id,
|
||||
"'planting' as event_type",
|
||||
'planted_at as event_at',
|
||||
:owner_id,
|
||||
:crop_id,
|
||||
:slug
|
||||
)
|
||||
end
|
||||
|
||||
def harvests_for_show
|
||||
Harvest.select(
|
||||
:id,
|
||||
"'harvest' as event_type",
|
||||
'harvested_at as event_at',
|
||||
:owner_id,
|
||||
:crop_id,
|
||||
:slug
|
||||
)
|
||||
end
|
||||
|
||||
def posts_for_show
|
||||
Post.select(
|
||||
:id,
|
||||
"'post' as event_type",
|
||||
'posts.created_at as event_at',
|
||||
'author_id as owner_id',
|
||||
'null as crop_id',
|
||||
:slug
|
||||
)
|
||||
end
|
||||
|
||||
def comments_for_show
|
||||
Comment.select(
|
||||
:id,
|
||||
"'comment' as event_type",
|
||||
'comments.created_at as event_at',
|
||||
'author_id as owner_id',
|
||||
'null as crop_id',
|
||||
'null as slug'
|
||||
)
|
||||
end
|
||||
|
||||
def photos_for_show
|
||||
Photo.select(
|
||||
:id,
|
||||
"'photo' as event_type",
|
||||
"photos.created_at as event_at",
|
||||
'photos.owner_id',
|
||||
'null as crop_id',
|
||||
'null as slug'
|
||||
)
|
||||
end
|
||||
|
||||
def seeds_for_show
|
||||
Seed.select(
|
||||
:id,
|
||||
"'seed' as event_type",
|
||||
"seeds.created_at as event_at",
|
||||
'seeds.owner_id',
|
||||
'crop_id',
|
||||
'slug'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ class NotificationsController < ApplicationController
|
||||
|
||||
# GET /notifications
|
||||
def index
|
||||
@notifications = Notification.by_recipient(current_member).order(:created_at).page(params[:page])
|
||||
@notifications = Notification.by_recipient(current_member).order(:created_at).paginate(page: params[:page], per_page: 30)
|
||||
end
|
||||
|
||||
# GET /notifications/1
|
||||
|
||||
@@ -41,20 +41,27 @@ class PlantingsController < ApplicationController
|
||||
end
|
||||
|
||||
def new
|
||||
@planting = Planting.new(planted_at: Time.zone.today)
|
||||
@planting = Planting.new(
|
||||
planted_at: Time.zone.today,
|
||||
owner: current_member,
|
||||
garden: current_member.gardens.first
|
||||
)
|
||||
@seed = Seed.find_by(slug: params[:seed_id]) if params[:seed_id]
|
||||
|
||||
# using find_by_id here because it returns nil, unlike find
|
||||
@crop = Crop.approved.find_by(id: params[:crop_id]) || Crop.new
|
||||
@garden = Garden.find_by(owner: current_member, id: params[:garden_id]) || Garden.new
|
||||
@crop = Crop.approved.find_by(id: params[:crop_id]) || Crop.new
|
||||
if params[:garden_id]
|
||||
@planting.garden = Garden.find_by(
|
||||
owner: current_member,
|
||||
id: params[:garden_id]
|
||||
)
|
||||
end
|
||||
|
||||
respond_with @planting
|
||||
end
|
||||
|
||||
def edit
|
||||
# the following are needed to display the form but aren't used
|
||||
@crop = Crop.new
|
||||
@garden = Garden.new
|
||||
@crop = Crop.new
|
||||
@gardens = @planting.owner.gardens.active.order_by_name
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -8,7 +8,7 @@ class PostsController < ApplicationController
|
||||
# GET /posts.json
|
||||
# GET /posts.rss
|
||||
def index
|
||||
@author = Member.find_by(slug: params[:author])
|
||||
@author = Member.find_by(slug: params[:member_slug])
|
||||
@posts = posts
|
||||
respond_with(@posts)
|
||||
end
|
||||
|
||||
@@ -3,9 +3,7 @@ class SessionsController < Devise::SessionsController
|
||||
|
||||
def create
|
||||
super do |_resource|
|
||||
if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
|
||||
flash[:alert] = "There are crops waiting to be wrangled."
|
||||
end
|
||||
flash[:alert] = "There are crops waiting to be wrangled." if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,9 +60,7 @@ module ApplicationHelper
|
||||
# Returns a string with the quantity and the right pluralization for a
|
||||
# given collection and model.
|
||||
def localize_plural(collection, model)
|
||||
size = collection.size
|
||||
model_name = model.model_name.human(count: size)
|
||||
"#{size} #{model_name}"
|
||||
pluralize(collection.size, model.model_name.to_s.downcase)
|
||||
end
|
||||
|
||||
def show_inactive_tickbox_path(type, owner, show_all)
|
||||
|
||||
@@ -1,88 +1,126 @@
|
||||
module ButtonsHelper
|
||||
include IconsHelper
|
||||
def garden_plant_something_button(garden)
|
||||
link_to new_planting_path(garden_id: garden.id), class: "btn btn-default btn-xs btn-primary" do
|
||||
def garden_plant_something_button(garden, classes: "btn btn-default")
|
||||
return unless can? :edit, garden
|
||||
|
||||
link_to new_planting_path(garden_id: garden.id), class: classes do
|
||||
planting_icon + ' ' + t('buttons.plant_something_here')
|
||||
end
|
||||
end
|
||||
|
||||
def garden_mark_active_button(garden)
|
||||
link_to t('buttons.mark_as_active'),
|
||||
garden_path(garden, garden: { active: 1 }),
|
||||
method: :put, class: 'btn btn-default btn-xs'
|
||||
def plant_something_button
|
||||
return unless can? :create, Planting
|
||||
|
||||
link_to new_planting_path, class: "btn btn-default" do
|
||||
planting_icon + ' ' + t('buttons.plant_something')
|
||||
end
|
||||
end
|
||||
|
||||
def garden_mark_inactive_button(garden)
|
||||
def garden_mark_active_button(garden, classes: 'btn')
|
||||
link_to t('buttons.mark_as_active'),
|
||||
garden_path(garden, garden: { active: 1 }),
|
||||
method: :put, class: classes
|
||||
end
|
||||
|
||||
def garden_mark_inactive_button(garden, classes: 'btn')
|
||||
link_to t('buttons.mark_as_inactive'),
|
||||
garden_path(garden, garden: { active: 0 }),
|
||||
method: :put, class: 'btn btn-default btn-xs',
|
||||
data: { confirm: 'All plantings associated with this garden will be marked as finished. Are you sure?' }
|
||||
garden_path(garden, garden: { active: 0 }),
|
||||
method: :put, class: classes,
|
||||
data: { confirm: 'All plantings associated with this garden will be marked as finished. Are you sure?' }
|
||||
end
|
||||
|
||||
def crop_plant_button(crop)
|
||||
create_button(Planting,
|
||||
new_planting_path(params: { crop_id: crop.id }),
|
||||
planting_icon, t('buttons.plant'))
|
||||
end
|
||||
|
||||
def crop_save_seeds_button(crop)
|
||||
create_button(Seed,
|
||||
new_seed_path(params: { crop_id: crop.id }),
|
||||
seed_icon, t('buttons.save_seeds'))
|
||||
end
|
||||
|
||||
def create_button(model_to_create, path, icon, label)
|
||||
return unless can?(:create, model_to_create)
|
||||
|
||||
link_to path, class: "btn btn-sm" do
|
||||
icon + ' ' + label
|
||||
end
|
||||
end
|
||||
|
||||
def crop_edit_button(crop)
|
||||
edit_button(edit_crop_path(crop))
|
||||
end
|
||||
|
||||
def seed_edit_button(seed)
|
||||
edit_button(edit_seed_path(seed))
|
||||
def seed_edit_button(seed, classes: "btn btn-raised btn-info")
|
||||
edit_button(edit_seed_path(seed), classes: classes)
|
||||
end
|
||||
|
||||
def harvest_edit_button(harvest)
|
||||
edit_button(edit_harvest_path(harvest))
|
||||
def harvest_edit_button(harvest, classes: "btn btn-raised btn-info")
|
||||
edit_button(edit_harvest_path(harvest), classes: classes)
|
||||
end
|
||||
|
||||
def garden_edit_button(garden)
|
||||
edit_button(edit_garden_path(garden))
|
||||
def garden_edit_button(garden, classes: "btn btn-raised btn-info")
|
||||
edit_button(edit_garden_path(garden), classes: classes)
|
||||
end
|
||||
|
||||
def planting_edit_button(planting)
|
||||
edit_button(edit_planting_path(planting))
|
||||
def planting_edit_button(planting, classes: "btn btn-raised btn-info")
|
||||
edit_button(edit_planting_path(planting), classes: classes)
|
||||
end
|
||||
|
||||
def planting_finish_button(planting)
|
||||
def planting_finish_button(planting, classes: 'btn btn-default btn-secondary')
|
||||
return unless can?(:edit, planting) || planting.finished
|
||||
|
||||
link_to planting_path(planting, planting: { finished: 1 }),
|
||||
method: :put, class: 'btn btn-default btn-xs append-date' do
|
||||
method: :put, class: "#{classes} append-date" do
|
||||
finished_icon + ' ' + t('buttons.mark_as_finished')
|
||||
end
|
||||
end
|
||||
|
||||
def planting_harvest_button(planting)
|
||||
return unless planting.active? && can?(:create, Harvest) && can?(:edit, planting)
|
||||
def seed_finish_button(seed, classes: 'btn btn-default')
|
||||
return unless can?(:create, Planting) && seed.active?
|
||||
|
||||
link_to new_planting_harvest_path(planting), class: "btn btn-default btn-xs" do
|
||||
harvest_icon + ' ' + t('buttons.harvest')
|
||||
link_to seed_path(seed, seed: { finished: 1 }), method: :put, class: "#{classes} append-date" do
|
||||
finished_icon + ' ' + t('buttons.mark_as_finished')
|
||||
end
|
||||
end
|
||||
|
||||
def planting_save_seeds_button(planting)
|
||||
def planting_harvest_button(planting, classes: 'btn btn-default')
|
||||
return unless planting.active? && can?(:create, Harvest) && can?(:edit, planting)
|
||||
|
||||
link_to new_planting_harvest_path(planting), class: classes do
|
||||
harvest_icon + ' ' + t('buttons.record_harvest')
|
||||
end
|
||||
end
|
||||
|
||||
def planting_save_seeds_button(planting, classes: 'btn btn-default')
|
||||
return unless can?(:edit, planting)
|
||||
|
||||
link_to new_planting_seed_path(planting), class: "btn btn-default btn-xs" do
|
||||
link_to new_planting_seed_path(planting), class: classes do
|
||||
seed_icon + ' ' + t('buttons.save_seeds')
|
||||
end
|
||||
end
|
||||
|
||||
def add_photo_button(model)
|
||||
def add_photo_button(model, classes: "btn btn-default")
|
||||
return unless can?(:edit, model) && can?(:create, Photo)
|
||||
|
||||
link_to new_photo_path(id: model.id, type: model_type_for_photo(model)),
|
||||
class: "btn btn-default btn-xs" do
|
||||
class: classes do
|
||||
photo_icon + ' ' + t('buttons.add_photo')
|
||||
end
|
||||
end
|
||||
|
||||
def edit_button(path)
|
||||
link_to path, class: "btn btn-default btn-xs" do
|
||||
def edit_button(path, classes: "btn btn-raised btn-info")
|
||||
link_to path, class: classes do
|
||||
edit_icon + ' ' + t('buttons.edit')
|
||||
end
|
||||
end
|
||||
|
||||
def delete_button(model, message: 'are_you_sure')
|
||||
def delete_button(model, message: 'are_you_sure', classes: 'btn btn-danger')
|
||||
return unless can? :destroy, model
|
||||
|
||||
link_to model, method: :delete, data: { confirm: t(message) }, class: 'btn btn-default btn-xs' do
|
||||
link_to model, method: :delete, data: { confirm: t(message) }, class: classes do
|
||||
delete_icon + ' ' + t('buttons.delete')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,19 +2,27 @@ module IconsHelper
|
||||
include FontAwesome::Sass::Rails::ViewHelpers
|
||||
|
||||
def garden_icon
|
||||
icon('fas', 'square')
|
||||
image_icon 'home'
|
||||
end
|
||||
|
||||
def planting_icon
|
||||
icon('fas', 'seedling')
|
||||
image_icon 'planting'
|
||||
end
|
||||
|
||||
def member_icon
|
||||
icon('fas', 'user')
|
||||
end
|
||||
|
||||
def harvest_icon
|
||||
icon('fas', 'carrot')
|
||||
image_icon 'harvest'
|
||||
end
|
||||
|
||||
def seed_icon
|
||||
icon('fas', 'heart')
|
||||
image_icon 'seeds'
|
||||
end
|
||||
|
||||
def comment_icon
|
||||
icon('fas', 'comment')
|
||||
end
|
||||
|
||||
def finished_icon
|
||||
@@ -38,7 +46,7 @@ module IconsHelper
|
||||
end
|
||||
|
||||
def blog_icon
|
||||
icon('fas', 'pen')
|
||||
image_icon 'post'
|
||||
end
|
||||
|
||||
def perennial_icon
|
||||
@@ -49,6 +57,14 @@ module IconsHelper
|
||||
planted_from
|
||||
end
|
||||
|
||||
def delete_association_icon
|
||||
icon('fas', 'backspace')
|
||||
end
|
||||
|
||||
def like_icon
|
||||
icon('fas', 'thumbs-up')
|
||||
end
|
||||
|
||||
def sunniness_icon(sunniness)
|
||||
if sunniness.present?
|
||||
image_tag("sunniness_#{sunniness}.png", class: 'img', alt: sunniness, width: 55)
|
||||
@@ -56,4 +72,8 @@ module IconsHelper
|
||||
image_tag("sunniness_not_specified.png", class: 'img', alt: 'unknown', width: 55)
|
||||
end
|
||||
end
|
||||
|
||||
def image_icon(icon)
|
||||
image_tag "icons/#{icon}.svg", class: 'img img-icon'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,50 +1,39 @@
|
||||
module PhotosHelper
|
||||
def crop_image_path(crop)
|
||||
if crop.default_photo.present?
|
||||
crop.default_photo.thumbnail_url
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
def crop_image_path(crop, full_size: false)
|
||||
photo_or_placeholder(crop, full_size: full_size)
|
||||
end
|
||||
|
||||
def garden_image_path(garden)
|
||||
if garden.default_photo.present?
|
||||
garden.default_photo.thumbnail_url
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
def garden_image_path(garden, full_size: false)
|
||||
photo_or_placeholder(garden, full_size: full_size)
|
||||
end
|
||||
|
||||
def planting_image_path(planting)
|
||||
if planting.photos.present?
|
||||
planting.photos.order(date_taken: :desc).first.thumbnail_url
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
def planting_image_path(planting, full_size: false)
|
||||
photo_or_placeholder(planting, full_size: full_size)
|
||||
end
|
||||
|
||||
def harvest_image_path(harvest)
|
||||
if harvest.photos.present?
|
||||
harvest.photos.order(date_taken: :desc).first.thumbnail_url
|
||||
elsif harvest.planting.present?
|
||||
planting_image_path(harvest.planting)
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
def harvest_image_path(harvest, full_size: false)
|
||||
photo_or_placeholder(harvest, full_size: full_size)
|
||||
end
|
||||
|
||||
def seed_image_path(seed)
|
||||
if seed.default_photo.present?
|
||||
seed.default_photo.thumbnail_url
|
||||
elsif seed.crop.default_photo.present?
|
||||
seed.crop.default_photo.thumbnail_url
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
def seed_image_path(seed, full_size: false)
|
||||
photo_or_placeholder(seed, full_size: full_size)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def photo_or_placeholder(item, full_size: false)
|
||||
if item.default_photo.present?
|
||||
item_photo(item, full_size: full_size)
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
end
|
||||
|
||||
def item_photo(item, full_size:)
|
||||
photo = item.default_photo
|
||||
full_size ? photo.fullsize_url : photo.thumbnail_url
|
||||
end
|
||||
|
||||
def placeholder_image
|
||||
'placeholder_150.png'
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ module PlantingsHelper
|
||||
elsif planting.planted_from.present?
|
||||
"#{planting.owner} planted #{planting.planted_from.pluralize}."
|
||||
else
|
||||
"#{planting.owner}."
|
||||
"#{planting.owner} planted #{planting.crop}."
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
7
app/helpers/posts_helper.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module PostsHelper
|
||||
def display_post_truncated(post)
|
||||
length = 300
|
||||
truncate(strip_tags(post.body), length: length,
|
||||
separator: ' ', omission: '... ') { link_to "Read more", post_path(post) }
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,4 @@
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
self.per_page = 12
|
||||
end
|
||||
|
||||
@@ -18,4 +18,8 @@ class Comment < ApplicationRecord
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{author.login_name} commented on #{post.subject}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ class Crop < ApplicationRecord
|
||||
## Scopes
|
||||
scope :recent, -> { approved.order(created_at: :desc) }
|
||||
scope :toplevel, -> { approved.where(parent_id: nil) }
|
||||
scope :popular, -> { approved.order("plantings_count desc, lower(name) asc") }
|
||||
scope :popular, -> { approved.order(Arel.sql("plantings_count desc, lower(name) asc")) }
|
||||
scope :pending_approval, -> { where(approval_status: "pending") }
|
||||
scope :approved, -> { where(approval_status: "approved") }
|
||||
scope :rejected, -> { where(approval_status: "rejected") }
|
||||
@@ -47,17 +47,15 @@ class Crop < ApplicationRecord
|
||||
validate :must_have_meaningful_reason_for_rejection
|
||||
## Wikipedia urls are only necessary when approving a crop
|
||||
validates :en_wikipedia_url,
|
||||
format: {
|
||||
with: %r{\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_\.()-]+\z},
|
||||
message: 'is not a valid English Wikipedia URL'
|
||||
},
|
||||
if: :approved?
|
||||
format: {
|
||||
with: %r{\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_\.()-]+\z},
|
||||
message: 'is not a valid English Wikipedia URL'
|
||||
},
|
||||
if: :approved?
|
||||
|
||||
####################################
|
||||
# Elastic search configuration
|
||||
if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
|
||||
searchkick word_start: %i(name alternate_names scientific_names), case_sensitive: false
|
||||
end
|
||||
searchkick word_start: %i(name alternate_names scientific_names), case_sensitive: false if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
|
||||
|
||||
def planting_photos
|
||||
Photo.joins(:plantings).where("plantings.crop_id": id)
|
||||
@@ -117,7 +115,7 @@ class Crop < ApplicationRecord
|
||||
end
|
||||
|
||||
def annual?
|
||||
!perennial
|
||||
perennial == false
|
||||
end
|
||||
|
||||
def interesting?
|
||||
|
||||
@@ -19,24 +19,24 @@ class Garden < ApplicationRecord
|
||||
default_scope { joins(:owner) } # Ensures owner exists
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :inactive, -> { where(active: false) }
|
||||
scope :order_by_name, -> { order("lower(name) asc") }
|
||||
scope :order_by_name, -> { order(Arel.sql("lower(name) asc")) }
|
||||
|
||||
validates :location, length: { maximum: 255 }
|
||||
validates :slug, uniqueness: true
|
||||
validates :name, uniqueness: { scope: :owner_id }
|
||||
|
||||
validates :name,
|
||||
format: {
|
||||
with: /\A\w+[\w ()]+\z/
|
||||
},
|
||||
length: { maximum: 255 }
|
||||
format: {
|
||||
with: /\A\w+[\w ()]+\z/
|
||||
},
|
||||
length: { maximum: 255 }
|
||||
|
||||
validates :area,
|
||||
numericality: {
|
||||
only_integer: false,
|
||||
greater_than_or_equal_to: 0
|
||||
},
|
||||
allow_nil: true
|
||||
numericality: {
|
||||
only_integer: false,
|
||||
greater_than_or_equal_to: 0
|
||||
},
|
||||
allow_nil: true
|
||||
|
||||
AREA_UNITS_VALUES = {
|
||||
"square metres" => "square metre",
|
||||
|
||||
@@ -54,8 +54,8 @@ class Member < ApplicationRecord
|
||||
# :token_authenticatable, :confirmable,
|
||||
# :lockable, :timeoutable and :omniauthable
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable,
|
||||
:confirmable, :lockable, :timeoutable, :omniauthable
|
||||
:recoverable, :rememberable, :trackable, :validatable,
|
||||
:confirmable, :lockable, :timeoutable, :omniauthable
|
||||
|
||||
# set up geocoding
|
||||
geocoded_by :location
|
||||
@@ -69,18 +69,18 @@ class Member < ApplicationRecord
|
||||
# Requires acceptance of the Terms of Service
|
||||
validates :tos_agreement, acceptance: { allow_nil: true, accept: true }
|
||||
validates :login_name,
|
||||
length: {
|
||||
minimum: 2, maximum: 25, message: "should be between 2 and 25 characters long"
|
||||
},
|
||||
exclusion: {
|
||||
in: %w(growstuff admin moderator staff nearby), message: "name is reserved"
|
||||
},
|
||||
format: {
|
||||
with: /\A\w+\z/, message: "may only include letters, numbers, or underscores"
|
||||
},
|
||||
uniqueness: {
|
||||
case_sensitive: false
|
||||
}
|
||||
length: {
|
||||
minimum: 2, maximum: 25, message: "should be between 2 and 25 characters long"
|
||||
},
|
||||
exclusion: {
|
||||
in: %w(growstuff admin moderator staff nearby), message: "name is reserved"
|
||||
},
|
||||
format: {
|
||||
with: /\A\w+\z/, message: "may only include letters, numbers, or underscores"
|
||||
},
|
||||
uniqueness: {
|
||||
case_sensitive: false
|
||||
}
|
||||
|
||||
#
|
||||
# Triggers
|
||||
|
||||
@@ -9,9 +9,9 @@ class Photo < ApplicationRecord
|
||||
# creates a relationship for each assignee type
|
||||
PHOTO_CAPABLE.each do |type|
|
||||
has_many type.downcase.pluralize.to_s.to_sym,
|
||||
through: :photographings,
|
||||
source: :photographable,
|
||||
source_type: type
|
||||
through: :photographings,
|
||||
source: :photographable,
|
||||
source_type: type
|
||||
end
|
||||
|
||||
default_scope { joins(:owner) } # Ensures the owner still exists
|
||||
|
||||
@@ -33,7 +33,7 @@ class Planting < ApplicationRecord
|
||||
##
|
||||
## Scopes
|
||||
default_scope { joins(:owner) } # Ensures the owner still exists
|
||||
scope :active, -> { where(finished_at: nil) }
|
||||
scope :active, -> { where('finished <> true').where('finished_at IS NULL OR finished_at < ?', Time.zone.now) }
|
||||
scope :interesting, -> { has_photos.one_per_owner.order(planted_at: :desc) }
|
||||
scope :recent, -> { order(created_at: :desc) }
|
||||
scope :one_per_owner, lambda {
|
||||
@@ -45,7 +45,7 @@ class Planting < ApplicationRecord
|
||||
##
|
||||
## Delegations
|
||||
delegate :name, :en_wikipedia_url, :default_scientific_name, :plantings_count,
|
||||
to: :crop, prefix: true
|
||||
to: :crop, prefix: true
|
||||
|
||||
##
|
||||
## Validations
|
||||
|
||||
@@ -48,6 +48,10 @@ class Post < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
subject
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_crops_posts_association
|
||||
|
||||
@@ -52,6 +52,8 @@ class Seed < ApplicationRecord
|
||||
scope :tradable, -> { where.not(tradable_to: 'nowhere') }
|
||||
scope :interesting, -> { tradable.has_location }
|
||||
scope :has_location, -> { joins(:owner).where.not("members.location": nil) }
|
||||
scope :recent, -> { order(created_at: :desc) }
|
||||
scope :active, -> { where('finished_at < ?', Time.zone.now) }
|
||||
|
||||
def default_photo
|
||||
photos.order(created_at: :desc).first
|
||||
|
||||
@@ -21,7 +21,6 @@ module Api
|
||||
# Predictions
|
||||
attribute :expected_lifespan
|
||||
attribute :finish_predicted_at
|
||||
attribute :percentage_grown
|
||||
attribute :first_harvest_date
|
||||
attribute :last_harvest_date
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
- content_for :title, 'Admin'
|
||||
|
||||
- content_for :breadcrumbs do
|
||||
%nav{"aria-label" => "breadcrumb"}
|
||||
%ol.breadcrumb
|
||||
%li.breadcrumb-item
|
||||
= link_to 'Home', root_path
|
||||
%li.breadcrumb-item.active= link_to 'Admin', admin_path
|
||||
|
||||
%h2 Manage
|
||||
|
||||
.row
|
||||
|
||||
@@ -1,32 +1,37 @@
|
||||
= form_for @alternate_name, html: { class: 'form-horizontal', role: "form" } do |f|
|
||||
- if @alternate_name.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@alternate_name.errors.size, "error")
|
||||
prohibited this alternate_name from being saved:
|
||||
%ul
|
||||
- @alternate_name.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
.card.col-md-8.col-lg-7.mx-auto.float-none.white.z-depth-1.py-2.px-2
|
||||
.card-body
|
||||
- if content_for? :title
|
||||
%h1.h2-responsive.text-center
|
||||
%strong=yield :title
|
||||
= form_for @alternate_name, html: { class: 'form-horizontal', role: "form" } do |f|
|
||||
- if @alternate_name.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@alternate_name.errors.size, "error")
|
||||
prohibited this alternate_name from being saved:
|
||||
%ul
|
||||
- @alternate_name.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
%p
|
||||
%span.help-block
|
||||
For detailed crop wrangling guidelines, please consult the
|
||||
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
on the Growstuff wiki.
|
||||
%p
|
||||
%span.help-block
|
||||
For detailed crop wrangling guidelines, please consult the
|
||||
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
on the Growstuff wiki.
|
||||
|
||||
.form-group
|
||||
= f.label :crop_id, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= collection_select(:alternate_name, :crop_id,
|
||||
Crop.all, :id, :name,
|
||||
{ selected: @alternate_name.crop_id || @crop.id },
|
||||
class: 'form-control')
|
||||
.form-group
|
||||
= f.label :crop_id, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= collection_select(:alternate_name, :crop_id,
|
||||
Crop.all, :id, :name,
|
||||
{ selected: @alternate_name.crop_id || @crop.id },
|
||||
class: 'form-control')
|
||||
|
||||
.form-group
|
||||
= f.label :name, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :name, class: 'form-control'
|
||||
.form-group
|
||||
= f.label :name, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :name, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit 'Save', class: 'btn btn-primary'
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit 'Save', class: 'btn btn-primary'
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
= form_for(@comment, html: { class: "form-horizontal", role: "form" }) do |f|
|
||||
- if @comment.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@comment.errors.size, "error")
|
||||
prohibited this comment from being saved:
|
||||
%ul
|
||||
- @comment.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
.card.col-md-8.col-lg-7.mx-auto.float-none.white.z-depth-1.py-2.px-2
|
||||
.card-body
|
||||
- if content_for? :title
|
||||
%h1.h2-responsive.text-center
|
||||
%strong=yield :title
|
||||
= form_for(@comment, html: { class: "form-horizontal", role: "form" }) do |f|
|
||||
- if @comment.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@comment.errors.size, "error")
|
||||
prohibited this comment from being saved:
|
||||
%ul
|
||||
- @comment.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.form-group
|
||||
= f.label :body, "Your comment:"
|
||||
= f.text_area :body, rows: 6, class: 'form-control', autofocus: 'autofocus'
|
||||
%span.help-block
|
||||
= render partial: "shared/markdown_help"
|
||||
.actions
|
||||
= f.submit 'Post comment', class: 'btn btn-primary'
|
||||
- if defined?(@post)
|
||||
.field
|
||||
= f.hidden_field :post_id, value: @post.id
|
||||
.md-form
|
||||
= f.text_area :body, rows: 6, class: 'form-control md-textarea', autofocus: 'autofocus'
|
||||
= f.label :body, "Your comment:"
|
||||
|
||||
%span.help-block
|
||||
= render partial: "shared/markdown_help"
|
||||
.actions.text-right
|
||||
= f.submit 'Post comment', class: 'btn btn-primary'
|
||||
- if defined?(@post)
|
||||
.field
|
||||
= f.hidden_field :post_id, value: @post.id
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
.well
|
||||
.comment
|
||||
.card.comment
|
||||
.card-body
|
||||
.row
|
||||
.col-md-1
|
||||
= render partial: "members/avatar", locals: { member: comment.author }
|
||||
.col-md-11
|
||||
.comment-meta
|
||||
.col-md-1= render "members/tiny", member: comment.author
|
||||
.col-md-11.border-left
|
||||
- if can?(:edit, comment) || can?(:destroy, comment)
|
||||
.dropdown.float-right
|
||||
%button#comment-edit-button.btn.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", type: "button"} Actions
|
||||
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "comment-edit-button"}
|
||||
- if can? :edit, comment
|
||||
= link_to edit_comment_path(comment), class: 'dropdown-item' do
|
||||
= edit_icon
|
||||
Edit
|
||||
- if can? :destroy, comment
|
||||
= link_to comment, method: :delete,
|
||||
data: { confirm: 'Are you sure?' }, class: 'dropdown-item text-danger' do
|
||||
= delete_icon
|
||||
Delete
|
||||
.comment-meta.text-muted
|
||||
Posted by
|
||||
- if comment.author.deleted?
|
||||
Member Deleted
|
||||
@@ -20,10 +32,3 @@
|
||||
:growstuff_markdown
|
||||
#{ strip_tags comment.body }
|
||||
|
||||
- if can?(:edit, comment) || can?(:destroy, comment)
|
||||
.comment-actions
|
||||
- if can? :edit, comment
|
||||
= link_to 'Edit', edit_comment_path(comment), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, comment
|
||||
= link_to 'Delete', comment, method: :delete,
|
||||
data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
= content_for :title, "Recent comments"
|
||||
|
||||
.pagination
|
||||
= page_entries_info @comments
|
||||
= will_paginate @comments
|
||||
|
||||
- @comments.each do |comment|
|
||||
%h2
|
||||
Comment on
|
||||
= link_to comment.post.subject, comment.post
|
||||
= render partial: "single", locals: { comment: comment }
|
||||
|
||||
.pagination
|
||||
= page_entries_info @comments
|
||||
= will_paginate @comments
|
||||
|
||||
%p
|
||||
Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']}
|
||||
= succeed "." do
|
||||
= link_to "comments RSS feed", comments_path(format: 'rss')
|
||||
@@ -1,6 +1,10 @@
|
||||
= content_for :title, "New comment"
|
||||
|
||||
= render partial: "posts/single", locals: { post: @post || @comment.post, subject: true }
|
||||
%section.blog-post
|
||||
.card.post{ id: "post-#{@post.id}" }
|
||||
.card-header
|
||||
%h2.display-3= @post.subject
|
||||
.card-body= render "posts/single", post: @post || @comment.post, subject: true
|
||||
|
||||
= render partial: "posts/comments", locals: { post: @post || @comment.post }
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
= content_for :title, @comment.post.subject
|
||||
- content_for :opengraph do
|
||||
= tag("meta", property: "og:image", content: avatar_uri(@comment.post.author, 200))
|
||||
= tag("meta", property: "og:image:user_generated", content: "true")
|
||||
= tag("meta", property: "og:title", content: @comment.post.subject)
|
||||
= tag("meta", property: "og:description", content: og_description(@comment.post.body))
|
||||
= 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'])
|
||||
|
||||
= render partial: "posts/single", locals: { post: @comment.post }
|
||||
|
||||
%h2 Showing 1 comment
|
||||
|
||||
= render partial: "single", locals: { comment: @comment }
|
||||
|
||||
= link_to "View all comments", post_path(@comment.post)
|
||||
@@ -1,16 +1,16 @@
|
||||
.crop-actions
|
||||
.btn-group
|
||||
- if @crop.approved? && signed_in?
|
||||
.crop-actions
|
||||
- if can? :create, Planting
|
||||
= link_to new_planting_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= link_to new_planting_path(crop_id: crop.id), class: 'btn btn-sm' do
|
||||
= planting_icon
|
||||
= t('buttons.plant_crop', crop_name: crop.name)
|
||||
|
||||
- if can? :create, Harvest
|
||||
= link_to new_harvest_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= link_to new_harvest_path(crop_id: crop.id), class: 'btn btn-sm' do
|
||||
= harvest_icon
|
||||
= t('buttons.harvest_crop', crop_name: crop.name)
|
||||
|
||||
|
||||
- if can? :create, Seed
|
||||
= link_to new_seed_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= link_to new_seed_path(crop_id: crop.id), class: 'btn btn-sm' do
|
||||
= seed_icon
|
||||
= t('buttons.add_seed_to_stash', crop_name: crop.name)
|
||||
|
||||
@@ -3,14 +3,25 @@
|
||||
- if crop.alternate_names.empty?
|
||||
%p None known.
|
||||
- else
|
||||
%ul
|
||||
%ul.list-group.list-group-flush
|
||||
- crop.alternate_names.each do |an|
|
||||
%li
|
||||
= an.name
|
||||
%li.list-group-item.d-flex.justify-content-between.align-items-center
|
||||
- if can? :edit, an
|
||||
= link_to 'Edit', edit_alternate_name_path(an), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, an
|
||||
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_alternate_name_path(crop_id: crop.id), class: 'btn btn-default btn-xs'
|
||||
.dropdown.planting-actions
|
||||
%a#crop-actions-altnames.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button", :href => '#'}
|
||||
= an.name
|
||||
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "crop-actions-altnames"}
|
||||
- if can? :edit, an
|
||||
= link_to edit_alternate_name_path(an), class: 'dropdown-item' do
|
||||
= edit_icon
|
||||
= t('.edit')
|
||||
- if can? :destroy, an
|
||||
= link_to an, method: :delete, data: { confirm: 'Are you sure?' }, class: 'dropdown-item' do
|
||||
= delete_icon
|
||||
= t('.delete')
|
||||
- else
|
||||
= an.name
|
||||
|
||||
%p.text-right
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_alternate_name_path(crop_id: crop.id), class: 'btn btn-default btn-xs'
|
||||
|
||||
30
app/views/crops/_crop.html.haml
Normal file
@@ -0,0 +1,30 @@
|
||||
.card.card-crop
|
||||
.crop-image
|
||||
= link_to image_tag(crop_image_path(crop, full_size: true),
|
||||
alt: '',
|
||||
class: 'img img-card'),
|
||||
crop
|
||||
|
||||
.card-body
|
||||
%h3.card-title= link_to crop, crop
|
||||
%p.crop-sci-name= crop.default_scientific_name
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
%p.card-text
|
||||
Median Lifespan
|
||||
%b= crop.median_lifespan
|
||||
days
|
||||
- unless crop.median_days_to_first_harvest.nil?
|
||||
%p.card-text
|
||||
First harvest expected
|
||||
%b= crop.median_days_to_first_harvest
|
||||
days after planting
|
||||
|
||||
- if crop.annual? && crop.median_days_to_last_harvest.present?
|
||||
%p.card-text
|
||||
Last harvest expected
|
||||
%b= crop.median_days_to_last_harvest
|
||||
days after planting
|
||||
- if member_signed_in?
|
||||
.card-footer
|
||||
= crop_plant_button(crop)
|
||||
= crop_save_seeds_button(crop)
|
||||
@@ -1,22 +1,36 @@
|
||||
%h4 Find #{crop.name} seeds
|
||||
- if crop.seeds.empty?
|
||||
%p
|
||||
There are no seeds available to trade on Growstuff right now.
|
||||
- else
|
||||
%ul
|
||||
- crop.seeds.tradable.each do |seed|
|
||||
%li
|
||||
= link_to "#{seed.owner} will trade #{seed.tradable_to}.", seed_path(seed)
|
||||
= render partial: 'members/location', locals: { member: seed.owner }
|
||||
%p
|
||||
= link_to "View all #{crop.name} seeds", crop_seeds_path(crop)
|
||||
%p
|
||||
= link_to "Purchase seeds via Ebay",
|
||||
crop_ebay_seeds_url(crop),
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "List #{crop.name} seeds to trade", new_seed_path(crop_id: crop.id)
|
||||
.card
|
||||
.card-header
|
||||
%h5.card-title Find #{crop.name} seeds
|
||||
- if crop.seeds.empty?
|
||||
.card-body
|
||||
%p There are no seeds available to trade on Growstuff right now.
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: 'list your seeds to trade' }
|
||||
%ul.list-group
|
||||
- crop.seeds.tradable.each do |seed|
|
||||
%li.list-group-item
|
||||
= link_to "#{seed.owner} will trade #{seed.tradable_to}.", seed_path(seed), class: 'card-link'
|
||||
= render 'members/location', member: seed.owner
|
||||
%li.list-group-item.d-flex.justify-content-between.align-items-center
|
||||
= link_to crop_seeds_path(crop), class: 'card-link' do
|
||||
= seed_icon
|
||||
View all #{crop.name} seeds
|
||||
%span.badge.badge-primary.badge-pill=crop.seeds.size
|
||||
|
||||
%ul.list-group
|
||||
%li.list-group-item
|
||||
= link_to crop_ebay_seeds_url(crop), class: 'card-link',
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer" do
|
||||
= icon 'fas', 'money-check-alt'
|
||||
Purchase seeds via Ebay
|
||||
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%li.list-group-item
|
||||
= link_to new_seed_path(crop_id: crop.id), class: 'card-link' do
|
||||
= seed_icon
|
||||
List #{crop.name} seeds to trade
|
||||
- else
|
||||
%li.list-group-item.active
|
||||
= icon 'fas', 'user'
|
||||
= render partial: 'shared/signin_signup', locals: { to: 'list your seeds to trade' }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
= form_for @crop, html: { class: 'form-horizontal', role: "form" } do |f|
|
||||
= bootstrap_form_for(@crop) do |f|
|
||||
- if @crop.errors.any?
|
||||
#error_explanation
|
||||
#error_explanation.alert.alert-warning{role: "alert"}
|
||||
%h3
|
||||
= pluralize(@crop.errors.size, "error")
|
||||
prohibited this crop from being saved:
|
||||
@@ -8,121 +8,99 @@
|
||||
- @crop.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
-# Handy link to crop wrangling policy/style guide, shown to wranglers only
|
||||
- if can? :wrangle, @crop
|
||||
%p
|
||||
%span.help-block
|
||||
For detailed crop wrangling guidelines, please consult the
|
||||
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
on the Growstuff wiki.
|
||||
.card.col-12.col-md-8.mx-auto.float-none.white
|
||||
.card-header
|
||||
- if content_for? :title
|
||||
%h1.h2-responsive.text-center
|
||||
%strong=yield :title
|
||||
.card-body
|
||||
-# Handy link to crop wrangling policy/style guide, shown to wranglers only
|
||||
- if can? :wrangle, @crop
|
||||
%p
|
||||
%span.help-block
|
||||
For detailed crop wrangling guidelines, please consult the
|
||||
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
on the Growstuff wiki.
|
||||
|
||||
-# Everyone (wranglers and requesters) sees the basic info section
|
||||
%h2 Basic information
|
||||
-# Everyone (wranglers and requesters) sees the basic info section
|
||||
%h2 Basic information
|
||||
|
||||
.form-group#new_crop
|
||||
= f.label :name, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :name, class: 'form-control'
|
||||
.form-group#new_crop
|
||||
= f.text_field :name
|
||||
%span.help-block
|
||||
The common name for the crop, in English (required).
|
||||
- if can? :wrangle, @crop
|
||||
Wranglers: please ensure this is singular, and capitalize
|
||||
proper nouns only.
|
||||
|
||||
.form-group
|
||||
= f.label :perennial, 'Lifespan', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.radio_button(:perennial, false)
|
||||
= f.label(:perennial_false, "Annual")
|
||||
%span.help-block Living and reproducing in a single year or less
|
||||
= f.radio_button(:perennial, true)
|
||||
= f.label(:perennial_true, "Perennial")
|
||||
%span.help-block Living more than two years
|
||||
%h2 Lifespan
|
||||
%p
|
||||
= f.radio_button(:perennial, false, label: 'Annual')
|
||||
%span.help-block Living and reproducing in a single year or less
|
||||
%p
|
||||
= f.radio_button(:perennial, true, label: "Perennial")
|
||||
%span.help-block Living more than two years
|
||||
|
||||
.form-group
|
||||
= f.label :en_wikipedia_url, 'Wikipedia URL', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :en_wikipedia_url, class: 'form-control', id: "en_wikipedia_url"
|
||||
= f.text_field :en_wikipedia_url, id: "en_wikipedia_url", label: 'Wikipedia URL'
|
||||
%span.help-block
|
||||
Link to the crop's page on the English language Wikipedia (required).
|
||||
|
||||
-# Only crop wranglers see the crop hierarchy (for now)
|
||||
- if can? :wrangle, @crop
|
||||
.form-group
|
||||
= f.label :parent_id, 'Parent crop', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= collection_select(:crop, :parent_id, Crop.all.order(:name), :id, :name,
|
||||
{ include_blank: true }, class: 'form-control')
|
||||
-# Only crop wranglers see the crop hierarchy (for now)
|
||||
- if can? :wrangle, @crop
|
||||
= f.collection_select(:parent_id, Crop.all.order(:name), :id, :name,
|
||||
{ include_blank: true, label: 'Parent crop'})
|
||||
%span.help-block Optional. For setting up crop hierarchies for varieties etc.
|
||||
|
||||
|
||||
-# Everyone (wranglers and requesters) gets to add scientific names
|
||||
%h2
|
||||
Scientific names
|
||||
= button_tag "+", id: "add-sci_name-row", type: "button"
|
||||
= button_tag "-", id: "remove-sci_name-row", type: "button"
|
||||
-# Everyone (wranglers and requesters) gets to add scientific names
|
||||
%h2 Scientific names
|
||||
= button_tag "+", id: "add-sci_name-row", type: "button"
|
||||
= button_tag "-", id: "remove-sci_name-row", type: "button"
|
||||
|
||||
.form-group#scientific_names
|
||||
- @crop.scientific_names.each.with_index do |sci, index|
|
||||
.template.col-md-12{ id: "sci_template[#{index + 1}]" }
|
||||
.col-md-2
|
||||
= label_tag :scientific_names, "Scientific name #{index + 1}:", class: 'control-label'
|
||||
.col-md-8
|
||||
= text_field_tag "sci_name[#{index + 1}]", sci.name, id: "sci_name[#{index + 1}]", class: 'form-control'
|
||||
%span.help-block Scientific name of crop.
|
||||
.col-md-2
|
||||
.form-group#scientific_names
|
||||
- @crop.scientific_names.each.with_index do |sci, index|
|
||||
.template.col-12{ id: "sci_template[#{index + 1}]" }
|
||||
.col-2
|
||||
= label_tag :scientific_names, "Scientific name #{index + 1}:", class: 'control-label'
|
||||
.col-8
|
||||
= text_field_tag "sci_name[#{index + 1}]", sci.name, id: "sci_name[#{index + 1}]", class: 'form-control'
|
||||
%span.help-block Scientific name of crop.
|
||||
%h2 Alternate names
|
||||
= button_tag "+", id: "add-alt_name-row", type: "button"
|
||||
= button_tag "-", id: "remove-alt_name-row", type: "button"
|
||||
|
||||
%h2
|
||||
Alternate names
|
||||
= button_tag "+", id: "add-alt_name-row", type: "button"
|
||||
= button_tag "-", id: "remove-alt_name-row", type: "button"
|
||||
.form-group#alternate_names
|
||||
- @crop.alternate_names.each.with_index do |alt, index|
|
||||
.template.col-12{ id: "alt_template[#{index + 1}]" }
|
||||
.col-2
|
||||
= label_tag :alternate_names, "Alternate name #{index + 1}:", class: 'control-label'
|
||||
.col-8
|
||||
= text_field_tag "alt_name[#{index + 1}]", alt.name, id: "alt_name[#{index + 1}]", class: 'form-control'
|
||||
%span.help-block Alternate name of crop.
|
||||
.col-2
|
||||
|
||||
.form-group#alternate_names
|
||||
- @crop.alternate_names.each.with_index do |alt, index|
|
||||
.template.col-md-12{ id: "alt_template[#{index + 1}]" }
|
||||
.col-md-2
|
||||
= label_tag :alternate_names, "Alternate name #{index + 1}:", class: 'control-label'
|
||||
.col-md-8
|
||||
= text_field_tag "alt_name[#{index + 1}]", alt.name, id: "alt_name[#{index + 1}]", class: 'form-control'
|
||||
%span.help-block Alternate name of crop.
|
||||
.col-md-2
|
||||
-# This is used for comments from crop requesters. We need to show it
|
||||
-# to everyone, but we don't include it on new crops from wranglers.
|
||||
|
||||
-# This is used for comments from crop requesters. We need to show it
|
||||
-# to everyone, but we don't include it on new crops from wranglers.
|
||||
- if (can?(:wrangle, @crop) && @crop.requester) || (cannot?(:wrangle, @crop) && @crop.new_record?)
|
||||
%h2 Crop request notes
|
||||
= f.text_area :request_notes, rows: 3, id: 'request_notes', label: 'Comments'
|
||||
|
||||
- if (can?(:wrangle, @crop) && @crop.requester) || (cannot?(:wrangle, @crop) && @crop.new_record?)
|
||||
%h2 Crop request notes
|
||||
.form-group
|
||||
= f.label :request_notes, 'Comments', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_area :request_notes, rows: 3, class: 'form-control', id: 'request_notes'
|
||||
-# A final explanation of what's going to happen next, for crop requesters
|
||||
- unless can? :wrangle, @crop
|
||||
%p
|
||||
When you submit this form, your suggestion will be sent to our team of
|
||||
volunteer crop wranglers for review. We'll let you know the outcome as soon as we can.
|
||||
|
||||
-# A final explanation of what's going to happen next, for crop requesters
|
||||
- unless can? :wrangle, @crop
|
||||
%p
|
||||
When you submit this form, your suggestion will be sent to our team of
|
||||
volunteer crop wranglers for review. We'll let you know the outcome as soon as we can.
|
||||
-# Now, for crop wranglers, let's have approval/rejection at the bottom of the page
|
||||
- if can?(:wrangle, @crop) && @crop.requester
|
||||
%h2 Approve or reject pending crops
|
||||
= f.select(:approval_status, @crop.approval_statuses, {})
|
||||
= f.select(:reason_for_rejection, @crop.reasons_for_rejection, include_blank: true)
|
||||
|
||||
-# Now, for crop wranglers, let's have approval/rejection at the bottom of the page
|
||||
- if can?(:wrangle, @crop) && @crop.requester
|
||||
%h2 Approve or reject pending crops
|
||||
.form-group
|
||||
= f.label :approval_status, 'Approval status', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.select(:approval_status, @crop.approval_statuses, {}, class: 'form-control')
|
||||
|
||||
.form-group
|
||||
= f.label :reason_for_rejection, 'Reason for rejection', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.select(:reason_for_rejection, @crop.reasons_for_rejection, include_blank: true, class: 'form-control')
|
||||
|
||||
.form-group
|
||||
= f.label :rejection_notes, 'Rejection notes', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_area :rejection_notes, rows: 3, class: 'form-control'
|
||||
= f.text_area :rejection_notes, rows: 3
|
||||
%span.help-block
|
||||
Please provide additional notes why this crop request was rejected if the above reasons do not apply.
|
||||
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit 'Save', class: 'btn btn-primary'
|
||||
.card-footer
|
||||
.text-right= f.submit 'Save'
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
%h4 #{crop.name.capitalize} harvests
|
||||
- if crop.harvests.empty?
|
||||
%p
|
||||
Nobody has harvested this crop yet.
|
||||
- else
|
||||
%ul
|
||||
- crop.harvests.order(harvested_at: :desc).limit(3).each do |harvest|
|
||||
%li
|
||||
= link_to "#{harvest.owner} harvested #{display_quantity(harvest)}.", harvest_path(harvest)
|
||||
= render 'members/location', member: harvest.owner
|
||||
%small
|
||||
= distance_of_time_in_words(harvest.harvested_at, Time.zone.now)
|
||||
ago.
|
||||
%p
|
||||
= link_to "View all #{crop.name} harvests", crop_harvests_path(crop)
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "Harvest #{crop.name}", new_harvest_path(crop_id: crop.id)
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: "track your #{crop.name} harvests" }
|
||||
.card
|
||||
.card-body
|
||||
%h3 #{crop.name.capitalize} harvests
|
||||
- if crop.harvests.empty?
|
||||
%p Nobody has harvested this crop yet.
|
||||
- unless crop.harvests.empty?
|
||||
%ul.list-group.list-group-flush
|
||||
- crop.harvests.order(harvested_at: :desc).limit(3).each do |harvest|
|
||||
%li.list-group-item
|
||||
= link_to harvest_path(harvest), class: 'card-link' do
|
||||
= harvest_icon
|
||||
#{harvest.owner} harvested #{display_quantity(harvest)}.
|
||||
.float-right= render 'members/location', member: harvest.owner
|
||||
.harvest-timeago
|
||||
%small #{distance_of_time_in_words(harvest.harvested_at, Time.zone.now)} ago.
|
||||
.card-footer
|
||||
%p= link_to "View all #{crop.name} harvests", crop_harvests_path(crop), class: 'card-link'
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "Harvest #{crop.name}", new_harvest_path(crop_id: crop.id), class: 'btn btn-block'
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: "track your #{crop.name} harvests" }
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
.well
|
||||
.row
|
||||
.col-md-4
|
||||
= link_to image_tag(crop_image_path(crop),
|
||||
alt: '',
|
||||
class: 'img crop-image'),
|
||||
crop
|
||||
.col-md-8
|
||||
%h3{ style: 'padding-top: 0px; margin-top: 0px' }
|
||||
= link_to crop, crop
|
||||
|
||||
%p
|
||||
%b Scientific name:
|
||||
= crop.default_scientific_name
|
||||
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
%p
|
||||
Median Lifespan
|
||||
%b= crop.median_lifespan
|
||||
days
|
||||
- unless crop.median_days_to_first_harvest.nil?
|
||||
%p
|
||||
First harvest expected
|
||||
%b= crop.median_days_to_first_harvest
|
||||
days after planting
|
||||
|
||||
- if crop.annual? && crop.median_days_to_last_harvest.present?
|
||||
%p
|
||||
Last harvest expected
|
||||
%b= crop.median_days_to_last_harvest
|
||||
days after planting
|
||||
|
||||
- if can? :create, Planting
|
||||
= link_to "Plant #{crop.name}", new_planting_path(params: { crop_id: crop.id }), class: 'btn btn-primary'
|
||||
- if can? :create, Seed
|
||||
= link_to "Add #{crop.name} seeds to stash", new_seed_path(params: { crop_id: crop.id }), class: 'btn btn-primary'
|
||||
@@ -1,10 +1,9 @@
|
||||
- [Planting, Harvest, Seed].each do |model_name|
|
||||
.row
|
||||
.col-md-12
|
||||
%h3
|
||||
= @crop.name
|
||||
= t("activerecord.models.#{model_name.to_s.downcase}.other")
|
||||
.row
|
||||
- photos.by_model(model_name).limit(6).each do |photo|
|
||||
.col-md-2.six-across
|
||||
.thumbnail= link_to image_tag(photo.thumbnail_url, alt: photo.title, class: 'img'), photo
|
||||
- if @crop.photos.size.positive?
|
||||
%h2 #{photo_icon} Photos
|
||||
- [Planting, Harvest, Seed].each do |model_name|
|
||||
- if photos.by_model(model_name).size.positive?
|
||||
%h3 #{@crop.name.capitalize} #{t("activerecord.models.#{model_name.to_s.downcase}.other")}
|
||||
= render 'photos/gallery', photos: photos.by_model(model_name).limit(8)
|
||||
|
||||
= link_to 'more photos »', crop_photos_path(@crop), class: 'btn'
|
||||
%hr/
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
%h4 See who's planted #{crop.name.pluralize}
|
||||
- if crop.plantings.empty?
|
||||
%p
|
||||
Nobody has planted this crop yet.
|
||||
- else
|
||||
%ul
|
||||
- crop.plantings.order(planted_at: :desc).limit(3).each do |planting|
|
||||
%li
|
||||
= link_to planting, planting_path(planting)
|
||||
= render partial: 'members/location', locals: { member: planting.owner }
|
||||
%small
|
||||
= distance_of_time_in_words(planting.created_at, Time.zone.now)
|
||||
ago.
|
||||
%p
|
||||
= link_to "View all #{crop.name} plantings", crop_plantings_path(crop)
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "Plant #{crop.name}", new_planting_path(crop_id: crop.id)
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: "track your #{crop.name} plantings" }
|
||||
.card
|
||||
.card-body
|
||||
%h3 See who's planted #{crop.name.pluralize}
|
||||
- unless crop.plantings.empty?
|
||||
%ul.list-group.list-group-flush
|
||||
- crop.plantings.order(planted_at: :desc).limit(5).each do |planting|
|
||||
%li.list-group-item
|
||||
= link_to planting, class: 'card-link' do
|
||||
= planting_icon
|
||||
= planting
|
||||
.float-right= render 'members/location', member: planting.owner
|
||||
.card-footer
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "Plant #{crop.name}", new_planting_path(crop_id: crop.id), class: 'btn btn-block'
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: "track your #{crop.name} plantings" }
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
- else
|
||||
.pagination
|
||||
= page_entries_info @posts
|
||||
= will_paginate @posts, params: { anchor: "posts" }
|
||||
= render 'layouts/pagination', collection: @posts
|
||||
- @posts.each do |post|
|
||||
= render partial: "posts/single", locals: { post: post, subject: true }
|
||||
= render 'posts/preview', post: post
|
||||
|
||||
.pagination
|
||||
= page_entries_info @posts
|
||||
= will_paginate @posts, params: { anchor: "posts" }
|
||||
= render 'layouts/pagination', collection: @posts
|
||||
|
||||
|
||||
@@ -1,32 +1,49 @@
|
||||
.predictions
|
||||
%h3
|
||||
= icon 'fas', 'magic'
|
||||
Predictions
|
||||
.card-deck.mx-auto.predictions
|
||||
- unless crop.perennial.nil?
|
||||
.row
|
||||
.col-md-12
|
||||
%p
|
||||
#{crop.name} is
|
||||
.col
|
||||
.card.predictions-card
|
||||
.card-body.text-center
|
||||
%h3
|
||||
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
|
||||
- if crop.perennial == true
|
||||
Perennial
|
||||
- elsif crop.perennial == false
|
||||
Annual
|
||||
|
||||
%p.display-1
|
||||
%i.far.fa-calendar
|
||||
|
||||
- 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)
|
||||
%small 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)
|
||||
.row
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
.prediction-metric.col-md-3.col-xs-5
|
||||
%h3 Median lifespan
|
||||
%strong= crop.median_lifespan
|
||||
%span days
|
||||
%small living and reproducing in a single year or less
|
||||
|
||||
- if crop.median_days_to_first_harvest.present?
|
||||
.prediction-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_lifespan.present?
|
||||
.col
|
||||
.card.predictions-card
|
||||
.card-body.text-center
|
||||
%h3 Median lifespan
|
||||
%p.display-1= crop.median_lifespan
|
||||
%i.fas.fa-sun-o.fa-5x.pt-3.amber-text
|
||||
%span days
|
||||
|
||||
|
||||
- if crop.median_days_to_first_harvest.present?
|
||||
.col
|
||||
.card.predictions-card
|
||||
.card-body.text-center
|
||||
%h3 First harvest expected
|
||||
%p.display-1= crop.median_days_to_first_harvest
|
||||
%span days after planting
|
||||
|
||||
- if crop.annual? && crop.median_days_to_last_harvest.present?
|
||||
.col
|
||||
.card.predictions-card
|
||||
.card-body.text-center
|
||||
%h3 Last harvest expected
|
||||
%p.display-1= crop.median_days_to_last_harvest
|
||||
%span days after planting
|
||||
|
||||
- if crop.annual? && crop.median_days_to_last_harvest.present?
|
||||
.prediction-metric.col-md-3.col-xs-5
|
||||
%h3 Last harvest expected
|
||||
%strong= crop.median_days_to_last_harvest
|
||||
%span days after planting
|
||||
|
||||
@@ -3,14 +3,23 @@
|
||||
- if crop.scientific_names.empty?
|
||||
%p None known.
|
||||
- else
|
||||
%ul
|
||||
%ul.list-group.list-group-flush
|
||||
- crop.scientific_names.each do |sn|
|
||||
%li
|
||||
= sn.name
|
||||
%li.list-group-item.d-flex.justify-content-between.align-items-center
|
||||
- if can? :edit, sn
|
||||
= link_to 'Edit', edit_scientific_name_path(sn), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, sn
|
||||
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_scientific_name_path(crop_id: crop.id), class: 'btn btn-default btn-xs'
|
||||
.dropdown.planting-actions
|
||||
%a#planting-actions-scinames.dropdown-toggle.card-link{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button", :href => '#'}= sn.name
|
||||
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "planting-actions-button"}
|
||||
= link_to edit_scientific_name_path(sn), class: 'dropdown-item' do
|
||||
= edit_icon
|
||||
= t('.edit')
|
||||
.dropdown-divider
|
||||
= link_to sn, method: :delete, data: { confirm: 'Are you sure?' }, class: 'dropdown-item text-danger' do
|
||||
= delete_icon
|
||||
= t('.delete')
|
||||
- else
|
||||
= sn.name
|
||||
|
||||
%p.text-right
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_scientific_name_path(crop_id: crop.id), class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
= form_tag search_crops_path, method: :get, id: 'navbar-search' do
|
||||
= label_tag :term, "Search crop database:", class: 'sr-only'
|
||||
.input
|
||||
.input-group
|
||||
= text_field_tag 'term', nil, class: 'search-query input-medium form-control', placeholder: 'Search crops'
|
||||
.input-group-btn
|
||||
%button.btn.btn-default{ style: "height: 34px;" }
|
||||
= submit_tag "Search", class: 'btn sr-only'
|
||||
%span.glyphicon.glyphicon-search
|
||||
= form_tag search_crops_path, method: :get, class: 'form-inline', id: 'navbar-search' do
|
||||
.input-group
|
||||
%input.form-control{name: 'term', "aria-label" => "Search crops", placeholder: "Search crops", type: "search", id: 'term' }/
|
||||
%button.btn.btn-default.text-white{type: "submit"}
|
||||
= icon 'fas', 'search'
|
||||
.sr-only Search
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
- cache cache_key_for(Crop, crop.id) do
|
||||
.thumbnail
|
||||
.crop-thumbnail
|
||||
- if crop
|
||||
= link_to image_tag(crop_image_path(crop),
|
||||
alt: crop.name, class: 'img'),
|
||||
crop
|
||||
.cropinfo
|
||||
.cropname
|
||||
= link_to crop.name, crop
|
||||
- unless crop.scientific_names.empty?
|
||||
.scientificname
|
||||
= crop.scientific_names.first.name
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
.planting-lifespan
|
||||
lifespan
|
||||
%strong= crop.median_lifespan
|
||||
days
|
||||
.card.card-crop
|
||||
.crop-image
|
||||
= link_to image_tag(crop_image_path(crop, full_size: true),
|
||||
alt: crop.name,
|
||||
class: 'img img-card'),
|
||||
crop
|
||||
|
||||
.card-body
|
||||
%h3.text-center.crop-name= link_to crop, crop
|
||||
%p.small.crop-sci-name.text-center= crop.default_scientific_name
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
- if can?(:edit, crop) || can?(:destroy, crop)
|
||||
%h4 Crop wrangling
|
||||
%p
|
||||
You are a
|
||||
= succeed "." do
|
||||
.alert.alert-success{role: "alert"}
|
||||
%h4 Crop wrangling
|
||||
%p
|
||||
You are a
|
||||
%strong CROP WRANGLER
|
||||
.dropdown.crop-actions
|
||||
%a#crop-actions-button.btn.btn-info.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button", href: '#'} Actions
|
||||
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "crop-actions-button"}
|
||||
= link_to edit_crop_path(crop), class: 'dropdown-item' do
|
||||
= edit_icon
|
||||
= t('.edit')
|
||||
|
||||
- if can? :destroy, crop
|
||||
.dropdown-divider
|
||||
= delete_button(crop, classes: 'dropdown-item text-danger')
|
||||
|
||||
%p= crop_edit_button(crop) if can? :edit, crop
|
||||
%p= delete_button(crop) if can? :destroy, crop
|
||||
|
||||
@@ -1,42 +1,38 @@
|
||||
- content_for :title, t('.title')
|
||||
- content_for :subtitle, t('.subtitle', crops_size: @crops.size)
|
||||
|
||||
- if can? :wrangle, Crop
|
||||
= link_to 'Wrangle Crops', wrangle_crops_path, class: 'btn btn-primary'
|
||||
- content_for :buttonbar do
|
||||
- if can? :wrangle, Crop
|
||||
= link_to 'Wrangle Crops', wrangle_crops_path, class: 'btn btn-secondary'
|
||||
- if can? :create, Crop
|
||||
= link_to 'Add New Crop', new_crop_path, class: 'btn btn-primary'
|
||||
|
||||
- if @num_requested_crops && @num_requested_crops.positive?
|
||||
= link_to(I18n.t('crops.requested.link', number_crops: @num_requested_crops), requested_crops_path)
|
||||
- content_for :breadcrumbs do
|
||||
%li.breadcrumb-item.active= link_to 'Crops', crops_path
|
||||
|
||||
%h1=t('.title')
|
||||
%p
|
||||
#{ENV['GROWSTUFF_SITE_NAME']} tracks who's growing what, where.
|
||||
View any crop page to see which of our members have planted it and find
|
||||
information on how to grow it yourself.
|
||||
|
||||
= form_tag(crops_path, method: :get, class: 'form-inline', role: 'form') do
|
||||
.form-group
|
||||
= label_tag :sort, "Sort by:", class: 'sr-only'
|
||||
= select_tag "sort",
|
||||
options_for_select({ "Sort by popularity": 'popular',
|
||||
"Sort alphabetically": 'alpha' },
|
||||
@sort || 'popular'),
|
||||
class: 'form-control'
|
||||
= submit_tag "Show", class: 'btn btn-primary'
|
||||
|
||||
.pagination
|
||||
= will_paginate @crops
|
||||
= bootstrap_form_tag(url: crops_path, method: :get, layout: :inline) do |f|
|
||||
= f.select "sort",
|
||||
options_for_select({ "popularity": 'popular',
|
||||
"alphabetically": 'alpha' },
|
||||
@sort || 'popular'),
|
||||
label: 'Sort by'
|
||||
= f.submit "Show"
|
||||
|
||||
.row
|
||||
- @crops.each do |crop|
|
||||
.col-md-2.six-across
|
||||
= render partial: "thumbnail", locals: { crop: crop }
|
||||
.pagination= render 'layouts/pagination', collection: @crops
|
||||
|
||||
- if can? :create, Crop
|
||||
%div
|
||||
= link_to 'New Crop', new_crop_path, class: 'btn btn-primary'
|
||||
.crops
|
||||
.row
|
||||
- @crops.each do |crop|
|
||||
.col-6.col-md-3= render 'crops/thumbnail', crop: crop
|
||||
|
||||
.pagination
|
||||
= will_paginate @crops
|
||||
|
||||
.pagination= render 'layouts/pagination', collection: @crops
|
||||
|
||||
%ul.list-inline
|
||||
%li The data on this page is available in the following formats:
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
- if @term
|
||||
- content_for :title, "Crops matching \"#{@term}\""
|
||||
- if @crops
|
||||
- content_for :subtitle, "#{@crops.size} total"
|
||||
- else
|
||||
- content_for :title, "Crop search"
|
||||
- content_for :breadcrumbs do
|
||||
%li.breadcrumb-item= link_to 'Crops', crops_path
|
||||
%li.breadcrumb-item.active= link_to 'Search', search_crops_path(term: @term)
|
||||
|
||||
%div
|
||||
= form_tag search_crops_path, method: :get, id: 'crop-search', class: 'form-inline' do
|
||||
.form-group
|
||||
= label_tag :term, "Search crops:", class: 'sr-only'
|
||||
= text_field_tag 'term', nil,
|
||||
class: 'search-query input-medium form-control',
|
||||
placeholder: 'Search crops',
|
||||
value: @term
|
||||
= submit_tag "Search", class: 'btn btn-primary'
|
||||
%section.crops-search-form
|
||||
|
||||
- if @term
|
||||
- content_for :title, "Crops matching \"#{@term}\""
|
||||
%h1 Crops matching "#{@term}"
|
||||
- if @crops
|
||||
%h2.text-muted Found #{@crops.size} total
|
||||
- else
|
||||
- content_for :title, "Crop search"
|
||||
%h1 Crop search
|
||||
|
||||
|
||||
= bootstrap_form_tag(url: search_crops_path, method: :get, html: { id: 'crop-search'}, layout: :inline) do |f|
|
||||
= f.label :term, "Search crops:", class: 'sr-only'
|
||||
= f.text_field 'term', class: 'search-query input-medium',
|
||||
placeholder: 'Search crops',
|
||||
label: 'crop',
|
||||
value: @term
|
||||
= f.submit "Search", class: 'btn btn-success'
|
||||
|
||||
- if @crops.empty?
|
||||
%h2 No results found
|
||||
@@ -25,13 +32,12 @@
|
||||
instead.
|
||||
|
||||
- else
|
||||
.pagination
|
||||
= will_paginate @crops
|
||||
.pagination= will_paginate @crops
|
||||
|
||||
#paginated_matches
|
||||
.crops
|
||||
.row
|
||||
- @crops.each do |c|
|
||||
.col-md-2.six-across= render partial: "thumbnail", locals: { crop: c }
|
||||
- @crops.each do |crop|
|
||||
.col-6.col-md-3= render 'crops/thumbnail', crop: crop
|
||||
|
||||
.pagination
|
||||
= will_paginate @crops
|
||||
|
||||
.pagination= will_paginate @crops
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
- content_for :title, @crop.name
|
||||
- content_for :subtitle, @crop.default_scientific_name
|
||||
- content_for :opengraph do
|
||||
- @crop.photos.each do |photo|
|
||||
= tag("meta", property: "og:image", content: photo.fullsize_url)
|
||||
@@ -11,114 +10,137 @@
|
||||
- content_for :scripts do
|
||||
= javascript_include_tag "charts"
|
||||
|
||||
= render partial: 'approval_status_message', locals: { crop: @crop }
|
||||
- content_for :breadcrumbs do
|
||||
%li.breadcrumb-item= link_to 'Crops', crops_path
|
||||
%li.breadcrumb-item.active= link_to @crop, @crop
|
||||
|
||||
- if @crop.approved?
|
||||
- content_for :buttonbar do
|
||||
= render 'crops/actions', crop: @crop
|
||||
%h1
|
||||
%strong= @crop.name.titleize
|
||||
%small.text-muted= @crop.default_scientific_name
|
||||
%p= render 'crops/actions', crop: @crop
|
||||
|
||||
= render 'approval_status_message', crop: @crop
|
||||
|
||||
.row
|
||||
.col-md-9
|
||||
%h2
|
||||
%p
|
||||
- if !@crop.plantings.empty?
|
||||
= @crop.name.titleize
|
||||
has been planted
|
||||
#{@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!
|
||||
- if @crop.perennial?
|
||||
#{@crop.name.capitalize} is a perennial crop (living more than two years)
|
||||
- elsif @crop.annual?
|
||||
#{@crop.name.capitalize} is an annual crop (living and reproducing in a single year or less)
|
||||
%hr/
|
||||
|
||||
|
||||
%h3 Predictions
|
||||
= render 'predictions', crop: @crop
|
||||
%hr/
|
||||
= render 'crops/photos', photos: @photos, crop: @crop
|
||||
|
||||
|
||||
%h2 Photos
|
||||
%p= render 'crops/photos', photos: @photos
|
||||
%p= link_to 'more photos', crop_photos_path(@crop)
|
||||
|
||||
.row
|
||||
.col-md-3
|
||||
%h3 Sunniness
|
||||
.card-deck.text-center
|
||||
.col-md-4
|
||||
%h3.section-heading.h3.pt-4 Sunniness
|
||||
= pie_chart crop_sunniness_path(@crop, format: :json), legend: "bottom"
|
||||
.col-md-3
|
||||
%h3 Planted from
|
||||
.col-md-4
|
||||
%h3.section-heading.h3.pt-4 Planted from
|
||||
= pie_chart crop_planted_from_path(@crop, format: :json), legend: "bottom"
|
||||
.col-md-3
|
||||
%h3 Harvested for
|
||||
.col-md-4
|
||||
%h3.section-heading.h3.pt-4 Harvested for
|
||||
= pie_chart crop_harvested_for_path(@crop, format: :json), legend: "bottom"
|
||||
|
||||
.varieties= render 'varieties', crop: @crop
|
||||
|
||||
%h3 Crop Map
|
||||
%h3
|
||||
= icon 'fas', 'map'
|
||||
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
|
||||
= render 'crops/posts', crop: @crop
|
||||
= render 'crops/posts', crop: @crop
|
||||
|
||||
.col-md-3
|
||||
= render 'wrangle', crop: @crop
|
||||
.card
|
||||
.crop-image
|
||||
= image_tag crop_image_path(@crop, full_size: true),
|
||||
class: 'img-card', alt: 'photo of crop'
|
||||
.card-body
|
||||
%h4 How to grow #{@crop.name.pluralize}
|
||||
= render 'grown_for', crop: @crop
|
||||
= render 'planting_advice', crop: @crop
|
||||
- if @crop.parent
|
||||
%hr/
|
||||
%p.parent-crop
|
||||
= @crop.name
|
||||
is a variety of
|
||||
= link_to @crop.parent, @crop.parent
|
||||
.list-group.list-group-flush
|
||||
.list-group-item.list-group-flush.d-flex.justify-content-between.align-items-center
|
||||
= link_to crop_plantings_path(@crop), class: 'card-link' do
|
||||
= planting_icon
|
||||
#{@crop.name.capitalize} plantings
|
||||
%span.badge.badge-primary.badge-pill=@crop.plantings.size
|
||||
.list-group-item.d-flex.justify-content-between.align-items-center
|
||||
= link_to crop_harvests_path(@crop), class: 'card-link' do
|
||||
= harvest_icon
|
||||
#{@crop.name.capitalize} harvests
|
||||
%span.badge.badge-primary.badge-pill=@crop.harvests.size
|
||||
|
||||
= render partial: 'wrangle', locals: { crop: @crop }
|
||||
.list-group-item.d-flex.justify-content-between.align-items-center
|
||||
= link_to crop_seeds_path(@crop), class: 'card-link' do
|
||||
= seed_icon
|
||||
#{@crop.name.capitalize} seeds
|
||||
%span.badge.badge-primary.badge-pill=@crop.seeds.size
|
||||
|
||||
%p
|
||||
%li
|
||||
= link_to crop_seeds_path(@crop) do
|
||||
View all #{@crop.name} seeds
|
||||
(#{@crop.seeds.size})
|
||||
%li
|
||||
= link_to crop_plantings_path(@crop) do
|
||||
View all #{@crop.name} plantings
|
||||
(#{@crop.plantings.size})
|
||||
%li
|
||||
= link_to crop_harvests_path(@crop) do
|
||||
View all #{@crop.name} harvests
|
||||
(#{@crop.harvests.size})
|
||||
- if member_signed_in?
|
||||
%p
|
||||
= link_to member_seeds_path(current_member, crop_slug: @crop.slug) do
|
||||
= display_seed_availability(@current_member, @crop)
|
||||
- if member_signed_in?
|
||||
.list-group-item.d-flex.justify-content-between.align-items-center
|
||||
= link_to member_seeds_path(current_member, crop_slug: @crop.slug) do
|
||||
= display_seed_availability(@current_member, @crop)
|
||||
|
||||
%h4 How to grow #{@crop.name.pluralize}
|
||||
|
||||
= render 'grown_for', crop: @crop
|
||||
= render 'planting_advice', crop: @crop
|
||||
|
||||
= render 'scientific_names', crop: @crop
|
||||
= render 'alternate_names', crop: @crop
|
||||
|
||||
- if @crop.parent
|
||||
.parent-crop
|
||||
= @crop.name
|
||||
is a variety of
|
||||
= succeed "." do
|
||||
= link_to @crop.parent, @crop.parent
|
||||
= render 'crops/thumbnail', crop: @crop.parent
|
||||
.card-body
|
||||
= render 'scientific_names', crop: @crop
|
||||
= render 'alternate_names', crop: @crop
|
||||
|
||||
= render 'plantings', crop: @crop
|
||||
= render 'harvests', crop: @crop
|
||||
= render 'find_seeds', crop: @crop
|
||||
|
||||
.card
|
||||
.card-body
|
||||
%h5.card-title Learn more about #{@crop.name.pluralize}
|
||||
%h6.card-subtitle.mb-2.text-muted resources outside #{ENV['GROWSTUFF_SITE_NAME']}
|
||||
|
||||
%h4 Learn more about #{@crop.name.pluralize}
|
||||
%ul
|
||||
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url, target: "_blank", rel: "noopener noreferrer"
|
||||
%li
|
||||
= link_to "OpenFarm - Growing guide", "https://openfarm.cc/en/crops/#{CGI.escape @crop.name}",
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
%li
|
||||
= link_to "Gardenate - Planting reminders", "http://www.gardenate.com/plant/#{CGI.escape @crop.name}",
|
||||
target: "_blank", rel: "noopener noreferrer"
|
||||
- if current_member && current_member.location
|
||||
%li
|
||||
= link_to "Google",
|
||||
'http://www.google.com/search?q=' + CGI.escape(['Growing',
|
||||
@crop.name,
|
||||
current_member.location].join(' ')),
|
||||
%ul.list-group.list-group-flush
|
||||
%li.list-group-item
|
||||
= link_to @crop.en_wikipedia_url, target: "_blank", rel: "noopener noreferrer" do
|
||||
= icon 'fas', 'external-link-alt'
|
||||
Wikipedia (English)
|
||||
|
||||
%li.list-group-item
|
||||
= link_to "https://openfarm.cc/en/crops/#{CGI.escape @crop.name}",
|
||||
class: 'card-link',
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
rel: "noopener noreferrer" do
|
||||
= icon 'fas', 'external-link-alt'
|
||||
OpenFarm - Growing guide
|
||||
%li.list-group-item
|
||||
= link_to "http://www.gardenate.com/plant/#{CGI.escape @crop.name}",
|
||||
target: "_blank",
|
||||
class: 'card-link',
|
||||
rel: "noopener noreferrer" do
|
||||
= icon 'fas', 'external-link-alt'
|
||||
Gardenate - Planting reminders
|
||||
- if current_member && current_member.location
|
||||
%li.list-group-item
|
||||
= link_to 'http://www.google.com/search?q=' + CGI.escape(['Growing', @crop.name, current_member.location].join(' ')),
|
||||
target: "_blank",
|
||||
class: 'card-link',
|
||||
rel: "noopener noreferrer" do
|
||||
= icon 'fas', 'external-link-alt'
|
||||
Google
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
- content_for :title, "Resend confirmation instructions"
|
||||
|
||||
= form_for(resource, as: resource_name,
|
||||
url: confirmation_path(resource_name),
|
||||
html: { method: :post, class: 'form-horizontal', role: 'form' }) do |f|
|
||||
= devise_error_messages!
|
||||
.form-page
|
||||
.card.form-card
|
||||
%h2 Resend confirmation instructions
|
||||
= form_for(resource, as: resource_name,
|
||||
url: confirmation_path(resource_name),
|
||||
html: { method: :post, class: 'form-horizontal', role: 'form' }) do |f|
|
||||
= render 'devise/shared/error_messages', resource: resource
|
||||
%p Enter either your login name or your email address to resend the confirmation email.
|
||||
|
||||
%p Enter either your login name or your email address to resend the confirmation email.
|
||||
= f.text_field :login, class: 'form-control', placeholder: 'email or login name'
|
||||
= f.submit "Resend confirmation instructions", class: 'btn btn-block my-4 btn-primary'
|
||||
|
||||
.form-group
|
||||
= f.label :login, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :login, class: 'form-control'
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit "Resend confirmation instructions", class: 'btn btn-primary'
|
||||
|
||||
.form-group
|
||||
.col-md-offset-2.col-md-8
|
||||
= render "devise/shared/links"
|
||||
.form-group
|
||||
.col-md-offset-2.col-md-8
|
||||
= render "devise/shared/links"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
= form_for(resource, as: resource_name,
|
||||
url: password_path(resource_name),
|
||||
html: { method: :put, class: 'form-horizontal', role: 'form' }) do |f|
|
||||
= devise_error_messages!
|
||||
= render 'devise/shared/error_messages', resource: resource
|
||||
= f.hidden_field :reset_password_token
|
||||
|
||||
.form-group
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
- content_for :title, "Forgot your password?"
|
||||
|
||||
= form_for(resource, as: resource_name,
|
||||
url: password_path(resource_name),
|
||||
html: { method: :post,
|
||||
class: 'form-horizontal', role: 'form' }) do |f|
|
||||
= devise_error_messages!
|
||||
.form-page
|
||||
%section.card.form-card
|
||||
%h2 Forgot your password?
|
||||
= form_for(resource, as: resource_name,
|
||||
url: password_path(resource_name),
|
||||
html: { method: :post,
|
||||
class: 'text-center border border-light p-5', role: 'form' }) do |f|
|
||||
= render 'devise/shared/error_messages', resource: resource
|
||||
|
||||
.form-group
|
||||
= f.label :login, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :login, class: 'form-control'
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit "Send me reset password instructions", class: 'btn btn-primary'
|
||||
= f.text_field :login, class: "form-control mb-4", placeholder: "E-mail", type: "email"
|
||||
= f.submit "Send me reset password instructions", class: 'btn btn-block my-4 btn-primary'
|
||||
|
||||
.form-group
|
||||
.col-md-offset-2.col-md-8
|
||||
= render "devise/shared/links"
|
||||
= render "devise/shared/links"
|
||||
|
||||