2017 refactor
This commit is contained in:
		
							parent
							
								
									572e0d6644
								
							
						
					
					
						commit
						8f852b102b
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -47,10 +47,6 @@ rerun.txt | |||||||
| pickle-email-*.html | pickle-email-*.html | ||||||
| .project | .project | ||||||
| 
 | 
 | ||||||
| # Ignore Gemfile.lock so that we always get the most up to date gems |  | ||||||
| # We'll be testing in 'preview' to avoid clashes  |  | ||||||
| Gemfile.lock |  | ||||||
| 
 |  | ||||||
| # Ignore Redis' dataset snapshot | # Ignore Redis' dataset snapshot | ||||||
| dump.rdb | dump.rdb | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										82
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								Gemfile
									
									
									
									
									
								
							| @ -5,58 +5,42 @@ gem 'pg' | |||||||
| gem 'rake', '11.1.2' | gem 'rake', '11.1.2' | ||||||
| gem 'ruby_dep', '1.3.1' # Lock at 1.3.1 since 1.4 requires ruby 2.5. We should unlock once we upgrade the ruby version on our server | gem 'ruby_dep', '1.3.1' # Lock at 1.3.1 since 1.4 requires ruby 2.5. We should unlock once we upgrade the ruby version on our server | ||||||
| 
 | 
 | ||||||
| # gem 'bcrypt-ruby', '3.0.0', require: 'bcrypt' |  | ||||||
| # gem 'bcrypt', '3.1.9' |  | ||||||
| # gem 'bcrypt', require: :ruby |  | ||||||
| gem 'rack-mini-profiler' | gem 'rack-mini-profiler' | ||||||
| 
 | 
 | ||||||
| gem 'haml' | gem 'haml' | ||||||
| gem 'nokogiri', '~> 1.6.8.rc2' | gem 'nokogiri' | ||||||
| 
 | 
 | ||||||
| if Dir.exists?('../lingua_franca') |  | ||||||
|   gem 'lingua_franca', :path => '../lingua_franca' |  | ||||||
| else |  | ||||||
|   gem 'lingua_franca', :git => 'git://github.com/lingua-franca/lingua_franca.git' |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| gem 'tzinfo-data' |  | ||||||
| gem 'sass' | gem 'sass' | ||||||
| gem 'sass-rails' | gem 'sass-rails' | ||||||
| 
 |  | ||||||
| if Dir.exists?('../bumbleberry') |  | ||||||
|   gem 'bumbleberry', :path => "../bumbleberry" |  | ||||||
| else |  | ||||||
|   gem 'bumbleberry', :git => 'git://github.com/bumbleberry/bumbleberry.git' |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| if Dir.exists?('../paypal-express') |  | ||||||
|   gem 'paypal-express', :path => "../paypal-express" |  | ||||||
| else |  | ||||||
|   gem 'paypal-express', :git => 'git://github.com/bikebike/paypal-express.git' |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| gem 'uglifier', '>= 1.3.0' | gem 'uglifier', '>= 1.3.0' | ||||||
| gem 'sorcery', '>= 0.8.1' | # replace this once these changes are merged in sorcery | ||||||
| gem 'oauth2', '~> 0.8.0' | gem 'sorcery', git: 'https://github.com/tg90nor/sorcery.git', branch: 'make-facebook-provider-use-json-token-parser' | ||||||
| gem 'carrierwave' | gem 'carrierwave' | ||||||
| gem 'carrierwave-imageoptimizer' | gem 'carrierwave-imageoptimizer' | ||||||
| gem 'mini_magick' | gem 'mini_magick' | ||||||
| gem 'geocoder' |  | ||||||
| gem 'paper_trail', '~> 3.0.5' |  | ||||||
| gem 'sitemap_generator' |  | ||||||
| gem 'activerecord-session_store' | gem 'activerecord-session_store' | ||||||
| gem 'sass-json-vars' |  | ||||||
| gem 'premailer-rails' | gem 'premailer-rails' | ||||||
| gem 'redcarpet' |  | ||||||
| gem 'sidekiq' | gem 'sidekiq' | ||||||
| gem 'letter_opener' | gem 'letter_opener' | ||||||
| gem 'launchy' | gem 'launchy' | ||||||
| gem 'to_spreadsheet', :git => 'git://github.com/glebm/to_spreadsheet.git' |  | ||||||
| 
 | 
 | ||||||
| group :test do | # Bike Collectives gems, when developing locally execute: | ||||||
|   gem 'rspec' | #   bundle config local.bikecollectives_core ../bikecollectives_core | ||||||
|   gem 'rspec-rails' | #   bundle config local.bumbleberry ../bumbleberry | ||||||
| end | #   bundle config local.lingua_franca ../lingua_franca | ||||||
|  | #   bundle config local.marmara ../marmara | ||||||
|  | gem 'bikecollectives_core', git: 'https://github.com/bikebike/bikecollectives_core.git', branch: 'master' | ||||||
|  | gem 'bumbleberry', git: 'https://github.com/bumbleberry/bumbleberry.git', branch: '2017' | ||||||
|  | gem 'lingua_franca', git: 'https://github.com/lingua-franca/lingua_franca.git', branch: '2017' | ||||||
|  | gem 'marmara', git: 'https://github.com/lingua-franca/marmara.git', branch: 'master' | ||||||
|  | 
 | ||||||
|  | # Bike!Bike! specific stuff | ||||||
|  | gem 'ianfleeton-paypal-express', require: 'paypal/express' | ||||||
|  | gem 'geocoder' | ||||||
|  | gem 'sitemap_generator' | ||||||
|  | gem 'sass-json-vars' | ||||||
|  | gem 'redcarpet' | ||||||
|  | gem 'to_spreadsheet', git: 'https://github.com/glebm/to_spreadsheet.git' | ||||||
| 
 | 
 | ||||||
| group :development do | group :development do | ||||||
|   gem 'better_errors' |   gem 'better_errors' | ||||||
| @ -67,17 +51,23 @@ group :development do | |||||||
|   gem 'capistrano-rails', '~> 1.1' |   gem 'capistrano-rails', '~> 1.1' | ||||||
|   gem 'capistrano-faster-assets', '~> 1.0' |   gem 'capistrano-faster-assets', '~> 1.0' | ||||||
| 
 | 
 | ||||||
|   gem 'eventmachine', :github => 'krzcho/eventmachine', :branch => 'master' |   gem 'eventmachine', git: 'https://github.com/krzcho/eventmachine', :branch => 'master' | ||||||
|   gem 'thin'# , :github => 'krzcho/thin', :branch => 'master' |   gem 'thin' | ||||||
|  |   gem 'rubocop', require: false | ||||||
|  |   gem 'haml-lint', require: false | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| group :test do | group :test do | ||||||
|  |   gem 'rspec' | ||||||
|  |   gem 'rspec-rails' | ||||||
|   gem 'gherkin3', '>= 3.1.0' |   gem 'gherkin3', '>= 3.1.0' | ||||||
|   gem 'cucumber' |   gem 'cucumber' | ||||||
|   gem 'cucumber-core' |   gem 'cucumber-core' | ||||||
|   gem 'cucumber-rails' |   gem 'cucumber-rails', require: false | ||||||
|  |   gem 'guard-cucumber' | ||||||
| 
 | 
 | ||||||
|   gem 'poltergeist' |   gem 'poltergeist' | ||||||
|  |   gem 'capybara-email' | ||||||
|   gem 'guard-rspec' |   gem 'guard-rspec' | ||||||
|   gem 'factory_girl_rails' |   gem 'factory_girl_rails' | ||||||
|   gem 'coveralls', require: false |   gem 'coveralls', require: false | ||||||
| @ -90,16 +80,22 @@ end | |||||||
| 
 | 
 | ||||||
| group :production, :preview do | group :production, :preview do | ||||||
|   gem 'rails_12factor' |   gem 'rails_12factor' | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | group :production, :preview do | ||||||
|  |   platforms :ruby do | ||||||
|  |     gem 'unicorn', require: false | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   gem 'daemon-spawn' |   gem 'daemon-spawn' | ||||||
|   gem 'daemons' |   gem 'daemons' | ||||||
|    |  | ||||||
|   platforms :ruby do |  | ||||||
|     gem 'unicorn' |  | ||||||
|   end |  | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| platforms 'mswin', 'mingw' do | platforms 'mswin', 'mingw' do | ||||||
|  |   gem 'tzinfo-data' | ||||||
|  |    | ||||||
|   group :test do |   group :test do | ||||||
|     gem 'wdm', '>= 0.1.0' |     gem 'wdm', '>= 0.1.0' | ||||||
|  |       gem 'win32console', require: false | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  | |||||||
							
								
								
									
										633
									
								
								Gemfile.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										633
									
								
								Gemfile.lock
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										25
									
								
								Guardfile
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								Guardfile
									
									
									
									
									
								
							| @ -22,3 +22,28 @@ guard :rspec do | |||||||
|   watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$})   { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } |   watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$})   { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | cucumber_options = { | ||||||
|  |   # Below are examples overriding defaults | ||||||
|  | 
 | ||||||
|  |   # cmd: 'bin/cucumber', | ||||||
|  |   # cmd_additional_args: '--profile guard', | ||||||
|  | 
 | ||||||
|  |   # all_after_pass: false, | ||||||
|  |   # all_on_start: false, | ||||||
|  |   # keep_failed: false, | ||||||
|  |   # feature_sets: ['features/frontend', 'features/experimental'], | ||||||
|  | 
 | ||||||
|  |   # run_all: { cmd_additional_args: '--profile guard_all' }, | ||||||
|  |   # focus_on: { 'wip' }, # @wip | ||||||
|  |   # notification: false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | guard "cucumber", cucumber_options do | ||||||
|  |   watch(%r{^features/.+\.feature$}) | ||||||
|  |   watch(%r{^features/support/.+$}) { "features" } | ||||||
|  | 
 | ||||||
|  |   watch(%r{^features/step_definitions/(.+)_steps\.rb$}) do |m| | ||||||
|  |     Dir[File.join("**/#{m[1]}.feature")][0] || "features" | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | |||||||
| @ -150,3 +150,8 @@ On hold until our design team determines a director for our identity. | |||||||
| ## Testing Practices ## | ## Testing Practices ## | ||||||
| 
 | 
 | ||||||
| Our focus will be on integration testing using Capybara. While testing the app records all translations that it finds, whether or not they exist, and which pages that they were found on. | Our focus will be on integration testing using Capybara. While testing the app records all translations that it finds, whether or not they exist, and which pages that they were found on. | ||||||
|  | 
 | ||||||
|  | ## Attribution ## | ||||||
|  | 
 | ||||||
|  | ### Icons ### | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								Rakefile
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								Rakefile
									
									
									
									
									
								
							| @ -1,5 +1,8 @@ | |||||||
| # Add your own tasks in files placed in lib/tasks ending in .rake, | # Add your own tasks in files placed in lib/tasks ending in .rake, | ||||||
| # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. | ||||||
|  | require 'rubygems' | ||||||
|  | require 'cucumber' | ||||||
|  | require 'cucumber/rake/task' | ||||||
| 
 | 
 | ||||||
| require File.expand_path('../config/application', __FILE__) | require File.expand_path('../config/application', __FILE__) | ||||||
| 
 | 
 | ||||||
| @ -61,3 +64,31 @@ task update_cities_fr: :environment do | |||||||
|     c.save! |     c.save! | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  | 
 | ||||||
|  | task :i18n do | ||||||
|  |   LinguaFranca.test LinguaFranca::TestModes::RECORD do | ||||||
|  |     Rake::Task[:cucumber].execute | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | task :css do | ||||||
|  |   ENV['CSS_TEST'] = '1' | ||||||
|  |   Rake::Task[:cucumber].execute | ||||||
|  |   ENV['CSS_TEST'] = nil | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | task :a11y do | ||||||
|  |   ENV['TEST_A11Y'] = '1' | ||||||
|  |   Rake::Task[:cucumber].execute | ||||||
|  |   ENV['TEST_A11Y'] = nil | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | task "cucumber:debug" do | ||||||
|  |   ENV['TEST_DEBUG'] = '1' | ||||||
|  |   Rake::Task[:cucumber].execute | ||||||
|  |   ENV['TEST_DEBUG'] = nil | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | Cucumber::Rake::Task.new(:cucumber) do |t| | ||||||
|  |   t.cucumber_opts = "features --format pretty" | ||||||
|  | end | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								app/assets/images/test-poster.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/assets/images/test-poster.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 76 KiB | 
| @ -21,6 +21,7 @@ | |||||||
|             var field = fields[i]; |             var field = fields[i]; | ||||||
|             var input = field.getElementsByTagName('input')[0]; |             var input = field.getElementsByTagName('input')[0]; | ||||||
|             var name = field.getElementsByClassName('user-name')[0]; |             var name = field.getElementsByClassName('user-name')[0]; | ||||||
|  |              | ||||||
|         } |         } | ||||||
|     }, false); |     }, false); | ||||||
| })(); | })(); | ||||||
|  | |||||||
| @ -1710,17 +1710,17 @@ ul.warnings { | |||||||
| 
 | 
 | ||||||
|         a.policy { |         a.policy { | ||||||
|             background-color: $colour-5; |             background-color: $colour-5; | ||||||
|             @include _(order, 1); |             // @include _(order, 1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         a.about { |         a.about { | ||||||
|             background-color: $colour-3; |             background-color: $colour-3; | ||||||
|             @include _(order, 1); |             // @include _(order, 1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         a.conferences { |         a.conferences { | ||||||
|             background-color: $colour-2; |             background-color: $colour-2; | ||||||
|             @include _(order, 1); |             // @include _(order, 1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         form, .register { |         form, .register { | ||||||
| @ -1728,7 +1728,8 @@ ul.warnings { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         a, form { |         a, form { | ||||||
|             width: 33%; |             width: 33.333%; | ||||||
|  |             float: left; | ||||||
|             @include _(flex, 1); |             @include _(flex, 1); | ||||||
|         } |         } | ||||||
|          |          | ||||||
| @ -2948,12 +2949,11 @@ a.logo { | |||||||
| .conference-banner { | .conference-banner { | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     padding: 0; |     padding: 0; | ||||||
|     margin: 0 -1em 2em; |     margin: 0; | ||||||
|     width: auto; |  | ||||||
| 
 | 
 | ||||||
|     .title { |     .title { | ||||||
|         font-size: 5vw; |         font-size: 5vw; | ||||||
|         margin: 1em auto 2em; |         margin: 1em auto 0; | ||||||
| 
 | 
 | ||||||
|         h1, h2 { |         h1, h2 { | ||||||
|             margin: 0; |             margin: 0; | ||||||
| @ -2971,6 +2971,7 @@ a.logo { | |||||||
| 
 | 
 | ||||||
|     img { |     img { | ||||||
|         max-width: 100%; |         max-width: 100%; | ||||||
|  |         margin-top: 2em; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -3311,8 +3312,11 @@ body.error-locale-not-available { | |||||||
| body { | body { | ||||||
|     #primary-content { |     #primary-content { | ||||||
|         @include _(transition, 'filter 250ms ease-in-out, -webkit-filter 250ms ease-in-out'); |         @include _(transition, 'filter 250ms ease-in-out, -webkit-filter 250ms ease-in-out'); | ||||||
|  | 
 | ||||||
|  |         @if capable_of(flexbox, true) { | ||||||
|             display: -webkit-flex; |             display: -webkit-flex; | ||||||
|             flex-direction: column; |             flex-direction: column; | ||||||
|  |         } | ||||||
|         min-height: 100vh; |         min-height: 100vh; | ||||||
|         overflow: hidden; |         overflow: hidden; | ||||||
|     } |     } | ||||||
| @ -4617,6 +4621,7 @@ html[data-ontop] { | |||||||
|         .nav a { |         .nav a { | ||||||
|             &[class] { |             &[class] { | ||||||
|                 width: auto; |                 width: auto; | ||||||
|  |                 float: none; | ||||||
|                 overflow: visible; |                 overflow: visible; | ||||||
|                 margin-left: 0.725em; |                 margin-left: 0.725em; | ||||||
|                 padding: 0.25em 0.5em; |                 padding: 0.25em 0.5em; | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| { | { | ||||||
|     "stylesheets": ["application", "editor"], |   "stylesheets": ["application", "editor", "admin"], | ||||||
|   "precompile": { |   "precompile": { | ||||||
|     "test": { |     "test": { | ||||||
|             "chrome": ["51"] |       "safari": ["5"], | ||||||
|  |       "chrome": ["55"] | ||||||
|     }, |     }, | ||||||
|     "development": { |     "development": { | ||||||
|             "and_chr": ["56"], |       "safari": ["5", "5.1"], | ||||||
|             "chrome": ["56"], |       "and_chr": ["57"], | ||||||
|  |       "chrome": ["57"], | ||||||
|       "edge": ["13"], |       "edge": ["13"], | ||||||
|       "firefox": ["50"], |       "firefox": ["50"], | ||||||
|       "ie": ["11"], |       "ie": ["11"], | ||||||
|  | |||||||
| @ -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,21 +1,19 @@ | |||||||
| module ActiveRecord | class ApplicationController < BaseController | ||||||
|   class PremissionDenied < RuntimeError |  | ||||||
|   end |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| class ApplicationController < LinguaFrancaApplicationController |  | ||||||
|   # Prevent CSRF attacks by raising an exception. |  | ||||||
|   # For APIs, you may want to use :null_session instead. |  | ||||||
|   protect_from_forgery with: :exception, :except => [:do_confirm, :js_error, :admin_update] |   protect_from_forgery with: :exception, :except => [:do_confirm, :js_error, :admin_update] | ||||||
| 
 | 
 | ||||||
|   before_filter :capture_page_info |   before_filter :capture_page_info | ||||||
| 
 | 
 | ||||||
|   helper_method :protect |   helper_method :protect | ||||||
| 
 | 
 | ||||||
|   @@test_host |   # @@test_host | ||||||
|   @@test_location |   # @@test_location | ||||||
|  | 
 | ||||||
|  |   def default_url_options | ||||||
|  |     { host: "#{request.protocol}#{request.host_with_port}", trailing_slash: true } | ||||||
|  |   end | ||||||
| 
 | 
 | ||||||
|   def capture_page_info |   def capture_page_info | ||||||
|  |     # capture request info in case an error occurs | ||||||
|     if request.method == "GET" && (params[:controller] != 'application' || params[:action] != 'contact') |     if request.method == "GET" && (params[:controller] != 'application' || params[:action] != 'contact') | ||||||
|       session[:last_request] |       session[:last_request] | ||||||
|       request_info = { |       request_info = { | ||||||
| @ -27,14 +25,11 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|           'env'          => Hash.new |           'env'          => Hash.new | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       request.env.each do | key, value | |       request.env.each do |key, value| | ||||||
|         request_info['request']['env'][key.to_s] = value.to_s |         request_info['request']['env'][key.to_s] = value.to_s | ||||||
|       end |       end | ||||||
|       session['request_info'] = request_info |       session['request_info'] = request_info | ||||||
|     end |     end | ||||||
|     # set the translator to the current user if we're logged in |  | ||||||
|     I18n.config.translator = current_user |  | ||||||
|     I18n.config.callback = self |  | ||||||
| 
 | 
 | ||||||
|     # get the current conferences and set them globally |     # get the current conferences and set them globally | ||||||
|     status_hierarchy = { |     status_hierarchy = { | ||||||
| @ -50,18 +45,16 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     @conference = @conferences.first |     @conference = @conferences.first | ||||||
| 
 | 
 | ||||||
|     # add some style sheets |     # add some style sheets | ||||||
|     @stylesheets ||= Array.new |     @stylesheets ||= Set.new | ||||||
|     # add the translations stylesheet if translating |     # add the translations stylesheet if translating | ||||||
|     @stylesheets << params[:controller] if params[:controller] == 'translations' |     @stylesheets << params[:controller] if params[:controller] == 'translations' | ||||||
| 
 | 
 | ||||||
|     @_inline_scripts ||= [] |     @_inline_scripts ||= Set.new | ||||||
|     @_inline_scripts << Rails.application.assets.find_asset('main.js').to_s |     @_inline_scripts << Rails.application.assets.find_asset('main.js').to_s | ||||||
| 
 | 
 | ||||||
|     ActionMailer::Base.default_url_options = {:host => "#{request.protocol}#{request.host_with_port}"} |     ActionMailer::Base.default_url_options = { | ||||||
| 
 |         host: "#{request.protocol}#{request.host_with_port}" | ||||||
|     if request.post? && params[:action] == 'do_confirm' |       } | ||||||
|       halt_redirection! |  | ||||||
|     end |  | ||||||
| 
 | 
 | ||||||
|     @alt_lang_urls = {} |     @alt_lang_urls = {} | ||||||
|     I18n.backend.enabled_locales.each do |locale| |     I18n.backend.enabled_locales.each do |locale| | ||||||
| @ -72,15 +65,10 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     # give each environment a different icon and theme colour so that we can easily see where we are. See https://css-tricks.com/give-development-domain-different-favicon-production |     # give each environment a different icon and theme colour so that we can easily see where we are. See https://css-tricks.com/give-development-domain-different-favicon-production | ||||||
|     @favicon = Rails.env.development? || Rails.env.preview? ? "favicon-#{Rails.env.to_s}.ico" : 'favicon.ico' |     @favicon = Rails.env.development? || Rails.env.preview? ? "favicon-#{Rails.env.to_s}.ico" : 'favicon.ico' | ||||||
|     @theme_colour = Rails.env.preview? ? '#EF57B4' : (Rails.env.development? ? '#D89E59' : '#00ADEF') |     @theme_colour = Rails.env.preview? ? '#EF57B4' : (Rails.env.development? ? '#D89E59' : '#00ADEF') | ||||||
| 
 |  | ||||||
|     # call the base method to detect the language |  | ||||||
|     super |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def home |   def home | ||||||
|     @workshops = [] |     if @conference.present? && @conference.id.present? | ||||||
| 
 |  | ||||||
|     if @conference.present? |  | ||||||
|       @workshops = Workshop.where(conference_id: @conference.id) |       @workshops = Workshop.where(conference_id: @conference.id) | ||||||
| 
 | 
 | ||||||
|       if @conference.workshop_schedule_published |       if @conference.workshop_schedule_published | ||||||
| @ -94,54 +82,17 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     @is_policy_page = true |     @is_policy_page = true | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def robots |   # def self.set_host(host) | ||||||
|     render :text => File.read("config/robots-#{Rails.env.production? ? 'live' : 'dev'}.txt"), :content_type => 'text/plain' |   #   @@test_host = host | ||||||
|   end |   # end | ||||||
| 
 | 
 | ||||||
|   def humans |   # def self.set_location(location) | ||||||
|     render :text => File.read("config/humans.txt"), :content_type => 'text/plain' |   #   @@test_location = location | ||||||
|   end |   # end | ||||||
| 
 | 
 | ||||||
|   def self.set_host(host) |   # def self.get_location() | ||||||
|     @@test_host = host |   #   @@test_location | ||||||
|   end |   # end | ||||||
| 
 |  | ||||||
|   def self.set_location(location) |  | ||||||
|     @@test_location = location |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def self.get_location() |  | ||||||
|     @@test_location |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def do_404 |  | ||||||
|     error_404(status: 404) |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def error_404(args = {}) |  | ||||||
|     params[:_original_action] = params[:action] |  | ||||||
|     params[:action] = 'error-404' |  | ||||||
|     @page_title = 'page_titles.404.Page_Not_Found' |  | ||||||
|     @main_title = 'error.404.title' |  | ||||||
|     render 'application/404', args |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def do_403(template = nil) |  | ||||||
|     @template = template |  | ||||||
|     @page_title ||= 'page_titles.403.Access_Denied' |  | ||||||
|     @main_title ||= @page_title |  | ||||||
|     params[:_original_action] = params[:action] |  | ||||||
|     params[:action] = 'error-403' |  | ||||||
|     render 'application/permission_denied', status: 403 |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def error_500(exception = nil) |  | ||||||
|     @page_title = 'page_titles.500.An_Error_Occurred' |  | ||||||
|     @main_title = 'error.500.title' |  | ||||||
|     params[:_original_action] = params[:action] |  | ||||||
|     params[:action] = 'error-500' |  | ||||||
|     render 'application/500', status: 500 |  | ||||||
|   end |  | ||||||
| 
 | 
 | ||||||
|   def js_error |   def js_error | ||||||
|     # send and email if this is production |     # send and email if this is production | ||||||
| @ -154,20 +105,30 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
| 
 | 
 | ||||||
|     begin |     begin | ||||||
|       # log the error |       # log the error | ||||||
|       logger.info "Javascript exception: #{params[:message]}" |       logger.info "A JavaScript error has occurred on #{params[:location]}:#{params[:lineNumber]}: #{params[:message]}" | ||||||
| 
 | 
 | ||||||
|       UserMailer.send_mail(:error_report) do  |       if Rails.env.preview? || Rails.env.production? | ||||||
|         [ |         requestHash = { | ||||||
|  |           'remote_ip'    => arg.remote_ip, | ||||||
|  |           'uuid'         => arg.uuid, | ||||||
|  |           'original_url' => arg.original_url, | ||||||
|  |           'env'          => Hash.new | ||||||
|  |         } | ||||||
|  |         request.env.each do | key, value | | ||||||
|  |           requestHash['env'][key.to_s] = value.to_s | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |         send_mail(:error_report, | ||||||
|             "A JavaScript error has occurred", |             "A JavaScript error has occurred", | ||||||
|             report, |             report, | ||||||
|             params[:message], |             params[:message], | ||||||
|             nil, |             nil, | ||||||
|           request, |             requestHash, | ||||||
|             params, |             params, | ||||||
|             current_user, |             current_user, | ||||||
|             Time.now.strftime("%d/%m/%Y %H:%M") |             Time.now.strftime("%d/%m/%Y %H:%M") | ||||||
|         ] |         ) | ||||||
|       end# if Rails.env.preview? || Rails.env.production? |       end | ||||||
|     rescue Exception => exception2 |     rescue Exception => exception2 | ||||||
|       logger.info exception2.to_s |       logger.info exception2.to_s | ||||||
|       logger.info exception2.backtrace.join("\n") |       logger.info exception2.backtrace.join("\n") | ||||||
| @ -175,31 +136,27 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     render json: {} |     render json: {} | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   rescue_from ActiveRecord::RecordNotFound do |exception| |   def confirmation_sent(user) | ||||||
|     do_404 |     template = 'login_confirmation_sent' | ||||||
|  |     @page_title ||= 'page_titles.403.Please_Check_Email' | ||||||
|  | 
 | ||||||
|  |     if (request.present? && request.referrer.present? && conference = /^\/conferences\/(\w+)\/register\/?$/.match(request.referrer.gsub(/^https?:\/\/.*?\//, '/'))) | ||||||
|  |       @this_conference = Conference.find_by!(slug: conference[1]) | ||||||
|  |       @banner_image = @this_conference.cover_url | ||||||
|  |       template = 'conferences/email_confirm' | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|   rescue_from ActiveRecord::PremissionDenied do |exception| |     do_403 template | ||||||
|     do_403 |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   rescue_from AbstractController::ActionNotFound do |exception| |  | ||||||
|     @banner_image = 'grafitti.jpg' |  | ||||||
|      |  | ||||||
|     if current_user |  | ||||||
|       @page_title = nil#'page_titles.Please_Login' |  | ||||||
|       do_403 'not_a_translator' |  | ||||||
|       #return |  | ||||||
|     else |  | ||||||
|       @page_title = 'page_titles.403.Please_Login' |  | ||||||
|       do_403 'translator_login' |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def locale_not_enabled!(locale = nil) |   def locale_not_enabled!(locale = nil) | ||||||
|     locale_not_available!(locale) |     locale_not_available!(locale) | ||||||
|   end |   end | ||||||
|    |    | ||||||
|  |   def locale_not_available | ||||||
|  |     locale_not_available!(params[:locale]) | ||||||
|  |   end | ||||||
|  |    | ||||||
|   def locale_not_available!(locale = nil) |   def locale_not_available!(locale = nil) | ||||||
|     set_default_locale |     set_default_locale | ||||||
|     params[:_original_action] = params[:action] |     params[:_original_action] = params[:action] | ||||||
| @ -210,12 +167,14 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     render 'application/locale_not_available', status: 404 |     render 'application/locale_not_available', status: 404 | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   unless Rails.env.test? | ||||||
|     rescue_from StandardError do |exception| |     rescue_from StandardError do |exception| | ||||||
|       handle_exception exception |       handle_exception exception | ||||||
| 
 | 
 | ||||||
|       # show the error page |       # show the error page | ||||||
|       error_500 exception |       error_500 exception | ||||||
|     end |     end | ||||||
|  |   end | ||||||
| 
 | 
 | ||||||
|   def handle_exception(exception) |   def handle_exception(exception) | ||||||
|     # log the error |     # log the error | ||||||
| @ -223,19 +182,28 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     logger.info exception.backtrace.join("\n") |     logger.info exception.backtrace.join("\n") | ||||||
| 
 | 
 | ||||||
|     # send and email if this is production |     # send and email if this is production | ||||||
|  |     if Rails.env.preview? || Rails.env.production? | ||||||
|       suppress(Exception) do |       suppress(Exception) do | ||||||
|       UserMailer.send_mail(:error_report) do  |         requestHash = { | ||||||
|         [ |           'remote_ip'    => arg.remote_ip, | ||||||
|  |           'uuid'         => arg.uuid, | ||||||
|  |           'original_url' => arg.original_url, | ||||||
|  |           'env'          => Hash.new | ||||||
|  |         } | ||||||
|  |         request.env.each do | key, value | | ||||||
|  |           requestHash['env'][key.to_s] = value.to_s | ||||||
|  |         end | ||||||
|  |         send_mail(:error_report, | ||||||
|             "An error has occurred in #{Rails.env}", |             "An error has occurred in #{Rails.env}", | ||||||
|             nil, |             nil, | ||||||
|             exception.to_s, |             exception.to_s, | ||||||
|             exception.backtrace.join("\n"), |             exception.backtrace.join("\n"), | ||||||
|           request, |             requestHash, | ||||||
|             params, |             params, | ||||||
|             current_user, |             current_user, | ||||||
|             Time.now.strftime("%d/%m/%Y %H:%M") |             Time.now.strftime("%d/%m/%Y %H:%M") | ||||||
|         ] |         ) | ||||||
|       end if Rails.env.preview? || Rails.env.production? |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     # raise the error if we are in development so that we can debug it |     # raise the error if we are in development so that we can debug it | ||||||
| @ -250,37 +218,6 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def generate_confirmation(user, url, expiry = nil) |  | ||||||
|     if user.is_a? String |  | ||||||
|       user = User.find_user(user) |  | ||||||
| 
 |  | ||||||
|       # if the user doesn't exist, just show them a 403 |  | ||||||
|       do_403 unless user.present? |  | ||||||
|     end |  | ||||||
|     expiry ||= (Time.now + 12.hours) |  | ||||||
|     session[:confirm_uid] = user.id |  | ||||||
| 
 |  | ||||||
|     unless user.locale.present? |  | ||||||
|       user.locale = I18n.locale |  | ||||||
|       user.save |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     # send the confirmation email and make sure it get sent as quickly as possible |  | ||||||
|     UserMailer.send_mail :email_confirmation do |  | ||||||
|       EmailConfirmation.create(user_id: user.id, expiry: expiry, url: url) |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def user_settings |  | ||||||
|     @conferences = Array.new |  | ||||||
|     if logged_in? |  | ||||||
|       Conference.all.each do | conference | |  | ||||||
|         @conferences << conference if conference.host? current_user |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|     @main_title = @page_title = 'page_titles.user_settings.Your_Account' |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def contact |   def contact | ||||||
|     @main_title = @page_title = 'page_titles.contact.Contact_Us' |     @main_title = @page_title = 'page_titles.contact.Contact_Us' | ||||||
|   end |   end | ||||||
| @ -290,32 +227,28 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|      |      | ||||||
|     if params[:reason] == 'conference' |     if params[:reason] == 'conference' | ||||||
| 
 | 
 | ||||||
|       @conference.organizations.each do | org | |       @conference.organizations.each do |org| | ||||||
|         org.users.each do | user | |         org.users.each do |user| | ||||||
|           email_list << user.named_email |           # email_list << user.named_email | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     UserMailer.send_mail(:contact) do  |     send_mail(:contact, | ||||||
|       [ |  | ||||||
|         current_user || params[:email], |         current_user || params[:email], | ||||||
|         params[:subject], |         params[:subject], | ||||||
|         params[:message], |         params[:message], | ||||||
|         email_list |         email_list | ||||||
|       ] |       ) | ||||||
|     end |  | ||||||
| 
 | 
 | ||||||
|     request_info = session['request_info'] || { 'request' => request, 'params' => params } |     request_info = session['request_info'] || { 'request' => request, 'params' => params } | ||||||
|     UserMailer.send_mail(:contact_details) do  |     send_mail(:contact_details, | ||||||
|       [ |  | ||||||
|         current_user || params[:email], |         current_user || params[:email], | ||||||
|         params[:subject], |         params[:subject], | ||||||
|         params[:message], |         params[:message], | ||||||
|         request_info['request'], |         request_info['request'], | ||||||
|         request_info['params'] |         request_info['params'] | ||||||
|       ] |       ) | ||||||
|     end |  | ||||||
| 
 | 
 | ||||||
|     redirect_to contact_sent_path |     redirect_to contact_sent_path | ||||||
|   end |   end | ||||||
| @ -326,31 +259,8 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     render 'contact' |     render 'contact' | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def update_user_settings |   def confirm_user | ||||||
|     return do_403 unless logged_in? |  | ||||||
|     current_user.firstname = params[:name] |  | ||||||
|     current_user.lastname = nil |  | ||||||
|     current_user.languages = (params[:languages] || { I18n.locale.to_s => true }).keys |  | ||||||
|     current_user.is_subscribed = params[:email_subscribe].present? |  | ||||||
|     current_user.save |  | ||||||
|     redirect_to settings_path |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def do_confirm(settings = nil) |  | ||||||
|     settings ||= {:template => 'login_confirmation_sent'} |  | ||||||
|     if params[:email] |     if params[:email] | ||||||
|       # see if we've already sent the confirmation email and are just confirming |  | ||||||
|       #  the email address |  | ||||||
|       if params[:token] |  | ||||||
|         user = User.find_user(params[:email]) |  | ||||||
|         confirm(user) |  | ||||||
|         return |  | ||||||
|       end |  | ||||||
|       user = User.get(params[:email]) |  | ||||||
| 
 |  | ||||||
|       # generate the confirmation, send the email and show the 403 |  | ||||||
|       referrer = params[:dest] || (request.present? && request.referer.present? ? request.referer.gsub(/^.*?\/\/.*?\//, '/') : settings_path) |  | ||||||
|       generate_confirmation(params[:email], referrer) |  | ||||||
|       template = 'login_confirmation_sent' |       template = 'login_confirmation_sent' | ||||||
|       @page_title ||= 'page_titles.403.Please_Check_Email' |       @page_title ||= 'page_titles.403.Please_Check_Email' | ||||||
| 
 | 
 | ||||||
| @ -365,75 +275,44 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|       @banner_image ||= 'grafitti.jpg' |       @banner_image ||= 'grafitti.jpg' | ||||||
|       @page_title ||= 'page_titles.403.Please_Login' |       @page_title ||= 'page_titles.403.Please_Login' | ||||||
| 
 | 
 | ||||||
|       do_403 (template || 'translator_login') |       do_403 template | ||||||
|     else |     else | ||||||
|       do_404 |       do_404 | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def confirm(uid = nil) |   def error_404(args = {}) | ||||||
|     @confirmation = EmailConfirmation.find_by_token(params[:token]) |     params[:_original_action] = params[:action] | ||||||
| 
 |     params[:action] = 'error-404' | ||||||
|     unless @confirmation.present? |     @page_title = 'page_titles.404.Page_Not_Found' | ||||||
|       @token_not_found = true |     @main_title = 'error.404.title' | ||||||
|       return do_404 |     super(args) | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     confirm_user = nil |  | ||||||
|     if uid.is_a?(User) |  | ||||||
|       confirm_user = uid |  | ||||||
|       uid = confirm_user.id |  | ||||||
|     end |  | ||||||
|     # check to see if we were given a user id to confirm against |  | ||||||
|     #  if we were, make sure it was the same one |  | ||||||
|     if (uid ||= (params[:uid] || session[:confirm_uid])) |  | ||||||
|       if uid == @confirmation.user_id |  | ||||||
|         session[:uid] = nil |  | ||||||
|         confirm_user ||= User.find uid |  | ||||||
|         auto_login(confirm_user) |  | ||||||
|       else |  | ||||||
|         @confirmation.delete |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       redirect_to (@confirmation.url || '/') |  | ||||||
|       return |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def do_403(template = nil) | ||||||
|     @banner_image = 'grafitti.jpg' |     @banner_image = 'grafitti.jpg' | ||||||
|     @page_title = 'page_titles.403.Please_Confirm_Email' |      | ||||||
|     do_403 'login_confirm' |     unless current_user | ||||||
|  |       @page_title = 'page_titles.403.Please_Login' | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|   def translator_request |     @template = template | ||||||
|     @banner_image = 'grafitti.jpg' |     @page_title ||= 'page_titles.403.Access_Denied' | ||||||
|     @page_title = 'page_titles.403.Translator_Request_Sent' |     @main_title ||= @page_title | ||||||
|     do_403 'translator_request_sent' |     params[:_original_action] = params[:action] | ||||||
|  |     params[:action] = 'error-403' | ||||||
|  | 
 | ||||||
|  |     super(template) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def user_logout |   def error_500(exception = nil) | ||||||
|     logout() |     @page_title = 'page_titles.500.An_Error_Occurred' | ||||||
|     redirect_to (params[:url] || '/') |     @main_title = 'error.500.title' | ||||||
|   end |     params[:_original_action] = params[:action] | ||||||
|  |     params[:action] = 'error-500' | ||||||
|  |     @exception = exception | ||||||
| 
 | 
 | ||||||
|   def find_user |     super(exception) | ||||||
|     user = User.find_user(params[:e]) |  | ||||||
| 
 |  | ||||||
|     if user.present? |  | ||||||
|       return render json: { |  | ||||||
|         name: user.name, |  | ||||||
|         email: user.email, |  | ||||||
|         exists: true |  | ||||||
|       } |  | ||||||
|     end |  | ||||||
|     render json: { |  | ||||||
|         name: I18n.t('user.not_found'), |  | ||||||
|         email: nil, |  | ||||||
|         exists: false |  | ||||||
|       } |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def login_user(u) |  | ||||||
|     auto_login(u) |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def on_translation_change(object, data, locale, translator_id) |   def on_translation_change(object, data, locale, translator_id) | ||||||
| @ -443,8 +322,8 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     if object.respond_to?(:get_translators) |     if object.respond_to?(:get_translators) | ||||||
|       object.get_translators(data, locale).each do |id, user| |       object.get_translators(data, locale).each do |id, user| | ||||||
|         if user.id != current_user.id && user.id != translator_id |         if user.id != current_user.id && user.id != translator_id | ||||||
|           UserMailer.send_mail mailer, user.locale do |           LinguaFranca.with_locale user.locale do | ||||||
|             { :args => [object, data, locale, user, translator] } |             send_mail(:send, mailer, object.id, data, locale, user.id, translator.id) | ||||||
|           end |           end | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| @ -457,8 +336,8 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     if object.respond_to?(:get_translators) |     if object.respond_to?(:get_translators) | ||||||
|       object.get_translators(data).each do |id, user| |       object.get_translators(data).each do |id, user| | ||||||
|         if user.id != current_user.id |         if user.id != current_user.id | ||||||
|           UserMailer.send_mail mailer, user.locale do |           LinguaFranca.with_locale user.locale do | ||||||
|             { :args => [object, data, user, current_user] } |             send_mail(:send, mailer, object.id, data, user.id, current_user.id) | ||||||
|           end |           end | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| @ -469,25 +348,34 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     # log it |     # log it | ||||||
|     logger.info "Missing translation found for: #{key}" |     logger.info "Missing translation found for: #{key}" | ||||||
| 
 | 
 | ||||||
|     # send and email if this is production |     # send an email if this is production | ||||||
|  |     if Rails.env.preview? || Rails.env.production? | ||||||
|       begin |       begin | ||||||
|       UserMailer.send_mail(:error_report) do  |         requestHash = { | ||||||
|         [ |           'remote_ip'    => arg.remote_ip, | ||||||
|  |           'uuid'         => arg.uuid, | ||||||
|  |           'original_url' => arg.original_url, | ||||||
|  |           'env'          => Hash.new | ||||||
|  |         } | ||||||
|  |         request.env.each do | key, value | | ||||||
|  |           requestHash['env'][key.to_s] = value.to_s | ||||||
|  |         end | ||||||
|  |         send_mail(:error_report, | ||||||
|             "A missing translation found in #{Rails.env}", |             "A missing translation found in #{Rails.env}", | ||||||
|             "<p>A translation for <code>#{key}</code> in <code>#{locale.to_s}</code> was found. The text that was rendered to the user was:</p><blockquote>#{str || 'nil'}</blockquote>", |             "<p>A translation for <code>#{key}</code> in <code>#{locale.to_s}</code> was found. The text that was rendered to the user was:</p><blockquote>#{str || 'nil'}</blockquote>", | ||||||
|             exception.to_s, |             exception.to_s, | ||||||
|             nil, |             nil, | ||||||
|           request, |             requestHash, | ||||||
|             params, |             params, | ||||||
|           current_user, |             current_user.id, | ||||||
|             Time.now.strftime("%d/%m/%Y %H:%M") |             Time.now.strftime("%d/%m/%Y %H:%M") | ||||||
|         ] |         ) | ||||||
|       end if Rails.env.preview? || Rails.env.production? |  | ||||||
|       rescue Exception => exception2 |       rescue Exception => exception2 | ||||||
|         logger.info exception2.to_s |         logger.info exception2.to_s | ||||||
|         logger.info exception2.backtrace.join("\n") |         logger.info exception2.backtrace.join("\n") | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |   end | ||||||
| 
 | 
 | ||||||
|   def set_success_message(message, is_ajax = false) |   def set_success_message(message, is_ajax = false) | ||||||
|     if is_ajax |     if is_ajax | ||||||
| @ -545,8 +433,8 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     @schedule = {} |     @schedule = {} | ||||||
|     day_1 = conference.start_date.wday |     day_1 = conference.start_date.wday | ||||||
| 
 | 
 | ||||||
|     @workshop_blocks.each_with_index do | info, block | |     @workshop_blocks.each_with_index do |info, block| | ||||||
|       info['days'].each do | block_day | |       info['days'].each do |block_day| | ||||||
|         day_diff = block_day.to_i - day_1 |         day_diff = block_day.to_i - day_1 | ||||||
|         day_diff += 7 if day_diff < 0 |         day_diff += 7 if day_diff < 0 | ||||||
|         day = (conference.start_date + day_diff.days).to_date |         day = (conference.start_date + day_diff.days).to_date | ||||||
| @ -559,9 +447,10 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     @workshops.each do | workshop | |     @workshops.each do |workshop| | ||||||
|       if workshop.block.present? |       if workshop.block.present? | ||||||
|         block = @workshop_blocks[workshop.block['block'].to_i] |         block = @workshop_blocks[workshop.block['block'].to_i] | ||||||
|  | 
 | ||||||
|         day_diff = workshop.block['day'].to_i - day_1 |         day_diff = workshop.block['day'].to_i - day_1 | ||||||
|         day_diff += 7 if day_diff < 0 |         day_diff += 7 if day_diff < 0 | ||||||
|         day = (conference.start_date + day_diff.days).to_date |         day = (conference.start_date + day_diff.days).to_date | ||||||
| @ -573,7 +462,7 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     @meals.each do | time, meal | |     @meals.each do |time, meal| | ||||||
|       day = meal['day'].to_date |       day = meal['day'].to_date | ||||||
|       time = meal['time'].to_f |       time = meal['time'].to_f | ||||||
|       @schedule[day] ||= {} |       @schedule[day] ||= {} | ||||||
| @ -584,7 +473,7 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|       @schedule[day][:times][time][:item] = meal |       @schedule[day][:times][time][:item] = meal | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     @events.each do | event | |     @events.each do |event| | ||||||
|       if event.present? && event.start_time.present? && event.end_time.present? |       if event.present? && event.start_time.present? && event.end_time.present? | ||||||
|         day = event.start_time.midnight.to_date |         day = event.start_time.midnight.to_date | ||||||
|         time = event.start_time.hour.to_f + (event.start_time.min / 60.0) |         time = event.start_time.hour.to_f + (event.start_time.min / 60.0) | ||||||
| @ -598,13 +487,13 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     @schedule = @schedule.sort.to_h |     @schedule = @schedule.sort.to_h | ||||||
|     @schedule.each do | day, data | |     @schedule.each do |day, data| | ||||||
|       @schedule[day][:times] = data[:times].sort.to_h |       @schedule[day][:times] = data[:times].sort.to_h | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     @schedule.each do | day, data | |     @schedule.each do |day, data| | ||||||
|       last_event = nil |       last_event = nil | ||||||
|       data[:times].each do | time, time_data | |       data[:times].each do |time, time_data| | ||||||
|         if last_event.present? |         if last_event.present? | ||||||
|           @schedule[day][:times][last_event][:next_event] = time |           @schedule[day][:times][last_event][:next_event] = time | ||||||
|         end |         end | ||||||
| @ -613,8 +502,8 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|       @schedule[day][:num_locations] = (data[:locations] || []).size |       @schedule[day][:num_locations] = (data[:locations] || []).size | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     @schedule.deep_dup.each do | day, data | |     @schedule.deep_dup.each do |day, data| | ||||||
|       data[:times].each do | time, time_data | |       data[:times].each do |time, time_data| | ||||||
|         if time_data[:next_event].present? || time_data[:length] > 0.5 |         if time_data[:next_event].present? || time_data[:length] > 0.5 | ||||||
|           span = 0.5 |           span = 0.5 | ||||||
|           length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length] |           length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length] | ||||||
| @ -631,7 +520,7 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
| 
 | 
 | ||||||
|     @schedule = @schedule.sort.to_h |     @schedule = @schedule.sort.to_h | ||||||
| 
 | 
 | ||||||
|     @schedule.each do | day, data | |     @schedule.each do |day, data| | ||||||
|       @schedule[day][:times] = data[:times].sort.to_h |       @schedule[day][:times] = data[:times].sort.to_h | ||||||
|       @schedule[day][:locations] ||= {} |       @schedule[day][:locations] ||= {} | ||||||
|        |        | ||||||
| @ -639,19 +528,19 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|       @schedule[day][:locations][0] = :add if do_analyze || @schedule[day][:locations].empty? |       @schedule[day][:locations][0] = :add if do_analyze || @schedule[day][:locations].empty? | ||||||
| 
 | 
 | ||||||
|       if do_analyze |       if do_analyze | ||||||
|         data[:times].each do | time, time_data | |         data[:times].each do |time, time_data| | ||||||
|           if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present? |           if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present? | ||||||
|             ids = time_data[:item][:workshops].keys |             ids = time_data[:item][:workshops].keys | ||||||
|             (0..ids.length).each do | i | |             (0..ids.length).each do |i| | ||||||
|               if time_data[:item][:workshops][ids[i]].present? |               if time_data[:item][:workshops][ids[i]].present? | ||||||
|                 workshop_i = time_data[:item][:workshops][ids[i]][:workshop] |                 workshop_i = time_data[:item][:workshops][ids[i]][:workshop] | ||||||
|                 conflicts = {} |                 conflicts = {} | ||||||
|                  |                  | ||||||
|                 (i+1..ids.length).each do | j | |                 (i+1..ids.length).each do |j| | ||||||
|                   workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil |                   workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil | ||||||
|                   if workshop_i.present? && workshop_j.present? |                   if workshop_i.present? && workshop_j.present? | ||||||
|                     workshop_i.active_facilitators.each do | facilitator_i | |                     workshop_i.active_facilitators.each do |facilitator_i| | ||||||
|                       workshop_j.active_facilitators.each do | facilitator_j | |                       workshop_j.active_facilitators.each do |facilitator_j| | ||||||
|                         if facilitator_i.id == facilitator_j.id |                         if facilitator_i.id == facilitator_j.id | ||||||
|                           @schedule[day][:times][time][:status] ||= {} |                           @schedule[day][:times][time][:status] ||= {} | ||||||
|                           @schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << { |                           @schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << { | ||||||
| @ -673,7 +562,7 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|                 needs = JSON.parse(workshop_i.needs || '[]').map &:to_sym |                 needs = JSON.parse(workshop_i.needs || '[]').map &:to_sym | ||||||
|                 amenities = JSON.parse(location.amenities || '[]').map &:to_sym |                 amenities = JSON.parse(location.amenities || '[]').map &:to_sym | ||||||
| 
 | 
 | ||||||
|                 needs.each do | need | |                 needs.each do |need| | ||||||
|                   @schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << { |                   @schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << { | ||||||
|                       name: :need_not_available, |                       name: :need_not_available, | ||||||
|                       need: need, |                       need: need, | ||||||
| @ -689,7 +578,7 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
| 
 | 
 | ||||||
|                 # collect common interested users |                 # collect common interested users | ||||||
|                 interests = [] |                 interests = [] | ||||||
|                 (0..ids.length).each do | j | |                 (0..ids.length).each do |j| | ||||||
|                   workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil |                   workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil | ||||||
|                   if workshop_i.present? && workshop_j.present? && workshop_i.id != workshop_j.id |                   if workshop_i.present? && workshop_j.present? && workshop_i.id != workshop_j.id | ||||||
|                     interests = interests | workshop_j.interested.map { | u | u.user_id } |                     interests = interests | workshop_j.interested.map { | u | u.user_id } | ||||||
| @ -744,4 +633,17 @@ class ApplicationController < LinguaFrancaApplicationController | |||||||
|     def html_value(value) |     def html_value(value) | ||||||
|       return value.present? && ActionView::Base.full_sanitizer.sanitize(value).strip.present? ? value : nil |       return value.present? && ActionView::Base.full_sanitizer.sanitize(value).strip.present? ? value : nil | ||||||
|     end |     end | ||||||
|  | 
 | ||||||
|  |     # send the confirmation email and make sure it get sent as quickly as possible | ||||||
|  |     def send_confirmation(confirmation) | ||||||
|  |       send_mail(:email_confirmation, confirmation.id) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def send_mail(*args) | ||||||
|  |       if Rails.env.preview? || Rails.env.production? | ||||||
|  |         UserMailer.delay(queue: Rails.env.to_s).send(*args) | ||||||
|  |       else | ||||||
|  |         UserMailer.send(*args).deliver_now | ||||||
|  |       end | ||||||
|  |     end | ||||||
| end | end | ||||||
|  | |||||||
| @ -151,7 +151,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|             }, |             }, | ||||||
|           data: [], |           data: [], | ||||||
|         } |         } | ||||||
|         @organizations.each do | org | |         @organizations.each do |org| | ||||||
|           if org.present? |           if org.present? | ||||||
|             address = org.locations.first |             address = org.locations.first | ||||||
|             @excel_data[:data] << { |             @excel_data[:data] << { | ||||||
| @ -167,7 +167,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|             } |             } | ||||||
|           end |           end | ||||||
|         end |         end | ||||||
|         return respond_to do | format | |         return respond_to do |format| | ||||||
|           format.xlsx { render xlsx: :stats, filename: "organizations" } |           format.xlsx { render xlsx: :stats, filename: "organizations" } | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| @ -183,7 +183,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
| 
 | 
 | ||||||
|       if request.format.xlsx? |       if request.format.xlsx? | ||||||
|         logger.info "Generating stats.xls" |         logger.info "Generating stats.xls" | ||||||
|         return respond_to do | format | |         return respond_to do |format| | ||||||
|           format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } |           format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| @ -194,7 +194,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|       @donation_count = 0 |       @donation_count = 0 | ||||||
|       @donations = 0 |       @donations = 0 | ||||||
|       @food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 } |       @food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 } | ||||||
|       @registrations.each do | r | |       @registrations.each do |r| | ||||||
|         if view_context.registration_status(r) == :registered |         if view_context.registration_status(r) == :registered | ||||||
|           @completed_registrations += 1 |           @completed_registrations += 1 | ||||||
| 
 | 
 | ||||||
| @ -223,7 +223,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
| 
 | 
 | ||||||
|       if request.format.xlsx? |       if request.format.xlsx? | ||||||
|         logger.info "Generating stats.xls" |         logger.info "Generating stats.xls" | ||||||
|         return respond_to do | format | |         return respond_to do |format| | ||||||
|           format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } |           format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" } | ||||||
|         end |         end | ||||||
|       else |       else | ||||||
| @ -233,7 +233,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         @donation_count = 0 |         @donation_count = 0 | ||||||
|         @donations = 0 |         @donations = 0 | ||||||
|         @food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 } |         @food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 } | ||||||
|         @registrations.each do | r | |         @registrations.each do |r| | ||||||
|           if view_context.registration_status(r) == :registered |           if view_context.registration_status(r) == :registered | ||||||
|             @completed_registrations += 1 |             @completed_registrations += 1 | ||||||
| 
 | 
 | ||||||
| @ -275,7 +275,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|             }, |             }, | ||||||
|           data: [], |           data: [], | ||||||
|         } |         } | ||||||
|         @hosts.each do | id, host | |         @hosts.each do |id, host| | ||||||
|           data = (host.housing_data || {}) |           data = (host.housing_data || {}) | ||||||
|           host_data = { |           host_data = { | ||||||
|             name: host.user.name, |             name: host.user.name, | ||||||
| @ -283,7 +283,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|             email: host.user.email, |             email: host.user.email, | ||||||
|             phone: data['phone'], |             phone: data['phone'], | ||||||
|             availability: data['availability'].present? && data['availability'][1].present? ? view_context.date_span(data['availability'][0].to_date, data['availability'][1].to_date) : '', |             availability: data['availability'].present? && data['availability'][1].present? ? view_context.date_span(data['availability'][0].to_date, data['availability'][1].to_date) : '', | ||||||
|             considerations: ((data['considerations'] || []).map { | consideration | view_context._"articles.conference_registration.host.considerations.#{consideration}" }).join(', '), |             considerations: ((data['considerations'] || []).map { |consideration| view_context._"articles.conference_registration.host.considerations.#{consideration}" }).join(', '), | ||||||
|             empty: '', |             empty: '', | ||||||
|             guests: { |             guests: { | ||||||
|               columns: [:name, :area, :email, :arrival_departure, :allergies, :food, :companion, :city], |               columns: [:name, :area, :email, :arrival_departure, :allergies, :food, :companion, :city], | ||||||
| @ -304,8 +304,8 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|             } |             } | ||||||
|           } |           } | ||||||
| 
 | 
 | ||||||
|           @housing_data[id][:guests].each do | space, space_data | |           @housing_data[id][:guests].each do |space, space_data| | ||||||
|             space_data.each do | guest_id, guest_data | |             space_data.each do |guest_id, guest_data| | ||||||
|               guest = guest_data[:guest] |               guest = guest_data[:guest] | ||||||
|               if guest.present? |               if guest.present? | ||||||
|                 companion = view_context.companion(guest) |                 companion = view_context.companion(guest) | ||||||
| @ -326,7 +326,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
| 
 | 
 | ||||||
|           @excel_data[:data] << host_data |           @excel_data[:data] << host_data | ||||||
|         end |         end | ||||||
|         return respond_to do | format | |         return respond_to do |format| | ||||||
|           format.xlsx { render xlsx: :stats, filename: "housing" } |           format.xlsx { render xlsx: :stats, filename: "housing" } | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| @ -458,7 +458,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|           }, |           }, | ||||||
|         data: [] |         data: [] | ||||||
|       } |       } | ||||||
|       User.AVAILABLE_LANGUAGES.each do | l | |       User.AVAILABLE_LANGUAGES.each do |l| | ||||||
|         @excel_data[:keys]["language_#{l}".to_sym] = "languages.#{l.to_s}"  |         @excel_data[:keys]["language_#{l}".to_sym] = "languages.#{l.to_s}"  | ||||||
|       end |       end | ||||||
|       ConferenceRegistration.all_spaces.each do |s| |       ConferenceRegistration.all_spaces.each do |s| | ||||||
| @ -468,7 +468,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|       ConferenceRegistration.all_considerations.each do |c| |       ConferenceRegistration.all_considerations.each do |c| | ||||||
|         @excel_data[:keys][c] = "articles.conference_registration.host.considerations.#{c.to_s}" |         @excel_data[:keys][c] = "articles.conference_registration.host.considerations.#{c.to_s}" | ||||||
|       end |       end | ||||||
|       @registrations.each do | r | |       @registrations.each do |r| | ||||||
|         user = r.user_id ? User.where(id: r.user_id).first : nil |         user = r.user_id ? User.where(id: r.user_id).first : nil | ||||||
|         if user.present? |         if user.present? | ||||||
|           companion = view_context.companion(r) |           companion = view_context.companion(r) | ||||||
| @ -528,7 +528,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|                 last_day: availability[1].present? ? view_context.date(availability[1].to_date, :span_same_year_date_1) : '' |                 last_day: availability[1].present? ? view_context.date(availability[1].to_date, :span_same_year_date_1) : '' | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|             User.AVAILABLE_LANGUAGES.each do | l | |             User.AVAILABLE_LANGUAGES.each do |l| | ||||||
|               can_speak = ((user.languages || []).include? l.to_s) |               can_speak = ((user.languages || []).include? l.to_s) | ||||||
|               data["language_#{l}".to_sym] = (can_speak ? (view_context._'articles.conference_registration.questions.bike.yes') : '') |               data["language_#{l}".to_sym] = (can_speak ? (view_context._'articles.conference_registration.questions.bike.yes') : '') | ||||||
|               data[:raw_values]["language_#{l}".to_sym] = can_speak |               data[:raw_values]["language_#{l}".to_sym] = can_speak | ||||||
| @ -573,12 +573,12 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|           first_day: view_context.conference_days_options_list(:before), |           first_day: view_context.conference_days_options_list(:before), | ||||||
|           last_day: view_context.conference_days_options_list(:after) |           last_day: view_context.conference_days_options_list(:after) | ||||||
|         } |         } | ||||||
|         User.AVAILABLE_LANGUAGES.each do | l | |         User.AVAILABLE_LANGUAGES.each do |l| | ||||||
|           @column_options["language_#{l}".to_sym] = [ |           @column_options["language_#{l}".to_sym] = [ | ||||||
|               [(view_context._"articles.conference_registration.questions.bike.yes"), true] |               [(view_context._"articles.conference_registration.questions.bike.yes"), true] | ||||||
|             ] |             ] | ||||||
|         end |         end | ||||||
|         ConferenceRegistration.all_considerations.each do | c | |         ConferenceRegistration.all_considerations.each do |c| | ||||||
|           @column_options[c.to_sym] = [ |           @column_options[c.to_sym] = [ | ||||||
|               [(view_context._"articles.conference_registration.questions.bike.yes"), true] |               [(view_context._"articles.conference_registration.questions.bike.yes"), true] | ||||||
|             ] |             ] | ||||||
| @ -589,7 +589,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|     def get_housing_data |     def get_housing_data | ||||||
|       @hosts = {} |       @hosts = {} | ||||||
|       @guests = {} |       @guests = {} | ||||||
|       ConferenceRegistration.where(:conference_id => @this_conference.id).each do | registration | |       ConferenceRegistration.where(:conference_id => @this_conference.id).each do |registration| | ||||||
|         if registration.can_provide_housing |         if registration.can_provide_housing | ||||||
|           @hosts[registration.id] = registration |           @hosts[registration.id] = registration | ||||||
|         elsif registration.housing.present? && registration.housing != 'none' |         elsif registration.housing.present? && registration.housing != 'none' | ||||||
| @ -603,11 +603,11 @@ class ConferenceAdministrationController < ApplicationController | |||||||
| 
 | 
 | ||||||
|       @housing_data = {} |       @housing_data = {} | ||||||
|       @hosts_affected_by_guests = {} |       @hosts_affected_by_guests = {} | ||||||
|       @hosts.each do | id, host | |       @hosts.each do |id, host| | ||||||
|         @hosts[id].housing_data ||= {} |         @hosts[id].housing_data ||= {} | ||||||
|         @housing_data[id] = { guests: {}, space: {} } |         @housing_data[id] = { guests: {}, space: {} } | ||||||
|         @hosts[id].housing_data['space'] ||= {} |         @hosts[id].housing_data['space'] ||= {} | ||||||
|         @hosts[id].housing_data['space'].each do | s, size | |         @hosts[id].housing_data['space'].each do |s, size| | ||||||
|           size = (size || 0).to_i |           size = (size || 0).to_i | ||||||
|           @housing_data[id][:guests][s.to_sym] = {} |           @housing_data[id][:guests][s.to_sym] = {} | ||||||
|           @housing_data[id][:space][s.to_sym] = size |           @housing_data[id][:space][s.to_sym] = size | ||||||
| @ -616,7 +616,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|        |        | ||||||
|       @guests_housed = 0 |       @guests_housed = 0 | ||||||
| 
 | 
 | ||||||
|       @guests.each do | guest_id, guest | |       @guests.each do |guest_id, guest| | ||||||
|         data = guest.housing_data || {} |         data = guest.housing_data || {} | ||||||
|         @hosts_affected_by_guests[guest_id] ||= [] |         @hosts_affected_by_guests[guest_id] ||= [] | ||||||
| 
 | 
 | ||||||
| @ -651,7 +651,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|             end |             end | ||||||
| 
 | 
 | ||||||
|             companions = data['companions'] || [] |             companions = data['companions'] || [] | ||||||
|             companions.each do | companion | |             companions.each do |companion| | ||||||
|               user = User.find_user(companion) |               user = User.find_user(companion) | ||||||
|               if user.present? |               if user.present? | ||||||
|                 reg = ConferenceRegistration.find_by( |                 reg = ConferenceRegistration.find_by( | ||||||
| @ -678,10 +678,10 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         end |         end | ||||||
|       end |       end | ||||||
|        |        | ||||||
|       @hosts.each do | id, host | |       @hosts.each do |id, host| | ||||||
|         host_data = host.housing_data |         host_data = host.housing_data | ||||||
| 
 | 
 | ||||||
|         @hosts[id].housing_data['space'].each do | space, size | |         @hosts[id].housing_data['space'].each do |space, size| | ||||||
|           # make sure the host isn't overbooked |           # make sure the host isn't overbooked | ||||||
|           space = space.to_sym |           space = space.to_sym | ||||||
|           space_available = (size || 0).to_i |           space_available = (size || 0).to_i | ||||||
| @ -755,7 +755,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         end |         end | ||||||
|       else |       else | ||||||
|         do_404 |         do_404 | ||||||
|         return nil |         return true | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       return false |       return false | ||||||
| @ -790,7 +790,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def admin_update_description |     def admin_update_description | ||||||
|       params[:info].each do | locale, value | |       params[:info].each do |locale, value| | ||||||
|         @this_conference.set_column_for_locale(:info, locale, html_value(value)) |         @this_conference.set_column_for_locale(:info, locale, html_value(value)) | ||||||
|       end |       end | ||||||
|       @this_conference.save |       @this_conference.save | ||||||
| @ -811,7 +811,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
| 
 | 
 | ||||||
|     def admin_update_payment_message |     def admin_update_payment_message | ||||||
|       begin |       begin | ||||||
|         params[:payment_message].each do | locale, value | |         params[:payment_message].each do |locale, value| | ||||||
|           @this_conference.set_column_for_locale(:payment_message, locale, html_value(value)) |           @this_conference.set_column_for_locale(:payment_message, locale, html_value(value)) | ||||||
|         end |         end | ||||||
|         @this_conference.save |         @this_conference.save | ||||||
| @ -883,7 +883,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         user_changed = false |         user_changed = false | ||||||
|         params.each do | key, value | |         params.each do |key, value| | ||||||
|           case key.to_sym |           case key.to_sym | ||||||
|           when :city |           when :city | ||||||
|             if value.present? |             if value.present? | ||||||
| @ -964,7 +964,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         do_404 |         do_404 | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       return nil |       return true | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def admin_update_housing |     def admin_update_housing | ||||||
| @ -1004,7 +1004,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         do_404 |         do_404 | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       return nil |       return true | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def admin_update_broadcast |     def admin_update_broadcast | ||||||
| @ -1014,36 +1014,32 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|       @send_to = params[:send_to] |       @send_to = params[:send_to] | ||||||
|       @register_template = :administration |       @register_template = :administration | ||||||
|       if params[:button] == 'send' |       if params[:button] == 'send' | ||||||
|         view_context.broadcast_to(@send_to).each do | user | |         view_context.broadcast_to(@send_to).each do |user| | ||||||
|           UserMailer.send_mail :broadcast do |           send_mail(:broadcast, | ||||||
|             [ |  | ||||||
|               "#{request.protocol}#{request.host_with_port}", |               "#{request.protocol}#{request.host_with_port}", | ||||||
|               @subject, |               @subject, | ||||||
|               @body, |               @body, | ||||||
|               user, |               user.id, | ||||||
|               @this_conference |               @this_conference.id | ||||||
|             ] |             ) | ||||||
|           end |  | ||||||
|         end |         end | ||||||
|         redirect_to administration_step_path(@this_conference.slug, :broadcast_sent) |         redirect_to administration_step_path(@this_conference.slug, :broadcast_sent) | ||||||
|         return nil |         return true | ||||||
|       elsif params[:button] == 'preview' |       elsif params[:button] == 'preview' | ||||||
|         @send_to_count = view_context.broadcast_to(@send_to).size |         @send_to_count = view_context.broadcast_to(@send_to).size | ||||||
|         @broadcast_step = :preview |         @broadcast_step = :preview | ||||||
|       elsif params[:button] == 'test' |       elsif params[:button] == 'test' | ||||||
|         @broadcast_step = :test |         @broadcast_step = :test | ||||||
|         UserMailer.send_mail :broadcast do |         send_mail(:broadcast, | ||||||
|           [ |  | ||||||
|             "#{request.protocol}#{request.host_with_port}", |             "#{request.protocol}#{request.host_with_port}", | ||||||
|             @subject, |             @subject, | ||||||
|             @body, |             @body, | ||||||
|             current_user, |             current_user.id, | ||||||
|             @this_conference |             @this_conference.id | ||||||
|           ] |           ) | ||||||
|         end |  | ||||||
|         @send_to_count = view_context.broadcast_to(@send_to).size |         @send_to_count = view_context.broadcast_to(@send_to).size | ||||||
|       end |       end | ||||||
|       return true |       return false | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def admin_update_locations |     def admin_update_locations | ||||||
| @ -1106,14 +1102,14 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       do_404 |       do_404 | ||||||
|       return nil |       return true | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def admin_update_events |     def admin_update_events | ||||||
|       case params[:button] |       case params[:button] | ||||||
|       when 'edit' |       when 'edit' | ||||||
|         redirect_to edit_event_path(@this_conference.slug, params[:id]) |         redirect_to edit_event_path(@this_conference.slug, params[:id]) | ||||||
|         return nil |         return true | ||||||
|       when 'save' |       when 'save' | ||||||
|         if params[:id].present? |         if params[:id].present? | ||||||
|           event = Event.find_by!(conference_id: @this_conference.id, id: params[:id]) |           event = Event.find_by!(conference_id: @this_conference.id, id: params[:id]) | ||||||
| @ -1127,11 +1123,11 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         event.end_time = event.start_time + params[:time_span].to_f.hours |         event.end_time = event.start_time + params[:time_span].to_f.hours | ||||||
| 
 | 
 | ||||||
|         # save translations |         # save translations | ||||||
|         (params[:info] || {}).each do | locale, value | |         (params[:info] || {}).each do |locale, value| | ||||||
|           event.set_column_for_locale(:title, locale, html_value(value), current_user.id) unless value = event._title(locale) |           event.set_column_for_locale(:title, locale, html_value(value), current_user.id) unless value = event._title(locale) | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         (params[:title] || {}).each do | locale, value | |         (params[:title] || {}).each do |locale, value| | ||||||
|           event.set_column_for_locale(:info, locale, value, current_user.id) unless value = event._info(locale) |           event.set_column_for_locale(:info, locale, value, current_user.id) unless value = event._info(locale) | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
| @ -1143,7 +1139,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       do_404 |       do_404 | ||||||
|       return nil |       return true | ||||||
|     end |     end | ||||||
|      |      | ||||||
|     def admin_update_workshop_times |     def admin_update_workshop_times | ||||||
| @ -1209,7 +1205,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
|         @location = params[:location] |         @location = params[:location] | ||||||
|         @event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil |         @event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil | ||||||
| 
 | 
 | ||||||
|         @workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do | workshop | |         @workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do |workshop| | ||||||
|           @ordered_workshops[workshop.id] = workshop |           @ordered_workshops[workshop.id] = workshop | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
| @ -1251,7 +1247,7 @@ class ConferenceAdministrationController < ApplicationController | |||||||
| 
 | 
 | ||||||
|     def get_empty(hash, keys) |     def get_empty(hash, keys) | ||||||
|       keys = [keys] unless keys.is_a?(Array) |       keys = [keys] unless keys.is_a?(Array) | ||||||
|       keys.each do | key | |       keys.each do |key| | ||||||
|         return key unless hash[key].present? |         return key unless hash[key].present? | ||||||
|       end |       end | ||||||
|       return nil |       return nil | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ require 'geocoder/calculations' | |||||||
| require 'rest_client' | require 'rest_client' | ||||||
| 
 | 
 | ||||||
| class ConferencesController < ApplicationController | class ConferencesController < ApplicationController | ||||||
|  | 
 | ||||||
|   def list |   def list | ||||||
|     @page_title = 'articles.conferences.headings.Conference_List' |     @page_title = 'articles.conferences.headings.Conference_List' | ||||||
|     @conference_list = { future: [], passed: [] } |     @conference_list = { future: [], passed: [] } | ||||||
| @ -17,7 +18,7 @@ class ConferencesController < ApplicationController | |||||||
|     set_conference |     set_conference | ||||||
|     do_403 unless @this_conference.is_public || @this_conference.host?(current_user) |     do_403 unless @this_conference.is_public || @this_conference.host?(current_user) | ||||||
| 
 | 
 | ||||||
|     @workshops = Workshop.where(:conference_id => @conference.id) |     @workshops = Workshop.where(:conference_id => @this_conference.id) | ||||||
| 
 | 
 | ||||||
|     if @this_conference.workshop_schedule_published |     if @this_conference.workshop_schedule_published | ||||||
|       @event_dlg = true |       @event_dlg = true | ||||||
| @ -59,7 +60,7 @@ class ConferencesController < ApplicationController | |||||||
|     steps = nil |     steps = nil | ||||||
|     return do_404 unless registration_steps.present? |     return do_404 unless registration_steps.present? | ||||||
| 
 | 
 | ||||||
|     @register_template = :administration if params[:admin_step].present? |     # @register_template = :administration if params[:admin_step].present? | ||||||
| 
 | 
 | ||||||
|     @errors = {} |     @errors = {} | ||||||
|     @warnings = [] |     @warnings = [] | ||||||
| @ -72,8 +73,19 @@ class ConferencesController < ApplicationController | |||||||
|         @register_template = steps[steps.find_index($1.to_sym) - 1] |         @register_template = steps[steps.find_index($1.to_sym) - 1] | ||||||
|       elsif form_step == :paypal_confirm |       elsif form_step == :paypal_confirm | ||||||
|         if @registration.present? && @registration.payment_confirmation_token == params[:confirmation_token] |         if @registration.present? && @registration.payment_confirmation_token == params[:confirmation_token] | ||||||
|  |           if Rails.env.test? | ||||||
|  |             @amount = params[:amount].to_f | ||||||
|  |             info = YAML.load(@registration.payment_info) | ||||||
|  |             info[:amount] = @amount | ||||||
|  |             @registration.payment_info = info.to_yaml | ||||||
|  |           else | ||||||
|             @amount = PayPal!.details(params[:token]).amount.total |             @amount = PayPal!.details(params[:token]).amount.total | ||||||
|           @registration.payment_info = {:payer_id => params[:PayerID], :token => params[:token], :amount => @amount}.to_yaml |             @registration.payment_info = { | ||||||
|  |                 payer_id: params[:PayerID], | ||||||
|  |                 token:    params[:token], | ||||||
|  |                 amount:   @amount | ||||||
|  |               }.to_yaml | ||||||
|  |           end | ||||||
| 
 | 
 | ||||||
|           @amount = (@amount * 100).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2') |           @amount = (@amount * 100).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2') | ||||||
| 
 | 
 | ||||||
| @ -86,7 +98,7 @@ class ConferencesController < ApplicationController | |||||||
|         info = YAML.load(@registration.payment_info) |         info = YAML.load(@registration.payment_info) | ||||||
|         @amount = nil |         @amount = nil | ||||||
|         status = nil |         status = nil | ||||||
|         if ENV['RAILS_ENV'] == 'test' |         if Rails.env.test? | ||||||
|           status = info[:status] |           status = info[:status] | ||||||
|           @amount = info[:amount] |           @amount = info[:amount] | ||||||
|         else |         else | ||||||
| @ -114,7 +126,7 @@ class ConferencesController < ApplicationController | |||||||
| 
 | 
 | ||||||
|         case form_step |         case form_step | ||||||
|         when :confirm_email |         when :confirm_email | ||||||
|           return do_confirm |           return confirm_email(params[:email], params[:token], register_path(@this_conference.slug)) | ||||||
|         when :contact_info |         when :contact_info | ||||||
|           if params[:name].present? && params[:name].gsub(/[\s\W]/, '').present? |           if params[:name].present? && params[:name].gsub(/[\s\W]/, '').present? | ||||||
|             current_user.firstname = params[:name].squish |             current_user.firstname = params[:name].squish | ||||||
| @ -188,18 +200,23 @@ class ConferencesController < ApplicationController | |||||||
|           amount = params[:amount].to_f |           amount = params[:amount].to_f | ||||||
| 
 | 
 | ||||||
|           if amount > 0 |           if amount > 0 | ||||||
|             @registration.payment_confirmation_token = ENV['RAILS_ENV'] == 'test' ? 'token' : Digest::SHA256.hexdigest(rand(Time.now.to_f * 1000000).to_i.to_s) |             # we can't really test paypal integration in our tests, so we'll fake it instead | ||||||
|             @registration.save |             if Rails.env.test? | ||||||
|              |               @registration.payment_confirmation_token = 'token' | ||||||
|             host = "#{request.protocol}#{request.host_with_port}" |               @registration.payment_info = {amount: amount}.to_yaml | ||||||
|             response = PayPal!.setup( |               @registration.save! | ||||||
|  |               redirect_to 'https://www.paypal.com' | ||||||
|  |             else | ||||||
|  |               @registration.payment_confirmation_token = Digest::SHA256.hexdigest(rand(Time.now.to_f * 1000000).to_i.to_s) | ||||||
|  |               @registration.save! | ||||||
|  |               pp = PayPal! | ||||||
|  |               response = pp.setup( | ||||||
|                 PayPalRequest(amount), |                 PayPalRequest(amount), | ||||||
|                 register_paypal_confirm_url(@this_conference.slug, :paypal_confirm, @registration.payment_confirmation_token), |                 register_paypal_confirm_url(@this_conference.slug, :paypal_confirm, @registration.payment_confirmation_token), | ||||||
|                 register_paypal_confirm_url(@this_conference.slug, :paypal_cancel, @registration.payment_confirmation_token), |                 register_paypal_confirm_url(@this_conference.slug, :paypal_cancel, @registration.payment_confirmation_token), | ||||||
|                 noshipping: true, |                 noshipping: true, | ||||||
|                 version: 204 |                 version: 204 | ||||||
|               ) |               ) | ||||||
|             if ENV['RAILS_ENV'] != 'test' |  | ||||||
|               redirect_to response.redirect_uri |               redirect_to response.redirect_uri | ||||||
|             end |             end | ||||||
|             return |             return | ||||||
| @ -219,7 +236,7 @@ class ConferencesController < ApplicationController | |||||||
|               # this step is only completed if a payment has been made |               # this step is only completed if a payment has been made | ||||||
|               if form_step != :payment || (@registration.registration_fees_paid || 0) > 0 |               if form_step != :payment || (@registration.registration_fees_paid || 0) > 0 | ||||||
|                 @registration.steps_completed ||= [] |                 @registration.steps_completed ||= [] | ||||||
|                 @registration.steps_completed << form_step |                 @registration.steps_completed << form_step.to_s | ||||||
|                 @registration.steps_completed.uniq! |                 @registration.steps_completed.uniq! | ||||||
|               end |               end | ||||||
|             end |             end | ||||||
| @ -334,9 +351,7 @@ class ConferencesController < ApplicationController | |||||||
|         steps -= [:questions] |         steps -= [:questions] | ||||||
|          |          | ||||||
|         # if this is a housing provider that is not attending the conference, remove these steps |         # if this is a housing provider that is not attending the conference, remove these steps | ||||||
|         if @registration.is_attending == 'n' |         steps -= [:payment, :workshops] if @registration.is_attending == 'n' | ||||||
|           steps -= [:payment, :workshops] |  | ||||||
|         end |  | ||||||
|       else |       else | ||||||
|         steps -= [:hosting] |         steps -= [:hosting] | ||||||
|       end |       end | ||||||
| @ -344,8 +359,6 @@ class ConferencesController < ApplicationController | |||||||
|       steps -= [:hosting, :questions] |       steps -= [:hosting, :questions] | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     steps += [:administration] if conference.host?(current_user) |  | ||||||
| 
 |  | ||||||
|     return steps |     return steps | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
| @ -394,11 +407,11 @@ class ConferencesController < ApplicationController | |||||||
| 
 | 
 | ||||||
|     def PayPalRequest(amount) |     def PayPalRequest(amount) | ||||||
|       Paypal::Payment::Request.new( |       Paypal::Payment::Request.new( | ||||||
|         :currency_code => 'USD',   # if nil, PayPal use USD as default |         currency_code: 'USD',                     # if nil, PayPal use USD as default | ||||||
|         :description   => 'Conference Registration',    # item description |         description:   'Conference Registration', # item description | ||||||
|         :quantity      => 1,      # item quantity |         quantity:      1,                         # item quantity | ||||||
|         :amount        => amount.to_f,   # item value |         amount:        amount.to_f,               # item value | ||||||
|         :custom_fields => { |         custom_fields: { | ||||||
|           CARTBORDERCOLOR: "00ADEF", |           CARTBORDERCOLOR: "00ADEF", | ||||||
|           LOGOIMG: "https://en.bikebike.org/assets/bblogo-paypal.png" |           LOGOIMG: "https://en.bikebike.org/assets/bblogo-paypal.png" | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -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 |  | ||||||
| @ -1,10 +1,10 @@ | |||||||
| 
 |  | ||||||
| class WorkshopsController < ApplicationController | class WorkshopsController < ApplicationController | ||||||
|  | 
 | ||||||
|   def workshops |   def workshops | ||||||
|     set_conference |     set_conference | ||||||
|     set_conference_registration! |     set_conference_registration! | ||||||
|     @workshops = Workshop.where(:conference_id => @this_conference.id) |     @workshops = Workshop.where(conference_id: @this_conference.id) | ||||||
|     @my_workshops = Workshop.joins(:workshop_facilitators).where(:workshop_facilitators => {:user_id => current_user.id}, :conference_id => @this_conference.id) |     @my_workshops = @workshops.select { |w| w.active_facilitator?(current_user) } | ||||||
|     render 'workshops/index' |     render 'workshops/index' | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
| @ -58,7 +58,7 @@ class WorkshopsController < ApplicationController | |||||||
| 
 | 
 | ||||||
|     @is_translating ||= false |     @is_translating ||= false | ||||||
|     if @is_translating |     if @is_translating | ||||||
|       return do_404 if @translation.to_s == @workshop.locale.to_s || !I18n.backend.enabled_locales.include?(@translation.to_s) |       return do_404 unless @translation.to_s != @workshop.locale.to_s && LinguaFranca.locale_enabled?(@translation.to_sym) | ||||||
|       return do_403 unless @workshop.can_translate?(current_user, @translation) |       return do_403 unless @workshop.can_translate?(current_user, @translation) | ||||||
| 
 | 
 | ||||||
|       @title = @workshop._title(@translation) |       @title = @workshop._title(@translation) | ||||||
|  | |||||||
							
								
								
									
										163
									
								
								app/helpers/admin_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								app/helpers/admin_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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
												Load Diff
											
										
									
								
							| @ -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 |  | ||||||
							
								
								
									
										729
									
								
								app/helpers/form_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										729
									
								
								app/helpers/form_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										100
									
								
								app/helpers/geocoder_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								app/helpers/geocoder_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										74
									
								
								app/helpers/i18n_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								app/helpers/i18n_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										88
									
								
								app/helpers/page_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/helpers/page_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
| @ -1,4 +1,16 @@ | |||||||
| module RegistrationHelper | module RegistrationHelper | ||||||
|  |   def registration_steps(conference = @conference) | ||||||
|  |     { | ||||||
|  |       pre: [:policy, :contact_info, :workshops], | ||||||
|  |       open: [:policy, :contact_info, :questions, :hosting, :payment, :workshops] | ||||||
|  |     }[@this_conference.registration_status] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def registration_status(registration) | ||||||
|  |     return :unregistered if registration.nil? | ||||||
|  |     return registration.status | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   def current_registration_steps(registration = @registration) |   def current_registration_steps(registration = @registration) | ||||||
|     return nil unless registration.present? |     return nil unless registration.present? | ||||||
| 
 | 
 | ||||||
| @ -6,7 +18,6 @@ module RegistrationHelper | |||||||
|     current_steps = [] |     current_steps = [] | ||||||
|     disable_steps = false |     disable_steps = false | ||||||
|     completed_steps = registration.steps_completed || [] |     completed_steps = registration.steps_completed || [] | ||||||
|     # registration_complete = registration_complete?(registration) |  | ||||||
| 
 | 
 | ||||||
|     if potential_provider(registration) |     if potential_provider(registration) | ||||||
|       steps -= [:questions] |       steps -= [:questions] | ||||||
| @ -14,24 +25,29 @@ module RegistrationHelper | |||||||
|       steps -= [:hosting] |       steps -= [:hosting] | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     steps.each do | step | |     steps -= [:payment] unless registration.conference.paypal_email_address.present? && registration.conference.paypal_username.present? && registration.conference.paypal_password.present? && registration.conference.paypal_signature.present? | ||||||
|  |     steps -= [:payment, :workshops] if registration.is_attending == 'n' | ||||||
|  |      | ||||||
|  |     steps.each do |step| | ||||||
|       # disable the step if we've already found an incomplete step |       # disable the step if we've already found an incomplete step | ||||||
|       enabled = !disable_steps# || registration_complete |       # enabled = !disable_steps# || registration_complete | ||||||
|       # record whether or not we've found an incomplete step |       # record whether or not we've found an incomplete step | ||||||
|       disable_steps ||= !completed_steps.include?(step.to_s) && ![:payment, :workshops].include?(step) |  | ||||||
| 
 | 
 | ||||||
|       current_steps << { |       current_steps << { | ||||||
|         name:    step, |         name:    step, | ||||||
|         enabled: enabled |         enabled: !disable_steps | ||||||
|       } |       } | ||||||
|  |       disable_steps ||= !completed_steps.include?(step.to_s)# && ![:payment, :workshops].include?(step) | ||||||
|     end |     end | ||||||
|  | 
 | ||||||
|     return current_steps |     return current_steps | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def current_step(registration = @registration) |   def current_step(registration = @registration) | ||||||
|     completed_steps = registration.steps_completed || [] |     completed_steps = registration.steps_completed || [] | ||||||
|     last_step = nil |     last_step = nil | ||||||
|     (current_registration_steps(registration) || []).each do | step | |     steps = current_registration_steps(registration) || [] | ||||||
|  |     steps.each do | step | | ||||||
|       # return the last enabled step if this one is disabled |       # return the last enabled step if this one is disabled | ||||||
|       return last_step unless step[:enabled] |       return last_step unless step[:enabled] | ||||||
| 
 | 
 | ||||||
| @ -43,6 +59,6 @@ module RegistrationHelper | |||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     # if all else fails, return the first step |     # if all else fails, return the first step | ||||||
|     return registration_steps(registration.conference).last |     return steps.last[:name] | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  | |||||||
							
								
								
									
										366
									
								
								app/helpers/table_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								app/helpers/table_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										288
									
								
								app/helpers/widgets_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								app/helpers/widgets_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @ -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,12 +1,12 @@ | |||||||
| require 'diffy' | require 'diffy' | ||||||
| 
 | 
 | ||||||
| class UserMailer < ActionMailer::Base | class UserMailer < ActionMailer::Base | ||||||
|   add_template_helper(ApplicationHelper) |  | ||||||
|   include LinguaFrancaHelper |   include LinguaFrancaHelper | ||||||
|  |   add_template_helper(ApplicationHelper) | ||||||
| 
 | 
 | ||||||
|   before_filter :set_host |   before_filter :set_host | ||||||
| 
 | 
 | ||||||
|   default from: "Bike!Bike! <noreply@bikebike.org>" |   default from: "Bike!Bike! <godwin@bikebike.org>" | ||||||
| 
 | 
 | ||||||
|   def email_confirmation(confirmation) |   def email_confirmation(confirmation) | ||||||
|     @confirmation = EmailConfirmation.find(confirmation) if confirmation.present? |     @confirmation = EmailConfirmation.find(confirmation) if confirmation.present? | ||||||
|  | |||||||
| @ -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,24 +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 |  | ||||||
|     [address, conference.city.city, conference.city.territory, conference.city.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 |  | ||||||
| @ -19,6 +19,6 @@ | |||||||
|         = checkbox :is_featured, @this_conference.id.present? && @this_conference.is_featured != false, 'forms.labels.generic.is_featured' |         = checkbox :is_featured, @this_conference.id.present? && @this_conference.is_featured != false, 'forms.labels.generic.is_featured' | ||||||
|       = columns(medium: 12) do |       = columns(medium: 12) do | ||||||
|         .actions.next-prev |         .actions.next-prev | ||||||
|           = button_tag :save, value: :save |           = button :save, value: :save | ||||||
|           - if @this_conference.id.present? |           - if @this_conference.id.present? | ||||||
|             = button_with_confirmation :delete, value: :delete, class: 'delete' |             = button_with_confirmation :delete, value: :delete, class: 'delete' | ||||||
|  | |||||||
| @ -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 | ||||||
|      |  | ||||||
| @ -9,6 +9,6 @@ | |||||||
|   = textfield :subject, nil, required: true, big: true |   = textfield :subject, nil, required: true, big: true | ||||||
|   = textarea :message, nil, required: true, plain: true |   = textarea :message, nil, required: true, plain: true | ||||||
|   .actions |   .actions | ||||||
|     = button_tag :send, value: :send |     = button :send, value: :send | ||||||
|     - if cancel_btn |     - if cancel_btn | ||||||
|       %button.close.subdued=_'forms.actions.generic.cancel' |       %button.close.subdued=_'forms.actions.generic.cancel' | ||||||
|  | |||||||
| @ -2,5 +2,5 @@ | |||||||
| = form_tag do_confirm_path, class: 'flex-form' do | = form_tag do_confirm_path, class: 'flex-form' do | ||||||
| 	= hidden_field_tag :dest, settings_path if dest.present? | 	= hidden_field_tag :dest, settings_path if dest.present? | ||||||
| 	= emailfield :email, nil, big: true | 	= emailfield :email, nil, big: true | ||||||
| 	= button_tag :continue, :value => :confirm_email | 	= button :continue, value: :confirm_email | ||||||
| 	= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: dest), class: [:button, :facebook] | 	= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: dest), class: [:button, :facebook] | ||||||
|  | |||||||
| @ -4,4 +4,4 @@ | |||||||
| 		= form_tag :do_confirm, :authenticity_token => false, class: 'flex-form' do | 		= form_tag :do_confirm, :authenticity_token => false, class: 'flex-form' do | ||||||
| 			= emailfield :email, nil, required: true, big: true | 			= emailfield :email, nil, required: true, big: true | ||||||
| 			= hidden_field_tag :token, @confirmation.token | 			= hidden_field_tag :token, @confirmation.token | ||||||
| 			= button_tag :login | 			= button :login | ||||||
|  | |||||||
| @ -6,4 +6,4 @@ | |||||||
| 	= columns(medium: 6) do | 	= columns(medium: 6) do | ||||||
| 		= form_tag :translator_request do | 		= form_tag :translator_request do | ||||||
| 			= text_area_tag :comment, nil, placeholder: true, required: true | 			= text_area_tag :comment, nil, placeholder: true, required: true | ||||||
| 			= button_tag :translator_request | 			= button :translator_request | ||||||
|  | |||||||
| @ -8,4 +8,4 @@ | |||||||
| 			.email-field.input-field | 			.email-field.input-field | ||||||
| 				= email_field_tag :email, nil, required: true | 				= email_field_tag :email, nil, required: true | ||||||
| 				= label_tag :email | 				= label_tag :email | ||||||
| 			= button_tag :login | 			= button :login | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| - content_for :og_image do | - content_for :og_image do | ||||||
|   = (@conference.present? ? @conference.poster.full.url : nil) || image_path('default_poster.jpg') |   - if @conference.present? | ||||||
| - if @conferences.present? |     = @conference.poster.full.url || image_path('default_poster.jpg') | ||||||
|  | - 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 ], sections: @conference.front_page_details | ||||||
|  | |||||||
| @ -6,4 +6,4 @@ | |||||||
| 			%p=_'articles.conference_registration.paragraphs.provide_email', :p			 | 			%p=_'articles.conference_registration.paragraphs.provide_email', :p			 | ||||||
| 			= form_tag oauth_save_path, class: 'flex-form' do | 			= form_tag oauth_save_path, class: 'flex-form' do | ||||||
| 				= emailfield :email, nil, required: true, big: true | 				= emailfield :email, nil, required: true, big: true | ||||||
| 				= button_tag :save, value: :save | 				= button :save, value: :save | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ | |||||||
|           = radiobuttons :preferred_language, I18n.backend.enabled_locales, current_user.locale || I18n.locale, 'languages', heading: 'articles.conference_registration.headings.preferred_language' |           = radiobuttons :preferred_language, I18n.backend.enabled_locales, current_user.locale || I18n.locale, 'languages', heading: 'articles.conference_registration.headings.preferred_language' | ||||||
|           = checkbox :email_subscribe, current_user.is_subscribed != false, 'articles.user_settings.email_subscribe', heading: 'articles.user_settings.headings.email_subscribe', help: 'articles.user_settings.paragraphs.email_subscribe', inline: true, right_help: true |           = checkbox :email_subscribe, current_user.is_subscribed != false, 'articles.user_settings.email_subscribe', heading: 'articles.user_settings.headings.email_subscribe', help: 'articles.user_settings.paragraphs.email_subscribe', inline: true, right_help: true | ||||||
|           .actions |           .actions | ||||||
|             = button_tag :save, value: :save |             = button :save, value: :save | ||||||
|       - else |       - else | ||||||
|         %h2=_'forms.actions.generic.login' |         %h2=_'forms.actions.generic.login' | ||||||
|         = render 'login' |         = render 'login' | ||||||
| @ -4,7 +4,7 @@ | |||||||
|   = admin_update_form do |   = admin_update_form do | ||||||
|     = checkboxes :organizations, (@organizations.map { |org| [org.name, org.id] }), @this_conference.organizations.map(&:id), 'test.test', vertical: true, big: true |     = checkboxes :organizations, (@organizations.map { |org| [org.name, org.id] }), @this_conference.organizations.map(&:id), 'test.test', vertical: true, big: true | ||||||
|     .actions.right.small |     .actions.right.small | ||||||
|       = button_tag :save, value: :set_organizations |       = button :save, value: :set_organizations | ||||||
|   - @this_conference.organizations.each do | organization | |   - @this_conference.organizations.each do | organization | | ||||||
|     %h4=organization.name |     %h4=organization.name | ||||||
|     - if organization.users.present? |     - if organization.users.present? | ||||||
| @ -16,11 +16,11 @@ | |||||||
|               = admin_update_form class: [:inline, :right] do |               = admin_update_form class: [:inline, :right] do | ||||||
|                 = hidden_field_tag :user_id, user.id |                 = hidden_field_tag :user_id, user.id | ||||||
|                 = hidden_field_tag :org_id, organization.id |                 = hidden_field_tag :org_id, organization.id | ||||||
|                 = button_tag :remove_member, value: :remove_org_member, class: [:small, :delete] |                 = button :remove_member, value: :remove_org_member, class: [:small, :delete] | ||||||
|     = admin_update_form class: 'mini-flex-form' do |     = admin_update_form class: 'mini-flex-form' do | ||||||
|       = hidden_field_tag :org_id, organization.id |       = hidden_field_tag :org_id, organization.id | ||||||
|       = emailfield :email, nil, required: true |       = emailfield :email, nil, required: true | ||||||
|       = button_tag :add_member, value: :add_org_member, class: :small |       = button :add_member, value: :add_org_member, class: :small | ||||||
| 
 | 
 | ||||||
|   %h3=_'articles.admin.info.headings.External_Administrators' |   %h3=_'articles.admin.info.headings.External_Administrators' | ||||||
|   %p=_'articles.admin.info.descriptions.External_Administrators' |   %p=_'articles.admin.info.descriptions.External_Administrators' | ||||||
| @ -32,10 +32,10 @@ | |||||||
|           - unless user.id == current_user.id && !current_user.administrator? |           - unless user.id == current_user.id && !current_user.administrator? | ||||||
|             = admin_update_form class: [:inline, :right] do |             = admin_update_form class: [:inline, :right] do | ||||||
|               = hidden_field_tag :user_id, user.id |               = hidden_field_tag :user_id, user.id | ||||||
|               = button_tag :remove_member, value: :remove_administrator, class: [:small, :delete] |               = button :remove_member, value: :remove_administrator, class: [:small, :delete] | ||||||
|   = admin_update_form class: 'mini-flex-form' do |   = admin_update_form class: 'mini-flex-form' do | ||||||
|     = userfield :email, nil, required: true |     = userfield :email, nil, required: true | ||||||
|     -#= emailfield :email, nil, required: true |     -#= emailfield :email, nil, required: true | ||||||
|     = button_tag :add_member, value: :add_administrator, class: :small |     = button :add_member, value: :add_administrator, class: :small | ||||||
| = columns(large: 2) do | = columns(large: 2) do | ||||||
|     |     | ||||||
|  | |||||||
| @ -20,8 +20,25 @@ | |||||||
|           = button_with_confirmation :send, (_'modals.admin.broadcast.confirm', vars: { number: "<strong>#{(@send_to_count || 0)}</strong>".html_safe }), value: :send, class: :delete if @broadcast_step == :test |           = button_with_confirmation :send, (_'modals.admin.broadcast.confirm', vars: { number: "<strong>#{(@send_to_count || 0)}</strong>".html_safe }), value: :send, class: :delete if @broadcast_step == :test | ||||||
|           = button_tag :edit, value: :edit |           = button_tag :edit, value: :edit | ||||||
|       - else |       - else | ||||||
|  | <<<<<<< HEAD | ||||||
|         = selectfield :send_to, nil, broadcast_options, full: true |         = selectfield :send_to, nil, broadcast_options, full: true | ||||||
|         = textfield :subject, @subject, required: true, big: true |         = textfield :subject, @subject, required: true, big: true | ||||||
|         = textarea :body, @body, lang: @this_conference.locale, edit_on: :focus |         = textarea :body, @body, lang: @this_conference.locale, edit_on: :focus | ||||||
|         .actions.right |         .actions.right | ||||||
|           = button_tag :preview, value: :preview |           = button_tag :preview, value: :preview | ||||||
|  | ======= | ||||||
|  |         .warning-info.make-room= _'articles.conference_registration.paragraphs.admin.broadcast.preview', vars: { send_to_count: "<strong>#{(@send_to_count || 0)}</strong>".html_safe } | ||||||
|  |       .test-preview | ||||||
|  |         %h3=@subject | ||||||
|  |         = richtext @body, 4 | ||||||
|  |       .actions.right | ||||||
|  |         = button :test, value: :test, class: :secondary if @broadcast_step == :preview | ||||||
|  |         = button_with_confirmation :send, (_'modals.admin.broadcast.confirm', vars: { number: "<strong>#{(@send_to_count || 0)}</strong>".html_safe }), value: :send, class: :delete if @broadcast_step == :test | ||||||
|  |         = button :edit, value: :edit | ||||||
|  |     - else | ||||||
|  |       = selectfield :send_to, nil, broadcast_options, full: true | ||||||
|  |       = textfield :subject, @subject, required: true, big: true | ||||||
|  |       = textarea :body, @body, lang: @this_conference.locale, edit_on: :focus | ||||||
|  |       .actions.right | ||||||
|  |         = button :preview, value: :preview | ||||||
|  | >>>>>>> d1db46f... 2017 refactor | ||||||
|  | |||||||
| @ -14,4 +14,4 @@ | |||||||
|   = row do |   = row do | ||||||
|     = columns(medium: 6, push: { medium: 1 }) do |     = columns(medium: 6, push: { medium: 1 }) do | ||||||
|       .actions |       .actions | ||||||
|         = button_tag :save, value: :save |         = button :save, value: :save | ||||||
|  | |||||||
| @ -2,4 +2,4 @@ | |||||||
|   = admin_update_form do |   = admin_update_form do | ||||||
|     = translate_textarea :info, @this_conference, label: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', edit_on: :focus |     = translate_textarea :info, @this_conference, label: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', edit_on: :focus | ||||||
|     .actions.right |     .actions.right | ||||||
|       = button_tag :save, value: :save |       = button :save, value: :save | ||||||
|  | |||||||
| @ -37,5 +37,5 @@ | |||||||
|         = length_select @length, small: true |         = length_select @length, small: true | ||||||
|       = translate_fields @event, { title: { type: :textfield, big: true, label: 'forms.labels.generic.title' }, info: { type: :textarea, label: 'forms.labels.generic.info', edit_on: :focus } } |       = translate_fields @event, { title: { type: :textfield, big: true, label: 'forms.labels.generic.title' }, info: { type: :textarea, label: 'forms.labels.generic.info', edit_on: :focus } } | ||||||
|       .actions.next-prev |       .actions.next-prev | ||||||
|         = button_tag :save, value: :save |         = button :save, value: :save | ||||||
|         = button_tag :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present? |         = button :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present? | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ | |||||||
|   = columns(medium: 12) do |   = columns(medium: 12) do | ||||||
|     .actions.next-prev |     .actions.next-prev | ||||||
|       - if @location.present? |       - if @location.present? | ||||||
|         = button_tag :save, value: :save |         = button :save, value: :save | ||||||
|         = button_tag :cancel, value: :cancel, class: :subdued, formnovalidate: true |         = button :cancel, value: :cancel, class: :subdued, formnovalidate: true | ||||||
|       - else |       - else | ||||||
|         = button_tag :create, value: :create |         = button :create, value: :create | ||||||
| @ -20,7 +20,7 @@ | |||||||
|             %td.form |             %td.form | ||||||
|               = admin_update_form do |               = admin_update_form do | ||||||
|                 = hidden_field_tag :meal, time |                 = hidden_field_tag :meal, time | ||||||
|                 = button_tag :delete, value: :delete, class: [:small, :delete] |                 = button :delete, value: :delete, class: [:small, :delete] | ||||||
|     = admin_update_form do |     = admin_update_form do | ||||||
|       %h3=_'articles.admin.locations.headings.add_meal', :t |       %h3=_'articles.admin.locations.headings.add_meal', :t | ||||||
|       .flex-inputs |       .flex-inputs | ||||||
| @ -30,6 +30,6 @@ | |||||||
|       = textfield :title, nil, required: true, big: true, help: 'articles.admin.locations.paragraphs.meal_title' |       = textfield :title, nil, required: true, big: true, help: 'articles.admin.locations.paragraphs.meal_title' | ||||||
|       = textfield :info, nil, help: 'articles.admin.locations.paragraphs.meal_info' |       = textfield :info, nil, help: 'articles.admin.locations.paragraphs.meal_info' | ||||||
|       .actions.next-prev |       .actions.next-prev | ||||||
|         = button_tag :add_meal, value: :add_meal |         = button :add_meal, value: :add_meal | ||||||
|   - else |   - else | ||||||
|     .warning-info=_'articles.admin.meals.no_locations_warning' |     .warning-info=_'articles.admin.meals.no_locations_warning' | ||||||
| @ -3,4 +3,4 @@ | |||||||
|     = translate_textarea :payment_message, @this_conference, default: 'articles.conference_registration.paragraphs.Payment', help: 'articles.conference_registration.paragraphs.admin.payment.message', edit_on: :focus, short: true |     = translate_textarea :payment_message, @this_conference, default: 'articles.conference_registration.paragraphs.Payment', help: 'articles.conference_registration.paragraphs.admin.payment.message', edit_on: :focus, short: true | ||||||
| 
 | 
 | ||||||
|     .actions.right |     .actions.right | ||||||
|       = button_tag :save, value: :save |       = button :save, value: :save | ||||||
|  | |||||||
| @ -5,4 +5,4 @@ | |||||||
|     = passwordfield :paypal_password, @this_conference.paypal_password |     = passwordfield :paypal_password, @this_conference.paypal_password | ||||||
|     = textfield :paypal_signature, @this_conference.paypal_signature |     = textfield :paypal_signature, @this_conference.paypal_signature | ||||||
|     .actions.right |     .actions.right | ||||||
|       = button_tag :save, value: :save |       = button :save, value: :save | ||||||
|  | |||||||
| @ -2,4 +2,4 @@ | |||||||
|   = form_tag administration_update_path(@this_conference.slug, :poster), multipart: true do |   = form_tag administration_update_path(@this_conference.slug, :poster), multipart: true do | ||||||
|     = filefield :poster, @this_conference.poster, required: true, label: false, preview: true |     = filefield :poster, @this_conference.poster, required: true, label: false, preview: true | ||||||
|     .actions.left |     .actions.left | ||||||
|       = button_tag :upload, value: :upload, id: 'upload-file' |       = button :upload, value: :upload, id: 'upload-file' | ||||||
|  | |||||||
| @ -7,4 +7,4 @@ | |||||||
|     = selectfield :distance_unit, @conditions['distance']['unit'], [:km, :mi], label: false, inline: true |     = selectfield :distance_unit, @conditions['distance']['unit'], [:km, :mi], label: false, inline: true | ||||||
|   = columns(medium: 12) do |   = columns(medium: 12) do | ||||||
|     .actions.right |     .actions.right | ||||||
|       = button_tag :save, value: :save_distance |       = button :save, value: :save_distance | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
|   = form_tag administration_update_path(@this_conference.slug, @admin_step) do |   = form_tag administration_update_path(@this_conference.slug, @admin_step) do | ||||||
|     - if @this_conference.workshop_schedule_published |     - if @this_conference.workshop_schedule_published | ||||||
|       %p=_'articles.conference_registration.paragraphs.admin.schedule.published', :p |       %p=_'articles.conference_registration.paragraphs.admin.schedule.published', :p | ||||||
|       .actions= button_tag :un_publish, value: :publish, class: :delete |       .actions= button :un_publish, value: :publish, class: :delete | ||||||
|     - else |     - else | ||||||
|       %p=_'articles.conference_registration.paragraphs.admin.schedule.un_published', :p |       %p=_'articles.conference_registration.paragraphs.admin.schedule.un_published', :p | ||||||
|       .actions= button_tag :publish, value: :publish |       .actions= button :publish, value: :publish | ||||||
|  | |||||||
| @ -1,9 +1,5 @@ | |||||||
| - if @warning_message | = columns(medium: 12) do | ||||||
|   = columns(medium: 12) do |  | ||||||
|     .warning-info=_"articles.admin.registrations.#{@warning_message}" |  | ||||||
| - else |  | ||||||
|   = columns(medium: 12) do |  | ||||||
|   = form_tag administration_update_path(@this_conference.slug, @admin_step) do |   = form_tag administration_update_path(@this_conference.slug, @admin_step) do | ||||||
|     = selectfield :registration_status, @this_conference.registration_status || 'closed', registration_status_options_list, inline_label: true |     = selectfield :registration_status, @this_conference.registration_status || 'closed', registration_status_options_list, inline_label: true | ||||||
|     .actions.left |     .actions.left | ||||||
|         = button_tag :save, value: :save |       = button :save, value: :save | ||||||
|  | |||||||
| @ -1,9 +1,5 @@ | |||||||
| - if @warning_message | - add_inline_script :registrations | ||||||
|   = columns(medium: 12) do | = columns(medium: 12) do | ||||||
|     .warning-info=_"articles.admin.registrations.#{@warning_message}" |  | ||||||
| - else |  | ||||||
|   - add_inline_script :registrations |  | ||||||
|   = columns(medium: 12) do |  | ||||||
|   .goes-fullscreen#registrations-table |   .goes-fullscreen#registrations-table | ||||||
|     .flex-column |     .flex-column | ||||||
|       = searchfield :search, nil, big: true, stretch: true |       = searchfield :search, nil, big: true, stretch: true | ||||||
| @ -18,4 +14,4 @@ | |||||||
|         = html_edit_table @excel_data, registrations_edit_table_options |         = html_edit_table @excel_data, registrations_edit_table_options | ||||||
|         .actions.right |         .actions.right | ||||||
|           %a.button.subdued{data: { 'closes-modal': 'new-registration' }}='Cancel' |           %a.button.subdued{data: { 'closes-modal': 'new-registration' }}='Cancel' | ||||||
|             = button_tag :save, value: :save, class: :modify |           = button :save, value: :save, class: :modify | ||||||
|  | |||||||
| @ -6,22 +6,22 @@ | |||||||
|     - else |     - else | ||||||
|       - add_inline_script :schedule if @entire_page |       - add_inline_script :schedule if @entire_page | ||||||
|       #schedule-preview |       #schedule-preview | ||||||
|         - @schedule.each do | day, data | |         - @schedule.each do |day, data| | ||||||
|           %h4=date(day, :weekday) |           %h4=date(day, :weekday).html_safe | ||||||
|           %table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]} |           %table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]} | ||||||
|             - if data[:locations].present? && data[:locations].values.first != :add |             - if data[:locations].present? && data[:locations].values.first != :add | ||||||
|               %thead |               %thead | ||||||
|                 %tr |                 %tr | ||||||
|                   %th.corner |                   %th.corner | ||||||
|                   - data[:locations].each do | id, location | |                   - data[:locations].each do |id, location| | ||||||
|                     %th=location.is_a?(Symbol) ? '' : location.title |                     %th=location.is_a?(Symbol) ? '' : _!(location.title) | ||||||
|             %tbody |             %tbody | ||||||
|               - data[:times].each do | time, time_data | |               - data[:times].each do |time, time_data| | ||||||
|                 %tr |                 %tr | ||||||
|                   - rowspan = (time_data[:length] * 2).to_i |                   - rowspan = (time_data[:length] * 2).to_i | ||||||
|                   %th=time(time) |                   %th=time(time).html_safe | ||||||
|                   - if time_data[:type] == :workshop |                   - if time_data[:type] == :workshop | ||||||
|                     - data[:locations].each do | id, location | |                     - data[:locations].each do |id, location| | ||||||
|                       - if time_data[:item][:workshops][id].present? |                       - if time_data[:item][:workshops][id].present? | ||||||
|                         - workshop = time_data[:item][:workshops][id][:workshop] |                         - workshop = time_data[:item][:workshops][id][:workshop] | ||||||
|                         - status = time_data[:item][:workshops][id][:status] |                         - status = time_data[:item][:workshops][id][:status] | ||||||
| @ -31,11 +31,11 @@ | |||||||
|                         - if workshop.present? && workshop.event_location.present? |                         - if workshop.present? && workshop.event_location.present? | ||||||
|                           = link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do |                           = link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do | ||||||
|                             .details |                             .details | ||||||
|                               .title=workshop.title |                               .title=_!workshop.title | ||||||
|                           %template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }} |                           %template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }} | ||||||
|                             %h1.title=workshop.title |                             %h1.title=_!workshop.title | ||||||
|                             %p.address |                             %p.address | ||||||
|                               = workshop.event_location.title + _!(': ') |                               = _!("#{workshop.event_location.title}:") | ||||||
|                               = location_link workshop.event_location |                               = location_link workshop.event_location | ||||||
|                             .workshop-description= richtext workshop.info, 1 |                             .workshop-description= richtext workshop.info, 1 | ||||||
|                           - if @can_edit |                           - if @can_edit | ||||||
| @ -46,10 +46,10 @@ | |||||||
|                                   %span.value="#{status[:conflict_score]} / #{workshop.interested.size}" |                                   %span.value="#{status[:conflict_score]} / #{workshop.interested.size}" | ||||||
|                                 - if status[:errors].present? |                                 - if status[:errors].present? | ||||||
|                                   .errors |                                   .errors | ||||||
|                                     - status[:errors].each do | error | |                                     - status[:errors].each do |error| | ||||||
|                                       .error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars] |                                       .error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars] | ||||||
|                               = hidden_field_tag :id, workshop.id |                               = hidden_field_tag :id, workshop.id | ||||||
|                               = button_tag :deschedule, value: :deschedule_workshop, class: [:delete, :small] |                               = button :deschedule, value: :deschedule_workshop, class: [:delete, :small] | ||||||
|                         - elsif @can_edit |                         - elsif @can_edit | ||||||
|                           .title="Block #{time_data[:item][:block] + 1}" |                           .title="Block #{time_data[:item][:block] + 1}" | ||||||
|                   - elsif time_data[:type] != :nil |                   - elsif time_data[:type] != :nil | ||||||
| @ -60,23 +60,23 @@ | |||||||
|                           - if location.present? |                           - if location.present? | ||||||
|                             %a.event-detail-link |                             %a.event-detail-link | ||||||
|                               .details |                               .details | ||||||
|                                 .title= time_data[:item]['title'] |                                 .title=_!(time_data[:item]['title']) | ||||||
|                                 .location= location.title |                                 .location=_!location.title | ||||||
|                             %template.event-details |                             %template.event-details | ||||||
|                               %h1.title=time_data[:item]['title'] |                               %h1.title=_!(time_data[:item]['title']) | ||||||
|                               %p.address |                               %p.address | ||||||
|                                 = location.title + _!(': ') |                                 = _!("#{location.title}:") | ||||||
|                                 = location_link location |                                 = location_link location | ||||||
|                         - when :event |                         - when :event | ||||||
|                           - if time_data[:item].event_location.present? |                           - if time_data[:item].event_location.present? | ||||||
|                             %a.event-detail-link |                             %a.event-detail-link | ||||||
|                               .details |                               .details | ||||||
|                                 .title= time_data[:item][:title] |                                 .title=_!(time_data[:item][:title]) if time_data[:item][:title] | ||||||
|                                 .location= time_data[:item].event_location.title |                                 .location=_!(time_data[:item].event_location.title) | ||||||
|                             %template.event-details |                             %template.event-details | ||||||
|                               %h1.title=time_data[:item][:title] |                               %h1.title=_!(time_data[:item][:title]) if time_data[:item][:title] | ||||||
|                               %p.address |                               %p.address | ||||||
|                                 = time_data[:item].event_location.title + _!(': ') |                                 = _!("#{time_data[:item].event_location.title}:") | ||||||
|                                 = location_link time_data[:item].event_location |                                 = location_link time_data[:item].event_location | ||||||
|                               = richtext time_data[:item][:info], 1 |                               = richtext time_data[:item][:info], 1 | ||||||
|       - if @entire_page |       - if @entire_page | ||||||
|  | |||||||
| @ -5,4 +5,4 @@ | |||||||
|       - for i in 1..5 do |       - for i in 1..5 do | ||||||
|         = numberfield "payment_amounts[#{i - 1}]", payment_amounts[i - 1], step: 0.01, min: 0.00, label: false |         = numberfield "payment_amounts[#{i - 1}]", payment_amounts[i - 1], step: 0.01, min: 0.00, label: false | ||||||
|     .actions.right |     .actions.right | ||||||
|       = button_tag :save, value: :save |       = button :save, value: :save | ||||||
|  | |||||||
| @ -15,5 +15,5 @@ | |||||||
|         .table-td=checkboxes :days, @block_days, info['days'].map(&:to_i), 'date.day_names', vertical: true, small: true |         .table-td=checkboxes :days, @block_days, info['days'].map(&:to_i), 'date.day_names', vertical: true, small: true | ||||||
|         .table-td.form |         .table-td.form | ||||||
|           = hidden_field_tag :workshop_block, block |           = hidden_field_tag :workshop_block, block | ||||||
|           = button_tag :delete_block, value: :delete_block, class: [:small, :delete] if block == @workshop_blocks.length - 2 |           = button :delete_block, value: :delete_block, class: [:small, :delete] if block == @workshop_blocks.length - 2 | ||||||
|           = button_tag (is_new ? :add_block : :update_block), value: :save_block, class: [:small, :add] |           = button (is_new ? :add_block : :update_block), value: :save_block, class: [:small, :add] | ||||||
|  | |||||||
| @ -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,7 +1,6 @@ | |||||||
| - links ||= [ :register ] | - links ||= [ :register ] | ||||||
| - sections ||= [ :info ] | - sections ||= [ :info ] | ||||||
| %article | = row(tag: :header) do | ||||||
|   = row(tag: :header) do |  | ||||||
|   = columns(class: 'conference-banner') do |   = columns(class: 'conference-banner') do | ||||||
|     .title |     .title | ||||||
|       %h1=_!conference.title |       %h1=_!conference.title | ||||||
| @ -11,8 +10,8 @@ | |||||||
|           .secondary |           .secondary | ||||||
|             = date_span(conference.start_date.to_date, conference.end_date.to_date) |             = date_span(conference.start_date.to_date, conference.end_date.to_date) | ||||||
|     - if conference.poster.present? |     - if conference.poster.present? | ||||||
|         %img{src: conference.poster.full.url || image_path('default_poster.jpg'), role: :presentation, alt: (_'images.conference.poster', vars: { conference_title: conference.title })} |       %img{src: conference.poster.full.url, role: :presentation, alt: (_'images.conference.poster', vars: { conference_title: conference.title })} | ||||||
| 
 | %article | ||||||
|   = row(class: 'conference-details') do |   = row(class: 'conference-details') do | ||||||
|     = columns(medium: 10, push: {medium: 1}) do |     = columns(medium: 10, push: {medium: 1}) do | ||||||
|       %h2=_!conference.title if conference.poster.present? |       %h2=_!conference.title if conference.poster.present? | ||||||
| @ -25,9 +24,9 @@ | |||||||
|         - else |         - else | ||||||
|           %h3=_'articles.workshops.headings.Proposed_Workshops' |           %h3=_'articles.workshops.headings.Proposed_Workshops' | ||||||
|           %p=_'articles.workshops.paragraphs.Proposed_Workshops' |           %p=_'articles.workshops.paragraphs.Proposed_Workshops' | ||||||
|           = render 'workshops/workshop_previews', :workshops => (conference.workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }) |           = render 'workshops/workshop_previews', workshops: (conference.workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }) | ||||||
|       .links |       .links | ||||||
|         = (link_to (_'forms.actions.generic.register'), register_path(conference.slug), class: [:button, :register]) if links.include?(:register) && conference.registration_status == :open |         = (link_to (_'forms.actions.generic.register'), register_path(conference.slug), class: [:button, :register]) if links.include?(:register) && conference.can_register? | ||||||
|         = (link_to (_'articles.workshops.info.read_more'), conference_path(conference.slug), class: :button) if links.include?(:read_more) |         = (link_to (_'articles.workshops.info.read_more'), conference_path(conference.slug), class: :button) if links.include?(:read_more) | ||||||
|         = (link_to (_'forms.actions.generic.administrate'), administrate_conference_path(conference.slug), class: [:button]) if links.include?(:administrate) |         = (link_to (_'forms.actions.generic.administrate'), administrate_conference_path(conference.slug), class: [:button]) if links.include?(:administrate) | ||||||
|         = (link_to (_'forms.actions.generic.edit'), edit_conference_path(conference.slug), class: [:button, :subdued]) if links.include?(:edit) |         = (link_to (_'forms.actions.generic.edit'), edit_conference_path(conference.slug), class: [:button, :subdued]) if links.include?(:edit) | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|     .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] | ||||||
|  | |||||||
| @ -5,5 +5,5 @@ | |||||||
|     = textfield :location, (params[:location] || location(@registration.city ||lookup_ip_location)), required: true, heading: 'articles.conference_registration.headings.location' |     = textfield :location, (params[:location] || location(@registration.city ||lookup_ip_location)), required: true, heading: 'articles.conference_registration.headings.location' | ||||||
|     = checkboxes :languages, User.AVAILABLE_LANGUAGES, (current_user.languages || [I18n.locale]).map(&:to_sym), 'languages', heading: 'articles.conference_registration.headings.languages' |     = checkboxes :languages, User.AVAILABLE_LANGUAGES, (current_user.languages || [I18n.locale]).map(&:to_sym), 'languages', heading: 'articles.conference_registration.headings.languages' | ||||||
|     .actions.next-prev |     .actions.next-prev | ||||||
|       = button_tag (params[:step] == :save ? :save : :next), value: :contact_info |       = button (params[:step] == :save ? :save : :next), value: :contact_info | ||||||
|       = button_tag :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true |       = button :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true | ||||||
|  | |||||||
| @ -48,4 +48,4 @@ | |||||||
| 	- if @conference.registration_open | 	- if @conference.registration_open | ||||||
| 		= form_tag register_path(@this_conference.slug) do | 		= form_tag register_path(@this_conference.slug) do | ||||||
| 			.actions | 			.actions | ||||||
| 				= button_tag :edit_registration, :value => :register | 				= button :edit_registration, :value => :register | ||||||
|  | |||||||
| @ -16,5 +16,5 @@ | |||||||
|       = checkboxes :considerations, ConferenceRegistration.all_considerations, @hosting_data['considerations'], 'articles.conference_registration.host.considerations', heading: 'articles.conference_registration.headings.host.considerations', help: 'articles.conference_registration.paragraphs.host.considerations', vertical: true |       = checkboxes :considerations, ConferenceRegistration.all_considerations, @hosting_data['considerations'], 'articles.conference_registration.host.considerations', heading: 'articles.conference_registration.headings.host.considerations', help: 'articles.conference_registration.paragraphs.host.considerations', vertical: true | ||||||
|       = textarea :notes, @hosting_data['notes'], help: 'articles.conference_registration.paragraphs.host.notes', edit_on: :focus |       = textarea :notes, @hosting_data['notes'], help: 'articles.conference_registration.paragraphs.host.notes', edit_on: :focus | ||||||
|     .actions.next-prev |     .actions.next-prev | ||||||
|       = button_tag (params[:step] == :save ? :save : :next), value: :hosting |       = button (params[:step] == :save ? :save : :next), value: :hosting | ||||||
|       = button_tag :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true |       = button :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true | ||||||
|  | |||||||
| @ -9,21 +9,22 @@ | |||||||
|   - else |   - else | ||||||
|     %p=@this_conference.payment_message || (_'articles.conference_registration.paragraphs.Payment', :p) |     %p=@this_conference.payment_message || (_'articles.conference_registration.paragraphs.Payment', :p) | ||||||
| = columns(large: 9, push: 1) do | = columns(large: 9, push: 1) do | ||||||
|  |   = show_errors :payment | ||||||
|   = form_tag register_path(@this_conference.slug), class: :payment do |   = form_tag register_path(@this_conference.slug), class: :payment do | ||||||
|     = hidden_field_tag :button, :payment |     = hidden_field_tag :button, :payment | ||||||
|     - payment_amounts = @this_conference.payment_amounts.present? ? @this_conference.payment_amounts : Conference.default_payment_amounts |     - payment_amounts = @this_conference.payment_amounts.present? ? @this_conference.payment_amounts : Conference.default_payment_amounts | ||||||
|     .graded-options{class: "option-count-#{payment_amounts.size}"} |     .graded-options{class: "option-count-#{payment_amounts.size}"} | ||||||
|       - payment_amounts.each_with_index do | amount, i | |       - payment_amounts.each_with_index do | amount, i | | ||||||
|         = button_tag :amount_25, name: :amount, value: amount.to_f.to_s, class: "option-#{i + 1}" do |         = button :amount_25, name: :amount, value: amount.to_f.to_s, class: "option-#{i + 1}" do | ||||||
|           =_! (number_to_currency amount, unit: '$') |           =_! (number_to_currency amount, unit: '$') | ||||||
|   = form_tag register_path(@this_conference.slug), class: ['custom-payment', :centered] do |   = form_tag register_path(@this_conference.slug), class: ['custom-payment', :centered] do | ||||||
|     %span.currency=_!'$' |     %span.currency=_!'$' # TODO: this needs to be localized | ||||||
|     = numberfield :amount, nil, required: true, step: 0.01, min: 0.00, label: false |     = numberfield :amount, nil, required: true, step: 0.01, min: 0.00, label: false | ||||||
|     = button_tag :custom_amount, value: :payment |     = button :custom_amount, value: :payment | ||||||
|     %p=_'articles.conference_registration.paragraphs.currency','(amounts are in $USD)' |     %p=_'articles.conference_registration.paragraphs.currency','(amounts are in $USD)' | ||||||
|   = form_tag register_path(@this_conference.slug), class: :payment do |   = form_tag register_path(@this_conference.slug), class: :payment do | ||||||
|     = hidden_field_tag :button, :payment |     = hidden_field_tag :button, :payment | ||||||
|     .actions.skip |     .actions.skip | ||||||
|       = button_tag :skip, name: :amount, value: '0.0' |       = button :skip, name: :amount, value: '0.0' | ||||||
| 
 | 
 | ||||||
| = columns(large: 2) | = columns(large: 2) | ||||||
|  | |||||||
| @ -2,4 +2,4 @@ | |||||||
|   %h3=_'articles.conference_registration.headings.payment_confirm' |   %h3=_'articles.conference_registration.headings.payment_confirm' | ||||||
|   %p=_'articles.conference_registration.paragraphs.payment_confirm', vars: {:amount => @amount} |   %p=_'articles.conference_registration.paragraphs.payment_confirm', vars: {:amount => @amount} | ||||||
|   = form_tag register_path(@this_conference.slug), :class => :payment do |   = form_tag register_path(@this_conference.slug), :class => :payment do | ||||||
| 		.actions= button_tag :confirm_amount, :value => :paypal_confirmed |     .actions= button :confirm_amount, :value => :paypal_confirmed | ||||||
|  | |||||||
| @ -5,4 +5,4 @@ | |||||||
| = columns(medium: 12) do | = columns(medium: 12) do | ||||||
|   %p=_'articles.conference_registration.paragraphs.Confirm_Agreement', :p |   %p=_'articles.conference_registration.paragraphs.Confirm_Agreement', :p | ||||||
|   = form_tag register_path(@this_conference.slug) do |   = form_tag register_path(@this_conference.slug) do | ||||||
| 		.actions= button_tag :agree, :value => :policy |     .actions= button :agree, value: :policy | ||||||
|  | |||||||
| @ -11,4 +11,4 @@ | |||||||
|     = emailfield :companion, (@registration.housing_data['companions'] || [nil]).first, heading: 'articles.conference_registration.headings.companion', help: 'articles.conference_registration.paragraphs.companion', big: true |     = emailfield :companion, (@registration.housing_data['companions'] || [nil]).first, heading: 'articles.conference_registration.headings.companion', help: 'articles.conference_registration.paragraphs.companion', big: true | ||||||
|     = textfield :allergies, @registration.allergies, heading: 'articles.conference_registration.headings.allergies' |     = textfield :allergies, @registration.allergies, heading: 'articles.conference_registration.headings.allergies' | ||||||
|     = textarea :other, @registration.other, plain: true, heading: 'articles.conference_registration.headings.other' |     = textarea :other, @registration.other, plain: true, heading: 'articles.conference_registration.headings.other' | ||||||
|     = button_tag :register, :value => :questions |     = button :register, value: :questions | ||||||
|  | |||||||
| @ -8,4 +8,4 @@ | |||||||
|       .email-field.input-field |       .email-field.input-field | ||||||
|         = email_field_tag :email, nil, required: true |         = email_field_tag :email, nil, required: true | ||||||
|         = label_tag :email |         = label_tag :email | ||||||
|       = button_tag :register, :value => :register |       = button :register, value: :register | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user