Godwin
8 years ago
302 changed files with 7159 additions and 8141 deletions
@ -0,0 +1,633 @@ |
|||||
|
GIT |
||||
|
remote: https://github.com/glebm/to_spreadsheet.git |
||||
|
revision: 4c08455646dd18de51cc1ec05717fbb240c78a68 |
||||
|
specs: |
||||
|
to_spreadsheet (1.0.6) |
||||
|
axlsx |
||||
|
chronic |
||||
|
nokogiri |
||||
|
rails |
||||
|
responders |
||||
|
|
||||
|
GIT |
||||
|
remote: https://github.com/ianfleeton/paypal-express |
||||
|
revision: 629749621de4c65dd6651649f98410315520fb3d |
||||
|
specs: |
||||
|
paypal-express (0.8.1) |
||||
|
activesupport (>= 2.3) |
||||
|
attr_required (>= 0.0.5) |
||||
|
rest-client |
||||
|
|
||||
|
GIT |
||||
|
remote: https://github.com/krzcho/eventmachine |
||||
|
revision: 651a35ee9df9826e048c3b3721e2c6b415c5a328 |
||||
|
branch: master |
||||
|
specs: |
||||
|
eventmachine (1.2.1) |
||||
|
|
||||
|
GIT |
||||
|
remote: https://github.com/tg90nor/sorcery.git |
||||
|
revision: 79b69a87ce168c47fab76921874aa7e8cb727002 |
||||
|
branch: make-facebook-provider-use-json-token-parser |
||||
|
specs: |
||||
|
sorcery (0.10.3) |
||||
|
bcrypt (~> 3.1) |
||||
|
oauth (~> 0.4, >= 0.4.4) |
||||
|
oauth2 (~> 1.0, >= 0.8.0) |
||||
|
|
||||
|
PATH |
||||
|
remote: ../bikecollectives_core |
||||
|
specs: |
||||
|
bikecollectives_core (0.1.0) |
||||
|
activerecord-session_store |
||||
|
carrierwave |
||||
|
carrierwave-imageoptimizer |
||||
|
haml |
||||
|
launchy |
||||
|
letter_opener |
||||
|
mini_magick |
||||
|
pg |
||||
|
premailer-rails |
||||
|
rails (~> 4.2.0) |
||||
|
redcarpet |
||||
|
sass |
||||
|
sass-json-vars |
||||
|
sass-rails |
||||
|
sidekiq |
||||
|
uglifier (>= 1.3.0) |
||||
|
|
||||
|
PATH |
||||
|
remote: ../bumbleberry |
||||
|
specs: |
||||
|
bumbleberry (0.0.1) |
||||
|
blockspring |
||||
|
cairo |
||||
|
railties |
||||
|
rsvg2 |
||||
|
sass-json-vars |
||||
|
sass-rails |
||||
|
|
||||
|
PATH |
||||
|
remote: ../lingua_franca |
||||
|
specs: |
||||
|
lingua_franca (0.0.1) |
||||
|
diffy |
||||
|
forgery |
||||
|
http_accept_language |
||||
|
i18n |
||||
|
rails (~> 4.2.0.rc2) |
||||
|
rails-i18n |
||||
|
rubyzip |
||||
|
|
||||
|
PATH |
||||
|
remote: ../marmara |
||||
|
specs: |
||||
|
marmara (1.0.2) |
||||
|
css_parser (>= 1.5.0.pre) |
||||
|
|
||||
|
GEM |
||||
|
remote: http://rubygems.org/ |
||||
|
specs: |
||||
|
actionmailer (4.2.0) |
||||
|
actionpack (= 4.2.0) |
||||
|
actionview (= 4.2.0) |
||||
|
activejob (= 4.2.0) |
||||
|
mail (~> 2.5, >= 2.5.4) |
||||
|
rails-dom-testing (~> 1.0, >= 1.0.5) |
||||
|
actionpack (4.2.0) |
||||
|
actionview (= 4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
rack (~> 1.6.0) |
||||
|
rack-test (~> 0.6.2) |
||||
|
rails-dom-testing (~> 1.0, >= 1.0.5) |
||||
|
rails-html-sanitizer (~> 1.0, >= 1.0.1) |
||||
|
actionview (4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
builder (~> 3.1) |
||||
|
erubis (~> 2.7.0) |
||||
|
rails-dom-testing (~> 1.0, >= 1.0.5) |
||||
|
rails-html-sanitizer (~> 1.0, >= 1.0.1) |
||||
|
activejob (4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
globalid (>= 0.3.0) |
||||
|
activemodel (4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
builder (~> 3.1) |
||||
|
activerecord (4.2.0) |
||||
|
activemodel (= 4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
arel (~> 6.0) |
||||
|
activerecord-session_store (1.0.0) |
||||
|
actionpack (>= 4.0, < 5.1) |
||||
|
activerecord (>= 4.0, < 5.1) |
||||
|
multi_json (~> 1.11, >= 1.11.2) |
||||
|
rack (>= 1.5.2, < 3) |
||||
|
railties (>= 4.0, < 5.1) |
||||
|
activesupport (4.2.0) |
||||
|
i18n (~> 0.7) |
||||
|
json (~> 1.7, >= 1.7.7) |
||||
|
minitest (~> 5.1) |
||||
|
thread_safe (~> 0.3, >= 0.3.4) |
||||
|
tzinfo (~> 1.1) |
||||
|
addressable (2.5.1) |
||||
|
public_suffix (~> 2.0, >= 2.0.2) |
||||
|
airbrussh (1.1.2) |
||||
|
sshkit (>= 1.6.1, != 1.7.0) |
||||
|
arel (6.0.4) |
||||
|
ast (2.3.0) |
||||
|
attr_required (1.0.1) |
||||
|
axlsx (2.0.1) |
||||
|
htmlentities (~> 4.3.1) |
||||
|
nokogiri (>= 1.4.1) |
||||
|
rubyzip (~> 1.0.0) |
||||
|
bcrypt (3.1.11-x64-mingw32) |
||||
|
bcrypt (3.1.11-x86-mingw32) |
||||
|
better_errors (2.1.1) |
||||
|
coderay (>= 1.0.0) |
||||
|
erubis (>= 2.6.6) |
||||
|
rack (>= 0.9.0) |
||||
|
binding_of_caller (0.7.2) |
||||
|
debug_inspector (>= 0.0.1) |
||||
|
blockspring (0.1.4) |
||||
|
rest-client (> 1.6.7) |
||||
|
builder (3.2.3) |
||||
|
cairo (1.15.5-x64-mingw32) |
||||
|
pkg-config (>= 1.1.5) |
||||
|
cairo (1.15.5-x86-mingw32) |
||||
|
pkg-config (>= 1.1.5) |
||||
|
callsite (0.0.11) |
||||
|
capistrano (3.8.0) |
||||
|
airbrussh (>= 1.0.0) |
||||
|
i18n |
||||
|
rake (>= 10.0.0) |
||||
|
sshkit (>= 1.9.0) |
||||
|
capistrano-bundler (1.2.0) |
||||
|
capistrano (~> 3.1) |
||||
|
sshkit (~> 1.2) |
||||
|
capistrano-faster-assets (1.0.2) |
||||
|
capistrano (>= 3.1) |
||||
|
capistrano-rails (1.2.3) |
||||
|
capistrano (~> 3.1) |
||||
|
capistrano-bundler (~> 1.1) |
||||
|
capybara (2.13.0) |
||||
|
addressable |
||||
|
mime-types (>= 1.16) |
||||
|
nokogiri (>= 1.3.3) |
||||
|
rack (>= 1.0.0) |
||||
|
rack-test (>= 0.5.4) |
||||
|
xpath (~> 2.0) |
||||
|
capybara-email (2.5.0) |
||||
|
capybara (~> 2.4) |
||||
|
mail |
||||
|
carrierwave (1.0.0) |
||||
|
activemodel (>= 4.0.0) |
||||
|
activesupport (>= 4.0.0) |
||||
|
mime-types (>= 1.16) |
||||
|
carrierwave-imageoptimizer (1.4.0) |
||||
|
carrierwave (>= 0.8, < 2.0) |
||||
|
image_optimizer (~> 1.6) |
||||
|
childprocess (0.6.3) |
||||
|
ffi (~> 1.0, >= 1.0.11) |
||||
|
chronic (0.10.2) |
||||
|
cliver (0.3.2) |
||||
|
coderay (1.1.1) |
||||
|
concurrent-ruby (1.0.5) |
||||
|
connection_pool (2.2.1) |
||||
|
coveralls (0.8.20) |
||||
|
json (>= 1.8, < 3) |
||||
|
simplecov (~> 0.14.1) |
||||
|
term-ansicolor (~> 1.3) |
||||
|
thor (~> 0.19.4) |
||||
|
tins (~> 1.6) |
||||
|
crack (0.4.3) |
||||
|
safe_yaml (~> 1.0.0) |
||||
|
css_parser (1.5.0.pre2) |
||||
|
addressable |
||||
|
cucumber (2.4.0) |
||||
|
builder (>= 2.1.2) |
||||
|
cucumber-core (~> 1.5.0) |
||||
|
cucumber-wire (~> 0.0.1) |
||||
|
diff-lcs (>= 1.1.3) |
||||
|
gherkin (~> 4.0) |
||||
|
multi_json (>= 1.7.5, < 2.0) |
||||
|
multi_test (>= 0.1.2) |
||||
|
cucumber-core (1.5.0) |
||||
|
gherkin (~> 4.0) |
||||
|
cucumber-rails (1.4.5) |
||||
|
capybara (>= 1.1.2, < 3) |
||||
|
cucumber (>= 1.3.8, < 4) |
||||
|
mime-types (>= 1.16, < 4) |
||||
|
nokogiri (~> 1.5) |
||||
|
railties (>= 3, < 5.1) |
||||
|
cucumber-wire (0.0.1) |
||||
|
daemon-spawn (0.4.2) |
||||
|
daemons (1.2.4) |
||||
|
database_cleaner (1.5.3) |
||||
|
debug_inspector (0.0.2) |
||||
|
diff-lcs (1.3) |
||||
|
diffy (3.2.0) |
||||
|
docile (1.1.5) |
||||
|
domain_name (0.5.20170404) |
||||
|
unf (>= 0.0.5, < 1.0.0) |
||||
|
erubis (2.7.0) |
||||
|
execjs (2.7.0) |
||||
|
factory_girl (4.8.0) |
||||
|
activesupport (>= 3.0.0) |
||||
|
factory_girl_rails (4.8.0) |
||||
|
factory_girl (~> 4.8.0) |
||||
|
railties (>= 3.0.0) |
||||
|
faraday (0.11.0) |
||||
|
multipart-post (>= 1.2, < 3) |
||||
|
ffi (1.9.18-x64-mingw32) |
||||
|
ffi (1.9.18-x86-mingw32) |
||||
|
forgery (0.6.0) |
||||
|
formatador (0.2.5) |
||||
|
gdk_pixbuf2 (3.1.1-x64-mingw32) |
||||
|
gio2 (= 3.1.1) |
||||
|
gdk_pixbuf2 (3.1.1-x86-mingw32) |
||||
|
gio2 (= 3.1.1) |
||||
|
geocoder (1.4.3) |
||||
|
gherkin (4.1.1) |
||||
|
gherkin3 (3.1.2) |
||||
|
gio2 (3.1.1-x64-mingw32) |
||||
|
glib2 (= 3.1.1) |
||||
|
gobject-introspection (= 3.1.1) |
||||
|
gio2 (3.1.1-x86-mingw32) |
||||
|
glib2 (= 3.1.1) |
||||
|
gobject-introspection (= 3.1.1) |
||||
|
git-version-bump (0.15.1) |
||||
|
glib2 (3.1.1-x64-mingw32) |
||||
|
cairo (>= 1.12.8) |
||||
|
pkg-config |
||||
|
glib2 (3.1.1-x86-mingw32) |
||||
|
cairo (>= 1.12.8) |
||||
|
pkg-config |
||||
|
globalid (0.3.7) |
||||
|
activesupport (>= 4.1.0) |
||||
|
gobject-introspection (3.1.1-x64-mingw32) |
||||
|
glib2 (= 3.1.1) |
||||
|
gobject-introspection (3.1.1-x86-mingw32) |
||||
|
glib2 (= 3.1.1) |
||||
|
guard (2.14.1) |
||||
|
formatador (>= 0.2.4) |
||||
|
listen (>= 2.7, < 4.0) |
||||
|
lumberjack (~> 1.0) |
||||
|
nenv (~> 0.1) |
||||
|
notiffany (~> 0.0) |
||||
|
pry (>= 0.9.12) |
||||
|
shellany (~> 0.0) |
||||
|
thor (>= 0.18.1) |
||||
|
guard-compat (1.2.1) |
||||
|
guard-cucumber (2.1.2) |
||||
|
cucumber (~> 2.0) |
||||
|
guard-compat (~> 1.0) |
||||
|
nenv (~> 0.1) |
||||
|
guard-rspec (4.7.3) |
||||
|
guard (~> 2.1) |
||||
|
guard-compat (~> 1.1) |
||||
|
rspec (>= 2.99.0, < 4.0) |
||||
|
haml (4.0.7) |
||||
|
tilt |
||||
|
haml-lint (0.999.999) |
||||
|
haml_lint |
||||
|
haml_lint (0.24.0) |
||||
|
haml (>= 4.0, < 5.1) |
||||
|
rainbow |
||||
|
rake (>= 10, < 13) |
||||
|
rubocop (>= 0.47.0) |
||||
|
sysexits (~> 1.1) |
||||
|
hashdiff (0.3.2) |
||||
|
htmlentities (4.3.4) |
||||
|
http-cookie (1.0.3) |
||||
|
domain_name (~> 0.5) |
||||
|
http_accept_language (2.1.0) |
||||
|
i18n (0.8.1) |
||||
|
image_optimizer (1.7.0) |
||||
|
json (1.8.6) |
||||
|
jwt (1.5.6) |
||||
|
kgio (2.11.0) |
||||
|
launchy (2.4.3) |
||||
|
addressable (~> 2.3) |
||||
|
letter_opener (1.4.1) |
||||
|
launchy (~> 2.2) |
||||
|
listen (3.1.5) |
||||
|
rb-fsevent (~> 0.9, >= 0.9.4) |
||||
|
rb-inotify (~> 0.9, >= 0.9.7) |
||||
|
ruby_dep (~> 1.2) |
||||
|
loofah (2.0.3) |
||||
|
nokogiri (>= 1.5.9) |
||||
|
lumberjack (1.0.11) |
||||
|
mail (2.6.4) |
||||
|
mime-types (>= 1.16, < 4) |
||||
|
meta_request (0.4.0) |
||||
|
callsite (~> 0.0, >= 0.0.11) |
||||
|
rack-contrib (~> 1.1) |
||||
|
railties (>= 3.0.0, < 5.1.0) |
||||
|
metaclass (0.0.4) |
||||
|
method_source (0.8.2) |
||||
|
mime-types (3.1) |
||||
|
mime-types-data (~> 3.2015) |
||||
|
mime-types-data (3.2016.0521) |
||||
|
mini_magick (4.7.0) |
||||
|
mini_portile2 (2.1.0) |
||||
|
minitest (5.10.1) |
||||
|
mocha (1.2.1) |
||||
|
metaclass (~> 0.0.1) |
||||
|
multi_json (1.12.1) |
||||
|
multi_test (0.1.2) |
||||
|
multi_xml (0.6.0) |
||||
|
multipart-post (2.0.0) |
||||
|
nenv (0.3.0) |
||||
|
net-scp (1.2.1) |
||||
|
net-ssh (>= 2.6.5) |
||||
|
net-ssh (4.1.0) |
||||
|
netrc (0.11.0) |
||||
|
nokogiri (1.6.8.1-x64-mingw32) |
||||
|
mini_portile2 (~> 2.1.0) |
||||
|
nokogiri (1.6.8.1-x86-mingw32) |
||||
|
mini_portile2 (~> 2.1.0) |
||||
|
notiffany (0.1.1) |
||||
|
nenv (~> 0.1) |
||||
|
shellany (~> 0.0) |
||||
|
oauth (0.5.1) |
||||
|
oauth2 (1.3.1) |
||||
|
faraday (>= 0.8, < 0.12) |
||||
|
jwt (~> 1.0) |
||||
|
multi_json (~> 1.3) |
||||
|
multi_xml (~> 0.5) |
||||
|
rack (>= 1.2, < 3) |
||||
|
pango (3.1.1-x64-mingw32) |
||||
|
cairo (>= 1.14.0) |
||||
|
glib2 (= 3.1.1) |
||||
|
pango (3.1.1-x86-mingw32) |
||||
|
cairo (>= 1.14.0) |
||||
|
glib2 (= 3.1.1) |
||||
|
parser (2.4.0.0) |
||||
|
ast (~> 2.2) |
||||
|
pg (0.20.0-x64-mingw32) |
||||
|
pg (0.20.0-x86-mingw32) |
||||
|
pkg-config (1.1.7) |
||||
|
poltergeist (1.14.0) |
||||
|
capybara (~> 2.1) |
||||
|
cliver (~> 0.3.1) |
||||
|
websocket-driver (>= 0.2.0) |
||||
|
powerpack (0.1.1) |
||||
|
premailer (1.10.2) |
||||
|
addressable |
||||
|
css_parser (>= 1.4.10) |
||||
|
htmlentities (>= 4.0.0) |
||||
|
premailer-rails (1.9.5) |
||||
|
actionmailer (>= 3, < 6) |
||||
|
premailer (~> 1.7, >= 1.7.9) |
||||
|
pry (0.10.4) |
||||
|
coderay (~> 1.1.0) |
||||
|
method_source (~> 0.8.1) |
||||
|
slop (~> 3.4) |
||||
|
public_suffix (2.0.5) |
||||
|
rack (1.6.5) |
||||
|
rack-contrib (1.4.0) |
||||
|
git-version-bump (~> 0.15) |
||||
|
rack (~> 1.4) |
||||
|
rack-mini-profiler (0.10.2) |
||||
|
rack (>= 1.2.0) |
||||
|
rack-protection (1.5.3) |
||||
|
rack |
||||
|
rack-test (0.6.3) |
||||
|
rack (>= 1.0) |
||||
|
rails (4.2.0) |
||||
|
actionmailer (= 4.2.0) |
||||
|
actionpack (= 4.2.0) |
||||
|
actionview (= 4.2.0) |
||||
|
activejob (= 4.2.0) |
||||
|
activemodel (= 4.2.0) |
||||
|
activerecord (= 4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
bundler (>= 1.3.0, < 2.0) |
||||
|
railties (= 4.2.0) |
||||
|
sprockets-rails |
||||
|
rails-deprecated_sanitizer (1.0.3) |
||||
|
activesupport (>= 4.2.0.alpha) |
||||
|
rails-dom-testing (1.0.8) |
||||
|
activesupport (>= 4.2.0.beta, < 5.0) |
||||
|
nokogiri (~> 1.6) |
||||
|
rails-deprecated_sanitizer (>= 1.0.1) |
||||
|
rails-html-sanitizer (1.0.3) |
||||
|
loofah (~> 2.0) |
||||
|
rails-i18n (4.0.9) |
||||
|
i18n (~> 0.7) |
||||
|
railties (~> 4.0) |
||||
|
rails_12factor (0.0.3) |
||||
|
rails_serve_static_assets |
||||
|
rails_stdout_logging |
||||
|
rails_serve_static_assets (0.0.5) |
||||
|
rails_stdout_logging (0.0.5) |
||||
|
railties (4.2.0) |
||||
|
actionpack (= 4.2.0) |
||||
|
activesupport (= 4.2.0) |
||||
|
rake (>= 0.8.7) |
||||
|
thor (>= 0.18.1, < 2.0) |
||||
|
rainbow (2.2.1) |
||||
|
raindrops (0.18.0) |
||||
|
rake (11.1.2) |
||||
|
rb-fsevent (0.9.8) |
||||
|
rb-inotify (0.9.8) |
||||
|
ffi (>= 0.5.0) |
||||
|
redcarpet (3.4.0) |
||||
|
redis (3.3.3) |
||||
|
responders (2.3.0) |
||||
|
railties (>= 4.2.0, < 5.1) |
||||
|
rest-client (2.0.1-x64-mingw32) |
||||
|
ffi (~> 1.9) |
||||
|
http-cookie (>= 1.0.2, < 2.0) |
||||
|
mime-types (>= 1.16, < 4.0) |
||||
|
netrc (~> 0.8) |
||||
|
rest-client (2.0.1-x86-mingw32) |
||||
|
ffi (~> 1.9) |
||||
|
http-cookie (>= 1.0.2, < 2.0) |
||||
|
mime-types (>= 1.16, < 4.0) |
||||
|
netrc (~> 0.8) |
||||
|
rspec (3.5.0) |
||||
|
rspec-core (~> 3.5.0) |
||||
|
rspec-expectations (~> 3.5.0) |
||||
|
rspec-mocks (~> 3.5.0) |
||||
|
rspec-core (3.5.4) |
||||
|
rspec-support (~> 3.5.0) |
||||
|
rspec-expectations (3.5.0) |
||||
|
diff-lcs (>= 1.2.0, < 2.0) |
||||
|
rspec-support (~> 3.5.0) |
||||
|
rspec-mocks (3.5.0) |
||||
|
diff-lcs (>= 1.2.0, < 2.0) |
||||
|
rspec-support (~> 3.5.0) |
||||
|
rspec-rails (3.5.2) |
||||
|
actionpack (>= 3.0) |
||||
|
activesupport (>= 3.0) |
||||
|
railties (>= 3.0) |
||||
|
rspec-core (~> 3.5.0) |
||||
|
rspec-expectations (~> 3.5.0) |
||||
|
rspec-mocks (~> 3.5.0) |
||||
|
rspec-support (~> 3.5.0) |
||||
|
rspec-support (3.5.0) |
||||
|
rsvg2 (3.1.1-x64-mingw32) |
||||
|
cairo (>= 1.12.8) |
||||
|
gdk_pixbuf2 (= 3.1.1) |
||||
|
pango (>= 3.1.1) |
||||
|
rsvg2 (3.1.1-x86-mingw32) |
||||
|
cairo (>= 1.12.8) |
||||
|
gdk_pixbuf2 (= 3.1.1) |
||||
|
pango (>= 3.1.1) |
||||
|
rubocop (0.48.1) |
||||
|
parser (>= 2.3.3.1, < 3.0) |
||||
|
powerpack (~> 0.1) |
||||
|
rainbow (>= 1.99.1, < 3.0) |
||||
|
ruby-progressbar (~> 1.7) |
||||
|
unicode-display_width (~> 1.0, >= 1.0.1) |
||||
|
ruby-progressbar (1.8.1) |
||||
|
ruby_dep (1.3.1) |
||||
|
rubyzip (1.0.0) |
||||
|
safe_yaml (1.0.4) |
||||
|
sass (3.4.23) |
||||
|
sass-json-vars (0.3.3) |
||||
|
sass (>= 3.1) |
||||
|
sass-rails (5.0.6) |
||||
|
railties (>= 4.0.0, < 6) |
||||
|
sass (~> 3.1) |
||||
|
sprockets (>= 2.8, < 4.0) |
||||
|
sprockets-rails (>= 2.0, < 4.0) |
||||
|
tilt (>= 1.1, < 3) |
||||
|
selenium-webdriver (3.3.0) |
||||
|
childprocess (~> 0.5) |
||||
|
rubyzip (~> 1.0) |
||||
|
websocket (~> 1.0) |
||||
|
shellany (0.0.1) |
||||
|
sidekiq (4.2.10) |
||||
|
concurrent-ruby (~> 1.0) |
||||
|
connection_pool (~> 2.2, >= 2.2.0) |
||||
|
rack-protection (>= 1.5.0) |
||||
|
redis (~> 3.2, >= 3.2.1) |
||||
|
simplecov (0.14.1) |
||||
|
docile (~> 1.1.0) |
||||
|
json (>= 1.8, < 3) |
||||
|
simplecov-html (~> 0.10.0) |
||||
|
simplecov-html (0.10.0) |
||||
|
sitemap_generator (5.3.1) |
||||
|
builder (~> 3.0) |
||||
|
slop (3.6.0) |
||||
|
sprockets (3.7.1) |
||||
|
concurrent-ruby (~> 1.0) |
||||
|
rack (> 1, < 3) |
||||
|
sprockets-rails (3.2.0) |
||||
|
actionpack (>= 4.0) |
||||
|
activesupport (>= 4.0) |
||||
|
sprockets (>= 3.0.0) |
||||
|
sshkit (1.13.1) |
||||
|
net-scp (>= 1.1.2) |
||||
|
net-ssh (>= 2.8.0) |
||||
|
sysexits (1.2.0) |
||||
|
term-ansicolor (1.5.0) |
||||
|
tins (~> 1.0) |
||||
|
thin (1.7.0) |
||||
|
daemons (~> 1.0, >= 1.0.9) |
||||
|
eventmachine (~> 1.0, >= 1.0.4) |
||||
|
rack (>= 1, < 3) |
||||
|
thor (0.19.4) |
||||
|
thread_safe (0.3.6) |
||||
|
tilt (2.0.7) |
||||
|
tins (1.13.2) |
||||
|
tzinfo (1.2.3) |
||||
|
thread_safe (~> 0.1) |
||||
|
tzinfo-data (1.2017.2) |
||||
|
tzinfo (>= 1.0.0) |
||||
|
uglifier (3.1.13) |
||||
|
execjs (>= 0.3.0, < 3) |
||||
|
unf (0.1.4) |
||||
|
unf_ext |
||||
|
unf_ext (0.0.7.2-x64-mingw32) |
||||
|
unf_ext (0.0.7.2-x86-mingw32) |
||||
|
unicode-display_width (1.1.3) |
||||
|
unicorn (5.3.0) |
||||
|
kgio (~> 2.6) |
||||
|
raindrops (~> 0.7) |
||||
|
wdm (0.1.1) |
||||
|
webmock (2.3.2) |
||||
|
addressable (>= 2.3.6) |
||||
|
crack (>= 0.3.2) |
||||
|
hashdiff |
||||
|
websocket (1.2.4) |
||||
|
websocket-driver (0.6.5) |
||||
|
websocket-extensions (>= 0.1.0) |
||||
|
websocket-extensions (0.1.2) |
||||
|
win32console (1.3.2-x86-mingw32) |
||||
|
xpath (2.0.0) |
||||
|
nokogiri (~> 1.3) |
||||
|
|
||||
|
PLATFORMS |
||||
|
x64-mingw32 |
||||
|
x86-mingw32 |
||||
|
|
||||
|
DEPENDENCIES |
||||
|
activerecord-session_store |
||||
|
better_errors |
||||
|
bikecollectives_core! |
||||
|
binding_of_caller |
||||
|
bumbleberry! |
||||
|
capistrano (~> 3.1) |
||||
|
capistrano-faster-assets (~> 1.0) |
||||
|
capistrano-rails (~> 1.1) |
||||
|
capybara-email |
||||
|
carrierwave |
||||
|
carrierwave-imageoptimizer |
||||
|
coveralls |
||||
|
cucumber |
||||
|
cucumber-core |
||||
|
cucumber-rails |
||||
|
daemon-spawn |
||||
|
daemons |
||||
|
database_cleaner |
||||
|
eventmachine! |
||||
|
factory_girl_rails |
||||
|
geocoder |
||||
|
gherkin3 (>= 3.1.0) |
||||
|
guard-cucumber |
||||
|
guard-rspec |
||||
|
haml |
||||
|
haml-lint |
||||
|
launchy |
||||
|
letter_opener |
||||
|
lingua_franca! |
||||
|
marmara! |
||||
|
meta_request |
||||
|
mini_magick |
||||
|
mocha |
||||
|
nokogiri (~> 1.6.8.rc2) |
||||
|
paypal-express! |
||||
|
pg |
||||
|
poltergeist |
||||
|
premailer-rails |
||||
|
rack-mini-profiler |
||||
|
rails (= 4.2.0) |
||||
|
rails_12factor |
||||
|
rake (= 11.1.2) |
||||
|
redcarpet |
||||
|
rspec |
||||
|
rspec-rails |
||||
|
rubocop |
||||
|
ruby_dep (= 1.3.1) |
||||
|
sass |
||||
|
sass-json-vars |
||||
|
sass-rails |
||||
|
selenium-webdriver |
||||
|
sidekiq |
||||
|
simplecov |
||||
|
sitemap_generator |
||||
|
sorcery! |
||||
|
thin |
||||
|
to_spreadsheet! |
||||
|
tzinfo-data |
||||
|
uglifier (>= 1.3.0) |
||||
|
unicorn |
||||
|
wdm (>= 0.1.0) |
||||
|
webmock |
||||
|
win32console |
||||
|
|
||||
|
BUNDLED WITH |
||||
|
1.14.4 |
After Width: | Height: | Size: 76 KiB |
@ -1,103 +1,105 @@ |
|||||
{ |
{ |
||||
"stylesheets": ["application", "editor"], |
"stylesheets": ["application", "editor"], |
||||
"precompile": { |
"precompile": { |
||||
"test": { |
"test": { |
||||
"chrome": ["51"] |
"safari": ["5"], |
||||
}, |
"chrome": ["55"] |
||||
"development": { |
|
||||
"and_chr": ["55"], |
|
||||
"chrome": ["55"], |
|
||||
"edge": ["13"], |
|
||||
"firefox": ["50"], |
|
||||
"ie": ["11"], |
|
||||
"ios_saf": ["8", "9"] |
|
||||
} |
|
||||
}, |
}, |
||||
"background-color": "#FFFEFE", |
"development": { |
||||
"breakpoint-unit": "px", |
"safari": ["5"], |
||||
"unresponsive-width": 1000, |
"and_chr": ["56"], |
||||
"row-width": 1000, |
"chrome": ["56"], |
||||
"total-columns": 12, |
"edge": ["13"], |
||||
"platforms": { |
"firefox": ["50"], |
||||
"mobile": { |
"ie": ["11"], |
||||
"range": [0,700] |
"ios_saf": ["8", "9"] |
||||
}, |
} |
||||
"desktop": { |
}, |
||||
"range": [0,0] |
"background-color": "#FFFEFE", |
||||
} |
"breakpoint-unit": "px", |
||||
|
"unresponsive-width": 1000, |
||||
|
"row-width": 1000, |
||||
|
"total-columns": 12, |
||||
|
"platforms": { |
||||
|
"mobile": { |
||||
|
"range": [0,700] |
||||
|
}, |
||||
|
"desktop": { |
||||
|
"range": [0,0] |
||||
|
} |
||||
|
}, |
||||
|
"breakpoints": { |
||||
|
"small": { |
||||
|
"range": [0], |
||||
|
"grid": "y", |
||||
|
"offset": "n", |
||||
|
"reset-order": "n" |
||||
}, |
}, |
||||
"breakpoints": { |
"medium": { |
||||
"small": { |
"range": [680], |
||||
"range": [0], |
"grid": "y", |
||||
"grid": "y", |
"offset": "n", |
||||
"offset": "n", |
"reset-order": "n" |
||||
"reset-order": "n" |
|
||||
}, |
|
||||
"medium": { |
|
||||
"range": [680], |
|
||||
"grid": "y", |
|
||||
"offset": "n", |
|
||||
"reset-order": "n" |
|
||||
}, |
|
||||
"large": { |
|
||||
"range": [1024], |
|
||||
"grid": "y", |
|
||||
"offset": "n", |
|
||||
"reset-order": "n" |
|
||||
}, |
|
||||
"small-only": { |
|
||||
"range": [0,319], |
|
||||
"grid": "n", |
|
||||
"offset": "n", |
|
||||
"reset-order": "n" |
|
||||
}, |
|
||||
"medium-only": { |
|
||||
"range": [320,1023], |
|
||||
"grid": "n", |
|
||||
"offset": "n", |
|
||||
"reset-order": "n" |
|
||||
} |
|
||||
}, |
}, |
||||
"grid-push": [1, 2], |
"large": { |
||||
"grid-pull": [1, 2], |
"range": [1024], |
||||
"font-loading-method": "http2", |
"grid": "y", |
||||
"fonts": { |
"offset": "n", |
||||
"primary": { |
"reset-order": "n" |
||||
"name": "Sanchez Light", |
|
||||
"location": "Sanchez", |
|
||||
"svg_id": "wf", |
|
||||
"ttf_type": "ttf", |
|
||||
"fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] |
|
||||
}, |
|
||||
"secondary": { |
|
||||
"name": "AlteHaasGroteskBold", |
|
||||
"location": "AlteHaasGroteskBold", |
|
||||
"svg_id": "alte_haas_groteskbold", |
|
||||
"ttf_type": "ttf", |
|
||||
"fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] |
|
||||
}, |
|
||||
"monospace": { |
|
||||
"name": "NotCourierSans", |
|
||||
"location": "NotCourierSans", |
|
||||
"svg_id": "notcouriersans", |
|
||||
"ttf_type": "ttf", |
|
||||
"fallback": ["Courier New", "monospace"], |
|
||||
"auto_load": "n" |
|
||||
}, |
|
||||
"monospace-bold": { |
|
||||
"name": "NotCourierSans", |
|
||||
"location": "NotCourierSans-Bold", |
|
||||
"svg_id": "notcouriersansbold", |
|
||||
"ttf_type": "ttf", |
|
||||
"fallback": ["Courier New", "monospace"], |
|
||||
"auto_load": "n", |
|
||||
"weight": "bold" |
|
||||
} |
|
||||
}, |
}, |
||||
"sprites": { |
"small-only": { |
||||
"icons": { |
"range": [0,319], |
||||
"bb-icon-logo": [0, 0, "182px", "149px"], |
"grid": "n", |
||||
"bb-icon-logo-text": ["182px", 0, "136px", "149px"] |
"offset": "n", |
||||
} |
"reset-order": "n" |
||||
|
}, |
||||
|
"medium-only": { |
||||
|
"range": [320,1023], |
||||
|
"grid": "n", |
||||
|
"offset": "n", |
||||
|
"reset-order": "n" |
||||
|
} |
||||
|
}, |
||||
|
"grid-push": [1, 2], |
||||
|
"grid-pull": [1, 2], |
||||
|
"font-loading-method": "http2", |
||||
|
"fonts": { |
||||
|
"primary": { |
||||
|
"name": "Sanchez Light", |
||||
|
"location": "Sanchez", |
||||
|
"svg_id": "wf", |
||||
|
"ttf_type": "ttf", |
||||
|
"fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] |
||||
|
}, |
||||
|
"secondary": { |
||||
|
"name": "AlteHaasGroteskBold", |
||||
|
"location": "AlteHaasGroteskBold", |
||||
|
"svg_id": "alte_haas_groteskbold", |
||||
|
"ttf_type": "ttf", |
||||
|
"fallback": ["Helvetica Neue", "Helvetica", "Arial", "Lucida Grande", "sans-serif"] |
||||
|
}, |
||||
|
"monospace": { |
||||
|
"name": "NotCourierSans", |
||||
|
"location": "NotCourierSans", |
||||
|
"svg_id": "notcouriersans", |
||||
|
"ttf_type": "ttf", |
||||
|
"fallback": ["Courier New", "monospace"], |
||||
|
"auto_load": "n" |
||||
|
}, |
||||
|
"monospace-bold": { |
||||
|
"name": "NotCourierSans", |
||||
|
"location": "NotCourierSans-Bold", |
||||
|
"svg_id": "notcouriersansbold", |
||||
|
"ttf_type": "ttf", |
||||
|
"fallback": ["Courier New", "monospace"], |
||||
|
"auto_load": "n", |
||||
|
"weight": "bold" |
||||
|
} |
||||
|
}, |
||||
|
"sprites": { |
||||
|
"icons": { |
||||
|
"bb-icon-logo": [0, 0, "182px", "149px"], |
||||
|
"bb-icon-logo-text": ["182px", 0, "136px", "149px"] |
||||
} |
} |
||||
|
} |
||||
} |
} |
||||
|
@ -1,268 +1,268 @@ |
|||||
@import "settings"; |
@import "settings"; |
||||
|
|
||||
body { |
body { |
||||
width: 100% !important; |
width: 100% !important; |
||||
-webkit-text-size-adjust: 100%; |
-webkit-text-size-adjust: 100%; |
||||
-ms-text-size-adjust: 100%; |
-ms-text-size-adjust: 100%; |
||||
margin: 1em; |
margin: 1em; |
||||
padding: 0; |
padding: 0; |
||||
} |
} |
||||
|
|
||||
.ExternalClass { |
.ExternalClass { |
||||
width: 100%; |
width: 100%; |
||||
line-height: 100%; |
line-height: 100%; |
||||
|
|
||||
p, span, font, td, div { |
p, span, font, td, div { |
||||
line-height: 100%; |
line-height: 100%; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
#backgroundTable { |
#backgroundTable { |
||||
margin: 0; |
margin: 0; |
||||
padding: 0; |
padding: 0; |
||||
width: 100% !important; |
width: 100% !important; |
||||
max-width: 100% !important; |
max-width: 100% !important; |
||||
line-height: 100% !important; |
line-height: 100% !important; |
||||
} |
} |
||||
|
|
||||
img { |
img { |
||||
outline: none; |
outline: none; |
||||
text-decoration: none; |
text-decoration: none; |
||||
-ms-interpolation-mode: bicubic; |
-ms-interpolation-mode: bicubic; |
||||
|
|
||||
a & { |
a & { |
||||
border: none; |
border: none; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
.image_fix { |
.image_fix { |
||||
display: block; |
display: block; |
||||
max-width: 100%; |
max-width: 100%; |
||||
} |
} |
||||
|
|
||||
a { |
a { |
||||
color: $colour-1; |
color: $colour-1; |
||||
|
|
||||
#outlook & { |
#outlook & { |
||||
padding: 0; |
padding: 0; |
||||
} |
} |
||||
|
|
||||
&:link { color: $colour-1; } |
&:link { color: $colour-1; } |
||||
&:visited { color: $colour-1; } |
&:visited { color: $colour-1; } |
||||
&:hover { color: $colour-5; } |
&:hover { color: $colour-5; } |
||||
|
|
||||
@media only screen and (max-device-width: 480px) { |
@media only screen and (max-device-width: 480px) { |
||||
&[href^="tel"], &[href^="sms"] { |
&[href^="tel"], &[href^="sms"] { |
||||
text-decoration: none; |
text-decoration: none; |
||||
color: $black; |
color: $black; |
||||
pointer-events: none; |
pointer-events: none; |
||||
cursor: default; |
cursor: default; |
||||
} |
} |
||||
|
|
||||
.mobile_link &[href^="tel"], .mobile_link &[href^="sms"] { |
.mobile_link &[href^="tel"], .mobile_link &[href^="sms"] { |
||||
text-decoration: default; |
text-decoration: default; |
||||
color: $colour-1 !important; |
color: $colour-1 !important; |
||||
pointer-events: auto; |
pointer-events: auto; |
||||
cursor: default; |
cursor: default; |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
p { |
p { |
||||
color: $black !important; |
color: $black !important; |
||||
font-size: 1.5em; |
font-size: 1.5em; |
||||
} |
} |
||||
|
|
||||
p, blockquote { |
p, blockquote { |
||||
margin: 1em; |
margin: 1em; |
||||
line-height: 1.3333em; |
line-height: 1.3333em; |
||||
} |
} |
||||
|
|
||||
blockquote { |
blockquote { |
||||
font-size: 1em; |
font-size: 1em; |
||||
} |
} |
||||
|
|
||||
h1 { |
h1 { |
||||
font-size: 2.5em; |
font-size: 2.5em; |
||||
line-height: 1.25em; |
line-height: 1.25em; |
||||
padding: 1em 0; |
padding: 1em 0; |
||||
|
|
||||
&:first-child { |
&:first-child { |
||||
padding-top: 0; |
padding-top: 0; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
h2 { |
h2 { |
||||
font-size: 1.8em; |
font-size: 1.8em; |
||||
line-height: 1.25em; |
line-height: 1.25em; |
||||
padding-bottom: 1em; |
padding-bottom: 1em; |
||||
} |
} |
||||
|
|
||||
blockquote { |
blockquote { |
||||
font-style: italic; |
font-style: italic; |
||||
margin-bottom: 2em; |
margin-bottom: 2em; |
||||
color: #666 !important; |
color: #666 !important; |
||||
border: 0.1em solid #CCC; |
border: 0.1em solid #CCC; |
||||
padding: 1em; |
padding: 1em; |
||||
border-style: none none solid solid; |
border-style: none none solid solid; |
||||
background-color: #F8F8F8; |
background-color: #F8F8F8; |
||||
} |
} |
||||
|
|
||||
h1, h2, h3, h4, h5, h6 { |
h1, h2, h3, h4, h5, h6 { |
||||
color: $black !important; |
color: $black !important; |
||||
|
|
||||
a { |
a { |
||||
color: $colour-1 !important; |
color: $colour-1 !important; |
||||
|
|
||||
&:active { |
&:active { |
||||
color: $colour-4 !important; |
color: $colour-4 !important; |
||||
} |
} |
||||
|
|
||||
&:visited { |
&:visited { |
||||
color: $colour-2 !important; |
color: $colour-2 !important; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|
||||
table { |
table { |
||||
border-collapse: collapse; |
border-collapse: collapse; |
||||
max-width: 512px; |
max-width: 512px; |
||||
min-width: 280px; |
min-width: 280px; |
||||
mso-table-lspace: 0pt; |
mso-table-lspace: 0pt; |
||||
mso-table-rspace: 0pt; |
mso-table-rspace: 0pt; |
||||
|
|
||||
td { |
td { |
||||
border-collapse: collapse; |
border-collapse: collapse; |
||||
} |
} |
||||
|
|
||||
th { |
th { |
||||
text-align: left; |
text-align: left; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
table#bb_full_width, |
table#bb_full_width, |
||||
table#ecxbb_full_width { |
table#ecxbb_full_width { |
||||
&, table { |
&, table { |
||||
max-width: none; |
max-width: none; |
||||
width: 100%; |
width: 100%; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
.error-report { |
.error-report { |
||||
width: 100%; |
width: 100%; |
||||
max-width: 100%; |
max-width: 100%; |
||||
border: 0.15em solid #CCC; |
border: 0.15em solid #CCC; |
||||
background-color: #EEE; |
background-color: #EEE; |
||||
font-size: 1.25em; |
font-size: 1.25em; |
||||
margin-bottom: 2em; |
margin-bottom: 2em; |
||||
|
|
||||
th { |
th { |
||||
background-color: #CCC; |
background-color: #CCC; |
||||
} |
} |
||||
|
|
||||
td, th { |
td, th { |
||||
padding: 0.25em 0.5em; |
padding: 0.25em 0.5em; |
||||
|
|
||||
&:last-child { |
&:last-child { |
||||
border-left: 0.15em solid #CCC; |
border-left: 0.15em solid #CCC; |
||||
min-width: 40em; |
min-width: 40em; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
td:last-child { |
td:last-child { |
||||
font-family: monospace; |
font-family: monospace; |
||||
word-break: break-word; |
word-break: break-word; |
||||
background-color: #FFF; |
background-color: #FFF; |
||||
font-size: 0.75em; |
font-size: 0.75em; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
code { |
code { |
||||
color: #C33; |
color: #C33; |
||||
font-size: 0.9em; |
font-size: 0.9em; |
||||
} |
} |
||||
|
|
||||
pre { |
pre { |
||||
font-size: 1.5em; |
font-size: 1.5em; |
||||
padding: 1em; |
padding: 1em; |
||||
background-color: #333; |
background-color: #333; |
||||
color: antiquewhite; |
color: antiquewhite; |
||||
word-break: break-word; |
word-break: break-word; |
||||
} |
} |
||||
|
|
||||
.diff, .ecxdiff { |
.diff, .ecxdiff { |
||||
margin: 1em 0 5em 1em; |
margin: 1em 0 5em 1em; |
||||
overflow: auto; |
overflow: auto; |
||||
|
|
||||
ul { |
ul { |
||||
list-style: none; |
list-style: none; |
||||
padding: 0; |
padding: 0; |
||||
margin: 0; |
margin: 0; |
||||
position: relative; |
position: relative; |
||||
} |
} |
||||
|
|
||||
li { |
li { |
||||
width: 40%; |
width: 40%; |
||||
display: inline-block; |
display: inline-block; |
||||
padding: 0.5em; |
padding: 0.5em; |
||||
margin: 0; |
margin: 0; |
||||
border-bottom: 1px solid #DDD; |
border-bottom: 1px solid #DDD; |
||||
//white-space: nowrap; |
//white-space: nowrap; |
||||
|
|
||||
&:nth-child(odd) { |
&:nth-child(odd) { |
||||
margin-right: -3px; |
margin-right: -3px; |
||||
float: left; |
float: left; |
||||
clear: left; |
clear: left; |
||||
} |
} |
||||
|
|
||||
ins { |
ins { |
||||
color: #080;//lighten($colour-3, 33%); |
color: #080;//lighten($colour-3, 33%); |
||||
} |
} |
||||
|
|
||||
del { |
del { |
||||
color: #800; |
color: #800; |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
// Buttons |
// Buttons |
||||
h3 { |
h3 { |
||||
b { |
b { |
||||
padding: 10px 20px; |
padding: 10px 20px; |
||||
line-height: 50px; |
line-height: 50px; |
||||
|
|
||||
a, a:visited { |
a, a:visited { |
||||
color: #FFF !important; |
color: #FFF !important; |
||||
background-color: $colour-5; |
background-color: $colour-5; |
||||
text-decoration: none !important; |
text-decoration: none !important; |
||||
border-radius: 4px; |
border-radius: 4px; |
||||
padding: 10px 15px; |
padding: 10px 15px; |
||||
margin-left: 20px; |
margin-left: 20px; |
||||
border-bottom: 3px solid darken($colour-5, 10%); |
border-bottom: 3px solid darken($colour-5, 10%); |
||||
-webkit-box-shadow: 0 0.5em 1.5em -0.75em #000; |
-webkit-box-shadow: 0 0.5em 1.5em -0.75em #000; |
||||
box-shadow: 0 0.5em 1.5em -0.75em #000; |
box-shadow: 0 0.5em 1.5em -0.75em #000; |
||||
cursor: pointer !important; |
cursor: pointer !important; |
||||
} |
} |
||||
|
|
||||
a:hover { |
a:hover { |
||||
background-color: darken($colour-5, 10%); |
background-color: darken($colour-5, 10%); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { |
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { |
||||
a[href^="tel"], a[href^="sms"] { |
a[href^="tel"], a[href^="sms"] { |
||||
text-decoration: none; |
text-decoration: none; |
||||
color: $colour-1; |
color: $colour-1; |
||||
pointer-events: none; |
pointer-events: none; |
||||
cursor: default; |
cursor: default; |
||||
|
|
||||
.mobile_link & { |
.mobile_link & { |
||||
text-decoration: default; |
text-decoration: default; |
||||
color: $colour-1 !important; |
color: $colour-1 !important; |
||||
pointer-events: auto; |
pointer-events: auto; |
||||
cursor: default; |
cursor: default; |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,6 +1,6 @@ |
|||||
require 'geocoder/calculations' |
require 'geocoder/calculations' |
||||
|
|
||||
class AdminController < ApplicationController |
class AdministrationController < ApplicationController |
||||
def new |
def new |
||||
return do_404 unless logged_in? && current_user.administrator? |
return do_404 unless logged_in? && current_user.administrator? |
||||
@this_conference = Conference.new |
@this_conference = Conference.new |
@ -1,101 +0,0 @@ |
|||||
class OauthsController < ApplicationController |
|
||||
skip_before_filter :require_login |
|
||||
|
|
||||
# sends the user on a trip to the provider, |
|
||||
# and after authorizing there back to the callback url. |
|
||||
def oauth |
|
||||
set_callback |
|
||||
session[:oauth_last_url] = params[:dest] || request.referer |
|
||||
login_at(auth_params[:provider]) |
|
||||
end |
|
||||
|
|
||||
def callback |
|
||||
set_callback |
|
||||
|
|
||||
user_info = (sorcery_fetch_user_hash auth_params[:provider] || {})[:user_info] |
|
||||
|
|
||||
email = user_info['email'] |
|
||||
fb_id = user_info['id'] |
|
||||
|
|
||||
# try to find the user by facebook id |
|
||||
user = User.find_by_fb_id(fb_id) |
|
||||
|
|
||||
# otherwise find the user by email |
|
||||
unless user.present? |
|
||||
# only look if the email address is present |
|
||||
user = User.find_user(email) if email.present? |
|
||||
end |
|
||||
|
|
||||
# create the user if the email is not recognized |
|
||||
if user.nil? |
|
||||
if email.present? |
|
||||
user = User.create(email: email, firstname: user_info['name'], fb_id: fb_id, locale: I18n.locale) |
|
||||
else |
|
||||
session[:oauth_update_user_info] = user_info |
|
||||
return redirect_to oauth_update_path |
|
||||
end |
|
||||
elsif user.fb_id.blank? || user.email.blank? |
|
||||
user.email = email |
|
||||
user.fb_id = fb_id |
|
||||
user.save! |
|
||||
end |
|
||||
|
|
||||
if user.present? && user.email.present? |
|
||||
# log in the user |
|
||||
auto_login(user) |
|
||||
end |
|
||||
|
|
||||
oauth_last_url = (session[:oauth_last_url] || home_path) |
|
||||
session.delete(:oauth_last_url) |
|
||||
redirect_to oauth_last_url |
|
||||
end |
|
||||
|
|
||||
def update |
|
||||
@main_title = @page_title = 'articles.conference_registration.headings.email_confirm' |
|
||||
@errors = { email: flash[:error] } if flash[:error].present? |
|
||||
render 'application/update_user' |
|
||||
end |
|
||||
|
|
||||
def save |
|
||||
unless params[:email].present? |
|
||||
return redirect_to oauth_update_path |
|
||||
end |
|
||||
|
|
||||
user = User.find_user(params[:email]) |
|
||||
|
|
||||
if user.present? |
|
||||
flash[:error] = :exists |
|
||||
return redirect_to oauth_update_path |
|
||||
end |
|
||||
|
|
||||
# create the user |
|
||||
user = User.new(email: params[:email], firstname: session[:oauth_update_user_info]['name'], fb_id: session[:oauth_update_user_info]['id']) |
|
||||
user.save! |
|
||||
|
|
||||
# log in |
|
||||
auto_login(user) |
|
||||
|
|
||||
# clear out the session |
|
||||
oauth_last_url = (session[:oauth_last_url] || home_path) |
|
||||
session.delete(:oauth_last_url) |
|
||||
session.delete(:oauth_update_user_info) |
|
||||
|
|
||||
# go to our final destination |
|
||||
redirect_to oauth_last_url |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def auth_params |
|
||||
params.permit(:code, :provider) |
|
||||
end |
|
||||
|
|
||||
def set_callback |
|
||||
# force https for prod |
|
||||
protocol = Rails.env.preview? || Rails.env.production? ? 'https://' : request.protocol |
|
||||
|
|
||||
# build the callback url |
|
||||
Sorcery::Controller::Config.send(params[:provider]).callback_url = |
|
||||
"#{protocol}#{request.env['HTTP_HOST']}/oauth/callback?provider=facebook" |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -0,0 +1,163 @@ |
|||||
|
module AdminHelper |
||||
|
|
||||
|
def administration_steps |
||||
|
{ |
||||
|
info: [:administrators, :dates, :description, :poster], |
||||
|
payment: [:payment_message, :suggested_amounts, :paypal], |
||||
|
registration: [:registration_status, :stats, :registrations, :broadcast], |
||||
|
housing: [:providers, :housing], |
||||
|
events: [:locations, :meals, :events], |
||||
|
schedule: [:workshop_times, :schedule, :publish_schedule] |
||||
|
} |
||||
|
end |
||||
|
|
||||
|
def administration_sub_steps |
||||
|
{ |
||||
|
location_edit: :locations, |
||||
|
event_edit: :events |
||||
|
} |
||||
|
end |
||||
|
|
||||
|
def get_administration_group(administration_step) |
||||
|
admin_step = administration_step.to_sym |
||||
|
admin_step = administration_sub_steps[admin_step] if administration_sub_steps[admin_step].present? |
||||
|
administration_steps.each do | group, steps | |
||||
|
steps.each do | step | |
||||
|
return group if step == admin_step |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return nil |
||||
|
end |
||||
|
|
||||
|
def broadcast_to(to, conference = nil) |
||||
|
conference ||= @this_conference || @conference |
||||
|
|
||||
|
users = [] |
||||
|
|
||||
|
case to.to_sym |
||||
|
when :registered |
||||
|
ConferenceRegistration.where(conference_id: conference.id).each do | r | |
||||
|
users << r.user if ((r.steps_completed || []).include? 'questions') && r.user.present? && r.is_attending != 'n' |
||||
|
end |
||||
|
when :pre_registered |
||||
|
ConferenceRegistration.where(conference_id: conference.id).each do | r | |
||||
|
users << r.user if registration_status(r) == :preregistered && r.is_attending != 'n' |
||||
|
end |
||||
|
when :workshop_facilitators |
||||
|
user_hash = {} |
||||
|
Workshop.where(conference_id: conference.id).each do | w | |
||||
|
w.active_facilitators.each do | u | |
||||
|
user_hash[u.id] ||= u if u.present? |
||||
|
end |
||||
|
end |
||||
|
users = user_hash.values |
||||
|
when :unregistered |
||||
|
ConferenceRegistration.where(conference_id: conference.id).each do | r | |
||||
|
users << r.user if registration_status(r) == :unregistered && r.is_attending != 'n' |
||||
|
end |
||||
|
when :housing_providers |
||||
|
ConferenceRegistration.where(conference_id: conference.id, can_provide_housing: true).each do | r | |
||||
|
users << r.user if r.user.present? |
||||
|
end |
||||
|
when :guests |
||||
|
ConferenceRegistration.where(conference_id: conference.id, housing: 'house').each do | r | |
||||
|
users << r.user if r.user.present? && r.is_attending != 'n' |
||||
|
end |
||||
|
when :all |
||||
|
User.all.each do | u | |
||||
|
users << u if u.present? && (u.is_subscribed.nil? || u.is_subscribed) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return users |
||||
|
end |
||||
|
|
||||
|
def get_housing_match(host, guest, space) |
||||
|
housing_data = guest.housing_data || [] |
||||
|
|
||||
|
if housing_data['host'].present? |
||||
|
if housing_data['host'] == host.id |
||||
|
return space == housing_data['space'] ? :selected_space : :other_space |
||||
|
end |
||||
|
|
||||
|
return :other_host |
||||
|
end |
||||
|
|
||||
|
if space_matches?(space, guest.housing) && available_dates_match?(host, guest) |
||||
|
return :good_match |
||||
|
end |
||||
|
|
||||
|
return :bad_match |
||||
|
end |
||||
|
|
||||
|
def get_workshop_match(workshop, day, block, location) |
||||
|
if workshop.event_location_id.present? && workshop.present? |
||||
|
if (Date.parse params[:day]).wday == workshop.block['day'] && block == workshop.block['block'].to_i |
||||
|
return :selected_space |
||||
|
end |
||||
|
|
||||
|
if location.present? && location.id == workshop.event_location_id |
||||
|
return :other_space |
||||
|
end |
||||
|
|
||||
|
return :other_host |
||||
|
end |
||||
|
|
||||
|
if location.present? |
||||
|
needs = JSON.parse(workshop.needs || '[]').map &:to_sym |
||||
|
amenities = JSON.parse(location.amenities || '[]').map &:to_sym |
||||
|
|
||||
|
if (needs & amenities).length < needs.length |
||||
|
return :bad_match |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
(((((@schedule[@day] || {})[:times] || {})[@time] || {})[:item] || {})[:workshops] || {}).each do | l, w | |
||||
|
if w[:workshop].id != workshop.id |
||||
|
f_a = w[:workshop].active_facilitators.map { | f | f.id } |
||||
|
f_b = workshop.active_facilitators.map { | f | f.id } |
||||
|
if (f_a & f_b).present? |
||||
|
return :bad_match |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
# housing_data = guest.housing_data || [] |
||||
|
|
||||
|
# if housing_data['host'].present? |
||||
|
# if housing_data['host'] == host.id |
||||
|
# return space == housing_data['space'] ? :selected_space : :other_space |
||||
|
# end |
||||
|
|
||||
|
# return :other_host |
||||
|
# end |
||||
|
|
||||
|
# if space_matches?(space, guest.housing) && available_dates_match?(host, guest) |
||||
|
# return :good_match |
||||
|
# end |
||||
|
|
||||
|
# return :bad_match |
||||
|
return :good_match |
||||
|
end |
||||
|
|
||||
|
def space_matches?(host_space, guest_space) |
||||
|
return false unless host_space.present? && guest_space.present? |
||||
|
|
||||
|
if host_space.to_s == 'bed_space' || host_space.to_s == 'floor_space' |
||||
|
return guest_space.to_s == 'house' |
||||
|
end |
||||
|
|
||||
|
return host_space.to_s == 'tent_space' && guest_space.to_s == 'tent' |
||||
|
end |
||||
|
|
||||
|
def available_dates_match?(host, guest) |
||||
|
return false unless host.housing_data['availability'].present? && host.housing_data['availability'][1].present? |
||||
|
if host.housing_data['availability'][0] <= guest.arrival && |
||||
|
host.housing_data['availability'][1] >= guest.departure |
||||
|
return true |
||||
|
end |
||||
|
|
||||
|
return false |
||||
|
end |
||||
|
end |
File diff suppressed because it is too large
@ -1,407 +0,0 @@ |
|||||
|
|
||||
module BikeBikeFormHelper |
|
||||
include ActionView::Helpers::FormTagHelper |
|
||||
|
|
||||
TEMPLATE_DIR = 'layouts/fields' |
|
||||
|
|
||||
def check_box_tag(name, value = "1", checked = false, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, checked, options), value) |
|
||||
end |
|
||||
|
|
||||
def color_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def date_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def datetime_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def datetime_local_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def email_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def file_field_tag(name, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, options)) |
|
||||
end |
|
||||
|
|
||||
def hidden_field_tag(name, value = nil, options = {}) |
|
||||
super(name, value, options) |
|
||||
end |
|
||||
|
|
||||
def month_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def number_field_tag(name, value = nil, options = {}) |
|
||||
options[:_no_wrapper] = true |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def password_field_tag(name = "password", value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def phone_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def radio_button_tag(name, value, checked = false, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, checked, options), value) |
|
||||
end |
|
||||
|
|
||||
def range_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def search_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def select_tag(name, option_tags = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, option_tags, options)) |
|
||||
end |
|
||||
|
|
||||
def telephone_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def text_area_tag(name, content = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, content, options), content) |
|
||||
end |
|
||||
|
|
||||
def text_field_tag(name, value = nil, options = {}) |
|
||||
if options[:_no_wrapper] |
|
||||
options.delete(:_no_wrapper) |
|
||||
options[:no_wrapper] = true |
|
||||
end |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def time_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def url_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def week_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def country_select_tag(name, value, options={}) |
|
||||
#options[:no_wrapper] = true |
|
||||
render_field(name, options = get_options(name, options), super(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def subregion_select_tag(name, value, parent_region_or_code, options = {}, html_options = {}) |
|
||||
render_field(name, options = get_options(name, options), super(name, value, parent_region_or_code, options), value) |
|
||||
end |
|
||||
|
|
||||
#def button_tag |
|
||||
#def field_set_tag |
|
||||
#def form_tag |
|
||||
#def image_submit_tag |
|
||||
#def label_tag |
|
||||
#def submit_tag |
|
||||
#def utf8_enforcer_tag |
|
||||
|
|
||||
# FormHelper methods |
|
||||
|
|
||||
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options, checked_value, unchecked_value)) |
|
||||
end |
|
||||
|
|
||||
def color_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options)) |
|
||||
end |
|
||||
|
|
||||
def date_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options)) |
|
||||
end |
|
||||
|
|
||||
def datetime_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options)) |
|
||||
end |
|
||||
|
|
||||
def datetime_local_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options)) |
|
||||
end |
|
||||
|
|
||||
def email_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options)) |
|
||||
end |
|
||||
|
|
||||
def file_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options)) |
|
||||
end |
|
||||
|
|
||||
def hidden_field(object_name, method, options = {}) |
|
||||
super(object_name, method, options) |
|
||||
end |
|
||||
|
|
||||
def month_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def number_field(object_name, method, options = {}) |
|
||||
options[:_no_wrapper] = true |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def password_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def phone_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def radio_button(object_name, method, tag_value, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, tag_value, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def range_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def search_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def telephone_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def text_area(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def text_field(object_name, method, options = {}) |
|
||||
if options[:_no_wrapper] |
|
||||
options.delete(:_no_wrapper) |
|
||||
options[:no_wrapper] = true |
|
||||
end |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def time_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def url_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def week_field(object_name, method, options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object_name, method, options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def form_for(*args, &block) |
|
||||
@record = args.first |
|
||||
|
|
||||
template = 'errors_' + @record.class.name.underscore |
|
||||
template = 'errors_default' unless lookup_context.exists?(template, [TEMPLATE_DIR], true) |
|
||||
|
|
||||
( render (TEMPLATE_DIR + '/' + template) ) + super(*args, &block) |
|
||||
end |
|
||||
|
|
||||
def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, collection, value_method, text_method, options, html_options, &block), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, collection, value_method, text_method, options, html_options, &block), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, collection, value_method, text_method, options, html_options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def select(object, method, choices = nil, options = {}, html_options = {}, &block) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, choices, options, html_options, &block), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, priority_zones, options, html_options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def country_select(object, method, priorities_or_options = {}, options_or_html_options = {}, html_options = {}) |
|
||||
if priorities_or_options.is_a? Array |
|
||||
options = options_or_html_options = get_options(method, priorities_or_options) |
|
||||
else |
|
||||
options = priorities_or_options = get_options(method, priorities_or_options) |
|
||||
end |
|
||||
render_field(method, options, super(object, method, priorities_or_options, options_or_html_options, html_options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
def subregion_select(object, method, parent_region_or_code, options = {}, html_options = {}) |
|
||||
render_field(method, options = get_options(method, options), super(object, method, parent_region_or_code, options, html_options), get_value(method, options)) |
|
||||
end |
|
||||
|
|
||||
# Custom fields |
|
||||
|
|
||||
def image_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), BikeBikeFormHelper.image_field_tag(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def organization_select_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), BikeBikeFormHelper.organization_select_field_tag(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
def user_select_field_tag(name, value = nil, options = {}) |
|
||||
render_field(name, options = get_options(name, options), BikeBikeFormHelper.user_select_field_tag(name, value, options), value) |
|
||||
end |
|
||||
|
|
||||
#def grouped_options_for_select |
|
||||
#def option_groups_from_collection_for_select |
|
||||
#def options_for_select |
|
||||
#def options_from_collection_for_select |
|
||||
#def time_zone_options_for_select |
|
||||
|
|
||||
def form_actions(actions = []) |
|
||||
BikeBikeFormHelper.form_actions(actions) |
|
||||
end |
|
||||
|
|
||||
class << self |
|
||||
|
|
||||
def form_actions(actions = []) |
|
||||
render(:actions, {:actions => actions.is_a?(Array) ? actions : [actions]}) |
|
||||
end |
|
||||
|
|
||||
def image_field_tag(name, value, options, form = nil) |
|
||||
render(:field_image_field, {:name => name, :value => value, :options => options, :form => form}) |
|
||||
end |
|
||||
|
|
||||
def organization_select_field_tag(name, value, options, form = nil) |
|
||||
render(:field_organization_select_field, {:name => name, :value => value, :options => options, :form => form}) |
|
||||
end |
|
||||
|
|
||||
def user_select_field_tag(name, value, options, form = nil) |
|
||||
render(:field_user_select_field, {:name => name, :value => value, :options => options, :form => form}) |
|
||||
end |
|
||||
|
|
||||
def get_options(name, options, type) |
|
||||
if options[:placeholder] === false |
|
||||
options.delete(:placeholder) |
|
||||
elsif (['email_field', 'number_field', 'phone_field', 'search_field', 'telephone_field', 'text_area', 'text_field', 'url_field'].include? type) |
|
||||
options[:placeholder] ||= I18n.translate('form.placeholder.Enter_your_' + name.to_s) |
|
||||
end |
|
||||
return options |
|
||||
end |
|
||||
|
|
||||
def render_field(type, name, options, html, value = nil) |
|
||||
options.symbolize_keys! |
|
||||
if (options.has_key?(:no_wrapper) && options[:no_wrapper]) || /country/.match(name.to_s) && /^subregion_select/.match(type.to_s) || options[:type] == 'hidden' |
|
||||
return html |
|
||||
end |
|
||||
|
|
||||
params = Hash.new |
|
||||
params[:name] = name.to_sym |
|
||||
params[:options] = options |
|
||||
params[:html] = html |
|
||||
params[:type] = type |
|
||||
params[:value] = value |
|
||||
|
|
||||
template = template_exists?(type) ? type : 'default' |
|
||||
params[:label_template] = options[:label] === false ? nil : get_label_template(type, options) |
|
||||
params[:label_position] = options[:label] === false ? :none : label_position(type, options) |
|
||||
|
|
||||
render(template, params) |
|
||||
end |
|
||||
|
|
||||
def get_label_template(type, options) |
|
||||
if !options[:label] && /select(_field)?$/.match(type.to_s) |
|
||||
return nil |
|
||||
end |
|
||||
template_exists?('label_' + type) ? type : 'default' |
|
||||
end |
|
||||
|
|
||||
def label_position(type, options) |
|
||||
# one of: :before, :after, :inside, or :none |
|
||||
case type |
|
||||
when 'image_field' |
|
||||
return :inside |
|
||||
when 'organization_select_field' |
|
||||
return :none |
|
||||
#when 'select_field' |
|
||||
# return :before |
|
||||
end |
|
||||
return :before |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def render (template, params) |
|
||||
view = ActionView::Base.new(ActionController::Base.view_paths, params) |
|
||||
view.extend ApplicationHelper |
|
||||
view.render (TEMPLATE_DIR + '/' + template.to_s) |
|
||||
end |
|
||||
|
|
||||
def template_exists? (template) |
|
||||
view = ActionView::Base.new(ActionController::Base.view_paths, {}) |
|
||||
view.extend ApplicationHelper |
|
||||
view.lookup_context.exists?(template, [TEMPLATE_DIR], true) |
|
||||
end |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def get_type() |
|
||||
caller[1][/`.*'/][1..-2].gsub(/^(.*?)(_tag)?$/, '\1') |
|
||||
end |
|
||||
|
|
||||
def get_value(method, options) |
|
||||
options && options[:object] ? options[:object][method] : nil |
|
||||
end |
|
||||
|
|
||||
def get_options(name, options) |
|
||||
options[:_controller] = params[:controller] |
|
||||
BikeBikeFormHelper.get_options(name, options, get_type()) |
|
||||
end |
|
||||
|
|
||||
def render_field(name, options, html, value = nil) |
|
||||
BikeBikeFormHelper.render_field(get_type(), name, options, html, value) |
|
||||
end |
|
||||
|
|
||||
class BikeBikeFormBuilder < ActionView::Helpers::FormBuilder |
|
||||
ActionView::Base.default_form_builder = BikeBikeFormHelper::BikeBikeFormBuilder |
|
||||
|
|
||||
def image_field(method, value, options = {}) |
|
||||
custom_field(method, value, options, 'image_field') |
|
||||
end |
|
||||
|
|
||||
def organization_select_field(method, value, options = {}) |
|
||||
custom_field(method, value, options, 'organization_select_field') |
|
||||
end |
|
||||
|
|
||||
def user_select_field(method, value, options = {}) |
|
||||
custom_field(method, value, options, 'user_select_field') |
|
||||
end |
|
||||
|
|
||||
def actions(actions = []) |
|
||||
BikeBikeFormHelper.form_actions(actions) |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def custom_field(method, value, options, type) |
|
||||
if defined? params |
|
||||
options[:_controller] = params[:controller] |
|
||||
end |
|
||||
options[:_record] = object |
|
||||
options = BikeBikeFormHelper.get_options(method, options, type) |
|
||||
html = BikeBikeFormHelper.send(type + '_tag', method, value, options, self) |
|
||||
BikeBikeFormHelper.render_field(type, method, options, html, value) |
|
||||
end |
|
||||
end |
|
||||
end |
|
@ -0,0 +1,729 @@ |
|||||
|
|
||||
|
module FormHelper |
||||
|
def off_screen(text, id = nil) |
||||
|
content_tag(:span, text.html_safe, id: id, class: 'screen-reader-text') |
||||
|
end |
||||
|
|
||||
|
def translate_fields(object, field_options = {}, options = {}) |
||||
|
html = '' |
||||
|
nav = '' |
||||
|
|
||||
|
# set the selected locale |
||||
|
selected_locale = (options[:locale] || object.locale || I18n.locale).to_sym |
||||
|
|
||||
|
I18n.backend.enabled_locales.each do | locale | |
||||
|
# ses if this should b the selected field |
||||
|
class_name = selected_locale == locale.to_sym ? 'selected' : nil |
||||
|
|
||||
|
# add the locale to the nav |
||||
|
nav += content_tag(:li, |
||||
|
content_tag(:a, _("languages.#{locale}"), href: 'javascript:void(0)'), |
||||
|
class: class_name, data: { locale: locale }).html_safe |
||||
|
|
||||
|
fields = '' |
||||
|
field_options.each do | name, __options | |
||||
|
_options = __options.deep_dup |
||||
|
# add the field |
||||
|
value = object.is_a?(Hash) ? object[locale.to_sym] : object.get_column_for_locale!(name, locale, false) |
||||
|
|
||||
|
# use the default value if we need to |
||||
|
if _options[:default].present? && value.blank? |
||||
|
value = _(_options[:default], locale: locale) |
||||
|
end |
||||
|
|
||||
|
_options[:index] = locale |
||||
|
_options[:lang] = locale |
||||
|
_options[:parent_options] = { lang: locale } |
||||
|
type = "#{_options[:type].to_s}" |
||||
|
_options.delete(:type) |
||||
|
|
||||
|
fields += self.send(type, name, value, _options).html_safe |
||||
|
end |
||||
|
|
||||
|
html += content_tag(:li, fields.html_safe, class: class_name, data: { locale: locale }).html_safe |
||||
|
end |
||||
|
|
||||
|
if options[:class].nil? |
||||
|
options[:class] = [] |
||||
|
elsif options[:class].is_a?(String) |
||||
|
options[:class] = [options[:class]] |
||||
|
end |
||||
|
options[:class] += ['translator', 'multi-field-translator'] |
||||
|
|
||||
|
(fieldset(nil, options) do |
||||
|
content_tag(:ul, nav.html_safe, class: 'locale-select').html_safe + |
||||
|
content_tag(:ul, html.html_safe, class: 'text-editors').html_safe |
||||
|
end).html_safe |
||||
|
end |
||||
|
|
||||
|
def translate_textarea(name, object, property = nil, options = {}) |
||||
|
html = '' |
||||
|
nav = '' |
||||
|
|
||||
|
# see if options was passed in as property |
||||
|
if options.blank? && property.is_a?(Hash) |
||||
|
options = property |
||||
|
property = nil |
||||
|
end |
||||
|
|
||||
|
# set the selected locale |
||||
|
selected_locale = (options[:locale] || object.locale || I18n.locale).to_sym |
||||
|
|
||||
|
I18n.backend.enabled_locales.each do | locale | |
||||
|
# ses if this should b the selected field |
||||
|
class_name = selected_locale == locale.to_sym ? 'selected' : nil |
||||
|
|
||||
|
# add the locale to the nav |
||||
|
nav += content_tag(:li, |
||||
|
content_tag(:a, _("languages.#{locale}"), href: 'javascript:void(0)'), |
||||
|
class: class_name, data: { locale: locale }).html_safe |
||||
|
|
||||
|
# add the field |
||||
|
value = object.is_a?(Hash) ? object[locale.to_sym] : object.get_column_for_locale!(name, locale, false) |
||||
|
|
||||
|
# use the default value if we need to |
||||
|
if options[:default].present? && value.blank? |
||||
|
value = _(options[:default], locale: locale) |
||||
|
end |
||||
|
|
||||
|
html += content_tag(:li, textarea(name, value, { |
||||
|
label: false, |
||||
|
edit_on: options[:edit_on], |
||||
|
parent_options: { |
||||
|
lang: locale |
||||
|
}, |
||||
|
index: locale |
||||
|
}).html_safe, class: class_name, data: { locale: locale }).html_safe |
||||
|
end |
||||
|
|
||||
|
if options[:class].nil? |
||||
|
options[:class] = [] |
||||
|
elsif options[:class].is_a?(String) |
||||
|
options[:class] = [options[:class]] |
||||
|
end |
||||
|
options[:class] += ['translator'] |
||||
|
|
||||
|
(fieldset(name, options) do |
||||
|
content_tag(:ul, nav.html_safe, class: 'locale-select').html_safe + |
||||
|
content_tag(:ul, html.html_safe, class: 'text-editors').html_safe |
||||
|
end).html_safe |
||||
|
end |
||||
|
|
||||
|
def textarea(name, value = nil, options = {}) |
||||
|
id = unique_id(name) |
||||
|
label_id = "#{id}-label" |
||||
|
description_id = nil |
||||
|
html = '' |
||||
|
|
||||
|
if options[:heading].present? |
||||
|
label_id = "#{name.to_s}-label" unless options[:label] |
||||
|
html += content_tag(:h3, _(options[:heading], :t, vars: options[:vars] || {}), id: label_id) |
||||
|
end |
||||
|
|
||||
|
if options[:label] == false |
||||
|
label_id = options[:labelledby] |
||||
|
elsif options[:label].present? |
||||
|
html += label_tag([name, id], nil, id: label_id) do |
||||
|
_(options[:label], :t, vars: options[:vars] || {}) |
||||
|
end |
||||
|
else |
||||
|
html += label_tag([name, id], nil, id: label_id) |
||||
|
end |
||||
|
|
||||
|
if options[:help].present? |
||||
|
description_id ||= "#{id}-desc" |
||||
|
html += content_tag(:div, _(options[:help], :s, 2), id: description_id, class: 'input-field-help') |
||||
|
end |
||||
|
|
||||
|
if options[:warning].present? |
||||
|
description_id ||= "#{id}-desc" |
||||
|
html += content_tag(:div, _(options[:warning], :s, 2), id: description_id, class: 'warning-info') |
||||
|
end |
||||
|
|
||||
|
aria = {} |
||||
|
aria[:labelledby] = label_id if label_id.present? |
||||
|
aria[:describedby] = description_id if description_id.present? |
||||
|
css_class = [ |
||||
|
options[:short] === true ? :short : nil |
||||
|
].compact |
||||
|
|
||||
|
html_name = name.to_s + (options[:index] ? "[#{options[:index]}]" : '') |
||||
|
if options[:plain] |
||||
|
html += (text_area_tag html_name, value, |
||||
|
id: id, |
||||
|
lang: options[:lang], |
||||
|
aria: aria, |
||||
|
class: css_class |
||||
|
) |
||||
|
else |
||||
|
html += content_tag(:div, value.present? ? value.html_safe : '', |
||||
|
id: id, |
||||
|
data: { name: html_name, 'edit-on': options[:edit_on] || :load }, |
||||
|
lang: options[:lang], |
||||
|
aria: aria, |
||||
|
tabindex: 0, |
||||
|
class: [:textarea] + css_class |
||||
|
) |
||||
|
|
||||
|
add_stylesheet :editor |
||||
|
add_inline_script :pen |
||||
|
add_inline_script :markdown |
||||
|
add_inline_script :editor |
||||
|
end |
||||
|
|
||||
|
parent_options = options[:parent_options] || {} |
||||
|
if parent_options[:class].nil? |
||||
|
parent_options[:class] = [] |
||||
|
elsif parent_options[:class].is_a?(String) |
||||
|
parent_options[:class] = [parent_options[:class]] |
||||
|
end |
||||
|
|
||||
|
parent_options[:class] += ['text-area-field', 'input-field'] |
||||
|
html = content_tag(:div, html.html_safe, parent_options).html_safe |
||||
|
html += _original_content(options[:original_value], options[:original_lang]) if options[:original_value].present? |
||||
|
|
||||
|
return html.html_safe |
||||
|
end |
||||
|
|
||||
|
def fieldset(name = nil, options = {}, &block) |
||||
|
html = '' |
||||
|
label = '' |
||||
|
description = '' |
||||
|
description_id = nil |
||||
|
errors = '' |
||||
|
|
||||
|
if name.present? |
||||
|
if options[:label] != false |
||||
|
label = content_tag(:legend, |
||||
|
_(( |
||||
|
options[:label].is_a?(String) ? |
||||
|
options[:label] : |
||||
|
"forms.labels.generic.#{name}"), :t, vars: options[:vars] || {})) |
||||
|
end |
||||
|
|
||||
|
if options[:help].present? |
||||
|
description_id = unique_id("#{name.to_s}-desc") |
||||
|
description = content_tag(:div, _(options[:help], :s, 2), class: 'input-field-help', id: description_id) |
||||
|
end |
||||
|
|
||||
|
errors = (show_errors name) |
||||
|
end |
||||
|
|
||||
|
html = label + errors + description + content_tag(:div, class: :fieldgroup, &block) |
||||
|
|
||||
|
aria = description_id.present? ? { describedby: description_id } : nil |
||||
|
(content_tag(:fieldset, html.html_safe, |
||||
|
aria: aria, |
||||
|
class: ((options[:class] || []) + [ |
||||
|
options[:inline] ? :inline : nil, |
||||
|
options[:inline_label] ? 'inline-label' : nil, |
||||
|
errors.present? ? 'has-error' : nil |
||||
|
]).compact |
||||
|
) |
||||
|
).html_safe |
||||
|
end |
||||
|
|
||||
|
def selectfield(name, value, select_options, options = {}) |
||||
|
unless select_options.first.is_a?(Array) |
||||
|
so = select_options |
||||
|
select_options = [] |
||||
|
so.each do | opt | |
||||
|
select_options << [ I18n.t("forms.options.#{name.to_s}.#{opt.to_s}"), opt] |
||||
|
end |
||||
|
end |
||||
|
textfield(name, value, options.merge({type: :select, options: select_options})) |
||||
|
end |
||||
|
|
||||
|
def telephonefield(name, value, options = {}) |
||||
|
textfield(name, value, options.merge({type: :telephone})) |
||||
|
end |
||||
|
|
||||
|
def numberfield(name, value, options = {}) |
||||
|
textfield(name, value, options.merge({type: :number})) |
||||
|
end |
||||
|
|
||||
|
def searchfield(name, value, options = {}) |
||||
|
textfield(name, value, options.merge({type: :search})) |
||||
|
end |
||||
|
|
||||
|
def userfield(name, value, options = {}) |
||||
|
# eventually this will be a dynamic field to find users, for now we'll just use emails |
||||
|
# add_inline_script :userfield |
||||
|
emailfield(name, value, options)# .merge({ |
||||
|
# parent_options: { class: ['user-field'] }, |
||||
|
# after: content_tag(:div, '', class: 'user-name') |
||||
|
# })) |
||||
|
end |
||||
|
|
||||
|
def emailfield(name, value, options = {}) |
||||
|
textfield(name, value, options.merge({type: :email})) |
||||
|
end |
||||
|
|
||||
|
def filefield(name, value, options = {}) |
||||
|
textfield(name, value, options.merge({type: :file})) |
||||
|
end |
||||
|
|
||||
|
def passwordfield(name, value, options = {}) |
||||
|
textfield(name, value, options.merge({type: :password})) |
||||
|
end |
||||
|
|
||||
|
def textfield(name, value, options = {}) |
||||
|
html = '' |
||||
|
id = unique_id(name) |
||||
|
html_name = name.to_s + (options[:index] ? "[#{options[:index]}]" : '') |
||||
|
description_id = nil |
||||
|
|
||||
|
if options[:heading].present? |
||||
|
description_id ||= "#{id.to_s}-desc" |
||||
|
html += content_tag(:h3, _(options[:heading], :t, vars: options[:vars] || {}), id: description_id) |
||||
|
end |
||||
|
|
||||
|
if options[:help].present? |
||||
|
description_id ||= "#{id.to_s}-desc" |
||||
|
html += content_tag(:div, _(options[:help], :s, 2, vars: options[:vars] || {}), class: 'input-field-help', id: description_id) |
||||
|
end |
||||
|
|
||||
|
html += show_errors name, value |
||||
|
|
||||
|
inside_label = '' |
||||
|
|
||||
|
if options[:type] == :file |
||||
|
inside_label = (content_tag(:div, class: 'file-field-selector') do |
||||
|
(options[:preview] ? content_tag(:img, nil, src: value.present? ? value.url : nil).html_safe : '').html_safe + |
||||
|
content_tag(:div, (value.present? ? File.basename(value.url) : (_'forms.labels.generic.no_file_selected')), class: 'file-field-name ' + (value.present? ? 'selected' : 'unselected')).html_safe + |
||||
|
content_tag(:a, (_'forms.actions.generic.select_file'), class: :button) |
||||
|
end) |
||||
|
end |
||||
|
|
||||
|
label_text = nil |
||||
|
if options[:label].present? |
||||
|
label_text = _(options[:label], :t, vars: options[:vars] || {}) |
||||
|
elsif options[:label] != false |
||||
|
label_text = (_"forms.labels.generic.#{name}") |
||||
|
elsif options[:type] == :select || options[:type] == :file |
||||
|
# add an empty label so that the drop down button will still appear |
||||
|
label_text = '' |
||||
|
end |
||||
|
|
||||
|
label_options = {} |
||||
|
# let the label be selected if the input is hidden |
||||
|
label_options[:tabindex] = 0 if options[:type] == :file |
||||
|
|
||||
|
unless label_text.nil? |
||||
|
html += label_tag id, (label_text + inside_label).html_safe |
||||
|
end |
||||
|
|
||||
|
input_options = { |
||||
|
id: id, |
||||
|
required: options[:required], |
||||
|
lang: options[:lang], |
||||
|
min: options[:min], |
||||
|
max: options[:max], |
||||
|
step: options[:step], |
||||
|
aria: description_id ? { describedby: description_id } : nil |
||||
|
} |
||||
|
|
||||
|
case name |
||||
|
when :address |
||||
|
input_options[:autocomplete] = 'address-line1' |
||||
|
when :name |
||||
|
input_options[:autocomplete] = 'name' |
||||
|
when :location |
||||
|
input_options[:autocomplete] = 'address-level2' |
||||
|
when :email |
||||
|
input_options[:autocomplete] = 'email' |
||||
|
when :phone |
||||
|
input_options[:autocomplete] = 'tel' |
||||
|
when :paypal_email_address, :paypal_username, :paypal_password, :paypal_signature |
||||
|
input_options[:autocomplete] = 'off' |
||||
|
end |
||||
|
|
||||
|
case options[:type] |
||||
|
when :select |
||||
|
option_list = options_for_select(options[:options], value) |
||||
|
|
||||
|
# make sure that we have an empty option if the select is required |
||||
|
if options[:required] && options[:options].first.present? && options[:options].first.last.present? |
||||
|
option_list = ('<option value=""> </option>' + option_list).html_safe |
||||
|
end |
||||
|
html += select_tag(html_name, option_list, input_options) |
||||
|
when :file |
||||
|
add_inline_script :filefield |
||||
|
input_options[:tabindex] = '-1' |
||||
|
html += off_screen(file_field_tag html_name, input_options) |
||||
|
else |
||||
|
input_options[:autocomplete] = 'off' if options[:type] == :search |
||||
|
html += send("#{(options[:type] || :text).to_s}_field_tag", html_name, value, input_options) |
||||
|
end |
||||
|
|
||||
|
if options[:after].present? |
||||
|
html += options[:after].html_safe |
||||
|
end |
||||
|
|
||||
|
html = content_tag(:div, html.html_safe, |
||||
|
class: [ |
||||
|
"#{(options[:type] || :text).to_s}-field", |
||||
|
'input-field', |
||||
|
value.present? ? nil : 'empty', |
||||
|
options[:big] ? 'big' : nil, |
||||
|
options[:small] ? 'small' : nil, |
||||
|
options[:stretch] ? 'stretch-item' : nil, |
||||
|
options[:full] ? 'full' : nil, |
||||
|
options[:inline_label] ? 'inline-label' : nil, |
||||
|
(@errors || {})[name].present? ? 'has-error' : nil |
||||
|
].compact + (((options[:parent_options] || {})[:class]) || [])) |
||||
|
|
||||
|
html += _original_content(options[:original_value], options[:original_lang]) if options[:original_value].present? |
||||
|
|
||||
|
return html.html_safe |
||||
|
end |
||||
|
|
||||
|
def radiobuttons(name, boxes, value, label_key, options = {}) |
||||
|
checkboxes(name, boxes, [value], label_key, options.merge({radiobuttons: true})) |
||||
|
end |
||||
|
|
||||
|
def checkbox(name, value, label_key, options = {}) |
||||
|
checkboxes(name, [true], value, label_key, options) |
||||
|
end |
||||
|
|
||||
|
def unique_id(id) |
||||
|
id = id.to_s.gsub('[', '_').gsub(']', '') |
||||
|
|
||||
|
@_ids ||= {} |
||||
|
@_ids[id] ||= 0 |
||||
|
|
||||
|
new_id = id |
||||
|
|
||||
|
if @_ids[id] > 0 |
||||
|
new_id += "--#{@_ids[id]}" |
||||
|
end |
||||
|
|
||||
|
@_ids[id] += 1 |
||||
|
|
||||
|
return new_id |
||||
|
end |
||||
|
|
||||
|
def checkboxes(name, boxes, values, label_key, options = {}) |
||||
|
html = '' |
||||
|
boxes.map! { |box| box.is_a?(String) ? box.to_sym : box } |
||||
|
values.map! { |value| value.is_a?(String) ? value.to_sym : value } if values.is_a?(Array) |
||||
|
|
||||
|
label_id = nil |
||||
|
description_id = nil |
||||
|
|
||||
|
if options[:heading].present? |
||||
|
label_id ||= unique_id("#{name.to_s}-label") |
||||
|
html += content_tag(:h3, _(options[:heading], :t, vars: options[:vars] || {}), id: label_id) |
||||
|
end |
||||
|
|
||||
|
help = nil |
||||
|
|
||||
|
if options[:help].present? |
||||
|
description_id ||= unique_id("#{name.to_s}-desc") |
||||
|
help = content_tag(:div, _(options[:help], :s, 2), class: 'input-field-help', id: description_id) |
||||
|
end |
||||
|
|
||||
|
html += help if help.present? && !options[:right_help] |
||||
|
|
||||
|
boxes_html = '' |
||||
|
|
||||
|
labels = nil |
||||
|
is_single = !values.is_a?(Array) |
||||
|
if boxes.length > 0 |
||||
|
if boxes.first.is_a?(Array) |
||||
|
labels = boxes.map(&:first) |
||||
|
boxes = boxes.map(&:last) |
||||
|
end |
||||
|
elsif !boxes.first.is_a?(Integer) |
||||
|
values = values.present? ? values.map(&:to_s) : [] unless is_single |
||||
|
boxes = boxes.map(&:to_s) |
||||
|
end |
||||
|
|
||||
|
# convert the required value into a pure boolean |
||||
|
required = !!options[:required] |
||||
|
|
||||
|
boxes.each_with_index do |box, i| |
||||
|
checked = (is_single ? values.present? : values.include?(box)) |
||||
|
values -= [box] if checked && !is_single |
||||
|
id = nil |
||||
|
if options[:radiobuttons].present? |
||||
|
id = unique_id("#{name.to_s}_#{box}") |
||||
|
boxes_html += radio_button_tag(name, box, checked, id: id, required: required) |
||||
|
else |
||||
|
_name = (is_single ? name : "#{name.to_s}[#{box}]") |
||||
|
id = unique_id(_name) |
||||
|
boxes_html += check_box_tag(_name, 1, checked, data: { toggles: options[:toggles] }.compact, id: id, required: required) |
||||
|
end |
||||
|
|
||||
|
# we only need the required attribute on one element |
||||
|
required = false |
||||
|
|
||||
|
if labels.present? |
||||
|
label = labels[i] |
||||
|
elsif is_single |
||||
|
label = _(label_key.to_s) |
||||
|
elsif box.is_a?(Integer) |
||||
|
label = I18n.t(label_key.to_s)[box] |
||||
|
else |
||||
|
label = _("#{label_key.to_s}.#{box}") |
||||
|
end |
||||
|
|
||||
|
boxes_html += label_tag(id, label) |
||||
|
end |
||||
|
|
||||
|
if options[:other].present? && !is_single |
||||
|
id = nil |
||||
|
if options[:radiobuttons].present? |
||||
|
id = unique_id("#{name.to_s}_other") |
||||
|
boxes_html += radio_button_tag(name, :other, values.present?, id: id) |
||||
|
else |
||||
|
_name = "#{name.to_s}[other]" |
||||
|
id = unique_id(_name) |
||||
|
boxes_html += check_box_tag(_name, 1, values.present?, id: id) |
||||
|
end |
||||
|
boxes_html += label_tag id, |
||||
|
content_tag(:div, |
||||
|
text_field_tag("other_#{name.to_s}", values.first, placeholder: (_"#{label_key}.other"), required: values.present?), |
||||
|
class: 'other') |
||||
|
end |
||||
|
|
||||
|
html += content_tag(:fieldset, content_tag(:div, boxes_html.html_safe, |
||||
|
class: [ |
||||
|
'check-box-field', |
||||
|
'input-field', |
||||
|
options[:vertical] ? 'vertical' : nil, |
||||
|
options[:inline] ? 'inline' : nil, |
||||
|
options[:small] ? 'small' : nil, |
||||
|
options[:big] ? 'big' : nil |
||||
|
].compact).html_safe, |
||||
|
aria: { |
||||
|
labelledby: label_id, |
||||
|
describedby: description_id |
||||
|
}, |
||||
|
class: [ |
||||
|
options[:centered] ? 'centered' : nil, |
||||
|
options[:right_help] ? 'right-help' : nil |
||||
|
].compact |
||||
|
) |
||||
|
|
||||
|
html += help if help.present? && options[:right_help] |
||||
|
|
||||
|
return html.html_safe |
||||
|
end |
||||
|
|
||||
|
def button(value = nil, options = {}, &block) |
||||
|
if !block_given? && (value.nil? || value.is_a?(Symbol)) |
||||
|
return button_tag(I18n.t("forms.actions.generic.#{(value || :button)}"), options) |
||||
|
end |
||||
|
|
||||
|
button_tag(value, options, &block) |
||||
|
end |
||||
|
|
||||
|
def conference_days_options(conference = nil) |
||||
|
conference ||= @this_conference || @conference |
||||
|
return [] unless conference |
||||
|
|
||||
|
dates = [] |
||||
|
day = conference.start_date - 7.days |
||||
|
last_day = conference.end_date + 7.days |
||||
|
|
||||
|
while day <= last_day |
||||
|
dates << day |
||||
|
day += 1.day |
||||
|
end |
||||
|
|
||||
|
return dates |
||||
|
end |
||||
|
|
||||
|
def conference_days_options_list(period, conference = nil, format = nil) |
||||
|
conference ||= @this_conference || @conference |
||||
|
return [] unless conference |
||||
|
|
||||
|
days = [] |
||||
|
|
||||
|
conference_days_options(conference).each do |day| |
||||
|
belongs_to_periods = [] |
||||
|
belongs_to_periods << :before if day <= conference.start_date |
||||
|
belongs_to_periods << :after if day >= conference.end_date |
||||
|
belongs_to_periods << :before_plus_one if day <= (conference.start_date + 1.day) |
||||
|
belongs_to_periods << :after_minus_one if day >= (conference.end_date - 1.day) |
||||
|
belongs_to_periods << :during if day >= conference.start_date && day <= conference.end_date |
||||
|
days << [date(day.to_date, format || :span_same_year_date_1), day.to_date] if belongs_to_periods.include?(period) |
||||
|
end |
||||
|
return days |
||||
|
end |
||||
|
|
||||
|
def registration_status_options_list(conference = nil) |
||||
|
conference ||= @this_conference || @conference |
||||
|
return [] unless conference |
||||
|
|
||||
|
options = Array.new |
||||
|
[:closed, :pre, :open].each do | opt | |
||||
|
options << [(_"forms.labels.generic.registration_statuses.#{opt}"), opt] |
||||
|
end |
||||
|
|
||||
|
return options |
||||
|
end |
||||
|
|
||||
|
def month_select(value = nil, args = {}) |
||||
|
options = (1..12).to_a.map { |month| [ (I18n.t "date.#{args[:format] || 'month_names'}")[month], month ] } |
||||
|
selectfield args[:name] || :month, value, options, args |
||||
|
end |
||||
|
|
||||
|
def month_day_select(value = nil, args = {}) |
||||
|
options = (1..31).to_a.map { |day| [ day, day ] } |
||||
|
selectfield args[:name] || :month_day, value, options, args |
||||
|
end |
||||
|
|
||||
|
def day_select(value = nil, args = {}) |
||||
|
selectfield :day, value, conference_days_options_list(:during, nil, args[:format]), args |
||||
|
end |
||||
|
|
||||
|
def hour_select(value = nil, args = {}, start_time = 8, end_time = 23.5, step = 0.5) |
||||
|
time = start_time |
||||
|
times = [] |
||||
|
while time <= end_time |
||||
|
times << [time(DateTime.now.midnight + time.hours), time] |
||||
|
time += step |
||||
|
end |
||||
|
selectfield :time, value, times, args |
||||
|
end |
||||
|
|
||||
|
def length_select(value = nil, args = {}, min_length = 0.5, max_length = 6, step = 0.5) |
||||
|
length = min_length |
||||
|
lengths = [] |
||||
|
while length <= max_length |
||||
|
lengths << [time_length(length), length] |
||||
|
length += step |
||||
|
end |
||||
|
selectfield :time_span, value, lengths, args |
||||
|
end |
||||
|
|
||||
|
def contact_reason_select |
||||
|
reasons = [] |
||||
|
[:website, :conference].each do | reason | |
||||
|
reasons << [ _("forms.labels.generic.reasons.#{reason.to_s}"), reason ] |
||||
|
end |
||||
|
[['Something about the website', :website]] |
||||
|
selectfield :reason, nil, reasons, required: true, heading: 'articles.contact.headings.reason', label: false, full: true |
||||
|
end |
||||
|
|
||||
|
def block_select(value = nil, args = {}) |
||||
|
blocks = {} |
||||
|
@workshop_blocks.each_with_index do | info, block | |
||||
|
info['days'].each do | day | |
||||
|
blocks[(day.to_i * 10) + block] = [ "#{(I18n.t 'date.day_names')[day.to_i]} Block #{block + 1}", "#{day}:#{block}" ] |
||||
|
end |
||||
|
end |
||||
|
selectfield :workshop_block, value, blocks.sort.to_h.values, args |
||||
|
end |
||||
|
|
||||
|
def location_select(value = nil, args = {}) |
||||
|
locations = [] |
||||
|
if @this_conference.event_locations.present? |
||||
|
@this_conference.event_locations.each do | location | |
||||
|
locations << [ location.title, location.id ] unless ((args[:invalid_locations] || []).include? location.id) |
||||
|
end |
||||
|
end |
||||
|
selectfield :event_location, value, locations, args |
||||
|
end |
||||
|
|
||||
|
def location_name(id) |
||||
|
begin |
||||
|
location = EventLocation.find(id) |
||||
|
rescue |
||||
|
return '' |
||||
|
end |
||||
|
return '' unless location.present? |
||||
|
return location.title |
||||
|
end |
||||
|
|
||||
|
def host_options_list(hosts) |
||||
|
options = [[nil, nil]] |
||||
|
hosts.each do | id, registration | |
||||
|
options << [registration.user.name, id] |
||||
|
end |
||||
|
return options |
||||
|
end |
||||
|
|
||||
|
def registration_step_menu |
||||
|
steps = current_registration_steps(@registration) |
||||
|
return '' unless steps.present? && steps.length > 1 |
||||
|
|
||||
|
pre_registration_steps = '' |
||||
|
post_registration_steps = '' |
||||
|
post_registration = false |
||||
|
|
||||
|
steps.each do | step | |
||||
|
text = _"articles.conference_registration.headings.#{step[:name].to_s}" |
||||
|
|
||||
|
if step[:name] == :workshops |
||||
|
post_registration = true |
||||
|
end |
||||
|
|
||||
|
h = content_tag :li, class: [step[:enabled] ? :enabled : nil, @register_template == step[:name] ? :current : nil, post_registration ? :post : :pre].compact do |
||||
|
if step[:enabled] |
||||
|
content_tag :div, (link_to text, register_step_path(@this_conference.slug, step[:name])).html_safe, class: :step |
||||
|
else |
||||
|
content_tag :div, text, class: :step |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
if post_registration |
||||
|
post_registration_steps += h.html_safe |
||||
|
else |
||||
|
pre_registration_steps += h.html_safe |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
html = ( |
||||
|
row class: 'flow-steps' do |
||||
|
columns do |
||||
|
(content_tag :ul, id: 'registration-steps' do |
||||
|
pre_registration_steps.html_safe + |
||||
|
post_registration_steps.html_safe |
||||
|
end).html_safe |
||||
|
end |
||||
|
end |
||||
|
) |
||||
|
|
||||
|
return html.html_safe |
||||
|
end |
||||
|
|
||||
|
def broadcast_options(conference = nil) |
||||
|
conference ||= @this_conference || @conference |
||||
|
|
||||
|
options = [ |
||||
|
:registered, |
||||
|
:pre_registered, |
||||
|
:workshop_facilitators, |
||||
|
:unregistered, |
||||
|
:housing_providers, |
||||
|
:guests, |
||||
|
:all |
||||
|
] |
||||
|
|
||||
|
if conference.registration_status != :open |
||||
|
options -= [:registered, :guests] |
||||
|
options -= [:pre_registered] unless conference.registration_status != :pre |
||||
|
end |
||||
|
|
||||
|
return options |
||||
|
end |
||||
|
|
||||
|
def show_errors(field, value = nil) |
||||
|
return '' unless @errors && @errors[field].present? |
||||
|
|
||||
|
error_txt = _"errors.messages.fields.#{field.to_s}.#{@errors[field]}", :s, vars: { value: value } |
||||
|
|
||||
|
content_tag(:div, error_txt, class: 'field-error').html_safe |
||||
|
end |
||||
|
|
||||
|
private |
||||
|
def _original_content(value, lang) |
||||
|
content_tag(:div, ( |
||||
|
content_tag(:h4, _('translate.content.Translation_of')) + |
||||
|
content_tag(:div, value, class: 'value', lang: lang) |
||||
|
).html_safe, class: 'original-text') |
||||
|
end |
||||
|
end |
@ -0,0 +1,100 @@ |
|||||
|
module GeocoderHelper |
||||
|
def lookup_ip |
||||
|
if request.remote_ip == '127.0.0.1' || request.remote_ip == '::1' |
||||
|
session['remote_ip'] || (session['remote_ip'] = open("http://checkip.dyndns.org").first.gsub(/^.*\s([\d\.]+).*$/s, '\1').gsub(/[^\.\d]/, '')) |
||||
|
else |
||||
|
request.remote_ip |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def get_remote_location |
||||
|
Geocoder.search(session['remote_ip'] || (session['remote_ip'] = open("http://checkip.dyndns.org").first.gsub(/^.*\s([\d\.]+).*$/s, '\1').gsub(/[^\.\d]/, '')), language: 'en').first |
||||
|
end |
||||
|
|
||||
|
def lookup_ip_location |
||||
|
begin |
||||
|
if is_test? && ApplicationController::get_location.present? |
||||
|
Geocoder.search(ApplicationController::get_location, language: 'en').first |
||||
|
elsif request.remote_ip == '127.0.0.1' || request.remote_ip == '::1' |
||||
|
get_remote_location |
||||
|
else |
||||
|
request.location || get_remote_location |
||||
|
end |
||||
|
rescue |
||||
|
nil |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def potential_provider(registration) |
||||
|
return false unless registration.present? && registration.city.present? && registration.conference.present? |
||||
|
conditions = registration.conference.provider_conditions || |
||||
|
Conference.default_provider_conditions |
||||
|
return city_distance_less_than(registration.conference.city, registration.city, |
||||
|
conditions['distance']['number'], conditions['distance']['unit']) |
||||
|
end |
||||
|
|
||||
|
def city_distance_less_than(city1, city2, max_distance, unit) |
||||
|
return false if city1.nil? || city2.nil? |
||||
|
return true if city1.id == city2.id |
||||
|
return false if max_distance < 1 |
||||
|
return Geocoder::Calculations.distance_between( |
||||
|
[city1.latitude, city1.longitude], [city2.latitude, city2.longitude], |
||||
|
units: unit.to_sym) < max_distance |
||||
|
end |
||||
|
|
||||
|
def location(location, locale = I18n.locale) |
||||
|
return nil if location.blank? |
||||
|
|
||||
|
city = nil |
||||
|
region = nil |
||||
|
country = nil |
||||
|
if location.is_a?(Location) || location.is_a?(City) |
||||
|
country = location.country |
||||
|
region = location.territory |
||||
|
city = location.city |
||||
|
elsif location.data.present? && location.data['address_components'].present? |
||||
|
component_map = { |
||||
|
'locality' => :city, |
||||
|
'administrative_area_level_1' => :region, |
||||
|
'country' => :country |
||||
|
} |
||||
|
location.data['address_components'].each do | component | |
||||
|
types = component['types'] |
||||
|
country = component['short_name'] if types.include? 'country' |
||||
|
region = component['short_name'] if types.include? 'administrative_area_level_1' |
||||
|
city = component['long_name'] if types.include? 'locality' |
||||
|
end |
||||
|
else |
||||
|
country = location.data['country_code'] |
||||
|
region = location.data['region_code'] |
||||
|
city = location.data['city'] |
||||
|
end |
||||
|
|
||||
|
# we need cities for our logic, don't let this continue if we don't have one |
||||
|
return nil unless city.present? |
||||
|
|
||||
|
hash = Hash.new |
||||
|
region_translation = region.present? && country.present? ? _("geography.subregions.#{country}.#{region}", locale: locale) : '' |
||||
|
country_translation = country.present? ? _("geography.countries.#{country}", locale: locale) : '' |
||||
|
hash[:city] = _!(city) if city.present? |
||||
|
hash[:region] = region_translation if region_translation.present? |
||||
|
hash[:country] = country_translation if country_translation.present? |
||||
|
|
||||
|
# return the formatted location or the first value if we only have one value |
||||
|
return hash.length > 1 ? _("geography.formats.#{hash.keys.join('_')}", locale: locale, vars: hash) : hash.values.first |
||||
|
end |
||||
|
|
||||
|
def location_link(location) |
||||
|
return '' unless location.present? && location.address.present? |
||||
|
content_tag(:a, (_!location.address), href: "http://www.google.com/maps/place/#{location.latitude},#{location.longitude}") |
||||
|
end |
||||
|
|
||||
|
def same_city?(location1, location2) |
||||
|
return false unless location1.present? && location2.present? |
||||
|
|
||||
|
location1 = location(location1) unless location1.is_a?(String) |
||||
|
location2 = location(location2) unless location2.is_a?(String) |
||||
|
|
||||
|
location1.eql? location2 |
||||
|
end |
||||
|
end |
@ -0,0 +1,74 @@ |
|||||
|
|
||||
|
module I18nHelper |
||||
|
def url_for_locale(locale, url = nil) |
||||
|
return url unless locale.present? |
||||
|
|
||||
|
unless url.present? |
||||
|
new_params = params.merge({action: (params[:_original_action] || params[:action])}) |
||||
|
new_params.delete(:_original_action) |
||||
|
|
||||
|
if Rails.env.development? || Rails.env.test? |
||||
|
return url_for(new_params.merge({lang: locale.to_s})) |
||||
|
end |
||||
|
|
||||
|
subdomain = Rails.env.preview? ? "preview-#{locale.to_s}" : locale.to_s |
||||
|
return url_for(new_params.merge(host: "#{subdomain}.bikebike.org")) |
||||
|
end |
||||
|
|
||||
|
return url if Rails.env.development? || Rails.env.test? |
||||
|
return "https://preview-#{locale.to_s}.bikebike.org#{url}" if Rails.env.preview? |
||||
|
"https://#{locale.to_s}.bikebike.org#{url}" |
||||
|
end |
||||
|
|
||||
|
def date(date, format = :long) |
||||
|
I18n.l(date.is_a?(String) ? Date.parse(date) : date, :format => format) |
||||
|
end |
||||
|
|
||||
|
def time(time, format = :short) |
||||
|
if time.is_a?(String) |
||||
|
time = Date.parse(time) |
||||
|
elsif time.is_a?(Float) || time.is_a?(Integer) |
||||
|
time = DateTime.now.midnight + time.hours |
||||
|
end |
||||
|
|
||||
|
I18n.l(time, format: format) |
||||
|
end |
||||
|
|
||||
|
def date_span(date1, date2) |
||||
|
key = 'same_month' |
||||
|
if date1.year != date2.year |
||||
|
key = 'different_year' |
||||
|
elsif date1.month != date2.month |
||||
|
key = 'same_year' |
||||
|
end |
||||
|
d1 = I18n.l(date1.to_date, format: "span_#{key}_date_1".to_sym) |
||||
|
d2 = I18n.l(date2.to_date, format: "span_#{key}_date_2".to_sym) |
||||
|
_('date.date_span', vars: {:date_1 => d1, :date_2 => d2}) |
||||
|
end |
||||
|
|
||||
|
def time_length(length) |
||||
|
hours = length.to_i |
||||
|
minutes = ((length - hours) * 60).to_i |
||||
|
hours = hours > 0 ? (I18n.t 'datetime.distance_in_words.x_hours', count: hours) : nil |
||||
|
minutes = minutes > 0 ? (I18n.t 'datetime.distance_in_words.x_minutes', count: minutes) : nil |
||||
|
return hours.present? ? (minutes.present? ? (I18n.t 'datetime.distance_in_words.x_and_y', x: hours, y: minutes) : hours) : minutes |
||||
|
end |
||||
|
|
||||
|
def hour_span(time1, time2) |
||||
|
(time2 - time1) / 3600 |
||||
|
end |
||||
|
|
||||
|
def hours(time1, time2) |
||||
|
time_length hour_span(time1, time2) |
||||
|
end |
||||
|
|
||||
|
def money(amount) |
||||
|
return _!('$0.00') if amount == 0 |
||||
|
_!((amount * 100).to_i.to_s.gsub(/^(.*)(\d\d)$/, '$\1.\2')) |
||||
|
end |
||||
|
|
||||
|
def percent(p) |
||||
|
return _!('0.00%') if p == 0 |
||||
|
_!((p * 10000).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2%')) |
||||
|
end |
||||
|
end |
@ -0,0 +1,88 @@ |
|||||
|
|
||||
|
module PageHelper |
||||
|
@@no_banner = true |
||||
|
@@banner_image = nil |
||||
|
@@has_content = true |
||||
|
@@body_class = nil |
||||
|
|
||||
|
def title(page_title) |
||||
|
content_for(:title) { page_title.to_s } |
||||
|
end |
||||
|
|
||||
|
def description(page_description) |
||||
|
content_for(:description) { page_description.to_s } |
||||
|
end |
||||
|
|
||||
|
def banner_image(banner_image, name: nil, id: nil, user_id: nil, src: nil) |
||||
|
@@no_banner = false |
||||
|
@@banner_image = banner_image |
||||
|
content_for(:banner_image) { banner_image.to_s } |
||||
|
end |
||||
|
|
||||
|
def has_content? |
||||
|
@@has_content |
||||
|
end |
||||
|
|
||||
|
def add_stylesheet(sheet) |
||||
|
@stylesheets ||= [] |
||||
|
@stylesheets << sheet unless @stylesheets.include?(sheet) |
||||
|
end |
||||
|
|
||||
|
def stylesheets |
||||
|
html = '' |
||||
|
Rack::MiniProfiler.step('inject_css') do |
||||
|
html += inject_css! |
||||
|
end |
||||
|
(@stylesheets || []).each do |css| |
||||
|
Rack::MiniProfiler.step("inject_css #{css}") do |
||||
|
html += inject_css! css.to_s |
||||
|
end |
||||
|
end |
||||
|
html += stylesheet_link_tag 'i18n-debug' if request.params['i18nDebug'] |
||||
|
return html.html_safe |
||||
|
end |
||||
|
|
||||
|
def add_inline_script(script) |
||||
|
@_inline_scripts ||= [] |
||||
|
script = Rails.application.assets.find_asset("#{script.to_s}.js").to_s |
||||
|
@_inline_scripts << script unless @_inline_scripts.include?(script) |
||||
|
end |
||||
|
|
||||
|
def inline_scripts |
||||
|
return '' unless @_inline_scripts.present? |
||||
|
"<script>#{@_inline_scripts.join("\n")}</script>".html_safe |
||||
|
end |
||||
|
|
||||
|
def dom_ready(&block) |
||||
|
content_for(:dom_ready, &block) |
||||
|
end |
||||
|
|
||||
|
def body_class(c) |
||||
|
@@body_class ||= Array.new |
||||
|
@@body_class << (c.is_a?(Array) ? c.join(' ') : c) |
||||
|
end |
||||
|
|
||||
|
def page_style |
||||
|
classes = Array.new |
||||
|
|
||||
|
classes << 'no-content' unless @@has_content |
||||
|
classes << 'has-banner-image' if @@banner_image |
||||
|
classes << @@body_class.join(' ') if @@body_class |
||||
|
|
||||
|
if params[:controller] |
||||
|
classes << params[:action] |
||||
|
unless params[:controller] == 'application' |
||||
|
classes << params[:controller] |
||||
|
|
||||
|
if params[:action] |
||||
|
classes << "#{params[:controller]}-#{params[:action]}" |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
return classes |
||||
|
end |
||||
|
|
||||
|
def yield_or_default(section, default = '') |
||||
|
content_for?(section) ? content_for(section) : default |
||||
|
end |
||||
|
end |
@ -0,0 +1,366 @@ |
|||||
|
module TableHelper |
||||
|
def html_edit_table(excel_data, options = {}) |
||||
|
attributes = { class: options[:class], id: options[:id] } |
||||
|
attributes[:data] = { 'update-url' => options[:editable] } if options[:editable].present? |
||||
|
|
||||
|
if options[:column_names].is_a? Hash |
||||
|
return content_tag(:table, attributes) do |
||||
|
max_columns = 0 |
||||
|
column_names = {} |
||||
|
(content_tag(:thead) do |
||||
|
headers = '' |
||||
|
options[:column_names].each do | header_name, columns | |
||||
|
column_names[header_name] ||= [] |
||||
|
headers += content_tag(:th, excel_data[:keys][header_name].present? ? _(excel_data[:keys][header_name]) : '', colspan: 2) |
||||
|
row_count = columns.size |
||||
|
columns.each do | column | |
||||
|
column_names[header_name] << column |
||||
|
if (options[:row_spans] || {})[column].present? |
||||
|
row_count += (options[:row_spans][column] - 1) |
||||
|
for i in 1...options[:row_spans][column] |
||||
|
column_names[header_name] << false |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
max_columns = row_count if row_count > max_columns |
||||
|
end |
||||
|
content_tag(:tr, headers.html_safe) |
||||
|
end) + (content_tag(:tbody) do |
||||
|
rows = '' |
||||
|
|
||||
|
for i in 0...max_columns |
||||
|
columns_html = '' |
||||
|
column_names.each do | header_name, columns | |
||||
|
column = columns[i] |
||||
|
if column.present? |
||||
|
attributes = { class: [excel_data[:column_types][column]], data: { 'column-id' => column } } |
||||
|
if (options[:row_spans] || {})[column].present? |
||||
|
attributes[:rowspan] = options[:row_spans][column] |
||||
|
end |
||||
|
columns_html += content_tag(:th, excel_data[:keys][column].present? ? _(excel_data[:keys][column]) : '', rowspan: attributes[:rowspan]) + |
||||
|
edit_column(nil, column, nil, attributes, excel_data, options) |
||||
|
elsif column != false |
||||
|
columns_html += content_tag(:td, ' ', colspan: 2, class: :empty) |
||||
|
end |
||||
|
end |
||||
|
rows += content_tag(:tr, columns_html.html_safe, { class: 'always-edit', data: { key: '' } }) |
||||
|
end |
||||
|
rows.html_safe |
||||
|
end) |
||||
|
end |
||||
|
else |
||||
|
return content_tag(:table, attributes) do |
||||
|
(content_tag(:tbody) do |
||||
|
rows = '' |
||||
|
excel_data[:columns].each do |column| |
||||
|
if (excel_data[:column_types] || {})[column] != :table && ((options[:column_names] || []).include? column) |
||||
|
rows += content_tag(:tr, { class: 'always-edit', data: { key: '' } }) do |
||||
|
attributes = { class: [excel_data[:column_types][column]], data: { 'column-id' => column } } |
||||
|
columns = content_tag(:th, excel_data[:keys][column].present? ? _(excel_data[:keys][column]) : '') + |
||||
|
edit_column(nil, column, nil, attributes, excel_data, options) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
rows.html_safe |
||||
|
end) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def html_table(excel_data, options = {}) |
||||
|
options[:html] = true |
||||
|
attributes = { class: options[:class], id: options[:id] } |
||||
|
attributes[:data] = { 'update-url' => options[:editable] } if options[:editable].present? |
||||
|
content_tag(:table, attributes) do |
||||
|
(content_tag(:thead) do |
||||
|
content_tag(:tr, excel_header_columns(excel_data)) |
||||
|
end) + |
||||
|
content_tag(:tbody, excel_rows(excel_data, {}, options)) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def excel_table(excel_data) |
||||
|
format_xls 'table' do |
||||
|
workbook use_autowidth: true |
||||
|
format bg_color: '333333' |
||||
|
format 'td', font_name: 'Calibri', fg_color: '333333' |
||||
|
format 'th', font_name: 'Calibri', b: true, bg_color: '333333', fg_color: 'ffffff' |
||||
|
format 'th.sub-table', font_name: 'Calibri', b: true, bg_color: 'DDDDDD', fg_color: '333333' |
||||
|
format 'td.datetime', num_fmt: 22, font_name: 'Courier New', sz: 10, fg_color: '333333' |
||||
|
format 'td.date.day', num_fmt: 14, font_name: 'Courier New', sz: 10, fg_color: '333333' |
||||
|
format 'td.money', num_fmt: 2, font_name: 'Courier New', sz: 10, fg_color: '333333' |
||||
|
format 'td.number', font_name: 'Courier New', sz: 10, fg_color: '333333' |
||||
|
format 'td.bold', font_name: 'Calibri', fg_color: '333333', b: true |
||||
|
end |
||||
|
|
||||
|
content_tag(:table) do |
||||
|
(content_tag(:thead) do |
||||
|
content_tag(:tr, excel_header_columns(excel_data)) |
||||
|
end) + |
||||
|
content_tag(:tbody, excel_rows(excel_data)) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def excel_header_columns(data, padding = {}, class_name = nil) |
||||
|
columns = '' |
||||
|
|
||||
|
data[:columns].each do |column| |
||||
|
unless data[:column_types].present? && data[:column_types][column] == :table |
||||
|
columns += content_tag(:th, data[:keys][column].present? ? _(data[:keys][column]) : '', class: class_name) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
pad_columns(columns, padding, :th) |
||||
|
end |
||||
|
|
||||
|
def excel_empty_row(data, padding = {}) |
||||
|
columns = '' |
||||
|
|
||||
|
data[:columns].each do |column| |
||||
|
unless data[:column_types].present? && data[:column_types][column] == :table |
||||
|
columns += content_tag(:td) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
content_tag(:tr, pad_columns(columns, padding)) |
||||
|
end |
||||
|
|
||||
|
def pad_columns(columns, padding, column_type = :td) |
||||
|
left = '' |
||||
|
|
||||
|
for i in 1..(padding['left'] || 0) |
||||
|
left += content_tag(:td) |
||||
|
end |
||||
|
|
||||
|
right = '' |
||||
|
for i in 1..(padding['right'] || 0) |
||||
|
right += content_tag(:td) |
||||
|
end |
||||
|
|
||||
|
(left + columns + right).html_safe |
||||
|
end |
||||
|
|
||||
|
def excel_columns(row, data, padding = {}, options = {}) |
||||
|
columns = '' |
||||
|
|
||||
|
data[:columns].each do |column| |
||||
|
value = row[column].present? ? (_!row[column].to_s) : '' |
||||
|
class_name = nil |
||||
|
is_sub_table = false |
||||
|
|
||||
|
if data[:column_types].present? && data[:column_types][column].present? |
||||
|
if data[:column_types][column] == :table |
||||
|
is_sub_table = true |
||||
|
else |
||||
|
class_name = data[:column_types][column] |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
unless is_sub_table |
||||
|
attributes = { class: [class_name] } |
||||
|
if options[:html] && row[:html_values].present? && row[:html_values][column].present? |
||||
|
value = row[:html_values][column] |
||||
|
end |
||||
|
|
||||
|
if options[:editable] |
||||
|
attributes[:data] = { 'column-id' => column } |
||||
|
end |
||||
|
|
||||
|
if (options[:column_names] || []).include? column |
||||
|
attributes[:tabindex] = 0 |
||||
|
end |
||||
|
|
||||
|
columns += content_tag(:td, value, attributes) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
pad_columns(columns, padding) |
||||
|
end |
||||
|
|
||||
|
def editor_columns(row, data, padding = {}, options = {}) |
||||
|
columns = '' |
||||
|
|
||||
|
data[:columns].each do |column| |
||||
|
value = row[column].present? ? (_!row[column].to_s) : '' |
||||
|
class_name = nil |
||||
|
is_sub_table = false |
||||
|
|
||||
|
if data[:column_types].present? && data[:column_types][column].present? |
||||
|
if data[:column_types][column] == :table |
||||
|
is_sub_table = true |
||||
|
else |
||||
|
class_name = data[:column_types][column] |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
unless is_sub_table |
||||
|
attributes = { class: [class_name] } |
||||
|
|
||||
|
if options[:editable] |
||||
|
attributes[:data] = { 'column-id' => column } |
||||
|
end |
||||
|
|
||||
|
if (options[:column_names] || []).include? column |
||||
|
columns += edit_column(row, column, value, attributes, data, options) |
||||
|
else |
||||
|
columns += content_tag(:td, value, attributes) |
||||
|
end |
||||
|
|
||||
|
end |
||||
|
end |
||||
|
|
||||
|
pad_columns(columns, padding) |
||||
|
end |
||||
|
|
||||
|
def edit_column(row, column, value, attributes, data, options) |
||||
|
attributes[:class] << 'has-editor' |
||||
|
raw_value = row.present? ? (row[:raw_values][column] || value) : nil |
||||
|
|
||||
|
if row.present? && options[:html] && row[:html_values].present? && row[:html_values][column].present? |
||||
|
value = row[:html_values][column] |
||||
|
end |
||||
|
|
||||
|
editor_attributes = { class: 'cell-editor', data: { value: raw_value.to_s } } |
||||
|
|
||||
|
# create the control but add the original value to set the width and height |
||||
|
editor_value = content_tag(:div, value, class: 'value') |
||||
|
if (options[:column_options] || {})[column].present? |
||||
|
value = (editor_value.html_safe + select_tag(column, options_for_select([['', '']] + options[:column_options][column], raw_value), editor_attributes)).html_safe |
||||
|
elsif data[:column_types][column] == :text |
||||
|
editor_attributes[:name] = column |
||||
|
value = (editor_value.html_safe + content_tag(:textarea, raw_value, editor_attributes)).html_safe |
||||
|
else |
||||
|
editor_attributes[:name] = column |
||||
|
editor_attributes[:value] = raw_value |
||||
|
editor_attributes[:required] = :required if (options[:required_columns] || []).include? column |
||||
|
type = data[:column_types][column] || :unknown |
||||
|
editor_attributes[:type] = { money: :number, number: :number, email: :email }[type] || :text |
||||
|
value = (editor_value.html_safe + content_tag(:input, nil, editor_attributes)).html_safe |
||||
|
end |
||||
|
|
||||
|
return content_tag(:td, value, attributes) |
||||
|
end |
||||
|
|
||||
|
def excel_sub_tables(row, data, padding = {}, options = {}) |
||||
|
rows = '' |
||||
|
|
||||
|
# shift the table right |
||||
|
new_padding = { |
||||
|
'left' => (padding['right'] || 0) + 1, |
||||
|
'right' => (padding['right'] || 0) - 1 |
||||
|
} |
||||
|
|
||||
|
data[:columns].each do |column| |
||||
|
if data[:column_types].present? && data[:column_types][column] == :table |
||||
|
rows += content_tag(:tr, excel_header_columns(row[column], new_padding, 'sub-table')) |
||||
|
rows += excel_rows(row[column], new_padding) |
||||
|
rows += excel_empty_row(row[column], new_padding) |
||||
|
end |
||||
|
|
||||
|
end |
||||
|
|
||||
|
rows.html_safe |
||||
|
end |
||||
|
|
||||
|
def excel_rows(data, padding = {}, options = {}) |
||||
|
rows = '' |
||||
|
data[:data].each do |row| |
||||
|
attributes = {} |
||||
|
|
||||
|
if options[:primary_key].present? |
||||
|
attributes[:data] = { key: row[options[:primary_key]] } |
||||
|
end |
||||
|
|
||||
|
attributes[:class] = [] |
||||
|
|
||||
|
if options[:editable] |
||||
|
attributes[:class] << :editable |
||||
|
end |
||||
|
|
||||
|
rows += content_tag(:tr, excel_columns(row, data, padding, options), attributes) + |
||||
|
excel_sub_tables(row, data, padding) |
||||
|
rows += content_tag(:tr, editor_columns(row, data, padding, options), class: :editor) if options[:editable] |
||||
|
end |
||||
|
rows.html_safe |
||||
|
end |
||||
|
|
||||
|
def registrations_edit_table_options |
||||
|
{ |
||||
|
id: 'create-table', |
||||
|
class: ['registrations', 'admin-edit', 'always-editing'], |
||||
|
primary_key: :id, |
||||
|
column_names: { |
||||
|
contact_info: [ |
||||
|
:name, |
||||
|
:email, |
||||
|
:is_subscribed, |
||||
|
:city, |
||||
|
:preferred_language |
||||
|
] + User.AVAILABLE_LANGUAGES.map { |l| "language_#{l}".to_sym }, |
||||
|
questions: [ |
||||
|
:registration_fees_paid, |
||||
|
:is_attending, |
||||
|
:arrival, |
||||
|
:departure, |
||||
|
:housing, |
||||
|
:bike, |
||||
|
:food, |
||||
|
:companion_email, |
||||
|
:allergies, |
||||
|
:other |
||||
|
], |
||||
|
hosting: [ |
||||
|
:can_provide_housing, |
||||
|
:address, |
||||
|
:phone, |
||||
|
:first_day, |
||||
|
:last_day |
||||
|
] + ConferenceRegistration.all_spaces + |
||||
|
ConferenceRegistration.all_considerations + [ |
||||
|
:notes |
||||
|
] |
||||
|
}, |
||||
|
row_spans: { |
||||
|
allergies: 3, |
||||
|
other: 2 |
||||
|
}, |
||||
|
required_columns: [:name, :email], |
||||
|
editable: administration_update_path(@this_conference.slug, @admin_step), |
||||
|
column_options: @column_options |
||||
|
} |
||||
|
end |
||||
|
|
||||
|
def registrations_table_options |
||||
|
{ |
||||
|
id: 'search-table', |
||||
|
class: ['registrations', 'admin-edit'], |
||||
|
primary_key: :id, |
||||
|
column_names: [ |
||||
|
:registration_fees_paid, |
||||
|
:is_attending, |
||||
|
:is_subscribed, |
||||
|
:city, |
||||
|
:preferred_language, |
||||
|
:arrival, |
||||
|
:departure, |
||||
|
:housing, |
||||
|
:bike, |
||||
|
:food, |
||||
|
:companion_email, |
||||
|
:allergies, |
||||
|
:other, |
||||
|
:can_provide_housing, |
||||
|
:address, |
||||
|
:phone, |
||||
|
:first_day, |
||||
|
:last_day, |
||||
|
:notes |
||||
|
] + |
||||
|
User.AVAILABLE_LANGUAGES.map { |l| "language_#{l}".to_sym } + |
||||
|
ConferenceRegistration.all_spaces + |
||||
|
ConferenceRegistration.all_considerations, |
||||
|
editable: administration_update_path(@this_conference.slug, @admin_step), |
||||
|
column_options: @column_options |
||||
|
} |
||||
|
end |
||||
|
end |
@ -0,0 +1,288 @@ |
|||||
|
require 'redcarpet' |
||||
|
|
||||
|
module WidgetsHelper |
||||
|
|
||||
|
def m(*args) |
||||
|
_(*args) { |t| |
||||
|
markdown(t) |
||||
|
} |
||||
|
end |
||||
|
|
||||
|
def markdown(object, attribute = nil) |
||||
|
return '' unless object |
||||
|
content = attribute ? object.send(attribute.to_s) : object |
||||
|
@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML.new({ |
||||
|
filter_html: true, |
||||
|
hard_wrap: true, |
||||
|
space_after_headers: true, |
||||
|
fenced_code_blocks: true, |
||||
|
link_attributes: { target: "_blank" } |
||||
|
}), { |
||||
|
autolink: true, |
||||
|
disable_indented_code_blocks: true, |
||||
|
superscript: true |
||||
|
}) |
||||
|
@markdown.render(content).html_safe |
||||
|
end |
||||
|
|
||||
|
def paragraph(object, attribute = nil) |
||||
|
return '' unless object |
||||
|
content = attribute ? object.send(attribute.to_s) : object |
||||
|
result = '' |
||||
|
if content =~ /<(p|span|h\d|div)[^>]*>/ |
||||
|
result = content.gsub(/\s*(style|class|id|width|height|font)=\".*?\"/, '') |
||||
|
.gsub(/ /, ' ') |
||||
|
.gsub(/<(\/)?\s*h\d\s*>/, '<\1h3>') |
||||
|
.gsub(/<p>(.*?)<br\s\/?>\s*(<br\s\/?>)+/, '<p>\1</p><p>') |
||||
|
.gsub(/<span[^>]*>\s*(.*?)\s*<\/span>/, '\1') |
||||
|
.gsub(/<p>\s*<\/p>/, '') |
||||
|
.gsub(/<(\/)?div>/, '<\1p>') |
||||
|
if !(result =~ /<p[^>]*>/) |
||||
|
result = '<p>' + result + '</p>' |
||||
|
end |
||||
|
else |
||||
|
result = markdown(object, attribute) |
||||
|
end |
||||
|
result.html_safe |
||||
|
end |
||||
|
|
||||
|
def nav_link(link, title = nil, class_name = nil) |
||||
|
if title.nil? && link.is_a?(Symbol) |
||||
|
title = link |
||||
|
link = send("#{link.to_s}_path") |
||||
|
end |
||||
|
if class_name.nil? && title.is_a?(Symbol) |
||||
|
class_name = title |
||||
|
end |
||||
|
title = _"page_titles.#{title.to_s.titlecase.gsub(/\s/, '_')}" |
||||
|
classes = [] |
||||
|
classes << class_name if class_name.present? |
||||
|
classes << "strlen-#{strip_tags(title).length}" |
||||
|
classes << 'current' if request.fullpath.start_with?(link.gsub(/^(.*?)\/$/, '\1')) |
||||
|
link_to "<span class=\"title\">#{title}</span>".html_safe, link, :class => classes |
||||
|
end |
||||
|
|
||||
|
def data_set(header_type, header_key, attributes = {}, &block) |
||||
|
raw_data_set(header_type, _(header_key), attributes, &block) |
||||
|
end |
||||
|
|
||||
|
def raw_data_set(header_type, header, attributes = {}, &block) |
||||
|
attributes[:class] = attributes[:class].split(' ') if attributes[:class].is_a?(String) |
||||
|
attributes[:class] = [attributes[:class].to_s] if attributes[:class].is_a?(Symbol) |
||||
|
attributes[:class] ||= [] |
||||
|
attributes[:class] << 'data-set' |
||||
|
content_tag(:div, attributes) do |
||||
|
content_tag(header_type, header, class: 'data-set-key') + |
||||
|
content_tag(:div, class: 'data-set-value', &block) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def admin_update_form(options = {}, &block) |
||||
|
form_tag(administration_update_path(@this_conference.slug, @admin_step), options, &block) |
||||
|
end |
||||
|
|
||||
|
def interest_button(workshop) |
||||
|
interested = workshop.interested?(current_user) ? :remove_interest : :show_interest |
||||
|
id = "#{interested.to_s.gsub('_', '-')}-#{workshop.id}" |
||||
|
return (off_screen (_"forms.actions.aria.#{interested.to_s}"), id) + |
||||
|
(button interested, :value => :toggle_interest, :class => (workshop.interested?(current_user) ? :delete : :add), aria: { labelledby: id }) |
||||
|
end |
||||
|
|
||||
|
def interest_text(workshop) |
||||
|
if workshop.interested?(current_user) |
||||
|
return _'articles.workshops.info.you_are_interested_count', :vars => {:count => (workshop.interested_count - 1)} |
||||
|
end |
||||
|
|
||||
|
return _'articles.workshops.info.interested_count', :vars => {:count => workshop.interested_count} |
||||
|
end |
||||
|
|
||||
|
def host_guests_table(registration) |
||||
|
id = registration.id |
||||
|
html = '' |
||||
|
|
||||
|
@housing_data[id][:guests].each do | area, guests | |
||||
|
guest_rows = '' |
||||
|
guests.each do | guest_id, guest | |
||||
|
status_html = '' |
||||
|
|
||||
|
@housing_data[id][:guest_data][guest_id][:errors].each do | error, value | |
||||
|
if value.is_a?(Array) |
||||
|
value.each do | v | |
||||
|
status_html += content_tag(:li, _("errors.messages.housing.space.#{error.to_s}", vars: v)) |
||||
|
end |
||||
|
else |
||||
|
status_html += content_tag(:li, _("errors.messages.housing.space.#{error.to_s}", vars: value)) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
@housing_data[id][:guest_data][guest_id][:warnings].each do | error, value | |
||||
|
if value.is_a?(Array) |
||||
|
value.each do | v | |
||||
|
status_html += content_tag(:li, _("warnings.messages.housing.space.#{error.to_s}", v)) |
||||
|
end |
||||
|
else |
||||
|
status_html += content_tag(:li, _("warnings.messages.housing.space.#{error.to_s}", vars: value)) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
if status_html.present? |
||||
|
status_html = content_tag(:ul, status_html.html_safe) |
||||
|
end |
||||
|
|
||||
|
guest_rows += content_tag :tr, id: "hosted-guest-#{guest_id}" do |
||||
|
(content_tag :td, guest[:guest].user.name) + |
||||
|
(content_tag :td do |
||||
|
(guest[:guest].city + |
||||
|
(content_tag :a, (_'actions.workshops.Remove'), href: '#', class: 'remove-guest', data: { guest: guest_id })).html_safe |
||||
|
end) + |
||||
|
(content_tag :td, status_html.html_safe, class: [:state, status_html.present? ? :unhappy : :happy]) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
space_size = (@housing_data[id][:space][area] || 0) |
||||
|
|
||||
|
# add empty rows to represent empty guest spots |
||||
|
for i in guests.size...space_size |
||||
|
guest_rows += content_tag :tr, class: 'empty-space' do |
||||
|
(content_tag :td, ' '.html_safe, colspan: 2) + |
||||
|
(content_tag :td) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
status_html = '' |
||||
|
if @housing_data[id][:warnings].present? && @housing_data[id][:warnings][:space].present? && @housing_data[id][:warnings][:space][area].present? |
||||
|
@housing_data[id][:warnings][:space][area].each do | w | |
||||
|
status_html += content_tag(:li, _("warnings.messages.housing.space.#{w.to_s}")) |
||||
|
end |
||||
|
end |
||||
|
if status_html.present? |
||||
|
status_html = content_tag(:ul, status_html.html_safe) |
||||
|
end |
||||
|
|
||||
|
html += content_tag :tr do |
||||
|
(content_tag :th, (_"forms.labels.generic.#{area}"), colspan: 2) + |
||||
|
(content_tag :th, status_html.html_safe, class: [:state, status_html.present? ? :unhappy : :happy]) |
||||
|
end |
||||
|
html += guest_rows |
||||
|
html += content_tag :tr, class: 'place-guest' do |
||||
|
content_tag :td, class: guests.size >= space_size ? 'full' : nil, colspan: 3 do |
||||
|
content_tag :a, (_'forms.actions.generic.place_guest'), class: 'select-guest', href: '#', data: { host: id, space: area } |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
content_tag :table, html.html_safe, class: 'host-table' |
||||
|
end |
||||
|
|
||||
|
def host_guests_widget(registration) |
||||
|
html = '' |
||||
|
classes = ['host'] |
||||
|
|
||||
|
id = registration.id |
||||
|
@housing_data[id][:guests].each do | area, guests | |
||||
|
max_space = @housing_data[id][:space][area] || 0 |
||||
|
area_name = (_"forms.labels.generic.#{area}") |
||||
|
status_html = '' |
||||
|
if @housing_data[id][:warnings].present? && @housing_data[id][:warnings][:space].present? && @housing_data[id][:warnings][:space][area].present? |
||||
|
@housing_data[id][:warnings][:space][area].each do | w | |
||||
|
status_html += content_tag(:div, _("warnings.housing.space.#{w.to_s}"), class: 'warning') |
||||
|
end |
||||
|
end |
||||
|
space_html = content_tag(:h5, area_name + _!(" (#{guests.size.to_s}/#{max_space.to_s})") + status_html.html_safe) |
||||
|
guest_items = '' |
||||
|
guests.each do | guest_id, guest | |
||||
|
guest_items += content_tag(:li, guest[:guest].user.name, id: "hosted-guest-#{guest_id}") |
||||
|
end |
||||
|
space_html += content_tag(:ul, guest_items.html_safe) |
||||
|
space_html += button :place_guest, type: :button, value: "#{area}:#{id}", class: [:small, 'place-guest', 'on-top-only', guests.size >= max_space ? (guests.size > max_space ? :overbooked : :booked) : nil, max_space > 0 ? nil : :unwanted] |
||||
|
html += content_tag(:div, space_html, class: [:space, area, max_space > 0 || guests.size > 0 ? nil : 'on-top-only']) |
||||
|
end |
||||
|
|
||||
|
classes << 'status-warning' if @housing_data[id][:warnings].present? |
||||
|
classes << 'status-error' if @housing_data[id][:errors].present? |
||||
|
|
||||
|
return { html: html.html_safe, class: classes.join(' ') } |
||||
|
end |
||||
|
|
||||
|
def signin_link |
||||
|
@login_dlg ||= true |
||||
|
link_to (_'forms.actions.generic.login'), settings_path, data: { 'sign-in': true } |
||||
|
end |
||||
|
|
||||
|
def link_with_confirmation(link_text, confirmation_text, path, args = {}) |
||||
|
@confirmation_dlg ||= true |
||||
|
args[:data] ||= {} |
||||
|
args[:data][:confirmation] = true |
||||
|
link_to path, args do |
||||
|
(link_text.to_s + content_tag(:template, confirmation_text, class: 'message')).html_safe |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def link_info_dlg(link_text, info_text, info_title, args = {}) |
||||
|
@info_dlg ||= true |
||||
|
args[:data] ||= {} |
||||
|
args[:data]['info-title'] = info_title |
||||
|
args[:data]['info-text'] = true |
||||
|
content_tag(:a, args) do |
||||
|
(link_text.to_s + content_tag(:template, info_text, class: 'message')).html_safe |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def button_with_confirmation(button_name, confirmation_text = nil, args = {}) |
||||
|
if confirmation_text.is_a? Hash |
||||
|
args = confirmation_text |
||||
|
confirmation_text = nil |
||||
|
end |
||||
|
|
||||
|
confirmation_text ||= (_"forms.confirmations.#{button_name.to_s}", :p) |
||||
|
@confirmation_dlg ||= true |
||||
|
args[:data] ||= {} |
||||
|
args[:data][:confirmation] = true |
||||
|
button button_name, args do |
||||
|
((_"forms.actions.generic.#{button_name.to_s}") + content_tag(:template, confirmation_text, class: 'message')).html_safe |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def richtext(text, reduce_headings = 2) |
||||
|
return '' unless text.present? |
||||
|
return _!(text). |
||||
|
gsub(/<(\/?)h4>/, '<\1h' + (reduce_headings + 4).to_s + '>'). |
||||
|
gsub(/<(\/?)h3>/, '<\1h' + (reduce_headings + 3).to_s + '>'). |
||||
|
gsub(/<(\/?)h2>/, '<\1h' + (reduce_headings + 2).to_s + '>'). |
||||
|
gsub(/<(\/?)h1>/, '<\1h' + (reduce_headings + 1).to_s + '>'). |
||||
|
html_safe |
||||
|
end |
||||
|
|
||||
|
def truncate(text) |
||||
|
strip_tags(text.gsub('>', '> ')).gsub(/^(.{40,60})\s.*$/m, '\1…').html_safe |
||||
|
end |
||||
|
|
||||
|
def companion(registration) |
||||
|
if registration.housing_data.present? && registration.housing_data['companions'].present? && registration.housing_data['companions'].first.present? |
||||
|
companion_user = User.find_user(registration.housing_data['companions'].first) |
||||
|
|
||||
|
if companion_user.present? |
||||
|
cr = ConferenceRegistration.where(user_id: companion_user.id).order(created_at: :desc).limit(1).first |
||||
|
|
||||
|
if cr.present? && ((cr.steps_completed || []).include? 'questions') |
||||
|
return companion_user |
||||
|
end |
||||
|
end |
||||
|
return :unregistered |
||||
|
end |
||||
|
return nil |
||||
|
end |
||||
|
|
||||
|
def comment(comment) |
||||
|
add_inline_script :time |
||||
|
add_js_translation('datetime.distance_in_words') |
||||
|
|
||||
|
content_tag(:div, class: 'comment-body') do |
||||
|
content_tag(:h4, _!(comment.user.name), class: 'comment-title') + |
||||
|
content_tag(:time, time(comment.created_at, :default), datetime: comment.created_at.to_s) + |
||||
|
content_tag(:div, class: 'comment-text') do |
||||
|
_!(markdown comment.comment) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
end |
@ -1,3 +0,0 @@ |
|||||
class Authentication < ActiveRecord::Base |
|
||||
belongs_to :user |
|
||||
end |
|
@ -1,166 +0,0 @@ |
|||||
require 'geocoder' |
|
||||
require 'geocoder/railtie' |
|
||||
require 'geocoder/calculations' |
|
||||
|
|
||||
Geocoder::Railtie.insert |
|
||||
|
|
||||
class City < ActiveRecord::Base |
|
||||
geocoded_by :address |
|
||||
translates :city |
|
||||
|
|
||||
reverse_geocoded_by :latitude, :longitude, :address => :full_address |
|
||||
after_validation :geocode, if: ->(obj){ obj.country_changed? or obj.territory_changed? or obj.city_changed? or obj.latitude.blank? or obj.longitude.blank? } |
|
||||
|
|
||||
def address |
|
||||
([city!, territory, country] - [nil, '']).join(', ') |
|
||||
end |
|
||||
|
|
||||
def get_translation(locale) |
|
||||
location = Geocoder.search(address, language: locale.to_s).first |
|
||||
|
|
||||
# if the service lets us down, return nil |
|
||||
return nil unless location.present? |
|
||||
|
|
||||
searched_component = false |
|
||||
location.data['address_components'].each do | component | |
|
||||
# city is usually labeled a 'locality' but sometimes this is missing and only 'colloquial_area' is present |
|
||||
if component['types'].first == 'locality' |
|
||||
return component['short_name'] |
|
||||
end |
|
||||
|
|
||||
if component['types'] == location.data['types'] |
|
||||
searched_component = component['short_name'] |
|
||||
end |
|
||||
end |
|
||||
|
|
||||
# return the type we searched for but it's still possible that it will be false |
|
||||
searched_component |
|
||||
end |
|
||||
|
|
||||
# this method will get called automatically if a translation is asked for but not found |
|
||||
def translate_city(locale) |
|
||||
translation = get_translation(locale) |
|
||||
|
|
||||
# if we found it, set it |
|
||||
if translation.present? |
|
||||
set_column_for_locale(:city, locale, translation) |
|
||||
save! |
|
||||
end |
|
||||
|
|
||||
return translation |
|
||||
end |
|
||||
|
|
||||
def to_s |
|
||||
([ |
|
||||
city, |
|
||||
territory.present? && country.present? ? I18n.t("geography.subregions.#{country}.#{territory}") : '', |
|
||||
country.present? ? I18n.t("geography.countries.#{country}") : '' |
|
||||
] - ['', nil]).join(', ') |
|
||||
end |
|
||||
|
|
||||
def self.search(str) |
|
||||
cache = CityCache.search(str) |
|
||||
|
|
||||
# return the city if this search is in our cache |
|
||||
return cache.city if cache.present? |
|
||||
|
|
||||
# look up the city in the geocoder |
|
||||
location = Geocoder.search(str, language: 'en').first |
|
||||
|
|
||||
# return nil to indicate that the service is down |
|
||||
return nil unless location.present? |
|
||||
# see if the city is already present in our database |
|
||||
city = City.find_by_place_id(location.data['place_id']) |
|
||||
|
|
||||
# if we didn't find a match by place id, collect the city, territory, and country from the result |
|
||||
unless city.present? |
|
||||
# google names things differently than we do, we'll look for these items |
|
||||
component_alises = { |
|
||||
'locality' => :city, |
|
||||
'administrative_area_level_1' => :territory, |
|
||||
'country' => :country |
|
||||
} |
|
||||
|
|
||||
# and populate this map to eventually create the city if we need to |
|
||||
city_data = { |
|
||||
locale: :en, |
|
||||
latitude: location.data['geometry']['location']['lat'], |
|
||||
longitude: location.data['geometry']['location']['lng'], |
|
||||
place_id: location.data['place_id'] |
|
||||
} |
|
||||
|
|
||||
# these things are definitely not cities, make sure we don't think they're one |
|
||||
not_a_city = [ |
|
||||
'administrative_area_level_1', |
|
||||
'country', |
|
||||
'street_address', |
|
||||
'street_number', |
|
||||
'postal_code', |
|
||||
'postal_code_prefix', |
|
||||
'route', |
|
||||
'intersection', |
|
||||
'premise', |
|
||||
'subpremise', |
|
||||
'natural_feature', |
|
||||
'airport', |
|
||||
'park', |
|
||||
'point_of_interest', |
|
||||
'bus_station', |
|
||||
'train_station', |
|
||||
'transit_station', |
|
||||
'room', |
|
||||
'post_box', |
|
||||
'parking', |
|
||||
'establishment', |
|
||||
'floor' |
|
||||
] |
|
||||
|
|
||||
searched_component = nil |
|
||||
location.data['address_components'].each do | component | |
|
||||
property = component_alises[component['types'].first] |
|
||||
city_data[property] = component['short_name'] if property.present? |
|
||||
|
|
||||
# ideally we will find the component that is labeled a locality but |
|
||||
# if that fails we will select what was searched for, hopefully they searched for a city |
|
||||
# and not an address or country |
|
||||
# some places are not labeled 'locality', search for 'Halifax NS' for example and you will |
|
||||
# get 'administrative_area_level_2' since Halifax is a municipality |
|
||||
if component['types'] == location.data['types'] && !not_a_city.include?(component['types'].first) |
|
||||
searched_component = component['short_name'] |
|
||||
end |
|
||||
end |
|
||||
|
|
||||
# fall back to the searched component |
|
||||
city_data[:city] ||= searched_component |
|
||||
|
|
||||
# we need to have the city and country at least |
|
||||
return false unless city_data[:city].present? && city_data[:country].present? |
|
||||
|
|
||||
# one last attempt to make sure we don't already have a record of this city |
|
||||
city = City.where(city: city_data[:city], territory: city_data[:territory], country: city_data[:country]).first |
|
||||
|
|
||||
# only if we still can't find the city, then save it as a new one |
|
||||
unless city.present? |
|
||||
city = City.new(city_data) |
|
||||
# if we found exactly what we were looking for, keep these location details |
|
||||
# otherwise we may have searched for 'The Bronx' and set the sity the 'New York' but these details will be about The Bronx |
|
||||
# so if we try to show New York on a map it will always point to The Bronx, not very fair to those from Staten Island |
|
||||
unless city_data[:city] == searched_component |
|
||||
new_location = Geocoder.search(str, language: 'en').first |
|
||||
city.latitude = new_location.data['geometry']['location']['lat'] |
|
||||
city.longitude = new_location.data['geometry']['location']['lng'] |
|
||||
city.place_id = new_location.data['place_id'] |
|
||||
end |
|
||||
|
|
||||
# and create the new city |
|
||||
city.save! |
|
||||
end |
|
||||
end |
|
||||
|
|
||||
# save this to our cache |
|
||||
CityCache.cache(str, city.id) |
|
||||
|
|
||||
# and return it |
|
||||
return city |
|
||||
end |
|
||||
end |
|
@ -1,21 +0,0 @@ |
|||||
class CityCache < ActiveRecord::Base |
|
||||
self.table_name = :city_cache |
|
||||
|
|
||||
belongs_to :city |
|
||||
|
|
||||
# look for a term to see if its already been searched for |
|
||||
def self.search(str) |
|
||||
CityCache.find_by_search(normalize_string(str)) |
|
||||
end |
|
||||
|
|
||||
# cache this search term |
|
||||
def self.cache(str, city_id) |
|
||||
CityCache.create(city_id: city_id, search: normalize_string(str)) |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def self.normalize_string(str) |
|
||||
# remove accents, unnecessary whitespace, punctuation, and lowcase tje string |
|
||||
I18n.transliterate(str).gsub(/[^\w\s]/, '').gsub(/\s\s+/, ' ').strip.downcase |
|
||||
end |
|
||||
end |
|
@ -1,37 +0,0 @@ |
|||||
class Comment < ActiveRecord::Base |
|
||||
belongs_to :user |
|
||||
|
|
||||
def comment_object |
|
||||
model_type.classify.constantize.find(model_id) |
|
||||
end |
|
||||
|
|
||||
def set_model(model) |
|
||||
model_type = model.class.name.tableize |
|
||||
model_id = model.id |
|
||||
end |
|
||||
|
|
||||
def self.for(model) |
|
||||
where(model_type: model.class.name.tableize, model_id: model.id).order(created_at: :asc) |
|
||||
end |
|
||||
|
|
||||
def self.create_for(model, user, comment) |
|
||||
create( |
|
||||
model_type: model.class.name.tableize, |
|
||||
model_id: model.id, |
|
||||
user_id: user.id, |
|
||||
comment: comment |
|
||||
) |
|
||||
end |
|
||||
|
|
||||
def add_comment(user, comment) |
|
||||
Comment.create_for(self, user, comment) |
|
||||
end |
|
||||
|
|
||||
def comments |
|
||||
Comment.for(self) |
|
||||
end |
|
||||
|
|
||||
def reply? |
|
||||
model_type == 'comments' |
|
||||
end |
|
||||
end |
|
@ -1,160 +0,0 @@ |
|||||
class Conference < ActiveRecord::Base |
|
||||
translates :info, :title, :payment_message |
|
||||
|
|
||||
mount_uploader :cover, CoverUploader |
|
||||
mount_uploader :poster, PosterUploader |
|
||||
|
|
||||
belongs_to :conference_type |
|
||||
belongs_to :city |
|
||||
|
|
||||
has_many :conference_host_organizations, dependent: :destroy |
|
||||
has_many :organizations, through: :conference_host_organizations |
|
||||
has_many :conference_administrators, dependent: :destroy |
|
||||
has_many :administrators, through: :conference_administrators, source: :user |
|
||||
has_many :event_locations |
|
||||
|
|
||||
has_many :workshops |
|
||||
|
|
||||
accepts_nested_attributes_for :conference_host_organizations, reject_if: proc {|u| u[:organization_id].blank?}, allow_destroy: true |
|
||||
|
|
||||
before_create :make_slug, :make_title |
|
||||
|
|
||||
def to_param |
|
||||
slug |
|
||||
end |
|
||||
|
|
||||
def host_organization?(org) |
|
||||
return false unless org.present? |
|
||||
org_id = org.is_a?(Organization) ? org.id : org |
|
||||
|
|
||||
organizations.each do |o| |
|
||||
return true if o.id = org_id |
|
||||
end |
|
||||
|
|
||||
return false |
|
||||
end |
|
||||
|
|
||||
def host?(user) |
|
||||
if user.present? |
|
||||
return true if user.administrator? |
|
||||
|
|
||||
conference_administrators.each do |u| |
|
||||
return true if user.id == u.id |
|
||||
end |
|
||||
|
|
||||
organizations.each do |o| |
|
||||
return true if o.host?(user) |
|
||||
end |
|
||||
end |
|
||||
return false |
|
||||
end |
|
||||
|
|
||||
def url(action = :show) |
|
||||
path(action) |
|
||||
end |
|
||||
|
|
||||
def path(action = :show) |
|
||||
action = action.to_sym |
|
||||
'/conferences/' + conference_type.slug + '/' + slug + (action == :show ? '' : '/' + action.to_s) |
|
||||
end |
|
||||
|
|
||||
def location |
|
||||
return nil unless organizations.present? |
|
||||
organizations.first.location |
|
||||
end |
|
||||
|
|
||||
def registered?(user) |
|
||||
registration = ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id) |
|
||||
return registration ? registration.is_attending : false |
|
||||
end |
|
||||
|
|
||||
def registration_exists?(user) |
|
||||
ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id).present? |
|
||||
end |
|
||||
|
|
||||
def registration_open |
|
||||
registration_status == :open |
|
||||
end |
|
||||
|
|
||||
def can_register? |
|
||||
registration_status == :open || registration_status == :pre |
|
||||
end |
|
||||
|
|
||||
def registration_status |
|
||||
s = read_attribute(:registration_status) |
|
||||
s.present? ? s.to_sym : nil |
|
||||
end |
|
||||
|
|
||||
def registration_status=(new_registration_status) |
|
||||
write_attribute :registration_status, new_registration_status.to_s |
|
||||
end |
|
||||
|
|
||||
def make_slug(reset = false) |
|
||||
if reset |
|
||||
self.slug = nil |
|
||||
end |
|
||||
|
|
||||
self.slug ||= Conference.generate_slug( |
|
||||
conferencetype || :annual, |
|
||||
conference_year, |
|
||||
city_name.gsub(/\s/, '') |
|
||||
) |
|
||||
end |
|
||||
|
|
||||
def make_title(reset = false) |
|
||||
if reset |
|
||||
self.title = nil |
|
||||
end |
|
||||
|
|
||||
self.title ||= Conference.generate_title( |
|
||||
conferencetype || :annual, |
|
||||
conference_year, |
|
||||
city_name.gsub(/\s/, '') |
|
||||
) |
|
||||
end |
|
||||
|
|
||||
def city_name |
|
||||
return city.city if city.present? |
|
||||
return location.present? ? location.city : nil |
|
||||
end |
|
||||
|
|
||||
def conference_year |
|
||||
self.year || (end_date.present? ? end_date.year : nil) |
|
||||
end |
|
||||
|
|
||||
def over? |
|
||||
return false unless end_date.present? |
|
||||
return end_date < DateTime.now |
|
||||
end |
|
||||
|
|
||||
def self.default_payment_amounts |
|
||||
[25, 50, 100] |
|
||||
end |
|
||||
|
|
||||
def self.conference_types |
|
||||
{ |
|
||||
annual: { slug: '%{city}%{year}', title: 'Bike!Bike! %{year}'}, |
|
||||
n: { slug: 'North%{year}', title: 'Bike!Bike! North %{year}'}, |
|
||||
s: { slug: 'South%{year}', title: 'Bike!Bike! South %{year}'}, |
|
||||
e: { slug: 'East%{year}', title: 'Bike!Bike! East %{year}'}, |
|
||||
w: { slug: 'West%{year}', title: 'Bike!Bike! West %{year}'}, |
|
||||
ne: { slug: 'Northeast%{year}', title: 'Bike!Bike! Northeast %{year}'}, |
|
||||
nw: { slug: 'Northwest%{year}', title: 'Bike!Bike! Northwest %{year}'}, |
|
||||
se: { slug: 'Southeast%{year}', title: 'Bike!Bike! Southeast %{year}'}, |
|
||||
sw: { slug: 'Southwest%{year}', title: 'Bike!Bike! Southwest %{year}'} |
|
||||
} |
|
||||
end |
|
||||
|
|
||||
def self.generate_slug(type, year, city) |
|
||||
Conference.conference_types[(type || :annual).to_sym][:slug].gsub('%{city}', city).gsub('%{year}', year.to_s) |
|
||||
end |
|
||||
|
|
||||
def self.generate_title(type, year, city) |
|
||||
Conference.conference_types[(type || :annual).to_sym][:title].gsub('%{city}', city).gsub('%{year}', year.to_s) |
|
||||
end |
|
||||
|
|
||||
def self.default_provider_conditions |
|
||||
{ 'distance' => { 'number' => 0, 'unit' => 'mi' }} |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class ConferenceAdmin < ActiveRecord::Base |
|
||||
end |
|
@ -1,4 +0,0 @@ |
|||||
class ConferenceAdministrator < ActiveRecord::Base |
|
||||
belongs_to :user |
|
||||
belongs_to :conference |
|
||||
end |
|
@ -1,4 +0,0 @@ |
|||||
class ConferenceHostOrganization < ActiveRecord::Base |
|
||||
belongs_to :conference |
|
||||
belongs_to :organization |
|
||||
end |
|
@ -1,74 +0,0 @@ |
|||||
class ConferenceRegistration < ActiveRecord::Base |
|
||||
belongs_to :conference |
|
||||
belongs_to :user |
|
||||
has_many :conference_registration_responses |
|
||||
|
|
||||
AttendingOptions = [:yes, :no] |
|
||||
|
|
||||
def languages |
|
||||
user.languages |
|
||||
end |
|
||||
|
|
||||
def self.all_housing_options |
|
||||
[:none, :tent, :house] |
|
||||
end |
|
||||
|
|
||||
def self.all_spaces |
|
||||
[:bed_space, :floor_space, :tent_space] |
|
||||
end |
|
||||
|
|
||||
def self.all_bike_options |
|
||||
[:yes, :no] |
|
||||
end |
|
||||
|
|
||||
def self.all_food_options |
|
||||
[:meat, :vegetarian, :vegan] |
|
||||
end |
|
||||
|
|
||||
def self.all_considerations |
|
||||
[:vegan, :smoking, :pets, :quiet] |
|
||||
end |
|
||||
|
|
||||
def city |
|
||||
city_id.present? ? City.find(city_id) : nil |
|
||||
end |
|
||||
|
|
||||
def status(was = false) |
|
||||
# our user hasn't registered if their user doesn't exist or they haven't entered a city |
|
||||
return :unregistered if user.nil? || check(:city, was).blank? |
|
||||
|
|
||||
# registration completes once a guest has entered a housing preference or |
|
||||
# a housing provider has opted in or out of providing housing |
|
||||
return :preregistered unless |
|
||||
check(:housing, was).present? || !check(:can_provide_housing, was).nil? |
|
||||
|
|
||||
# they must be registered |
|
||||
return :registered |
|
||||
end |
|
||||
|
|
||||
around_update :check_status |
|
||||
|
|
||||
def check_status |
|
||||
yield |
|
||||
|
|
||||
old_status = status(true) |
|
||||
new_status = status |
|
||||
|
|
||||
if old_status.present? && old_status != new_status |
|
||||
if (conference.registration_status == :pre && new_status == :preregistered) || |
|
||||
(conference.registration_status == :open && new_status == :registered) |
|
||||
|
|
||||
UserMailer.send_mail :registration_confirmation do |
|
||||
{ |
|
||||
:args => self |
|
||||
} |
|
||||
end |
|
||||
end |
|
||||
end |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def check(field, was) |
|
||||
send("#{field}#{was ? '_was' : ''}") |
|
||||
end |
|
||||
end |
|
@ -1,4 +0,0 @@ |
|||||
class ConferenceRegistrationFormField < ActiveRecord::Base |
|
||||
belongs_to :conference |
|
||||
belongs_to :registration_form_field |
|
||||
end |
|
@ -1,5 +0,0 @@ |
|||||
class ConferenceRegistrationResponse < ActiveRecord::Base |
|
||||
belongs_to :conference_registration |
|
||||
belongs_to :user |
|
||||
#belongs_to :conference, :through => :conference_registration |
|
||||
end |
|
@ -1,7 +0,0 @@ |
|||||
class ConferenceType < ActiveRecord::Base |
|
||||
#belongs_to :conference |
|
||||
|
|
||||
def to_param |
|
||||
slug |
|
||||
end |
|
||||
end |
|
@ -1,40 +0,0 @@ |
|||||
class EmailConfirmation < ActiveRecord::Base |
|
||||
belongs_to :user |
|
||||
before_create :prepare |
|
||||
|
|
||||
def prepare |
|
||||
# clean up any expired records |
|
||||
EmailConfirmation.delete_all(['expiry < ?', Time.now]) |
|
||||
|
|
||||
# fill in defaults |
|
||||
self.expiry ||= Time.now + 1.day |
|
||||
|
|
||||
while self.token.nil? do |
|
||||
# create a token based on the user id and current time |
|
||||
self.token = generate_token |
|
||||
|
|
||||
# conflicts should be extremely rare, but let's just be sure |
|
||||
if EmailConfirmation.exists?(:token => self.token) |
|
||||
self.token = nil # keep the loop going |
|
||||
# because we generate the token based on the time, just make sure |
|
||||
# some time has passed |
|
||||
sleep 0.1 |
|
||||
end |
|
||||
end |
|
||||
end |
|
||||
|
|
||||
def valid_for_user?(user) |
|
||||
user.id == user_id && !expired? |
|
||||
end |
|
||||
|
|
||||
def expired? |
|
||||
expiry >= Time.now |
|
||||
end |
|
||||
|
|
||||
protected |
|
||||
|
|
||||
def generate_token |
|
||||
Digest::SHA256.hexdigest(user_id.to_s + (Time.now.to_f * 1000000).to_i.to_s) |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,20 +0,0 @@ |
|||||
class Event < ActiveRecord::Base |
|
||||
translates :info, :title |
|
||||
|
|
||||
belongs_to :conference |
|
||||
belongs_to :event_location |
|
||||
|
|
||||
def conference_day |
|
||||
return nil unless start_time.present? && end_time.present? |
|
||||
|
|
||||
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0) |
|
||||
w_start_day = start_time.change(hour: 0, minute: 0, second: 0) |
|
||||
return (((w_start_day - start_day) / 86400) + 1).to_i |
|
||||
end |
|
||||
|
|
||||
def duration |
|
||||
return nil unless start_time.present? && end_time.present? |
|
||||
((end_time - start_time) / 60).to_i |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,25 +0,0 @@ |
|||||
require 'geocoder' |
|
||||
require 'geocoder/railtie' |
|
||||
|
|
||||
Geocoder::Railtie.insert |
|
||||
|
|
||||
class EventLocation < ActiveRecord::Base |
|
||||
belongs_to :conference |
|
||||
geocoded_by :full_address |
|
||||
|
|
||||
reverse_geocoded_by :latitude, :longitude, :address => :full_address |
|
||||
after_validation :geocode, if: ->(obj){ obj.address_changed? } |
|
||||
|
|
||||
def full_address |
|
||||
l = conference.location |
|
||||
[address, l.city, l.territory, l.country].join(', ') |
|
||||
end |
|
||||
|
|
||||
def self.all_spaces |
|
||||
Workshop.all_spaces + [:event_space] |
|
||||
end |
|
||||
|
|
||||
def self.all_amenities |
|
||||
Workshop.all_needs |
|
||||
end |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class EventType < ActiveRecord::Base |
|
||||
end |
|
@ -1,21 +0,0 @@ |
|||||
class Location < ActiveRecord::Base |
|
||||
#attr_accessible :title, :country, :territory, :city, :street, :postal_code, :latitude, :longitude |
|
||||
has_many :locations_organization |
|
||||
has_many :organizations, :through => :locations_organization |
|
||||
|
|
||||
geocoded_by :full_address |
|
||||
|
|
||||
reverse_geocoded_by :latitude, :longitude, :address => :full_address |
|
||||
after_validation :geocode, if: ->(obj){ obj.country_changed? or obj.territory_changed? or obj.city_changed? or obj.street_changed? or obj.postal_code_changed? or obj.latitude.blank? or obj.longitude.blank? } |
|
||||
|
|
||||
def full_address |
|
||||
addr = title |
|
||||
addr = (addr ? ', ' : '') + (street || '') |
|
||||
addr = (addr ? ', ' : '') + (city || '') |
|
||||
addr = (addr ? ', ' : '') + (territory || '') |
|
||||
addr = (addr ? ' ' : '') + (country || '') |
|
||||
addr = (addr ? ' ' : '') + (postal_code || '') |
|
||||
addr |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,6 +0,0 @@ |
|||||
class LocationsOrganization < ActiveRecord::Base |
|
||||
belongs_to :location |
|
||||
belongs_to :organization |
|
||||
|
|
||||
self.primary_key = :location_id |
|
||||
end |
|
@ -1,77 +0,0 @@ |
|||||
class Organization < ActiveRecord::Base |
|
||||
mount_uploader :logo, LogoUploader |
|
||||
mount_uploader :avatar, AvatarUploader |
|
||||
mount_uploader :cover, CoverUploader |
|
||||
|
|
||||
has_many :locations_organization |
|
||||
has_many :locations, through: :locations_organization |
|
||||
|
|
||||
has_many :user_organization_relationships, dependent: :destroy |
|
||||
has_many :users, through: :user_organization_relationships |
|
||||
|
|
||||
accepts_nested_attributes_for :locations, :reject_if => proc {|l| l[id].blank?} |
|
||||
accepts_nested_attributes_for :user_organization_relationships, :reject_if => proc {|u| u[:user_id].blank?}, :allow_destroy => true |
|
||||
before_create :make_slug |
|
||||
|
|
||||
def location |
|
||||
locations.first |
|
||||
end |
|
||||
|
|
||||
def longitude |
|
||||
location.longitude |
|
||||
end |
|
||||
|
|
||||
def latitude |
|
||||
location.latitude |
|
||||
end |
|
||||
|
|
||||
def to_param |
|
||||
slug |
|
||||
end |
|
||||
|
|
||||
def host?(user) |
|
||||
return false unless user.present? |
|
||||
return true if user.administrator? |
|
||||
|
|
||||
users.each do |u| |
|
||||
return true if u.id == user.id |
|
||||
end |
|
||||
return false |
|
||||
end |
|
||||
|
|
||||
def generate_slug(name, location = nil) |
|
||||
s = name.gsub(/[^a-z1-9]+/i, '-').chomp('-').gsub(/\-([A-Z])/, '\1') |
|
||||
if Organization.find_by(:slug => s).present? && !location.nil? |
|
||||
if location.city.present? |
|
||||
s += '-' + location.city |
|
||||
end |
|
||||
if Organization.find_by(:slug => s).present? && location.territory.present? |
|
||||
s += '-' + location.territory |
|
||||
end |
|
||||
if Organization.find_by(:slug => s).present? |
|
||||
s += '-' + location.country |
|
||||
end |
|
||||
end |
|
||||
attempt = 1 |
|
||||
ss = s |
|
||||
|
|
||||
while Organization.find_by(:slug => s) |
|
||||
attempt += 1 |
|
||||
s = ss + '-' + attempt.to_s |
|
||||
end |
|
||||
s |
|
||||
end |
|
||||
|
|
||||
def self.find_by_city(city) |
|
||||
Organization.joins(:locations).where(locations: { |
|
||||
city_id: city.is_a?(City) ? city.id : city |
|
||||
}) |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def make_slug |
|
||||
if !self.slug |
|
||||
self.slug = generate_slug(self.name, self.locations && self.locations[0]) |
|
||||
end |
|
||||
end |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class OrganizationStatus < ActiveRecord::Base |
|
||||
end |
|
@ -1,75 +0,0 @@ |
|||||
class RegistrationFormField < ActiveRecord::Base |
|
||||
Types = { |
|
||||
:single => [:title, :required, :input_type, :help], |
|
||||
:multiple => [:title, :required, :selection_type, :options, :other, :help] |
|
||||
} |
|
||||
|
|
||||
Fields = { |
|
||||
:title => {:control => 'text_field'}, |
|
||||
:input_type => {:control => 'select', :options => [[:text_field, :text_area, :number_field, :date_field, :time_field, :phone_field, :checkbox]], :option => true}, |
|
||||
:selection_type => {:control => 'select', :options => [[:check_box, :radio_button, :select]], :option => true}, |
|
||||
:options => {:control => 'text_area', :option => true}, |
|
||||
:help => {:control => 'text_area'}, |
|
||||
:other => {:control => 'check_box', :option => true}, |
|
||||
:required => {:control => 'check_box'} |
|
||||
} |
|
||||
|
|
||||
def self.TypesForField(field) |
|
||||
types = [] |
|
||||
Types.each do |k, t| |
|
||||
if t.include?(field) |
|
||||
types << k |
|
||||
end |
|
||||
end |
|
||||
types |
|
||||
end |
|
||||
|
|
||||
def input_type |
|
||||
get_from_options 'input_type' |
|
||||
end |
|
||||
|
|
||||
def selection_type |
|
||||
get_from_options 'selection_type' |
|
||||
end |
|
||||
|
|
||||
def other |
|
||||
get_from_options 'other' |
|
||||
end |
|
||||
|
|
||||
def self.GetOptions(type, values) |
|
||||
o = {} |
|
||||
Fields.each do |k, f| |
|
||||
if f[:option] && Types[type.to_sym].include?(k) |
|
||||
o[k] = values[k] |
|
||||
end |
|
||||
end |
|
||||
o |
|
||||
end |
|
||||
|
|
||||
def self.GetNonOptionKeys(type, values) |
|
||||
o = [] |
|
||||
Fields.each do |k, f| |
|
||||
if !f[:option] && Types[type.to_sym].include?(k) |
|
||||
o << k |
|
||||
end |
|
||||
end |
|
||||
o |
|
||||
end |
|
||||
|
|
||||
def repeats?() |
|
||||
field_type.to_s == 'multiple' && selection_type.to_s != 'select' |
|
||||
end |
|
||||
|
|
||||
def is_array?() |
|
||||
field_type.to_s == 'multiple' && selection_type.to_s != 'radio_button' |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def get_from_options(key) |
|
||||
if options |
|
||||
_options = ActiveSupport::JSON.decode(options) |
|
||||
return _options[key] |
|
||||
end |
|
||||
nil |
|
||||
end |
|
||||
end |
|
@ -1,68 +0,0 @@ |
|||||
class User < ActiveRecord::Base |
|
||||
authenticates_with_sorcery! do |config| |
|
||||
config.authentications_class = Authentication |
|
||||
end |
|
||||
|
|
||||
validates :email, uniqueness: true |
|
||||
|
|
||||
mount_uploader :avatar, AvatarUploader |
|
||||
|
|
||||
has_many :user_organization_relationships |
|
||||
has_many :organizations, through: :user_organization_relationships |
|
||||
has_many :conferences, through: :conference_administrators |
|
||||
has_many :authentications, :dependent => :destroy |
|
||||
accepts_nested_attributes_for :authentications |
|
||||
|
|
||||
before_update do |user| |
|
||||
user.locale ||= I18n.locale |
|
||||
user.email.downcase! |
|
||||
end |
|
||||
|
|
||||
before_save do |user| |
|
||||
user.locale ||= I18n.locale |
|
||||
user.email.downcase! |
|
||||
end |
|
||||
|
|
||||
def can_translate?(to_locale = nil, from_locale = nil) |
|
||||
is_translator unless to_locale.present? |
|
||||
|
|
||||
from_locale = I18n.locale unless from_locale.present? |
|
||||
return languages.present? && |
|
||||
to_locale.to_s != from_locale.to_s && |
|
||||
languages.include?(to_locale.to_s) && |
|
||||
languages.include?(from_locale.to_s) |
|
||||
end |
|
||||
|
|
||||
def name |
|
||||
firstname || username || email |
|
||||
end |
|
||||
|
|
||||
def named_email |
|
||||
name = firstname || username |
|
||||
return email unless name |
|
||||
return "#{name} <#{email}>" |
|
||||
end |
|
||||
|
|
||||
def administrator? |
|
||||
role == 'administrator' |
|
||||
end |
|
||||
|
|
||||
def self.AVAILABLE_LANGUAGES |
|
||||
[:en, :es, :fr, :ar] |
|
||||
end |
|
||||
|
|
||||
def self.get(email) |
|
||||
user = find_user(email) |
|
||||
|
|
||||
unless user |
|
||||
user = create(email: email, locale: I18n.locale) |
|
||||
end |
|
||||
|
|
||||
return user |
|
||||
end |
|
||||
|
|
||||
def self.find_user(email) |
|
||||
User.where('lower(email) = ?', email.downcase).first |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,11 +0,0 @@ |
|||||
class UserOrganizationRelationship < ActiveRecord::Base |
|
||||
belongs_to :user |
|
||||
belongs_to :organization |
|
||||
|
|
||||
Administrator = 'administrator' |
|
||||
Member = 'member' |
|
||||
|
|
||||
DefaultRelationship = Member |
|
||||
|
|
||||
AllRelationships = [Administrator, Member] |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class Version < ActiveRecord::Base |
|
||||
end |
|
@ -1,180 +0,0 @@ |
|||||
class Workshop < ActiveRecord::Base |
|
||||
translates :info, :title |
|
||||
|
|
||||
belongs_to :conference |
|
||||
belongs_to :event_location |
|
||||
|
|
||||
has_many :workshop_facilitators, :dependent => :destroy |
|
||||
has_many :users, :through => :workshop_facilitators |
|
||||
|
|
||||
accepts_nested_attributes_for :workshop_facilitators, :reject_if => proc {|u| u[:user_id].blank?}, :allow_destroy => true |
|
||||
|
|
||||
before_create :make_slug |
|
||||
|
|
||||
def to_param |
|
||||
slug |
|
||||
end |
|
||||
|
|
||||
def role(user) |
|
||||
return nil unless user |
|
||||
workshop_facilitators.each do |u| |
|
||||
if u.user_id == user.id |
|
||||
return conference.registration_exists?(user) ? u.role.to_sym : :unregistered |
|
||||
end |
|
||||
end |
|
||||
return nil |
|
||||
end |
|
||||
|
|
||||
def facilitator?(user) |
|
||||
!!role(user) |
|
||||
end |
|
||||
|
|
||||
def active_facilitators |
|
||||
users = [] |
|
||||
workshop_facilitators.each do |u| |
|
||||
users << User.find(u.user_id) unless u.role.to_sym == :requested || u.user_id.nil? |
|
||||
end |
|
||||
return users |
|
||||
end |
|
||||
|
|
||||
def active_facilitator?(user) |
|
||||
facilitator?(user) && !requested_collaborator?(user) |
|
||||
end |
|
||||
|
|
||||
def public_facilitator?(user) |
|
||||
return false if !active_facilitator?(user) |
|
||||
return true if creator?(user) |
|
||||
conference.registered?(user) |
|
||||
end |
|
||||
|
|
||||
def creator?(user) |
|
||||
role(user) == :creator |
|
||||
end |
|
||||
|
|
||||
def collaborator?(user) |
|
||||
role(user) == :collaborator |
|
||||
end |
|
||||
|
|
||||
def requested_collaborator?(user) |
|
||||
role(user) == :requested |
|
||||
end |
|
||||
|
|
||||
def can_edit?(user) |
|
||||
creator?(user) || collaborator?(user) || conference.host?(user) |
|
||||
end |
|
||||
|
|
||||
def can_remove?(owner, facilitator) |
|
||||
# creators cannot be removed |
|
||||
return false if creator?(facilitator) |
|
||||
|
|
||||
# creator can remove anyone, facilitators can remove themselves |
|
||||
return creator?(owner) || owner.id == facilitator.id |
|
||||
end |
|
||||
|
|
||||
def can_delete?(user) |
|
||||
creator?(user) || conference.host?(user) |
|
||||
end |
|
||||
|
|
||||
def can_show_interest?(user) |
|
||||
user.present? && !active_facilitator?(user) |
|
||||
end |
|
||||
|
|
||||
def interested?(user) |
|
||||
user.present? && !active_facilitator?(user) && WorkshopInterest.find_by(workshop_id: id, user_id: user.id) |
|
||||
end |
|
||||
|
|
||||
def interested_count |
|
||||
interested.size |
|
||||
end |
|
||||
|
|
||||
def interested |
|
||||
return [] unless id |
|
||||
return @interested if @interested.present? |
|
||||
|
|
||||
collaborators = [] |
|
||||
workshop_facilitators.each do |f| |
|
||||
collaborators << f.user_id unless f.role.to_sym == :requested || f.user_id.nil? |
|
||||
end |
|
||||
return 10 unless collaborators.present? |
|
||||
@interested = WorkshopInterest.where("workshop_id=#{id} AND user_id NOT IN (#{collaborators.join ','})") || [] |
|
||||
end |
|
||||
|
|
||||
def can_translate?(user, lang) |
|
||||
return false unless user.present? |
|
||||
user.can_translate?(lang, locale) || (can_edit?(user) && lang.to_s != locale.to_s) |
|
||||
end |
|
||||
|
|
||||
def conference_day |
|
||||
return nil unless start_time.present? && end_time.present? |
|
||||
|
|
||||
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0) |
|
||||
w_start_day = start_time.change(hour: 0, minute: 0, second: 0) |
|
||||
return (((w_start_day - start_day) / 86400) + 1).to_i |
|
||||
end |
|
||||
|
|
||||
def duration |
|
||||
return nil unless start_time.present? && end_time.present? |
|
||||
((end_time - start_time) / 60).to_i |
|
||||
end |
|
||||
|
|
||||
def self.all_themes |
|
||||
[:race_gender, :mechanics, :funding, :organization, :community] |
|
||||
end |
|
||||
|
|
||||
def self.all_spaces |
|
||||
[:meeting_room, :workshop, :outdoor_meeting] |
|
||||
end |
|
||||
|
|
||||
def self.all_needs |
|
||||
[:sound, :projector, :tools] |
|
||||
end |
|
||||
|
|
||||
def get_translators(data, loc = nil) |
|
||||
notify_list = {} |
|
||||
active_facilitators.each do |facilitator| |
|
||||
notify_list[facilitator.id] = facilitator |
|
||||
end |
|
||||
|
|
||||
data.each do | column, value | |
|
||||
( |
|
||||
loc.present? ? |
|
||||
get_translators_for_column_and_locale(column, loc) : |
|
||||
get_translators_for_column(column) |
|
||||
).each do |id| |
|
||||
notify_list[id] = User.find(id) |
|
||||
end |
|
||||
end |
|
||||
return notify_list |
|
||||
end |
|
||||
|
|
||||
def comments |
|
||||
Comment.for(self) |
|
||||
end |
|
||||
|
|
||||
def add_comment(user, comment) |
|
||||
Comment.create_for(self, user, comment) |
|
||||
end |
|
||||
|
|
||||
private |
|
||||
def make_slug |
|
||||
if !self.slug |
|
||||
s = self.title.gsub(/[^a-z1-9]+/i, '-').chomp('-').gsub(/\-([A-Z])/, '\1') |
|
||||
if Organization.find_by(:slug => s) && self.locations && self.locations[0] |
|
||||
s += '-' + self.locations[0].city |
|
||||
if Organization.find_by(:slug => s) && locations[0].territory |
|
||||
s += '-' + self.locations[0].territory |
|
||||
end |
|
||||
if Organization.find_by(:slug => s) |
|
||||
s += '-' + self.locations[0].country |
|
||||
end |
|
||||
end |
|
||||
attempt = 1 |
|
||||
ss = s |
|
||||
while Organization.find_by(:slug => s) |
|
||||
attempt += 1 |
|
||||
s = ss + '-' + attempt |
|
||||
end |
|
||||
self.slug = s |
|
||||
end |
|
||||
end |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class WorkshopFacilitator < ActiveRecord::Base |
|
||||
end |
|
@ -1,4 +0,0 @@ |
|||||
class WorkshopInterest < ActiveRecord::Base |
|
||||
belongs_to :workshop |
|
||||
has_one :user |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class WorkshopPresentationStyle < ActiveRecord::Base |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class WorkshopRequestedResource < ActiveRecord::Base |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class WorkshopResource < ActiveRecord::Base |
|
||||
end |
|
@ -1,2 +0,0 @@ |
|||||
class WorkshopStream < ActiveRecord::Base |
|
||||
end |
|
@ -1,104 +0,0 @@ |
|||||
# encoding: utf-8 |
|
||||
require 'carrierwave/processing/mini_magick' |
|
||||
|
|
||||
class AvatarUploader < CarrierWave::Uploader::Base |
|
||||
|
|
||||
include CarrierWave::ImageOptimizer |
|
||||
include CarrierWave::MiniMagick |
|
||||
|
|
||||
# Include RMagick or MiniMagick support: |
|
||||
# include CarrierWave::RMagick |
|
||||
# include CarrierWave::MiniMagick |
|
||||
|
|
||||
# Choose what kind of storage to use for this uploader: |
|
||||
|
|
||||
storage :file |
|
||||
process :optimize |
|
||||
|
|
||||
@@sizes = {:thumb => [120, 120], :icon => [48, 48], :preview => [360, 120], :normal => [512, 512]} |
|
||||
# storage :fog |
|
||||
|
|
||||
# Override the directory where uploaded files will be stored. |
|
||||
# This is a sensible default for uploaders that are meant to be mounted: |
|
||||
def store_dir |
|
||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" |
|
||||
end |
|
||||
|
|
||||
# Provide a default URL as a default if there hasn't been a file uploaded: |
|
||||
# def default_url |
|
||||
# # For Rails 3.1+ asset pipeline compatibility: |
|
||||
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) |
|
||||
# |
|
||||
#"/images/fallback/" + [version_name, "default.png"].compact.join('_') |
|
||||
# "http://placehold.it/" + (@@sizes[version_name] || [300, 300]).join('x') |
|
||||
#end |
|
||||
|
|
||||
# Process files as they are uploaded: |
|
||||
# process :scale => [200, 300] |
|
||||
# |
|
||||
#def scale(width, height) |
|
||||
#end |
|
||||
|
|
||||
# Create different versions of your uploaded files: |
|
||||
version :thumb do |
|
||||
process :resize_to_fill => @@sizes[:thumb] |
|
||||
end |
|
||||
|
|
||||
version :icon do |
|
||||
process :resize_to_fill => @@sizes[:icon] |
|
||||
end |
|
||||
|
|
||||
version :preview do |
|
||||
process :resize_to_fit => @@sizes[:preview] |
|
||||
end |
|
||||
|
|
||||
version :normal do |
|
||||
process :resize_to_fit => @@sizes[:normal] |
|
||||
end |
|
||||
|
|
||||
# Add a white list of extensions which are allowed to be uploaded. |
|
||||
# For images you might use something like this: |
|
||||
# def extension_white_list |
|
||||
# %w(jpg jpeg gif png) |
|
||||
# end |
|
||||
|
|
||||
# Override the filename of the uploaded files: |
|
||||
# Avoid using model.id or version_name here, see uploader/store.rb for details. |
|
||||
# def filename |
|
||||
# "something.jpg" if original_filename |
|
||||
# end |
|
||||
|
|
||||
def image |
|
||||
@image ||= MiniMagick::Image.open(file.path) |
|
||||
end |
|
||||
|
|
||||
def is_landscape? |
|
||||
image['width'] > (image['height'] * 1.25) |
|
||||
end |
|
||||
|
|
||||
#def recreate_versions!(*versions) |
|
||||
# if !current_path.nil? |
|
||||
# current_path = "'" + (current_path || '') + "'" |
|
||||
# end |
|
||||
# super(*versions) |
|
||||
#end |
|
||||
|
|
||||
# def manipulate! |
|
||||
# cache_stored_file! if !cached? |
|
||||
# image = ::MiniMagick::Image.open(current_path) |
|
||||
# |
|
||||
# begin |
|
||||
# image.format(@format.to_s.downcase) if @format |
|
||||
# image = yield(image) |
|
||||
# image.write(current_path) |
|
||||
# image.run_command("identify", '"' + current_path + '"') |
|
||||
# ensure |
|
||||
# image.destroy! |
|
||||
# end |
|
||||
# rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e |
|
||||
# default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en) |
|
||||
# message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default) |
|
||||
# raise CarrierWave::ProcessingError, message |
|
||||
# end |
|
||||
|
|
||||
end |
|
@ -1,54 +0,0 @@ |
|||||
# encoding: utf-8 |
|
||||
require 'carrierwave/processing/mini_magick' |
|
||||
|
|
||||
class CoverUploader < CarrierWave::Uploader::Base |
|
||||
|
|
||||
include CarrierWave::ImageOptimizer |
|
||||
include CarrierWave::MiniMagick |
|
||||
|
|
||||
storage :file |
|
||||
process :optimize |
|
||||
|
|
||||
def store_dir |
|
||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" |
|
||||
end |
|
||||
|
|
||||
version :preview do |
|
||||
process :resize_to_fit => [480, 240] |
|
||||
end |
|
||||
|
|
||||
version :full do |
|
||||
process :resize_to_fit => [1200, 800] |
|
||||
end |
|
||||
|
|
||||
def image |
|
||||
@image ||= MiniMagick::Image.open(file.path) |
|
||||
end |
|
||||
|
|
||||
def is_landscape? |
|
||||
image['width'] > image['height'] |
|
||||
end |
|
||||
|
|
||||
def manipulate! |
|
||||
cache_stored_file! if !cached? |
|
||||
image = ::MiniMagick::Image.open(current_path) |
|
||||
|
|
||||
begin |
|
||||
image.format(@format.to_s.downcase) if @format |
|
||||
image = yield(image) |
|
||||
image.write(current_path) |
|
||||
begin |
|
||||
image.run_command("identify", current_path) |
|
||||
rescue |
|
||||
image.run_command("identify", '"' + current_path + '"') |
|
||||
end |
|
||||
ensure |
|
||||
image.destroy! |
|
||||
end |
|
||||
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e |
|
||||
default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en) |
|
||||
message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default) |
|
||||
raise CarrierWave::ProcessingError, message |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,57 +0,0 @@ |
|||||
# encoding: utf-8 |
|
||||
|
|
||||
class LogoUploader < CarrierWave::Uploader::Base |
|
||||
|
|
||||
# Include RMagick or MiniMagick support: |
|
||||
# include CarrierWave::RMagick |
|
||||
include CarrierWave::ImageOptimizer |
|
||||
include CarrierWave::MiniMagick |
|
||||
|
|
||||
# Include RMagick or MiniMagick support: |
|
||||
# include CarrierWave::RMagick |
|
||||
# include CarrierWave::MiniMagick |
|
||||
|
|
||||
# Choose what kind of storage to use for this uploader: |
|
||||
|
|
||||
storage :file |
|
||||
process :optimize |
|
||||
|
|
||||
# Override the directory where uploaded files will be stored. |
|
||||
# This is a sensible default for uploaders that are meant to be mounted: |
|
||||
def store_dir |
|
||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" |
|
||||
end |
|
||||
|
|
||||
# Provide a default URL as a default if there hasn't been a file uploaded: |
|
||||
# def default_url |
|
||||
# # For Rails 3.1+ asset pipeline compatibility: |
|
||||
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) |
|
||||
# |
|
||||
# "/images/fallback/" + [version_name, "default.png"].compact.join('_') |
|
||||
# end |
|
||||
|
|
||||
# Process files as they are uploaded: |
|
||||
# process :scale => [200, 300] |
|
||||
# |
|
||||
# def scale(width, height) |
|
||||
# # do something |
|
||||
# end |
|
||||
|
|
||||
# Create different versions of your uploaded files: |
|
||||
# version :thumb do |
|
||||
# process :scale => [50, 50] |
|
||||
# end |
|
||||
|
|
||||
# Add a white list of extensions which are allowed to be uploaded. |
|
||||
# For images you might use something like this: |
|
||||
# def extension_white_list |
|
||||
# %w(jpg jpeg gif png) |
|
||||
# end |
|
||||
|
|
||||
# Override the filename of the uploaded files: |
|
||||
# Avoid using model.id or version_name here, see uploader/store.rb for details. |
|
||||
# def filename |
|
||||
# "something.jpg" if original_filename |
|
||||
# end |
|
||||
|
|
||||
end |
|
@ -1,69 +0,0 @@ |
|||||
# encoding: utf-8 |
|
||||
require 'carrierwave/processing/mini_magick' |
|
||||
|
|
||||
class PosterUploader < CarrierWave::Uploader::Base |
|
||||
|
|
||||
include CarrierWave::ImageOptimizer |
|
||||
include CarrierWave::MiniMagick |
|
||||
|
|
||||
storage :file |
|
||||
process :optimize |
|
||||
|
|
||||
@@sizes = { |
|
||||
:thumb => [120, 120], |
|
||||
:icon => [48, 48], |
|
||||
:preview => [512, 512], |
|
||||
:full => [1024, 1024] |
|
||||
} |
|
||||
|
|
||||
def store_dir |
|
||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" |
|
||||
end |
|
||||
|
|
||||
version :thumb do |
|
||||
process :resize_to_fill => @@sizes[:thumb] |
|
||||
end |
|
||||
|
|
||||
version :icon do |
|
||||
process :resize_to_fill => @@sizes[:icon] |
|
||||
end |
|
||||
|
|
||||
version :preview do |
|
||||
process :resize_to_fit => @@sizes[:preview] |
|
||||
end |
|
||||
|
|
||||
version :full do |
|
||||
process :resize_to_fit => @@sizes[:full] |
|
||||
end |
|
||||
|
|
||||
def image |
|
||||
@image ||= MiniMagick::Image.open(file.path) |
|
||||
end |
|
||||
|
|
||||
def is_landscape? |
|
||||
image['width'] > image['height'] |
|
||||
end |
|
||||
|
|
||||
def manipulate! |
|
||||
cache_stored_file! if !cached? |
|
||||
image = ::MiniMagick::Image.open(current_path) |
|
||||
|
|
||||
begin |
|
||||
image.format(@format.to_s.downcase) if @format |
|
||||
image = yield(image) |
|
||||
image.write(current_path) |
|
||||
begin |
|
||||
image.run_command("identify", current_path) |
|
||||
rescue |
|
||||
image.run_command("identify", '"' + current_path + '"') |
|
||||
end |
|
||||
ensure |
|
||||
image.destroy! |
|
||||
end |
|
||||
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e |
|
||||
default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en) |
|
||||
message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default) |
|
||||
raise CarrierWave::ProcessingError, message |
|
||||
end |
|
||||
|
|
||||
end |
|
@ -1,6 +1,5 @@ |
|||||
= render :partial => 'application/header', :locals => {:image_file => 'parts.jpg'} |
= render partial: 'application/header', locals: {image_file: 'parts.jpg'} |
||||
= row do |
= row do |
||||
= columns(medium: 12) do |
= columns(medium: 12) do |
||||
%p= _'error.500.description', :p |
%p= _'error.500.description', :p |
||||
= render 'contact', cancel_btn: false, contact_reason: :website |
= render 'contact', cancel_btn: false, contact_reason: :website |
||||
|
|
@ -1,4 +1,4 @@ |
|||||
= row do |
= row do |
||||
= columns(medium: 12) do |
= columns(medium: 12) do |
||||
%h2=_'articles.permission_denied.headings.confirmation_sent' |
%h2=_'articles.permission_denied.headings.confirmation_sent' |
||||
%p=_'articles.conference_registration.paragraphs.email_confirm', :p |
%p=_'articles.conference_registration.paragraphs.email_confirm', :p |
||||
|
@ -1,10 +1,10 @@ |
|||||
= render :partial => 'application/header', :locals => {:image_file => @banner_image || 'grafitti.jpg'} |
= render :partial => 'application/header', :locals => {:image_file => @banner_image || 'grafitti.jpg'} |
||||
%article |
%article |
||||
= row do |
= row do |
||||
= columns do |
= columns do |
||||
- if @sent |
- if @sent |
||||
%h2=_'articles.contact.headings.sent', :t |
%h2=_'articles.contact.headings.sent', :t |
||||
%p=_'articles.contact.paragraphs.sent', :p |
%p=_'articles.contact.paragraphs.sent', :p |
||||
- else |
- else |
||||
%h2=_'articles.contact.headings.contact' |
%h2=_'articles.contact.headings.contact' |
||||
= render 'contact', cancel_btn: false |
= render 'contact', cancel_btn: false |
@ -1,5 +1,6 @@ |
|||||
- content_for :og_image do |
- content_for :og_image do |
||||
= @conference.poster.full.url || image_path('default_poster.jpg') |
- if @conference.present? |
||||
|
= @conference.poster.full.url || image_path('default_poster.jpg') |
||||
- if @conferences |
- if @conferences |
||||
- @conferences.each do | conference | |
- @conferences.each do | conference | |
||||
= render 'conferences/conference', conference: conference, links: [ :read_more, :register ] |
= render 'conferences/conference', conference: conference, links: [ :read_more, :register ] |
||||
|
@ -1,10 +1,10 @@ |
|||||
= render :partial => 'application/header', :locals => {:image_file => @banner_image || '403.jpg'} |
= render :partial => 'application/header', :locals => {:image_file => @banner_image || '403.jpg'} |
||||
%article |
%article |
||||
- if @template.present? |
- if @template.present? |
||||
=render @template |
=render @template |
||||
- else |
- else |
||||
= row do |
= row do |
||||
= columns do |
= columns do |
||||
%h2=_'error.403.title','Sorry, you currently don\'t have access to this page' |
%h2=_'error.403.title','Sorry, you currently don\'t have access to this page' |
||||
%p=_'error.403.description', :p |
%p=_'error.403.description', :p |
||||
= render 'contact', cancel_btn: false, contact_reason: :website |
= render 'contact', cancel_btn: false, contact_reason: :website |
@ -1,85 +1,86 @@ |
|||||
= columns(medium: 12) do |
= row do |
||||
- conference = @this_conference || @conference |
= columns(medium: 12) do |
||||
- if conference.event_locations.blank? && @entire_page |
- conference = @this_conference || @conference |
||||
.warning-info=_'articles.admin.schedule.no_locations_warning' |
- if conference.event_locations.blank? && @entire_page |
||||
- else |
.warning-info=_'articles.admin.schedule.no_locations_warning' |
||||
- add_inline_script :schedule if @entire_page |
- else |
||||
#schedule-preview |
- add_inline_script :schedule if @entire_page |
||||
- @schedule.each do | day, data | |
#schedule-preview |
||||
%h4=date(day, :weekday) |
- @schedule.each do |day, data| |
||||
%table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]} |
%h4=date(day, :weekday) |
||||
- if data[:locations].present? && data[:locations].values.first != :add |
%table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]} |
||||
%thead |
- if data[:locations].present? && data[:locations].values.first != :add |
||||
%tr |
%thead |
||||
%th.corner |
%tr |
||||
- data[:locations].each do | id, location | |
%th.corner |
||||
%th=location.is_a?(Symbol) ? '' : location.title |
- data[:locations].each do |id, location| |
||||
%tbody |
%th=location.is_a?(Symbol) ? '' : _!(location.title) |
||||
- data[:times].each do | time, time_data | |
%tbody |
||||
%tr |
- data[:times].each do |time, time_data| |
||||
- rowspan = (time_data[:length] * 2).to_i |
%tr |
||||
%th=time(time) |
- rowspan = (time_data[:length] * 2).to_i |
||||
- if time_data[:type] == :workshop |
%th=time(time) |
||||
- data[:locations].each do | id, location | |
- if time_data[:type] == :workshop |
||||
- if time_data[:item][:workshops][id].present? |
- data[:locations].each do |id, location| |
||||
- workshop = time_data[:item][:workshops][id][:workshop] |
- if time_data[:item][:workshops][id].present? |
||||
- status = time_data[:item][:workshops][id][:status] |
- workshop = time_data[:item][:workshops][id][:workshop] |
||||
- else |
- status = time_data[:item][:workshops][id][:status] |
||||
- workshop = status = nil |
- else |
||||
%td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id }} |
- workshop = status = nil |
||||
- if workshop.present? && workshop.event_location.present? |
%td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id }} |
||||
= link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do |
- if workshop.present? && workshop.event_location.present? |
||||
.details |
= link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do |
||||
.title=workshop.title |
|
||||
%template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }} |
|
||||
%h1.title=workshop.title |
|
||||
%p.address |
|
||||
= workshop.event_location.title + _!(': ') |
|
||||
= location_link workshop.event_location |
|
||||
.workshop-description= richtext workshop.info, 1 |
|
||||
- if @can_edit |
|
||||
= form_tag administration_update_path(conference.slug, @admin_step), class: 'deschedule-workshop' do |
|
||||
.status |
|
||||
.conflict-score |
|
||||
%span.title Conflicts: |
|
||||
%span.value="#{status[:conflict_score]} / #{workshop.interested.size}" |
|
||||
- if status[:errors].present? |
|
||||
.errors |
|
||||
- status[:errors].each do | error | |
|
||||
.error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars] |
|
||||
= hidden_field_tag :id, workshop.id |
|
||||
= button_tag :deschedule, value: :deschedule_workshop, class: [:delete, :small] |
|
||||
- elsif @can_edit |
|
||||
.title="Block #{time_data[:item][:block] + 1}" |
|
||||
- elsif time_data[:type] != :nil |
|
||||
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1} |
|
||||
- case time_data[:type] |
|
||||
- when :meal |
|
||||
- location = EventLocation.where(id: time_data[:item]['location'].to_i).first |
|
||||
- if location.present? |
|
||||
%a.event-detail-link |
|
||||
.details |
.details |
||||
.title= time_data[:item]['title'] |
.title=_!workshop.title |
||||
.location= location.title |
%template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }} |
||||
%template.event-details |
%h1.title=_!workshop.title |
||||
%h1.title=time_data[:item]['title'] |
|
||||
%p.address |
%p.address |
||||
= location.title + _!(': ') |
= _!("#{workshop.event_location.title}:") |
||||
= location_link location |
= location_link workshop.event_location |
||||
- when :event |
.workshop-description= richtext workshop.info, 1 |
||||
- if time_data[:item].event_location.present? |
- if @can_edit |
||||
%a.event-detail-link |
= form_tag administration_update_path(conference.slug, @admin_step), class: 'deschedule-workshop' do |
||||
.details |
.status |
||||
.title= time_data[:item][:title] |
.conflict-score |
||||
.location= time_data[:item].event_location.title |
%span.title Conflicts: |
||||
%template.event-details |
%span.value="#{status[:conflict_score]} / #{workshop.interested.size}" |
||||
%h1.title=time_data[:item][:title] |
- if status[:errors].present? |
||||
%p.address |
.errors |
||||
= time_data[:item].event_location.title + _!(': ') |
- status[:errors].each do |error| |
||||
= location_link time_data[:item].event_location |
.error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars] |
||||
= richtext time_data[:item][:info], 1 |
= hidden_field_tag :id, workshop.id |
||||
- if @entire_page |
= button :deschedule, value: :deschedule_workshop, class: [:delete, :small] |
||||
#workshop-selector |
- elsif @can_edit |
||||
= form_tag administration_update_path(@this_conference.slug, @admin_step), class: 'workshop-dlg', id: 'workshop-table-form' do |
.title="Block #{time_data[:item][:block] + 1}" |
||||
%h3 Select a Workshop |
- elsif time_data[:type] != :nil |
||||
#table |
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1} |
||||
|
- case time_data[:type] |
||||
|
- when :meal |
||||
|
- location = EventLocation.where(id: time_data[:item]['location'].to_i).first |
||||
|
- if location.present? |
||||
|
%a.event-detail-link |
||||
|
.details |
||||
|
.title=_!(time_data[:item]['title']) |
||||
|
.location=_!location.title |
||||
|
%template.event-details |
||||
|
%h1.title=_!(time_data[:item]['title']) |
||||
|
%p.address |
||||
|
= _!("#{location.title}:") |
||||
|
= location_link location |
||||
|
- when :event |
||||
|
- if time_data[:item].event_location.present? |
||||
|
%a.event-detail-link |
||||
|
.details |
||||
|
.title=_!(time_data[:item][:title]) if time_data[:item][:title] |
||||
|
.location=_!(time_data[:item].event_location.title) |
||||
|
%template.event-details |
||||
|
%h1.title=_!(time_data[:item][:title]) if time_data[:item][:title] |
||||
|
%p.address |
||||
|
= _!("#{time_data[:item].event_location.title}:") |
||||
|
= location_link time_data[:item].event_location |
||||
|
= richtext time_data[:item][:info], 1 |
||||
|
- if @entire_page |
||||
|
#workshop-selector |
||||
|
= form_tag administration_update_path(@this_conference.slug, @admin_step), class: 'workshop-dlg', id: 'workshop-table-form' do |
||||
|
%h3 Select a Workshop |
||||
|
#table |
||||
|
@ -1,6 +0,0 @@ |
|||||
= columns(medium: 3, large: 2) do |
|
||||
= admin_menu |
|
||||
= columns(medium: 9, large: 10) do |
|
||||
%h3.subtitle=_("menu.submenu.admin.#{@admin_step.titlecase.gsub(/\s/, '_')}") |
|
||||
%p=(_"articles.admin.#{@admin_step.gsub(/\s/, '_')}.description", :p) unless @hide_description === true |
|
||||
%div{id: "admin-#{@admin_step}"}= render "conferences/admin/#{@admin_step}" |
|
@ -1,13 +1,13 @@ |
|||||
= columns(medium: 12) do |
= columns(medium: 12) do |
||||
%p=_"articles.conference_registration.paragraphs.#{@this_conference.registration_status == :open ? '': 'Pre_'}Registration_Details" |
%p=_"articles.conference_registration.paragraphs.#{@this_conference.registration_status == :open ? '': 'Pre_'}Registration_Details" |
||||
%h3=_'articles.conference_registration.headings.Verify_Account' |
%h3=_'articles.conference_registration.headings.Verify_Account' |
||||
%p=_'articles.conference_registration.paragraphs.Verify_Account' |
%p=_'articles.conference_registration.paragraphs.Verify_Account' |
||||
|
|
||||
= form_tag register_path(@this_conference.slug), class: 'flex-form' do |
= form_tag register_path(@this_conference.slug), class: 'flex-form' do |
||||
.email-field.input-field.big |
.email-field.input-field.big |
||||
= email_field_tag :email, nil, required: true |
= email_field_tag :email, nil, required: true |
||||
= label_tag :email |
= label_tag :email |
||||
= button_tag :continue, :value => :confirm_email |
= button :continue, value: :confirm_email |
||||
= columns(medium: 12, class: 'flex-column') do |
= columns(medium: 12, class: 'flex-column') do |
||||
%p.stretch-item=_'articles.conference_registration.paragraphs.facebook_sign_in' |
%p.stretch-item=_'articles.conference_registration.paragraphs.facebook_sign_in' |
||||
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(:provider => :facebook), class: [:button, :facebook] |
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(:provider => :facebook), class: [:button, :facebook] |
||||
|
@ -1,6 +1,6 @@ |
|||||
%article |
%article |
||||
= row do |
= row do |
||||
= columns(medium: 12) do |
= columns(medium: 12) do |
||||
%h2=_'articles.conference_registration.headings.email_confirm','Please confirm your email address' |
%h2=_'articles.conference_registration.headings.email_confirm','Please confirm your email address' |
||||
= columns(medium: 12) do |
= columns(medium: 12) do |
||||
%p=_'articles.conference_registration.paragraphs.email_confirm', :p |
%p=_'articles.conference_registration.paragraphs.email_confirm', :p |
||||
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue