diff --git a/Gemfile b/Gemfile index 4615049..4e5c171 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,7 @@ gem 'oauth2', '~> 0.8.0' gem 'carrierwave' gem 'carrierwave-imageoptimizer' gem 'mini_magick' +gem 'carmen', :path => '../carmen/' if File.directory?('../carmen/') && RbConfig::CONFIG['target_os'] =~ /mswin|mingw|cygwin/i gem 'carmen-rails' gem 'nested_form' gem 'acts_as_list' @@ -30,6 +31,7 @@ gem 'wysiwyg-rails' gem 'rails-assets-cdn' gem 'sitemap_generator' gem 'activerecord-session_store' +gem 'paypal-express' group :development, :test do gem 'rspec' @@ -47,6 +49,7 @@ end group :test do gem 'capybara' + gem 'poltergeist' gem 'guard-rspec' gem 'factory_girl_rails' gem 'coveralls', require: false diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..8afcfcf --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,417 @@ +GIT + remote: git://github.com/josevalim/rails-footnotes.git + revision: 087914beabb56c2e9979f63eeb0183591065dde3 + specs: + rails-footnotes (4.0.2) + rails (>= 3.2) + +GIT + remote: git://github.com/svenfuchs/i18n-active_record.git + revision: 2d9a22b6a4e5d809782cdbfa65b14d9e47aa27fc + specs: + i18n-active_record (0.0.2) + i18n (>= 0.5.0) + +PATH + remote: ../carmen/ + specs: + carmen (1.0.1) + +GEM + remote: http://rubygems.org/ + specs: + actionmailer (4.0.0) + actionpack (= 4.0.0) + mail (~> 2.5.3) + actionpack (4.0.0) + activesupport (= 4.0.0) + builder (~> 3.1.0) + erubis (~> 2.7.0) + rack (~> 1.5.2) + rack-test (~> 0.6.2) + activemodel (4.0.0) + activesupport (= 4.0.0) + builder (~> 3.1.0) + activerecord (4.0.0) + activemodel (= 4.0.0) + activerecord-deprecated_finders (~> 1.0.2) + activesupport (= 4.0.0) + arel (~> 4.0.0) + activerecord-deprecated_finders (1.0.3) + activerecord-session_store (0.1.0) + actionpack (>= 4.0.0, < 5) + activerecord (>= 4.0.0, < 5) + railties (>= 4.0.0, < 5) + activesupport (4.0.0) + i18n (~> 0.6, >= 0.6.4) + minitest (~> 4.2) + multi_json (~> 1.3) + thread_safe (~> 0.1) + tzinfo (~> 0.3.37) + acts_as_list (0.4.0) + activerecord (>= 3.0) + addressable (2.3.6) + arel (4.0.2) + attr_required (1.0.0) + awesome_print (1.2.0) + bcrypt (3.1.7-x86-mingw32) + better_errors (1.1.0) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + builder (3.1.4) + callsite (0.0.11) + capistrano (2.15.5) + highline + net-scp (>= 1.0.0) + net-sftp (>= 2.0.0) + net-ssh (>= 2.0.14) + net-ssh-gateway (>= 1.1.0) + capybara (2.4.1) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + carmen-rails (1.0.1) + carmen (~> 1.0.0) + rails + carrierwave (0.10.0) + activemodel (>= 3.2.0) + activesupport (>= 3.2.0) + json (>= 1.7) + mime-types (>= 1.16) + carrierwave-imageoptimizer (1.2.1) + carrierwave (~> 0.8) + image_optimizer (~> 1.2) + celluloid (0.15.2) + timers (~> 1.1.0) + childprocess (0.5.3) + ffi (~> 1.0, >= 1.0.11) + chunky_png (1.3.1) + cliver (0.3.2) + coderay (1.1.0) + coffee-rails (4.0.1) + coffee-script (>= 2.2.0) + railties (>= 4.0.0, < 5.0) + coffee-script (2.3.0) + coffee-script-source + execjs + coffee-script-source (1.7.1) + compass (0.12.7) + chunky_png (~> 1.2) + fssm (>= 0.2.7) + sass (~> 3.2.19) + compass-rails (1.1.7) + compass (>= 0.12.2) + sprockets (<= 2.11.0) + coveralls (0.7.0) + multi_json (~> 1.3) + rest-client + simplecov (>= 0.7) + term-ansicolor + thor + crack (0.4.2) + safe_yaml (~> 1.0.0) + cucumber (1.3.15) + builder (>= 2.1.2) + diff-lcs (>= 1.1.3) + gherkin (~> 2.12) + multi_json (>= 1.7.5, < 2.0) + multi_test (>= 0.1.1) + cucumber-rails (1.4.1) + capybara (>= 1.1.2, < 3) + cucumber (>= 1.3.8, < 2) + mime-types (~> 1.16) + nokogiri (~> 1.5) + rails (>= 3, < 5) + database_cleaner (1.3.0) + debug_inspector (0.0.2) + diff-lcs (1.2.5) + docile (1.1.5) + erubis (2.7.0) + execjs (2.2.1) + factory_girl (4.4.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.4.1) + factory_girl (~> 4.4.0) + railties (>= 3.0.0) + faraday (0.9.0) + multipart-post (>= 1.2, < 3) + ffi (1.9.3-x86-mingw32) + font-awesome-rails (4.1.0.0) + railties (>= 3.2, < 5.0) + forgery (0.6.0) + formatador (0.2.5) + foundation-rails (5.3.1.0) + railties (>= 3.1.0) + sass (>= 3.2.0) + fssm (0.2.10) + geocoder (1.2.3) + gherkin (2.12.2-x86-mingw32) + multi_json (~> 1.3) + guard (2.6.1) + formatador (>= 0.2.4) + listen (~> 2.7) + lumberjack (~> 1.0) + pry (>= 0.9.12) + thor (>= 0.18.1) + guard-rspec (4.2.10) + guard (~> 2.1) + rspec (>= 2.14, < 4.0) + haml (4.0.5) + tilt + haml-rails (0.5.1) + actionpack (~> 4.0.0) + activesupport (~> 4.0.0) + haml (>= 3.1, < 5.0) + railties (~> 4.0.0) + highline (1.6.21) + hike (1.2.3) + httpauth (0.2.1) + i18n (0.6.11) + image_optimizer (1.2.1) + jquery-rails (3.1.1) + railties (>= 3.0, < 5.0) + thor (>= 0.14, < 2.0) + jquery-ui-rails (5.0.0) + railties (>= 3.2.16) + json (1.8.1) + jwt (0.1.13) + multi_json (>= 1.5) + launchy (2.4.2) + addressable (~> 2.3) + listen (2.7.9) + celluloid (>= 0.15.2) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + lumberjack (1.0.9) + mail (2.5.4) + mime-types (~> 1.16) + treetop (~> 1.4.8) + meta_request (0.3.3) + callsite (~> 0.0, >= 0.0.11) + rack-contrib (~> 1.1) + railties (>= 3.0.0, < 5.0.0) + method_source (0.8.2) + mime-types (1.25.1) + mini_magick (3.7.0) + subexec (~> 0.2.1) + mini_portile (0.6.0) + minitest (4.7.5) + multi_json (1.10.1) + multi_test (0.1.1) + multipart-post (2.0.0) + nested_form (0.3.2) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-sftp (2.1.2) + net-ssh (>= 2.6.5) + net-ssh (2.9.1) + net-ssh-gateway (1.2.0) + net-ssh (>= 2.6.5) + netrc (0.7.7) + nokogiri (1.6.2.1-x86-mingw32) + mini_portile (= 0.6.0) + oauth (0.4.7) + oauth2 (0.8.1) + faraday (~> 0.8) + httpauth (~> 0.1) + jwt (~> 0.1.4) + multi_json (~> 1.0) + rack (~> 1.2) + paper_trail (3.0.3) + activerecord (>= 3.0, < 5.0) + activesupport (>= 3.0, < 5.0) + paypal-express (0.5.5) + activesupport (>= 2.3) + attr_required (>= 0.0.5) + restclient_with_cert + pg (0.17.1-x86-mingw32) + poltergeist (1.5.1) + capybara (~> 2.1) + cliver (~> 0.3.1) + multi_json (~> 1.0) + websocket-driver (>= 0.2.0) + polyglot (0.3.5) + pry (0.10.0-x86-mingw32) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + win32console (~> 1.3) + rack (1.5.2) + rack-contrib (1.1.0) + rack (>= 0.9.1) + rack-test (0.6.2) + rack (>= 1.0) + rails (4.0.0) + actionmailer (= 4.0.0) + actionpack (= 4.0.0) + activerecord (= 4.0.0) + activesupport (= 4.0.0) + bundler (>= 1.3.0, < 2.0) + railties (= 4.0.0) + sprockets-rails (~> 2.0.0) + rails-assets-cdn (0.1.0) + rails + rails_12factor (0.0.2) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.2) + rails_stdout_logging (0.0.3) + railties (4.0.0) + actionpack (= 4.0.0) + activesupport (= 4.0.0) + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (10.3.2) + rb-fsevent (0.9.4) + rb-inotify (0.9.5) + ffi (>= 0.5.0) + rest-client (1.7.2-x86-mingw32) + ffi (~> 1.9) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + restclient_with_cert (0.0.8) + rest-client (>= 1.6) + rspec (3.0.0) + rspec-core (~> 3.0.0) + rspec-expectations (~> 3.0.0) + rspec-mocks (~> 3.0.0) + rspec-core (3.0.2) + rspec-support (~> 3.0.0) + rspec-expectations (3.0.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.0.0) + rspec-mocks (3.0.2) + rspec-support (~> 3.0.0) + rspec-rails (3.0.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.0.0) + rspec-expectations (~> 3.0.0) + rspec-mocks (~> 3.0.0) + rspec-support (~> 3.0.0) + rspec-support (3.0.2) + rubyzip (1.1.6) + rvm-capistrano (1.5.3) + capistrano (~> 2.15.4) + safe_yaml (1.0.3) + sass (3.2.19) + sass-rails (4.0.3) + railties (>= 4.0.0, < 5.0) + sass (~> 3.2.0) + sprockets (~> 2.8, <= 2.11.0) + sprockets-rails (~> 2.0) + selenium-webdriver (2.42.0) + childprocess (>= 0.5.0) + multi_json (~> 1.0) + rubyzip (~> 1.0) + websocket (~> 1.0.4) + simplecov (0.9.0) + docile (~> 1.1.0) + multi_json + simplecov-html (~> 0.8.0) + simplecov-html (0.8.0) + sitemap_generator (5.0.4) + builder + slop (3.6.0) + sorcery (0.8.6) + bcrypt (~> 3.1) + oauth (~> 0.4, >= 0.4.4) + oauth2 (>= 0.8.0, < 1.0.0) + sprockets (2.11.0) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + sprockets-rails (2.0.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + sprockets (~> 2.8) + subexec (0.2.3) + term-ansicolor (1.3.0) + tins (~> 1.0) + thor (0.19.1) + thread_safe (0.3.4) + tilt (1.4.1) + timers (1.1.0) + tins (1.3.0) + treetop (1.4.15) + polyglot + polyglot (>= 0.3.1) + tzinfo (0.3.40) + uglifier (2.5.3) + execjs (>= 0.3.0) + json (>= 1.8.0) + wdm (0.1.0) + webmock (1.18.0) + addressable (>= 2.3.6) + crack (>= 0.3.2) + websocket (1.0.7) + websocket-driver (0.3.4) + win32console (1.3.2-x86-mingw32) + wysiwyg-rails (1.1.6) + font-awesome-rails (= 4.1.0.0) + railties (>= 3.2, < 5.0) + xpath (2.0.0) + nokogiri (~> 1.3) + +PLATFORMS + x86-mingw32 + +DEPENDENCIES + activerecord-session_store + acts_as_list + awesome_print + better_errors + binding_of_caller + capistrano + capybara + carmen! + carmen-rails + carrierwave + carrierwave-imageoptimizer + coffee-rails (~> 4.0.0) + compass-rails (~> 1.1.3) + coveralls + cucumber-rails + database_cleaner + factory_girl_rails + font-awesome-rails + forgery + foundation-rails + geocoder + guard-rspec + haml + haml-rails + i18n-active_record! + jquery-rails + jquery-ui-rails + launchy + meta_request + mini_magick + nested_form + oauth2 (~> 0.8.0) + paper_trail + paypal-express + pg + poltergeist + rails (= 4.0.0) + rails-assets-cdn + rails-footnotes! + rails_12factor + rspec + rspec-rails + rvm-capistrano + sass-rails (~> 4.0.0) + selenium-webdriver + simplecov + sitemap_generator + sorcery (>= 0.8.1) + uglifier (>= 1.3.0) + wdm (>= 0.1.0) + webmock + wysiwyg-rails diff --git a/app/assets/images/Thumbs.db b/app/assets/images/Thumbs.db index a712181..bfe0cef 100644 Binary files a/app/assets/images/Thumbs.db and b/app/assets/images/Thumbs.db differ diff --git a/app/assets/images/bblogo.png b/app/assets/images/bblogo.png new file mode 100644 index 0000000..40f8a20 Binary files /dev/null and b/app/assets/images/bblogo.png differ diff --git a/app/assets/stylesheets/sass/_base.scss b/app/assets/stylesheets/sass/_base.scss index 9d28a30..117e8fd 100644 --- a/app/assets/stylesheets/sass/_base.scss +++ b/app/assets/stylesheets/sass/_base.scss @@ -1,4 +1,43 @@ table#translations { + table-layout: fixed; + padding: 0; + + .key, .pages { + width: 25%; + overflow: hidden; + + &:hover { + overflow: visible; + } + } + + .pages { + position: relative; + + ul { + font-size: 1em; + margin: 0; + list-style: none; + position: absolute; + left: 0; + top: 0; + } + + a { + display: block; + } + + &:hover { + ul { + z-index: 100; + } + + a { + background-color: $white; + } + } + } + td.value { position: relative; cursor: text; @@ -396,6 +435,48 @@ ul.tags, outline: none !important; } +#register-dlg { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: transparent; + visibility: hidden; + z-index: 100; + @include text-shadow(none); + @include transition(background-color 250ms ease-in-out 125ms, visibility 0 linear 250ms); + + form { + position: fixed; + min-width: 30em; + left: 110%; + right: 0; + max-width: 30em; + bottom: 0; + margin: auto; + top: 0; + background-color: $white; + height: 10em; + padding: 1em; + z-index: 101; + @include transform(skewX(-30deg)); + @include transition(all 250ms ease-in-out 0); + } + + &.open { + background-color: rgba($primary-color, 0.8); + visibility: visible; + @include transition(background-color 250ms ease-in-out); + + form { + left: 0; + @include transform(skewX(0)); + @include transition(all 250ms ease-in-out 125ms); + } + } +} + @include breakpoint(medium) { .organizations-index, .conferences-index { diff --git a/app/assets/stylesheets/sass/_layout.scss b/app/assets/stylesheets/sass/_layout.scss index c757dda..9e5de4a 100644 --- a/app/assets/stylesheets/sass/_layout.scss +++ b/app/assets/stylesheets/sass/_layout.scss @@ -85,7 +85,7 @@ body { float: left; .logo { - width: auto; + width: 100%; height: 90%;//2em; fill: $primary-color; position: absolute; @@ -236,6 +236,11 @@ body { text-align: center; } + form { + text-align: center; + padding: 2em 0; + } + @include breakpoint(medium) { + #content { padding-top: 0; @@ -333,23 +338,33 @@ main { //} } - .align-bottom > div { - margin-bottom: 3em; - } + //.align-bottom > div { + //margin-bottom: 3em; + //} .button { width: 75%; color: inherit; border-color: inherit; - background-color: rgba(darken($article-color, 0), 0.33); + background-color: rgba(darken($primary-color, 0), 0.33); padding: 0.75em 1em; + white-space: nowrap; @include text-shadow(none); &:hover { - background-color: $article-color; + background-color: $primary-color; color: $white; border-color: transparent; } + + &#register-now { + background-color: rgba(darken($warning-color, 0), 0.33); + margin-top: 0; + + &:hover { + background-color: $warning-color; + } + } } .organizations & { @@ -433,7 +448,8 @@ main { } } - .page-style-emphasize-banner & { + .page-style-emphasize-banner &, + .conferences & { figure img { box-shadow: 0 0 2em $black; } @@ -495,6 +511,10 @@ main { } } + .page-style-article.small-banner & { + min-height: 10em; + } + .page-style-list & { min-height: 10em; height: 30em; @@ -505,6 +525,10 @@ main { font-size: 6vw; } } + + .row .align-bottom.buttons { + height: 14em; + } } @include breakpoint(large) { @@ -526,6 +550,10 @@ main { border-bottom-left-radius: inherit; } + .button { + //margin-top: 20%; + } + .page-style-list & { height: 15em; height: 15vw; @@ -560,6 +588,10 @@ main { .row .align-bottom { height: auto; + + &.buttons { + height: 10em; + } } } } @@ -623,13 +655,15 @@ main { position: absolute; top: 100%; right: 0.25em; - margin: 0.25em 0.25em 0 0; + //margin: 0.25em 0.25em 0 0; + margin: -1em 0.25em 0 0; font-size: 0.8em; text-align: right; text-shadow: none; @include opacity(0.5); clear: right; z-index: 2; + mix-blend-mode: luminosity; > span { display: none; @@ -1043,3 +1077,7 @@ table { .clearfix { @include clearfix; } + +article.row { + margin-left: 0; +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1b508e4..b9ba8b9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,9 +14,32 @@ class ApplicationController < ActionController::Base before_filter :capture_page_info + @@test_host + @@test_location + def capture_page_info init_vars $page_info = {:path => request.env['PATH_INFO'], :controller => params['controller'], :action => params['action']} + ActionMailer::Base.default_url_options = {:host => "#{request.protocol}#{request.host_with_port}"} + lang = I18n.backend.set_locale (is_test? && @@test_host.present? ? @@test_host : request.host) + if lang.blank? + do_404 + elsif lang != true + @lang = lang + render 'pages/language_not_enabled', status: 404 + end + end + + def self.set_host(host) + @@test_host = host + end + + def self.set_location(location) + @@test_location = location#.nil? nil : Geocoder.search(location) + end + + def self.get_location() + @@test_location end def do_404 diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 94a80bd..92d453e 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -6,7 +6,6 @@ class ConferencesController < ApplicationController # GET /conferences def index - #puts params @conference_type = nil if params['conference_type'] @conference_type = ConferenceType.find_by!(:slug => params['conference_type']) @@ -111,50 +110,72 @@ class ConferencesController < ApplicationController end def register_submit - #set_conference next_step = nil if !session[:registration] session[:registration] = Hash.new session[:registration][:path] = Array.new end - case params['step'] + + case session[:registration_step] || params['step'] + when 'confirm' + if session[:registration][:is_participant] + registration = ConferenceRegistration.find(session[:registration][:registration_id]) + if registration.completed + complete_registration + next_step = 'thanks' + else + next_step = 'organizations' + end + else + complete_registration + next_step = 'thanks' + end when 'register' session[:registration][:email] = params[:email] - user = User.find_by(:email => params[:email]) - #registration = ConferenceRegistration.new(:conference_id => @conference.id, :is_attending => 'yes', :is_participant => params[:is_participant], :is_volunteer => params[:is_volunteer]) - session[:registration][:user] = Hash.new - session[:registration][:organizations] = Array.new - session[:registration][:user][:id] = user ? user.id : nil - if user - user.organizations.each { |org| session[:registration][:organizations] << org.id } + registration = ConferenceRegistration.find_by(:email => params[:email]) + if !registration.nil? + session[:registration] = YAML.load(registration.data) + session[:registration][:registration_id] = registration.id + next_step = (registration.completed.blank? && registration.is_participant.present? ? 'organizations' : 'thanks') + else + if !session[:registration][:user] || !session[:registration][:user][:firstname] + user = User.find_by(:email => params[:email]) + session[:registration][:user] = Hash.new + session[:registration][:user][:id] = user ? user.id : nil + session[:registration][:user][:firstname] = user ? (user.firstname || user.username) : nil + session[:registration][:user][:lastname] = user ? user.lastname : nil + session[:registration][:user][:username] = user ? user.username : nil + end + next_step = 'primary' end - session[:registration][:user][:firstname] = user ? (user.firstname || user.username) : nil - session[:registration][:user][:lastname] = user ? user.lastname : nil - session[:registration][:user][:username] = user ? user.username : nil - next_step = 'primary' when 'primary' - if !params[:firstname] || !params[:lastname] - error = _'registration.register.no_name_error','Oh, c\'mon, please tell us your name. We promise not to share it with anyone, we just don\'t want to get you mixed up with someone else.' + if params[:firstname].blank? || params[:lastname].blank? + error = _'registration.register.no_name_error',"Oh, c'mon, please tell us your name. We promise not to share it with anyone, we just don't want to get you mixed up with someone else." + end + if (params[:is_volunteer] || 'false').to_sym != :true && (params[:is_participant] || 'false').to_sym != :true + error ||= _'registration.register.no_role_error',"Please let us know if you're attending the conference or volunteering (or both)" end session[:registration][:user][:firstname] = params[:firstname] - session[:registration][:user][:firstname] = params[:lastname] - session[:registration][:is_volunteer] = params[:is_volunteer] - session[:registration][:is_participant] = params[:is_participant] + session[:registration][:user][:lastname] = params[:lastname] + session[:registration][:is_volunteer] = (params[:is_volunteer] || 'false').to_sym == :true + session[:registration][:is_participant] = (params[:is_participant] || 'false').to_sym == :true if !session[:registration][:user][:id] - session[:registration][:user][:username] = params[:username] || (params[:firstname] + ' ' + params[:lastname]) + session[:registration][:user][:username] = !error && params[:username].blank? ? (params[:firstname] + ' ' + params[:lastname]) : params[:username] end - if params[:is_volunteer] + if session[:registration][:is_volunteer] next_step = 'volunteer_questions' - elsif params[:is_participant] - next_step = 'organizations' - else - error = _'registration.register.no_role_error',"Please let us know if you're attending the conference or volunteering (or both)" + elsif session[:registration][:is_participant] + next_step = 'questions' end when 'organizations' - session[:registration][:organizations] = Array.new - if params[:org].length > 0 - params[:org].each { |org| session[:registration][:organizations] << org } + @registration = ConferenceRegistration.find(session[:registration][:registration_id]) + if (params[:org] && params[:org].length > 0) || params[:add_new_org] + session[:registration][:organizations] = Array.new + if params[:org] + params[:org].each { |org| session[:registration][:organizations] << (org.is_a?(Array) ? org.first : org).to_i } + end + update_registration_data if params[:add_new_org] session[:registration][:new_organization] ||= Array.new @@ -168,28 +189,43 @@ class ConferencesController < ApplicationController end next_step = 'new_organization' else - next_step = 'questions' + if session[:registration][:is_workshop_host] + next_step = 'new_workshop' + session[:registration][:workshop] ||= Array.new + session[:registration][:workshop][0] ||= Hash.new + session[:registration][:workshop_index] = 0 + else + complete_registration + next_step = 'thanks' + end + end + elsif params[:no_org] + if !session[:registration][:is_workshop_host] + next_step = 'new_workshop' + session[:registration][:workshop] ||= Array.new + session[:registration][:workshop][0] ||= Hash.new + session[:registration][:workshop_index] = 0 + else + complete_registration + next_step = 'thanks' end - elsif params[:add_new_org] - session[:registration][:questions] ||= Hash.new - next_step = 'questions' else error = _'registration.register.no_organization_error',"Please select an organization or enter a new one" end when 'new_organization' - if !params[:city] - message = _'register.new_organization.no_city_error','Please enter your organization\'s city' - end - if !params[:street] - message = _'register.new_organization.no_street_error','Please enter your organization\'s street address' + if params[:name].blank? + error = _'register.new_organization.no_name_error',"Please tell us your organization's name" end - if !params[:organization_email] - message = _'register.new_organization.no_email_error','Please tell us your organization\'s email address. We need it so that we can send out invitaions for upcoming conferences. No spam, we promise, and you\'ll be able to edit your preferences before we start ending out email.' + if params[:organization_email].blank? + error ||= _'register.new_organization.no_email_error',"Please tell us your organization's email address. We need it so that we can send out invitations for upcoming conferences. No spam, we promise, and you'll be able to edit your preferences before we start ending out email." elsif params[:organization_email].strip.casecmp(session[:registration][:email].strip) - message = _'register.new_organization.same_email_as_attendee_error','This email needs to be different than your own personal email, we need to keep in touch with your organization even if you\'re gone in years to come.' + error ||= _'register.new_organization.same_email_as_attendee_error',"This email needs to be different than your own personal email, we need to keep in touch with your organization even if you're gone in years to come." end - if !params[:name] - message = _'register.new_organization.no_name_error','Please tell us your organization\'s name' + if params[:street].blank? + error ||= _'register.new_organization.no_street_error','Please enter your organization\'s street address' + end + if params[:city].blank? + error ||= _'register.new_organization.no_city_error','Please enter your organization\'s city' end i = params[:new_org_index].to_i session[:registration][:new_organization][i][:country] = params[:organization_country] @@ -200,23 +236,26 @@ class ConferencesController < ApplicationController session[:registration][:new_organization][i][:email] = params[:organization_email] session[:registration][:new_organization][i][:name] = params[:organization_name] - if params[:organization_logo] - if session[:registration][:new_organization][i][:organization_logo] - FileUtils.rm session[:registration][:new_organization][i][:organization_logo] - end + if params[:logo] && !session[:registration][:new_organization][i][:saved] + begin + if session[:registration][:new_organization][i][:logo] + FileUtils.rm session[:registration][:new_organization][i][:logo] + end + rescue; end base_dir = File.join("public", "registration_data") FileUtils.mkdir_p(base_dir) unless File.directory?(base_dir) - hash_dir = rand(36**16).to_s(36) + hash_dir = rand_hash dir = File.join(base_dir, hash_dir) while File.directory?(dir) - hash_dir = rand(36**16).to_s(36) + hash_dir = rand_hash dir = File.join(base_dir, hash_dir) end FileUtils.mkdir_p(dir) - session[:registration][:new_organization][i][:organization_logo] = File.join("registration_data", hash_dir, params[:organization_logo].original_filename) - FileUtils.cp params[:organization_logo].tempfile.path, File.join("public", session[:registration][:new_organization][i][:organization_logo]) + session[:registration][:new_organization][i][:logo] = File.join("registration_data", hash_dir, params[:logo].original_filename) + FileUtils.cp params[:logo].tempfile.path, File.join("public", session[:registration][:new_organization][i][:logo]) end - if params[:add_another_org] && params[:add_another_org].to_sym == :on + update_registration_data + if params[:add_another_org] && params[:add_another_org].to_sym == :true next_step = 'new_organization' if params[:previous] session[:registration][:new_org_index] = [0, i - 1].max @@ -233,25 +272,37 @@ class ConferencesController < ApplicationController if session[:registration][:new_organization][i + 1] session[:registration][:new_organization] = session[:registration][:new_organization].first(i + 1) end - next_step = 'questions' + if session[:registration][:is_workshop_host] + next_step = 'new_workshop' + session[:registration][:workshop] ||= Array.new + session[:registration][:workshop][0] ||= Hash.new + session[:registration][:workshop_index] = 0 + else + complete_registration + next_step = 'thanks' + end end when 'questions' session[:registration][:questions] = params[:questions].deep_symbolize_keys - session[:registration][:is_workshop_host] = params[:is_workshop_host].to_i - if !params[:is_workshop_host].to_i.zero? - next_step = 'new_workshop' - session[:registration][:workshop] ||= Array.new - session[:registration][:workshop][0] ||= Hash.new - session[:registration][:workshop_index] = 0 - else - next_step = 'submit' + session[:registration][:is_workshop_host] = !params[:is_workshop_host].to_i.zero? + next_step = 'organizations' + if params[:submit] || params[:next] + if !session[:registration][:organizations] + user = User.find_by(:email => session[:registration][:email]) + session[:registration][:organizations] = Array.new + if user + user.organizations.each { |org| session[:registration][:organizations] << org.id } + end + end + create_registration end when 'volunteer_questions' session[:registration][:volunteer_questions] = params[:volunteer_questions].deep_symbolize_keys if session[:registration][:is_participant] - next_step = 'organizations' + next_step = 'questions' else - next_step = 'submit' + create_registration + next_step = 'thanks' end when 'new_workshop' i = params[:workshop_index].to_i @@ -259,15 +310,18 @@ class ConferencesController < ApplicationController session[:registration][:workshop][i][:info] = params[:workshop_info] session[:registration][:workshop][i][:stream] = params[:workshop_stream] session[:registration][:workshop][i][:presentation_style] = params[:workshop_presentation_style] + session[:registration][:workshop][i][:notes] = params[:workshop_notes] - if !params[:workshop_info] - error = _'registration.register.no_workshop_info_error','Please describe your workshop as best as you can to give other participants an idea of what to expect' + if params[:workshop_title].blank? + error = _'registration.register.no_workshop_title_error','Please give your workshop a title' end - if !params[:workshop_title] - error = _'registration.register.no_workshop_title_error','Please give your workshop a title' + if params[:workshop_info].blank? + error ||= _'registration.register.no_workshop_info_error','Please describe your workshop as best as you can to give other participants an idea of what to expect' end + update_registration_data + if params[:previous] session[:registration][:workshop_index] = [0, i - 1].max elsif params[:add_another_workshop] @@ -281,11 +335,14 @@ class ConferencesController < ApplicationController if session[:registration][:workshop][i + 1] session[:registration][:workshop] = session[:registration][:workshop].first(i + 1) end - next_step = 'submit' + next_step = 'thanks' + complete_registration + end + when 'thanks' + @registration = ConferenceRegistration.find(session[:registration][:registration_id]) + if @registration.is_confirmed.blank? + send_confirmation end - when 'submit' - UserMailer.conference_registration_email(@conference, session[:registration]).deliver - session.delete(:registration) next_step = 'thanks' when 'cancel' if params[:yes] @@ -294,45 +351,77 @@ class ConferencesController < ApplicationController else return {error: false, next_step: session[:registration][:path].pop} end + when 'already_registered' + send_confirmation + next_step = 'thanks' + when 'pay_now', 'payment-confirmed', 'payment-cancelled' + next_step = 'thanks' end - if params[:previous] - next_step = session[:registration][:path].pop - else - if !params[:cancel] && error - return {error: true, message: error, next_step: params['step']} - end - if session[:registration] && params['step'] - session[:registration][:path] << params['step'] - end + session.delete(:registration_step) + #if params[:previous] + # next_step = session[:registration][:path].pop + #else + if !params[:cancel] && error + return {error: true, message: error, next_step: params['step']} + end + if session[:registration] && session[:registration][:path] && params['step'] + session[:registration][:path] << params['step'] end + #end {error: false, next_step: params[:cancel] ? 'cancel' : next_step} end def register + is_post = request.post? || session[:registration_step] set_conference + + if !@conference.registration_open + do_404 + return + end + data = register_submit - @register_step = request.post? ? data[:next_step] : 'register' + @register_step = is_post ? data[:next_step] : 'register' @error_message = data[:error] ? data[:message] : nil template = (@register_step == 'register' ? '' : 'register_') + @register_step + if !File.exists?(Rails.root.join("app", "views", params[:controller], "_#{template}.html.haml")) do_404 return end + if session[:registration] session[:registration][@register_step.to_sym] ||= Hash.new end @actions = nil + @multipart = false case @register_step - when 'register' + when 'register', 'organizations', 'new_organization', 'new_workshop', 'volunteer_questions' @actions = :next - when 'primary', 'organizations', 'new_organization', 'new_workshop', 'volunteer_questions' - @actions = [:previous, :cancel, :next] + if @register_step == 'new_organization' + @multipart = true + end + when 'thanks' + @registration = ConferenceRegistration.find(session[:registration][:registration_id]) + if @registration.is_confirmed.blank? + @actions = :resend_confirmation_email + end + next_step = 'thanks' + #if @registration.complete && @registration.is_participant && @registration.payment_info.nil? + #` @actions = [:submit_payment] + when 'primary' + @actions = [:cancel, :next] when 'submit' - @actions = [:previous, :cancel, :submit] + @actions = [:cancel, :submit] when 'cancel' @actions = [:no, :yes] + when 'already_registered' + @registration = ConferenceRegistration.find_by(:email => session[:registration][:email]) + if !@registration.complete + @actions = :resend_confirmation_email + end when 'questions' - @actions = [:previous, :cancel, :next] + @actions = [:cancel, :submit] @housing_options = { 'I will fend for myself thanks' => 'none', 'I will need a real bed' => 'bed', @@ -342,13 +431,17 @@ class ConferencesController < ApplicationController session[:registration][:questions][:housing] ||= 'couch' @loaner_bike_options = { 'No' => 'no', - 'Yes' => 'medium', + 'Yes, an average size should do' => 'medium', 'Yes but a small one please' => 'small', 'Yes but a large one please' => 'large' } session[:registration][:questions][:loaner_bike] ||= 'medium' - session[:registration][:questions][:diet] ||= Hash.new + #session[:registration][:questions][:diet] ||= Hash.new end + + #puts ' ------yyyy----------------- ' + #puts @register_step + if request.xhr? @register_content = render_to_string :partial => template render :json => {status: 200, html: @register_content} @@ -358,6 +451,94 @@ class ConferencesController < ApplicationController end end + def register_confirm + set_conference + @conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token]) + if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && !@conference_registration.complete + @conference_registration.is_confirmed = true + @conference_registration.save! + session[:registration] = YAML.load(@conference_registration.data) + session[:registration][:path] = Array.new + session[:registration][:registration_id] = @conference_registration.id + session[:registration_step] = 'confirm' + redirect_to action: 'register' + else + do_404 + end + end + + def register_pay_registration + set_conference + @conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token]) + if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && @conference_registration.complete + if params[:payment_amount].nil? + session[:registration] = YAML.load(@conference_registration.data) + session[:registration][:registration_id] = @conference_registration.id + session[:registration][:path] = Array.new + session[:registration_step] = 'pay_now' + redirect_to action: 'register' + else + host = "#{request.protocol}#{request.host_with_port}" + begin + paypal_info = get_secure_info(:paypal) + request = Paypal::Express::Request.new( + :username => paypal_info[:username].strip!, + :password => paypal_info[:password].strip!, + :signature => paypal_info[:signature].strip! + ) + payment_request = Paypal::Payment::Request.new( + :currency_code => 'USD', # if nil, PayPal use USD as default + :description => 'Conference Registration', # item description + :quantity => 1, # item quantity + :amount => params[:payment_amount].to_f, # item value + :custom_fields => { + CARTBORDERCOLOR: "00ADEF", + LOGOIMG: "https://cdn.bikebike.org/assets/bblogo.png" + } + ) + response = request.setup( + payment_request, + host + (@conference.url + "/register/confirm-payment/#{@conference_registration.payment_confirmation_token}/").gsub(/\/\/+/, '/'), + host + (@conference.url + "/register/cancel-payment/#{@conference_registration.confirmation_token}/").gsub(/\/\/+/, '/') + ) + redirect_to response.redirect_uri + rescue Exception => e + ddd + end + end + else + do_404 + end + end + + def register_confirm_payment + set_conference + @conference_registration = ConferenceRegistration.find_by(payment_confirmation_token: params[:confirmation_token]) + if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && @conference_registration.complete && @conference_registration.payment_info.nil? + @conference_registration.payment_info = "#{params[:PayerID]}:#{params[:token]}" + @conference_registration.save! + session[:registration] = YAML.load(@conference_registration.data) + session[:registration][:registration_id] = @conference_registration.id + session[:registration][:path] = Array.new + session[:registration_step] = 'payment-confirmed' + redirect_to action: 'register' + else + do_404 + end + end + + def register_cancel_payment + set_conference + @conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token]) + if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && @conference_registration.complete && @conference_registration.payment_info.nil? + session[:registration] = YAML.load(@conference_registration.data) + session[:registration][:registration_id] = @conference_registration.id + session[:registration][:path] = Array.new + session[:registration_step] = 'payment-cancelled' + redirect_to action: 'register' + end + end + def register_step set_conference data = params @@ -456,4 +637,133 @@ class ConferencesController < ApplicationController end end end + + def update_registration_data + if session[:registration][:registration_id] + registration = ConferenceRegistration.find(session[:registration][:registration_id]) + registration.data = YAML.load(registration.data).merge(session[:registration]).to_yaml + registration.save! + end + end + + def complete_registration + if session[:registration][:registration_id] + registration = ConferenceRegistration.find(session[:registration][:registration_id]) + session[:registration] = YAML.load(registration.data) + registration.completed = true + if registration.is_confirmed + registration.complete = true + + user = User.find_by(:email => session[:registration][:email]) + if !user + user = User.new(:email => session[:registration][:email], :username => session[:registration][:user][:username], :role => 'user') + end + user.firstname = session[:registration][:user][:firstname] + user.lastname = session[:registration][:user][:lastname] + user.save! + + if session[:registration][:is_participant] + UserOrganizationRelationship.destroy_all(:user_id => user.id) + session[:registration][:organizations].each { |org_id| + found = false + org = Organization.find(org_id.is_a?(Array) ? org_id.first : org_id) + org.user_organization_relationships.each {|rel| found = found && rel.user_id == user.id} + if !found + org.user_organization_relationships << UserOrganizationRelationship.new(:user_id => user.id, :relationship => UserOrganizationRelationship::Administrator) + end + org.save! + } + + if session[:registration][:new_organization] + session[:registration][:new_organization].each { |new_org| + found = false + org = Organization.find_by(:email_address => new_org[:email]) + if org.nil? + org = Organization.new( + :name => new_org[:name], + :email_address => new_org[:email], + :info => new_org[:info] + ) + org.locations << Location.new(:country => new_org[:country], :territory => new_org[:territory], :city => new_org[:city], :street => new_org[:street]) + end + org.user_organization_relationships.each {|rel| found = found && rel.user_id == user.id} + if !found + org.user_organization_relationships << UserOrganizationRelationship.new(:user_id => user.id, :relationship => UserOrganizationRelationship::Administrator) + end + org.save! + org.avatar = "#{request.protocol}#{request.host_with_port}/#{new_org[:logo]}" + cover = get_panoramio_image(org.locations.first) + org.cover = cover[:image] + org.cover_attribution_id = cover[:attribution_id] + org.cover_attribution_user_id = cover[:attribution_user_id] + org.cover_attribution_name = cover[:attribution_user_name] + org.cover_attribution_src = cover[:attribution_src] + org.save! + } + end + + if session[:registration][:is_workshop_host] && session[:registration][:workshop] + session[:registration][:workshop].each { |new_workshop| + workshop = Workshop.new( + :conference_id => @conference.id, + :title => new_workshop[:title], + :info => new_workshop[:info], + :workshop_stream_id => WorkshopStream.find_by(:slug => new_workshop[:stream]).id, + :workshop_presentation_style => WorkshopPresentationStyle.find_by(:slug => new_workshop[:presentation_style]) + ) + workshop.workshop_facilitators << WorkshopFacilitator.new(:user_id => user.id) + workshop.save! + } + end + end + + send_confirmation_confirmation(registration, session[:registration]) + + session.delete(:registration) + session[:registration] = Hash.new + session[:registration][:registration_id] = registration.id + end + registration.save! + end + end + + def create_registration + if !session[:registration][:registration_id] + registration = ConferenceRegistration.new( + :conference_id => @conference.id, + :user_id => session[:registration][:user][:id], + :email => session[:registration][:email], + :is_attending => 'yes', + :is_participant => session[:registration][:is_participant], + :is_volunteer => session[:registration][:is_volunteer], + :is_confirmed => false, + :complete => false, + :completed => false, + :confirmation_token => rand_hash(32, :conference_registration, :confirmation_token), + :payment_confirmation_token => rand_hash(32, :conference_registration, :payment_confirmation_token), + :data => session[:registration].to_yaml + ) + registration.save! + session[:registration][:registration_id] = registration.id + send_confirmation(registration, session[:registration]) + end + end + + def send_confirmation(registration = nil, data = nil) + registration ||= ConferenceRegistration.find(session[:registration][:registration_id]) + data ||= YAML.load(registration.data) + UserMailer.conference_registration_email(@conference, data, registration).deliver + end + + def send_confirmation_confirmation(registration = nil, data = nil) + registration ||= ConferenceRegistration.find(session[:registration][:registration_id]) + data ||= YAML.load(registration.data) + UserMailer.conference_registration_confirmed_email(@conference, data, registration).deliver + end + + def send_payment_received(registration = nil, data = nil) + registration ||= ConferenceRegistration.find(session[:registration][:registration_id]) + data ||= YAML.load(registration.data) + UserMailer.conference_registration_payment_received(@conference, data, registration).deliver + end end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index f42f643..cfc3a04 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -22,8 +22,8 @@ class OrganizationsController < ApplicationController if !@organizations.has_key?(country.name) @organizations[country.name] = Hash.new end - territory = country.subregions.coded(location.territory) - territory_name = territory ? territory.name : 0 + territory = country.subregions? ? country.subregions.coded(location.territory) : nil + territory_name = territory.nil? ? 0 : territory.name if !@organizations[country.name].has_key?(territory_name) @organizations[country.name][territory_name] = Hash.new end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 204a1b1..66f0c5a 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,12 +1,12 @@ include ApplicationHelper class PagesController < ApplicationController - protect_from_forgery :except => :location_territories + protect_from_forgery :except => :location_territories #skip_before_filter :verify_authenticity_token, only: [:translate] def home - @conferences = Conference.all - @conference = Conference.find(:first, :order => "start_date DESC") + #@conferences = Conference.all + @conference = Conference.order("start_date DESC").first end def resources @@ -51,23 +51,23 @@ class PagesController < ApplicationController #render json: (Carmen:::RegionCollection.new(Carmen::Country.coded(params[:country])) || []).to_json territories = {} country = Carmen::Country.coded(params[:country]) - if country - country.subregions.each { |t| territories[t.code] = t.name } - end + if country + country.subregions.each { |t| territories[t.code] = t.name } + end render json: territories.to_json end def translations - if !current_user - raise ActiveRecord::PremissionDenied - end + #if !current_user + # raise ActiveRecord::PremissionDenied + #end @lang = params[:lang] - @translations = I18n.backend.get_translation_info + @translations = is_test? ? {} : I18n.backend.get_translation_info I18n.config.enforce_available_locales = false end def translation_list - if !current_user + if !current_user && is_production? raise ActiveRecord::PremissionDenied end total = 0 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 18954d1..78bd97e 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -9,6 +9,8 @@ module ApplicationHelper @@banner_image = nil @@has_content = true @@front_page = false + @@body_class = nil + @@test_location = nil def init_vars @@keyQueue = nil @@ -20,6 +22,7 @@ module ApplicationHelper @@banner_image = nil @@has_content = true @@front_page = false + @@body_class = nil end def this_is_the_front_page @@ -100,6 +103,11 @@ module ApplicationHelper 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(style) classes = ['page-style-' + style.to_s] #if @@no_banner @@ -114,6 +122,9 @@ module ApplicationHelper if @@banner_image classes << 'has-banner-image' end + if @@body_class + classes << @@body_class.join(' ') + end if params[:controller] classes << params[:controller] @@ -440,7 +451,9 @@ module ApplicationHelper end def lookup_ip_location - if request.remote_ip == '127.0.0.1' + if is_test? && ApplicationController::get_location.present? + Geocoder.search(ApplicationController::get_location).first + elsif request.remote_ip == '127.0.0.1' Geocoder.search(session['remote_ip'] || (session['remote_ip'] = open("http://checkip.dyndns.org").first.gsub(/^.*\s([\d\.]+).*$/s, '\1').gsub(/[^\.\d]/, ''))).first else request.location @@ -492,6 +505,10 @@ module ApplicationHelper Rails.env == 'production' end + def is_test? + Rails.env == 'test' + end + def subdomain request.env['SERVER_NAME'].gsub(/^(\w+)\..*$/, '\1') end @@ -505,6 +522,56 @@ module ApplicationHelper location.city + (territory ? ' ' + territory.name : '') + ', ' + Carmen::Country.coded(location.country).name end + def rand_hash(length = 16, model = nil, field = nil) + if field + hash = rand_hash(length) + while !model.to_s.to_s.singularize.classify.constantize.find_by(field => hash).nil? + hash = rand_hash(length) + end + end + rand(36**length).to_s(36) + end + + def get_panoramio_image(location) + if is_test? + params[:image] = 'panoramio.jpg' + params[:attribution_id] = 1234 + params[:attribution_user_id] = 5678 + params[:attribution_name] = 'Some Guy' + params[:attribution_src] = 'panoramio' + return params + end + + location = location.city + ', ' + (location.territory ? location.territory + ' ' : '') + location.country + $panoramios ||= Hash.new + $panoramios[location] ||= 0 + $panoramios[location] += 1 + result = Geocoder.search(location).first + if result + points = Geocoder::Calculations.bounding_box([result.latitude, result.longitude], 5, { :unit => :km }) + options = {:set => :public, :size => :original, :from => 0, :to => 20, :mapfilter => false, :miny => points[0], :minx => points[1], :maxy => points[2], :maxx => points[3]} + url = 'http://www.panoramio.com/map/get_panoramas.php?' + options.to_query + response = JSON.parse(open(url).read) + response['photos'].each { |img| + if img['width'].to_i > 980 + if Organization.find_by(:cover_attribution_id => img['photo_id'], :cover_attribution_src => 'panoramio').nil? && Conference.find_by(:cover_attribution_id => img['photo_id'], :cover_attribution_src => 'panoramio').nil? + params[:image] = img['photo_file_url'] + params[:attribution_id] = img['photo_id'] + params[:attribution_user_id] = img['owner_id'] + params[:attribution_name] = img['owner_name'] + params[:attribution_src] = 'panoramio' + return params + end + end + } + end + return nil + end + + def get_secure_info(name) + YAML.load(File.read(Rails.root.parent.join("secure/#{name.to_s}.yml")))[Rails.env].symbolize_keys + end + private def _form_field(type, name, value, options) if type == 'check_box' diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 47350e6..a9b0c0f 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -1,5 +1,5 @@ class UserMailer < ActionMailer::Base - default from: "noreply@bikebike.org" + default from: "Bike!Bike! " # Subject can be set in your I18n file at config/locales/en.yml # with the following lookup: @@ -23,9 +23,19 @@ class UserMailer < ActionMailer::Base mail to: "to@example.org" end - def conference_registration_email(conference, data) + def conference_registration_email(conference, data, conference_registration) + @data = data + @conference = conference + @url = "https://bikebike.org"#UserMailer.default_url_options[:host] + @confirmation_url = UserMailer.default_url_options[:host] + "/#{@conference.url}/register/confirm/#{conference_registration.confirmation_token}/".gsub(/\/\/+/, '/') + mail to: data[:email], subject: (_'register.email.registration.subject',"Please confirm your registration for #{conference.title}", vars: {:conference_title => conference.title}) + end + + def conference_registration_confirmed_email(conference, data, conference_registration) @data = data @conference = conference - mail to: data[:email], subject: 'Please confirm your registration for ' + conference.title + @url = "https://bikebike.org"#UserMailer.default_url_options[:host] + @confirmation_url = UserMailer.default_url_options[:host] + "/#{@conference.url}/register/pay-registration/#{conference_registration.confirmation_token}/".gsub(/\/\/+/, '/') + mail to: data[:email], subject: (_'register.email.registration_confirmed.subject',"Thanks for confirming your registration for #{conference.title}", vars: {:conference_title => conference.title}) end end diff --git a/app/models/conference.rb b/app/models/conference.rb index aa36b85..f86ec46 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -7,8 +7,8 @@ class Conference < ActiveRecord::Base has_many :conference_host_organizations, :dependent => :destroy has_many :organizations, :through => :conference_host_organizations - has_many :conference_registration_form_fields, :order => 'position ASC', :dependent => :destroy#, :class_name => '::ConferenceRegistrationFormField' - has_many :registration_form_fields, :through => :conference_registration_form_fields + #has_many :conference_registration_form_fields, :order => 'position ASC', :dependent => :destroy#, :class_name => '::ConferenceRegistrationFormField' + #has_many :registration_form_fields, :through => :conference_registration_form_fields has_many :workshops diff --git a/app/models/location.rb b/app/models/location.rb index 9e85760..990e902 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -1,9 +1,10 @@ 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 + 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? } diff --git a/app/models/organization.rb b/app/models/organization.rb index ae08189..24c2b5f 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -11,6 +11,7 @@ class Organization < ActiveRecord::Base 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 @@ -28,4 +29,33 @@ class Organization < ActiveRecord::Base slug 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 + + private + def make_slug + if !self.slug + self.slug = generate_slug(self.name, self.locations && self.locations[0]) + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index 10b80c4..83ec6de 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,8 +3,8 @@ class User < ActiveRecord::Base config.authentications_class = Authentication end - validates :password, presence: true, confirmation: true, length: { minimum: 3 }, unless: ("id?" || "password_confirmation?") - validates :password_confirmation, presence: true, unless: ("id?" || "password?") + #validates :password, presence: true, confirmation: true, length: { minimum: 3 }, unless: ("id?" || "password_confirmation?") + #validates :password_confirmation, presence: true, unless: ("id?" || "password?") validates :email, uniqueness: true diff --git a/app/models/workshop.rb b/app/models/workshop.rb index eaf8846..3e20500 100644 --- a/app/models/workshop.rb +++ b/app/models/workshop.rb @@ -1,7 +1,37 @@ class Workshop < ActiveRecord::Base belongs_to :conference + 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 + + 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 diff --git a/app/views/conferences/_header.html.haml b/app/views/conferences/_header.html.haml index 559323e..773373b 100644 --- a/app/views/conferences/_header.html.haml +++ b/app/views/conferences/_header.html.haml @@ -1,12 +1,16 @@ - banner_image @conference.cover_url, id: @conference.cover_attribution_id, name: @conference.cover_attribution_name, user_id: @conference.cover_attribution_user_id, src: @conference.cover_attribution_src +- small_banner = (params['controller'] == 'conferences' && params['action'] != 'show') +- if small_banner + - body_class('small-banner') - page_style (params['controller'] == 'conferences' ? 'article' : 'emphasize-banner') - content_for :banner do .row - .columns.small-12.banner - %figure - %img{src: @conference.poster.full.url} - .columns.medium-8.align-bottom + - if !small_banner + .columns.small-12.banner + %figure + %img{src: @conference.poster.full.url} + .columns.medium-7.align-bottom - title = @conference.conference_type.slug == 'bikebike' ? 'Bike!Bike! '+@conference.start_date.year.to_s : @conference.title %div %h1 @@ -33,11 +37,31 @@ = info.html_safe - else %p= ActionView::Base.full_sanitizer.sanitize(@conference.info).gsub(/^(.{300,350}\.)(.*)$/m, '\1...') - .columns.medium-4.centered.align-bottom + .columns.medium-5.centered.align-bottom.buttons %div - - if @conference.registration_open - %a.button.arrow-r{href: @conference.url(:register)} - =_'conference.Register_Now' - if params['controller'] != 'conferences' %a.button.more{href: @conference.url} =_'conference.More_Info' + - if @conference.registration_open && !small_banner + %a.button#register-now{href: @conference.url(:register)} + =_'conference.Register_Now' + #register-dlg + = form_tag (@conference.url + '/register/').gsub(/\/\/+/, '/'), :method => :post do + = hidden_field_tag :step, 'register' + = email_field_tag :email + = form_actions :register +- if !small_banner && @conference.registration_open + - content_for :dom_ready do + :plain + $('#register-now').click(function(e) { + e.preventDefault(); + if ($('#register-dlg').hasClass('open')) { + $('#register-dlg form').submit(); + } + $('#register-dlg').toggleClass('open'); + }); + $('#register-dlg').click(function(e) { + if ($(e.target).attr('id') == 'register-dlg') { + $('#register-dlg').toggleClass('open'); + } + }); \ No newline at end of file diff --git a/app/views/conferences/_register.html.haml b/app/views/conferences/_register.html.haml index 478bac0..0fe6984 100644 --- a/app/views/conferences/_register.html.haml +++ b/app/views/conferences/_register.html.haml @@ -1 +1,2 @@ = email_field_tag :email, session[:registration][:email] + diff --git a/app/views/conferences/_register_already_registered.html.haml b/app/views/conferences/_register_already_registered.html.haml new file mode 100644 index 0000000..c81fade --- /dev/null +++ b/app/views/conferences/_register_already_registered.html.haml @@ -0,0 +1,14 @@ +- if @registration.complete + %h3=_'registration.already_registered.complete.title','You Have Already Registered' + .columns.medium-10.medium-offset-1.end + %p.help + =_'registration.already_registered.complete.help','There\'s nothing more to do, you have already registered so we\'ll see you in ' + = @conference.organizations.first.locations.first.city +- elsif @registration.is_confirmed + %h3=_'registration.already_registered.confirmed.title','You\'re Already Registered but we are missing some Information' + .columns.medium-10.medium-offset-1.end + %p.help=_'registration.already_registered.complete.help','You\'re already set to go but we had a few more questions for you. If you need us to resed your confirmation, just click the button below.' +- else + %h3=_'registration.already_registered.not_confirmed.title','We\'re awaiting your Confirmation' + .columns.medium-10.medium-offset-1.end + %p.help=_'registration.already_registered.not_confirmed.help','You already sent us the information we need but we need you to confirm. If you don\'t have the email anymore, we can resend it to you.' \ No newline at end of file diff --git a/app/views/conferences/_register_new_organization.html.haml b/app/views/conferences/_register_new_organization.html.haml index fa8597d..50fef70 100644 --- a/app/views/conferences/_register_new_organization.html.haml +++ b/app/views/conferences/_register_new_organization.html.haml @@ -2,16 +2,17 @@ = hidden_field_tag :new_org_index, org_index - if session[:registration][:new_organization].length > 1 %h3=_'registration.new_organization.list.title','Your New Organizations' - %ul.columns.medium-10.medium-offset-1 + %ul.columns.medium-11.medium-offset-1.end - session[:registration][:new_organization].each_with_index do |new_organization, index| - - if new_organization[:title] + - if new_organization[:name] %li - - if index == org_index && new_organization[:title] - %strong=new_organization[:title] + - if index == org_index && new_organization[:name] + %strong=new_organization[:name] - else - = new_organization[:title] + = new_organization[:name] %h3=_'registration.new_organization.title','Your Organization Information' -.columns.medium-12= text_field_tag :organization_name, session[:registration][:new_organization][org_index][:name], :required => true +.columns.medium-12 + = text_field_tag :organization_name, session[:registration][:new_organization][org_index][:name], :required => true .columns.medium-12= text_area_tag :organization_info, session[:registration][:new_organization][org_index][:info], :data => {:editor => ""} .columns.medium-7 = email_field_tag :organization_email, session[:registration][:new_organization][org_index][:email], :required => true @@ -20,7 +21,7 @@ = country_select_tag :organization_country, session[:registration][:new_organization][org_index][:country], :required => true = subregion_select_tag :organization_territory, session[:registration][:new_organization][org_index][:territory], session[:registration][:new_organization][org_index][:country] || 'US', html: {class: session[:registration][:new_organization][org_index][:country] ? 'can' : 'cant', data: {:country => session[:registration][:new_organization][org_index][:country]}} .columns.medium-5 - = image_field_tag :organization_logo + = image_field_tag :logo .columns = check_box_tag :add_another_org, (org_index <= session[:registration][:new_organization].length - 1) diff --git a/app/views/conferences/_register_new_workshop.html.haml b/app/views/conferences/_register_new_workshop.html.haml index 8377b92..3df839b 100644 --- a/app/views/conferences/_register_new_workshop.html.haml +++ b/app/views/conferences/_register_new_workshop.html.haml @@ -14,11 +14,11 @@ .columns.medium-10.medium-offset-1= text_field_tag :workshop_title, session[:registration][:workshop][workshop_index][:title], :required => true .columns.medium-10.medium-offset-1= text_area_tag :workshop_info, session[:registration][:workshop][workshop_index][:info], :required => true, :data => {:editor => ""} .columns.medium-5.medium-offset-1 - %h4=_'registration.workshop.streams.title','Stream' - %p.help=_'registration.workshop.streams.help','Select the stream that best categorizes your workshop' + %h4=_'registration.workshop.streams.title','Themes' + %p.help=_'registration.workshop.streams.help','Select the theme that best categorizes your workshop' - streams = Hash.new - - streams[_'workshop_stream.select_one','Select a stream'] = '' - - WorkshopStream.all.each do |stream| + - streams[_'workshop_stream.select_one','Select a theme'] = '' + - WorkshopStream.order('"order" ASC').each do |stream| - streams[_'workshop_stream.' + stream.slug] = stream.slug = select_tag :workshop_stream, options_for_select(streams, session[:registration][:workshop][workshop_index][:stream] || '') .columns.medium-5.end @@ -26,12 +26,15 @@ %p.help=_'registration.workshop.styles.help','Select the style that best describes how you will run your workshop' - styles = Hash.new - styles[_'workshop_presentation_style.select_one','Select a style'] = '' - - WorkshopPresentationStyle.all.each do |style| + - WorkshopPresentationStyle.order('"order" ASC').each do |style| - styles[_'workshop_presentation_style.' + style.slug] = style.slug = select_tag :workshop_presentation_style, options_for_select(styles, session[:registration][:workshop][workshop_index][:presentation_style] || '') +.columns.medium-10.medium-offset-1.end + %h4=_'registration.workshop.notes.title','Additional notes for Organizers' + %p=_'registration.workshop.notes.help','Anything else that the conference organizers should know? Is anyone helping you facilitate?' + = text_area_tag :workshop_notes, session[:registration][:workshop][workshop_index][:notes], :label => false .columns.medium-10.medium-offset-1 - - #xx = check_box_tag :add_another_workshop, "1", (workshop_index < session[:registration][:workshop].length - 1) - content_for :footer_scripts do -= javascript_include_tag 'editor' \ No newline at end of file + = javascript_include_tag 'editor' \ No newline at end of file diff --git a/app/views/conferences/_register_organizations.html.haml b/app/views/conferences/_register_organizations.html.haml index f91f2e2..c51fbe2 100644 --- a/app/views/conferences/_register_organizations.html.haml +++ b/app/views/conferences/_register_organizations.html.haml @@ -1,3 +1,11 @@ +- registration = ConferenceRegistration.find(session[:registration][:registration_id]) +- if registration && registration.is_confirmed + %h3=_'register.organizations.confirm_thanks.title','Thanks for confirming!' + - if session[:registration][:is_workshop_host] + %p=_'register.organizations.confirm_thanks.is_workshop_host.help','Before you finish, we would just like to find out where you\'re coming from and get some info about your workshop.' + - else + %p=_'register.organizations.confirm_thanks.is_not_workshop_host.help','Before you finish, we would just like to find out where you\'re coming from.' + %p=_'register.organizations.confirm_thanks.payment_notice','After that you will also be able to pay for registration.' %h3 =_'register.organizations.title','Who do you Represent?' %p=_'register.organizations.description','Please let us know where you\'re coming from! Find your organizations on the right, they are listed by how close they are to you right now.' @@ -8,8 +16,6 @@ - my_location = lookup_ip_location - lids = Location.near(my_location.latitude.to_s+', '+my_location.longitude.to_s, 999999, order: 'distance').map{|l|l.id} - orgs = Hash.new - -# orgs = Organization.joins(:locations_organization).where('locations_organizations.location_id' => lids) - -# orgs.each do |org| - lids.each do |lid| - org = Organization.joins(:locations_organization).where('locations_organizations.location_id' => lid).first - if org && !orgs.has_key?(org.id) diff --git a/app/views/conferences/_register_primary.html.haml b/app/views/conferences/_register_primary.html.haml index ad7bfa5..b71bea8 100644 --- a/app/views/conferences/_register_primary.html.haml +++ b/app/views/conferences/_register_primary.html.haml @@ -6,5 +6,5 @@ .columns %h3=_'registration.primary.role_title','Attending as:' .columns.small-offset-1 - = check_box_tag :is_participant, session[:registration][:is_participant] - = check_box_tag :is_volunteer, session[:registration][:is_volunteer] + = check_box_tag :is_participant, 'true', session[:registration][:is_participant] + = check_box_tag :is_volunteer, 'true', session[:registration][:is_volunteer] diff --git a/app/views/conferences/_register_questions.html.haml b/app/views/conferences/_register_questions.html.haml index ff09518..2bbc073 100644 --- a/app/views/conferences/_register_questions.html.haml +++ b/app/views/conferences/_register_questions.html.haml @@ -13,19 +13,19 @@ .columns.medium-8.medium-offset-2.end = select_tag '[questions][loaner_bike]', options_for_select(@loaner_bike_options, session[:registration][:questions][:loaner_bike]) +-#.columns.medium-offset-1.end +-# %h4=_'registration.questions.diet','We\'ll be serving some food. Do you have any dietary restrictions?' +-#.columns.medium-8.medium-offset-2.end +-# = check_box_tag '[questions][diet][no_meat]', session[:registration][:questions][:diet][:no_meat] +-# = check_box_tag '[questions][diet][no_dairy]', session[:registration][:questions][:diet][:no_dairy] +-# = check_box_tag '[questions][diet][no_animal_products]', session[:registration][:questions][:diet][:no_animal_products] +-# = check_box_tag '[questions][diet][no_gluten]', session[:registration][:questions][:diet][:no_gluten] +-# = check_box_tag '[questions][diet][no_nuts]', session[:registration][:questions][:diet][:no_nuts] +-# %h5=_'registration.questions.diet_extra.title','Anything else?' +-# = text_area_tag '[questions][diet][diet_extra]', session[:registration][:questions][:diet_extra], :label => false .columns.medium-offset-1.end - %h4=_'registration.questions.diet','We\'ll be serving some food. Do you have any dietary restrictions?' -.columns.medium-8.medium-offset-2.end - = check_box_tag '[questions][diet][no_meat]', session[:registration][:questions][:diet][:no_meat] - = check_box_tag '[questions][diet][no_dairy]', session[:registration][:questions][:diet][:no_dairy] - = check_box_tag '[questions][diet][no_animal_products]', session[:registration][:questions][:diet][:no_animal_products] - = check_box_tag '[questions][diet][no_gluten]', session[:registration][:questions][:diet][:no_gluten] - = check_box_tag '[questions][diet][no_nuts]', session[:registration][:questions][:diet][:no_nuts] - %h5=_'registration.questions.diet_extra.title','Anything else?' - = text_area_tag '[questions][diet][diet_extra]', session[:registration][:questions][:diet_extra], :label => false -.columns.medium-offset-1.end - %h4=_'registration.questions.workshop','Would you ilke to host a workshop?' - %p.help=_'registration.questions.workshop.help','Did you have an idea for a workshop that you\d like to help run? If so, we\'ll ask some follow-up questions on the following page.' + %h4=_'registration.questions.workshop','Would you like to host a workshop?' + %p.help=_'registration.questions.workshop.help','Did you have an idea for a workshop that you\'d like to help run? If so, we\'ll ask some follow-up questions later on.' .columns.medium-8.medium-offset-2.end = select_tag :is_workshop_host, options_for_select({(_'Yes') => 1, (_'No') => 0}, session[:registration][:is_workshop_host] || 0) .columns.medium-offset-1.end diff --git a/app/views/conferences/_register_thanks.html.haml b/app/views/conferences/_register_thanks.html.haml index ec0392a..fa066a7 100644 --- a/app/views/conferences/_register_thanks.html.haml +++ b/app/views/conferences/_register_thanks.html.haml @@ -1,6 +1,25 @@ -%h3=_'registration.thanks.title','Thanks for submitting your registration' -.columns.medium-offset-1.end - %h4=_'registration.thanks.remember_to_confirm','Remember to confirm your registration upon receiving the confirmation email' - %p.help - =_'registration.thanks.remember_to_confirm.help','If you experience any technical issues, please contact Godwin directly at' - %a{href: 'mailto:goodgodwin@hotmail.com'}='goodgodwin@hotmail.com' +- if @registration && @registration.complete + - city = @conference.organizations.first.locations.first.city + %h3=_'registration.thanks.complete.title','Thanks for completing your registration' + .columns + - if !@registration.is_participant + %p=_'registration.thanks.all_done.volunteer','Thanks for submitting your volunteer infomation. We\'ll see you at Bike!Bike!' + - elsif @registration.payment_info.nil? + %p=_'registration.thanks.all_done.please_pay',"Thank you for completing your registration. We'll see you at Bike!Bike! If you have not already done so, we ask that you pay the registration donation as soon as you can." + = form_tag ("#{@conference.url}/register/pay-registration/#{@registration.confirmation_token}/").gsub(/\/\/+/, '/'), :method => :post, :class => 'row' do + = hidden_field_tag :confirmation_token, @registration.confirmation_token + .columns.small-4.small-offset-2 + = number_field_tag :payment_amount, 25.00, :step => 0.01, :min => 0.01 + .columns.small-4.end + = form_actions :submit_payment + - else + %p=_'registration.thanks.all_done.paid',"You're all done and paid up! We'll see you in #{city}.", vars: {:city => city} + %p=_'register.email.registration_confirmed.info',"We'll have housing, loaner bikes, and food arranged for your arrival. If you have any other questions or concerns, please email bikebike2014columbus@gmail.com." + %p=_'register.email.registration_confirmed.contact',"For urgent/emergency matters, you can reach our Outreach Coordinator, Reda, at 503-984-9191 or Jason at 614-364-3636." +- else + %h3=_'registration.thanks.title','Thanks for submitting your registration' + .columns + %h4=_'registration.thanks.remember_to_confirm','Remember to confirm your registration upon receiving the confirmation email. If you need it to be resent, just press the button below.' +%p.help + =_'registration.thanks.remember_to_confirm.help','If you experience any technical issues, please contact Godwin directly at' + %a{href: 'mailto:goodgodwin@hotmail.com'}='goodgodwin@hotmail.com' diff --git a/app/views/conferences/_register_volunteer_questions.html.haml b/app/views/conferences/_register_volunteer_questions.html.haml index 31f4a1b..20e817c 100644 --- a/app/views/conferences/_register_volunteer_questions.html.haml +++ b/app/views/conferences/_register_volunteer_questions.html.haml @@ -6,25 +6,31 @@ = text_field_tag '[volunteer_questions][address]', session[:registration][:volunteer_questions][:address] = text_field_tag '[volunteer_questions][phone_number]', session[:registration][:volunteer_questions][:phone_number] +-#.columns.medium-offset-1.end +-# %h4=_'registration.volunteer_questions.has_kitchen','Do have a kitchen / cook space to offer?' +-#.columns.medium-8.medium-offset-2.end +-# = select_tag '[volunteer_questions][has_kitchen]', options_for_select({(_'Yes') => 1, (_'No') => 0}, session[:registration][:volunteer_questions][:has_kitchen] || 0) .columns.medium-offset-1.end - %h4=_'registration.volunteer_questions.has_kitchen','Do have a kitchen / cook space to offer?' + %h4=_'registration.volunteer_questions.tasks.title','How can you help out?' .columns.medium-8.medium-offset-2.end - = select_tag '[volunteer_questions][has_kitchen]', options_for_select({(_'Yes') => 1, (_'No') => 0}, session[:registration][:volunteer_questions][:has_kitchen] || 0) + - session[:registration][:volunteer_questions][:tasks] ||= Hash.new + = check_box_tag '[volunteer_questions][tasks][cooking]', session[:registration][:volunteer_questions][:tasks][:cooking] + = check_box_tag '[volunteer_questions][tasks][manual_labour]', session[:registration][:volunteer_questions][:tasks][:manual_labour] .columns.medium-offset-1.end %h4=_'registration.volunteer_questions.has_housing','Do you have housing to offer for out of town attendees?' .columns.medium-offset-2.medium-5 %h5=_'registration.volunteer_questions.beds','Spare Beds:' .columns.medium-3.end - = number_field_tag '[volunteer_questions][beds]', session[:registration][:volunteer_questions][:beds] || 0, :label => false + = number_field_tag '[volunteer_questions][beds]', session[:registration][:volunteer_questions][:beds] || 0, :label => false, min: 0 .columns.medium-offset-2.medium-5 %h5=_'registration.volunteer_questions.couch_space','Number you can accomodate on couches/floor space:' .columns.medium-3.end - = number_field_tag '[volunteer_questions][beds]', session[:registration][:volunteer_questions][:couch_space] || 0, :label => false + = number_field_tag '[volunteer_questions][couch_space]', session[:registration][:volunteer_questions][:couch_space] || 0, :label => false, min: 0 .columns.medium-offset-2.medium-5 %h5=_'registration.volunteer_questions.tents','Estimated number of tests you\'d be willing to have in your yard:' .columns.medium-3.end - = number_field_tag '[volunteer_questions][tents]', session[:registration][:volunteer_questions][:tents] || 0, :label => false + = number_field_tag '[volunteer_questions][tents]', session[:registration][:volunteer_questions][:tents] || 0, :label => false, min: 0 .columns.medium-offset-1.end %h4=_'registration.volunteer_questions.other','Anything else you\'d like to tell us?' .columns.medium-8.medium-offset-2.end diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml index 0031c5a..d6dc6da 100644 --- a/app/views/conferences/show.html.haml +++ b/app/views/conferences/show.html.haml @@ -4,15 +4,12 @@ - title @conference.title - description "#{@conference.title} conference in #{location_name} for DIY bicycle collectives, co-ops, and advocacy groups" = render 'header' - -=# tabs! - %article.row .columns.large-10 - if @register_step - %h2='Register!' + %h2='Conference Registration' - if @actions - = form_tag (@conference.url + '/register/').gsub(/\/\/+/, '/'), :method => :post do + = form_tag (@conference.url + '/register/').gsub(/\/\/+/, '/'), :method => :post, :multipart => @multipart do = hidden_field_tag :step, @register_step - if @error_message .columns.medium-8.medium-centered diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index e578ca1..d47d859 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -36,6 +36,15 @@ - if content_for?(:side_bar) %aside#side-bar = yield :side_bar + %form{action: 'https://www.paypal.com/cgi-bin/webscr', method: 'post', target: '_top'} + %input{type: 'hidden', name: 'cmd', value: '_donations'} + %input{type: 'hidden', name: 'business', value: 'info@thirdhand.org'} + %input{type: 'hidden', name: 'lc', value: 'US'} + %input{type: 'hidden', name: 'item_name', value: 'Bike!Bike!'} + %input{type: 'hidden', name: 'no_note', value: '0'} + %input{type: 'hidden', name: 'currency_code', value: 'USD'} + %button{type: 'submit', value: 'PP-DonationsBF:paypal_logo.png:NonHostedGuest'}=_'donate.button_label','Make a Donation!' + - if has_content? #content=yield - else diff --git a/app/views/layouts/user_mailer.html.haml b/app/views/layouts/user_mailer.html.haml new file mode 100644 index 0000000..156ebb3 --- /dev/null +++ b/app/views/layouts/user_mailer.html.haml @@ -0,0 +1,76 @@ +!!! Strict +%html{xmlns: "http://www.w3.org/1999/xhtml"} + %head + %meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/ + %meta{content: "width=device-width, initial-scale=1.0", name: "viewport"}/ + %title Your Message Subject or Title + :css + #outlook a {padding:0;} + body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;} + .ExternalClass {width:100%;} + .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} + #backgroundTable {margin:0; padding:0; width:100% !important; line-height: 100% !important;} + img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;} + a img {border:none;} + .image_fix {display:block;} + p {margin: 1em 0;text-align:left;font-size: 1.25em} + h1, h2, h3, h4, h5, h6 {color: black !important;margin-bottom: 1.5em;line-height:1.5em} + h2 {text-align:left;font-size:1.3em;} + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color: white !important;margin-bottom:1em} + h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: white !important;} + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: white !important;} + table td {border-collapse: collapse;} + table { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; } + a {color: #00ADEF;} + @media only screen and (max-device-width: 480px) { + a[href^="tel"], a[href^="sms"] { + text-decoration: none; + color: #00ADEF; + pointer-events: none; + cursor: default; + } + + .mobile_link a[href^="tel"], .mobile_link a[href^="sms"] { + text-decoration: default; + color: #00ADEF !important; + pointer-events: auto; + cursor: default; + } + } + @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { + a[href^="tel"], a[href^="sms"] { + text-decoration: none; + color: blue; /* or whatever your want */ + pointer-events: none; + cursor: default; + } + + .mobile_link a[href^="tel"], .mobile_link a[href^="sms"] { + text-decoration: default; + color: #00ADEF !important; + pointer-events: auto; + cursor: default; + } + } + @media only screen and (-webkit-min-device-pixel-ratio: 2) {} + @media only screen and (-webkit-device-pixel-ratio:.75){} + @media only screen and (-webkit-device-pixel-ratio:1){} + @media only screen and (-webkit-device-pixel-ratio:1.5){} + /[if IEMobile 7] + + /[if gte mso 9] + + %body + %table#backgroundTable{border: "0", cellpadding: "0", cellspacing: "0"} + %tr + %td + %div{style:'width:100%;background-color:#00ADEF;padding: 25px 0 200px;text-align: center;'} + %div{style:'max-width:600px;border:3px solid #00ADEF;margin:25px auto;background-color:#FFF;display:inline-block;width:75%;'} + = yield + %div{style: 'text-align:center;padding-bottom:25px'} + %a{href: "#{@url}"} + 2014 Bike!Bike! diff --git a/app/views/layouts/user_mailer.text.haml b/app/views/layouts/user_mailer.text.haml new file mode 100644 index 0000000..abd1c3f --- /dev/null +++ b/app/views/layouts/user_mailer.text.haml @@ -0,0 +1,5 @@ +='========== Bike!Bike! ==========' + += yield + +="===== #{@url} ======" diff --git a/app/views/pages/404.html.haml b/app/views/pages/404.html.haml index a7b2f44..2297acc 100644 --- a/app/views/pages/404.html.haml +++ b/app/views/pages/404.html.haml @@ -1 +1,9 @@ -404!d \ No newline at end of file +- page_title = _'error.404.page_title.This_Page_Does_Not_Exist' +- title page_title +- banner_title page_title + +.row + %h1 + =_'error.404.title','This page does not exist!' + %p + =_'error.404.description', :p \ No newline at end of file diff --git a/app/views/pages/language_not_enabled.html.haml b/app/views/pages/language_not_enabled.html.haml new file mode 100644 index 0000000..aadb298 --- /dev/null +++ b/app/views/pages/language_not_enabled.html.haml @@ -0,0 +1,9 @@ +- page_title = _'error.no_lang.page_title.Language_not_enabled' +- title page_title +- banner_title page_title + +.row + %h1 + =(_ 'language_not_yet_translated', vars: {:language => (_ ('languages.' + @lang))}) + %p + =_'error.no_lang.description', :p \ No newline at end of file diff --git a/app/views/pages/permission_denied.html.haml b/app/views/pages/permission_denied.html.haml index ad367c9..c3b87c8 100644 --- a/app/views/pages/permission_denied.html.haml +++ b/app/views/pages/permission_denied.html.haml @@ -1,9 +1,9 @@ -- page_title = _'error.title.Permission_Denied' +- page_title = _'error.403.page_title.Permission_Denied' - title page_title - banner_title page_title .row %h1 - ='This page is inaccessible to you' + =_'error.403.title','This page is inaccessible to you' %p - =_'error.desc.permission_denied', :p \ No newline at end of file + =_'error.403.description', :p \ No newline at end of file diff --git a/app/views/pages/translation_list.html.haml b/app/views/pages/translation_list.html.haml index 7383245..720e7b4 100644 --- a/app/views/pages/translation_list.html.haml +++ b/app/views/pages/translation_list.html.haml @@ -12,11 +12,11 @@ - if code && @completeness.has_key?(code.to_s) %li.text-center - completeness = @completeness[code.to_s] - - percent = @total_translations ? ((completeness / @total_translations.to_f) * 100).to_i : 0 - %a{:href => "/translations/#{code}/", :class => (percent > 99 ? 'complete' : percent > 67 ? 'needs-work' : nil)} + -# percent = @total_translations ? ((completeness / @total_translations.to_f) * 100).to_i : 0 + %a{:href => "/translations/#{code}/", :class => (completeness > 99 ? 'complete' : completeness > 67 ? 'needs-work' : nil)} %h3=_"languages.#{code}" .completeness - = "#{completeness} / #{@total_translations} (#{percent}%)" + = "#{completeness} / #{@total_translations} (#{completeness}%)" %h2= _ 'languages.inactive' %ul.languages.inactive.small-block-grid-1.medium-block-grid-3.large-block-grid-4.grid.links - @language_codes.each do |code| diff --git a/app/views/pages/translations.html.haml b/app/views/pages/translations.html.haml index 3d2eed0..25142a3 100644 --- a/app/views/pages/translations.html.haml +++ b/app/views/pages/translations.html.haml @@ -11,10 +11,10 @@ %th.key=_'translations.Pages' %th.key=_'translations.Value' - @translations.sort{| a1, a2 | a1[0].downcase <=> a2[0].downcase}.each do |k,translation| - - current_translation = Translation.locale(@lang.to_sym).lookup(k)#[0].value #_ translation[0], :strict, locale: @lang.to_sym + - current_translation = Translation.locale(@lang.to_sym).lookup(k) - current_translation = current_translation.size() > 0 ? current_translation = current_translation[0].value : nil - - cached = (translation['languages'] && translation['languages'].include?(@lang)) - - vars = translation.has_key?('vars') && translation['vars'].size() > 0 ? translation['vars'] : nil + - cached = (translation && translation['languages'] && translation['languages'].include?(@lang)) + - vars = translation && translation.has_key?('vars') && translation['vars'].size() > 0 ? translation['vars'] : nil - (vars && vars.include?(:count) ? I18n.backend.get_pluralization_rules(@lang) : [nil]).each do |pluralization| - key = k + (pluralization ? ".#{pluralization.to_s}" : '') %tr{:class => current_translation ? 'exists' : 'not-exists', :data => {:key => key}} @@ -28,9 +28,10 @@ %li=v %td.pages %ul - - translation['pages'].each do |page| - %li - %a{:href => page}=page + - if translation + - translation['pages'].each do |page| + %li + %a{:href => page}=page %td.value.primary - if current_translation = current_translation @@ -43,5 +44,5 @@ - unless current_translation %a{:href => '#', :class => 'auto-translate button small'}='Auto' --# content_for :footer_scripts -= javascript_include_tag 'translations' +- content_for :footer_scripts do + = javascript_include_tag 'translations' diff --git a/app/views/user_mailer/conference_registration_confirmed_email.html.haml b/app/views/user_mailer/conference_registration_confirmed_email.html.haml new file mode 100644 index 0000000..a49389f --- /dev/null +++ b/app/views/user_mailer/conference_registration_confirmed_email.html.haml @@ -0,0 +1,10 @@ +%img{src: "#{@url}/#{@conference.poster.full.url}", style: "max-width: 100%;"} +%div{style: 'padding: 25px'} + %h1=_'register.email.registration_confirmed.thank_you',"Hi #{@data[:user][:username]}, thank you for completing your registration. We'll see you at Bike!Bike!" + %h2=_'register.email.registration_confirmed.please_pay',"If you have not already done so, we ask that you pay the registration donation as soon as you can. At your convenience please visit the link below." + %div{style: 'text-align:center'} + %h1{style: 'background-color:#F11845;text-align:center;display:inline-block;padding: 5px 20px 10px;'} + %a{href: @confirmation_url, style: 'color:#FFF;text-decoration:none;'} + =_'register.email.registration_confirmed.pay_now',"Pay Registration Fees" + %p=(_'register.email.registration_confirmed.info',"We'll have housing, loaner bikes, and food arranged for your arrival. If you have any other questions or concerns, please email bikebike2014columbus@gmail.com").gsub(/(\w+@\w+\.\w{2,3})/, '\1').html_safe + %p=_'register.email.registration_confirmed.contact',"For urgent/emergency matters, you can reach our Outreach Coordinator, Reda, at 503-984-9191 or Jason at 614-364-3636." \ No newline at end of file diff --git a/app/views/user_mailer/conference_registration_confirmed_email.text.haml b/app/views/user_mailer/conference_registration_confirmed_email.text.haml new file mode 100644 index 0000000..50ac6ae --- /dev/null +++ b/app/views/user_mailer/conference_registration_confirmed_email.text.haml @@ -0,0 +1,9 @@ +=_'register.email.registration_confirmed.thank_you',"Hi #{@data[:user][:username]}, thank you for completing your registration. We'll see you at Bike!Bike!" + +=_'register.email.registration_confirmed.please_pay',"If you have not already done so, we ask that you pay the registration donation as soon as you can. At your convenience please visit the link below." + += @confirmation_url + +=_'register.email.registration_confirmed.info',"We'll have housing, loaner bikes, and food arranged for your arrival. If you have any other questions or concerns, please email bikebike2014columbus@gmail.com." + +=_'register.email.registration_confirmed.contact',"For urgent/emergency matters, you can reach our Outreach Coordinator, Reda, at 503-984-9191 or Jason at 614-364-3636." diff --git a/app/views/user_mailer/conference_registration_email.html.haml b/app/views/user_mailer/conference_registration_email.html.haml new file mode 100644 index 0000000..ce85782 --- /dev/null +++ b/app/views/user_mailer/conference_registration_email.html.haml @@ -0,0 +1,7 @@ +%img{src: "#{@url}/#{@conference.poster.full.url}", style: "max-width: 100%;"} +%div{style: 'padding: 25px'} + %h1=_'register.email.registration.please_confirm',"Hi #{@data[:user][:username]}, please confirm your registration for #{@conference.title}", vars: {:username => @data[:user][:username]} + %div{style: 'text-align:center'} + %h1{style: 'background-color:#F11845;text-align:center;display:inline-block;padding: 5px 20px 10px;'} + %a{href: @confirmation_url, style: 'color:#FFF;text-decoration:none;'} + =_'register.email.registration.confirm_button',"Yes I'm Really Coming!" \ No newline at end of file diff --git a/app/views/user_mailer/conference_registration_email.text.haml b/app/views/user_mailer/conference_registration_email.text.haml index 088d8c0..2b95786 100644 --- a/app/views/user_mailer/conference_registration_email.text.haml +++ b/app/views/user_mailer/conference_registration_email.text.haml @@ -1 +1 @@ -= @data.to_json.to_s \ No newline at end of file +=_('register.email.registration.please_confirm',"Hi #{@data[:user][:username]}, please confirm your registration for #{@conference.title}", vars: {:username => @data[:user][:username]}) + ": #{@confirmation_url}" \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index 7d3fcf6..b8c5ba2 100644 --- a/config/application.rb +++ b/config/application.rb @@ -13,24 +13,25 @@ ENV['JPEGOPTIM_BIN'] = 'jpegoptim' ENV['OPTIPNG_BIN'] = 'optipng' module BikeBike - class Application < Rails::Application - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. - # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - config.i18n.default_locale = :en #:de - config.i18n.enforce_available_locales = false - # config.action_controller.default_url_options = { :trailing_slash => true } - #config.middleware.swap 'Rack::MethodOverride', 'Rack::MethodOverrideWithParams' - #config.i18n.exception_handler = I18n::MissingTranslationExceptionHandler.new - #require '/app/helpers/bike_bike_form_helper' - #ActionView::Base.default_form_builder - #config.action_view.default_form_builder = 'BikeBikeFormHelper::BikeBikeFormBuilder' + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + config.i18n.default_locale = :en #:de + config.i18n.enforce_available_locales = false + self.paths['config/database'] = Rails.root.parent.join("secure/database.yml").to_s + # config.action_controller.default_url_options = { :trailing_slash => true } + #config.middleware.swap 'Rack::MethodOverride', 'Rack::MethodOverrideWithParams' + #config.i18n.exception_handler = I18n::MissingTranslationExceptionHandler.new + #require '/app/helpers/bike_bike_form_helper' + #ActionView::Base.default_form_builder + #config.action_view.default_form_builder = 'BikeBikeFormHelper::BikeBikeFormBuilder' end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 714523b..471e16b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -45,13 +45,15 @@ BikeBike::Application.configure do } config.action_mailer.raise_delivery_errors = true config.action_mailer.perform_deliveries = true - #config.force_ssl = true + #config.force_ssl = true #config.action_mailer.default_charset = 'utf-8' - #Carmen.i18n_backend.locale_paths = '' - #puts "CARMEN\t" + Carmen.i18n_backend.locale_paths + #Carmen.i18n_backend.locale_paths = '' + #puts "CARMEN\t" + Carmen.i18n_backend.locale_paths - #PerfTools::CpuProfiler.start('/tmp/dev_prof') - config.serve_static_assets = true - #config.assets.precompile = false + #PerfTools::CpuProfiler.start('/tmp/dev_prof') + config.serve_static_assets = true + #config.assets.precompile = false + Paypal.sandbox! + #Paypal.sandbox = false end diff --git a/config/environments/test.rb b/config/environments/test.rb index 6af352a..9fafaee 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,37 +1,38 @@ BikeBike::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true - - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false - - # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false - - # Disable request forgery protection in test environment. - config.action_controller.allow_forgery_protection = false - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - config.action_mailer.default_url_options = { host: 'localhost' } - - # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure static asset server for tests with Cache-Control for performance. + config.serve_static_assets = true + config.static_cache_control = "public, max-age=3600" + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + config.action_mailer.default_url_options = { host: 'localhost' } + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + Paypal.sandbox! end diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb index e5fd9df..e14cff9 100644 --- a/config/initializers/i18n.rb +++ b/config/initializers/i18n.rb @@ -48,7 +48,8 @@ module I18n end return self.lorem_ipsum(behavior, behavior_size) end - key.to_s.gsub(/^world\..*\.(.+)\.name$/, '\1').gsub(/^.*\.(.+)?$/, '\1').gsub('_', ' ') + #key.to_s.gsub(/^world\..*\.(.+)\.name$/, '\1').gsub(/^.*\.(.+)?$/, '\1').gsub('_', ' ') + key.to_s.gsub(/^world\.(.+)\.name$/, '\1').gsub(/^.*\.(.+)?$/, '\1').gsub('_', ' ') end def call(exception, locale, key, options) @@ -68,6 +69,21 @@ module I18n @@translation_cache_file = 'config/locales/.translation-cache.yml' @@pluralization_rules_file = 'config/locales/pluralization-rules.yml' @@translation_cache + @@testing_started = false + @@hosts + + def self.init_tests!(new_translations = nil) + if Rails.env.test? + if !@@testing_started + @@testing_started = true + File.open(@@translations_file, 'w+') + File.open(@@translation_cache_file, 'w+') + end + if !new_translations.nil? + record_translation(new_translations) + end + end + end def needs_translation(key) @@needs_translation ||= Array.new @@ -90,12 +106,9 @@ module I18n end def initialize - if Rails.env.test? || !File.exist?(@@translation_cache_file) + if !File.exist?(@@translation_cache_file) File.open(@@translation_cache_file, 'w+') end - if Rails.env.test? - File.open(@@translations_file, 'w+') - end @@translation_cache = YAML.load(File.read(@@translation_cache_file)) || Hash.new super end @@ -105,8 +118,6 @@ module I18n YAML.load_file(@@translations_file) || {} rescue Exception => e # sometimes concurrency issues cause an exception during testing - puts e.class - x sleep(1/2.0) get_translation_info() end @@ -121,6 +132,30 @@ module I18n YAML.load_file(@@pluralization_rules_file).keys end + def set_locale(host) + @@hosts ||= Hash.new + default = I18n.default_locale.to_s + lang = @@hosts[host] + if lang === false + lang = nil + elsif lang.nil? + if (lang = host.gsub(/^(dev|test|www)[\-\.](.*)$/, '\2').gsub(/^(([^\.]+)\.)?[^\.]+\.[^\.]+$/, '\2')).blank? + lang = default + end + if get_language_codes().include? lang + if !language_enabled? lang + I18n.locale = default + return lang + end + else + lang = nil + end + end + I18n.locale = default unless lang.present? + # return nil if the language doesn exist, false if it is not enabled, or the code if it is enabled + lang.present? ? true : false + end + def get_language_completion(lang) total = 0 complete = 0 @@ -128,7 +163,11 @@ module I18n total += 1 complete += v['languages'].include?(lang.to_s) ? 1 : 0 } - total ? complete / total : 0 + (total ? complete / total.to_f : 0.0) * 100.0 + end + + def language_enabled?(lang) + lang.to_s == I18n.default_locale.to_s || get_language_completion(lang) > 66 end def request_translation(key, vars, options) @@ -142,10 +181,26 @@ module I18n return result end + def record_translation(key) + translations = get_translation_info() + translations ||= Hash.new + + if key.is_a(Array) + key.each { |k| translations[k.to_s] ||= Hash.new } + else + translations[key.to_s] ||= Hash.new + end + File.open(@@translations_file, 'w') { |f| f.write translations.to_yaml } + end + protected def lookup(locale, key, scope = [], options = {}) result = nil + if key.is_a?(String) + key = key.gsub(/(^\[|\])/, '').gsub(/\[/, '.') + end + if @@translation_cache && @@translation_cache.has_key?(locale.to_s) && @@translation_cache[locale.to_s].has_key?(key.to_s) result = @@translation_cache[locale.to_s][key.to_s] end diff --git a/config/locales/translation-info.yml b/config/locales/translation-info.yml index db60049..1653a8a 100644 --- a/config/locales/translation-info.yml +++ b/config/locales/translation-info.yml @@ -1,31 +1,430 @@ --- -nola_2013.about: +world.ca.ns.name: + languages: + - en + pages: + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":1489,"locale":"en","key":"world.ca.ns.name","value":"Nova Scotia","interpolations":[],"is_proc":false,"created_at":"2014-05-04T05:27:57.814Z","updated_at":"2014-05-04T05:27:57.821Z"}' +time.formats.date: + languages: + - en + pages: + - "/" + data: + - '{"id":1618,"locale":"en","key":"time.formats.date","value":"%B %d, %Y","interpolations":[],"is_proc":false,"created_at":null,"updated_at":null}' +date.month_names: + languages: + - en + pages: + - "/" + data: + - '{"id":1620,"locale":"en","key":"date.month_names","value":["~","January","February","March","April","May","June","July","August","September","October","November","December"],"interpolations":[],"is_proc":true,"created_at":"2014-07-06T19:53:45.689Z","updated_at":"2014-07-06T19:53:45.689Z"}' +conference.More_Info: + languages: + - en + pages: + - "/" + data: + - '{"id":92004,"locale":"en","key":"conference.More_Info","value":"More Info","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:04:56.683Z","updated_at":"2014-07-22T00:04:56.696Z"}' +Conferences: + languages: + - de + - en + pages: + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":1503,"locale":"de","key":"Conferences","value":"Konferenzen","interpolations":[],"is_proc":false,"created_at":"2014-05-04T14:27:46.772Z","updated_at":"2014-05-04T14:27:46.789Z"}' + - '{"id":1481,"locale":"en","key":"Conferences","value":"Conferences","interpolations":[],"is_proc":false,"created_at":"2014-05-04T05:05:06.760Z","updated_at":"2014-05-04T05:26:07.021Z"}' +Organizations: + languages: + - en + - de + pages: + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":1482,"locale":"en","key":"Organizations","value":"Organizations","interpolations":[],"is_proc":false,"created_at":"2014-05-04T05:05:46.445Z","updated_at":"2014-07-21T01:51:57.345Z"}' + - '{"id":1505,"locale":"de","key":"Organizations","value":"Organisationen","interpolations":[],"is_proc":false,"created_at":"2014-05-04T14:29:44.542Z","updated_at":"2014-05-04T14:29:44.557Z"}' +Resources: + languages: + - en + - de + pages: + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":1483,"locale":"en","key":"Resources","value":"Resources","interpolations":[],"is_proc":false,"created_at":"2014-05-04T05:05:50.964Z","updated_at":"2014-05-04T05:25:53.510Z"}' + - '{"id":1506,"locale":"de","key":"Resources","value":"Ressourcen","interpolations":[],"is_proc":false,"created_at":"2014-05-04T14:36:08.331Z","updated_at":"2014-05-04T14:36:08.438Z"}' +donate.button_label: languages: [] pages: - - / + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" data: [] -home.its_awesome: +conference.Register_Now: + languages: + - en + pages: + - "/" + data: + - '{"id":92005,"locale":"en","key":"conference.Register_Now","value":"Register Now","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:05:01.141Z","updated_at":"2014-07-22T00:05:01.155Z"}' +form.placeholder.Enter_your_step: + languages: + - en + pages: + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91970,"locale":"en","key":"form.placeholder.Enter_your_step","value":"NIL","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:48:28.017Z","updated_at":"2014-07-21T01:48:28.028Z"}' +form.placeholder.Enter_your_email: + languages: + - en + pages: + - "/" + data: + - '{"id":91961,"locale":"en","key":"form.placeholder.Enter_your_email","value":"someone@example.com","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:39:53.873Z","updated_at":"2014-07-21T02:17:18.066Z"}' +form.label.email: + languages: + - en + pages: + - "/" + data: + - '{"id":91944,"locale":"en","key":"form.label.email","value":"Email","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:33:11.129Z","updated_at":"2014-07-21T01:33:11.140Z"}' +register: + languages: + - en + pages: + - "/" + data: + - '{"id":91980,"locale":"en","key":"register","value":"Register","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:52:22.219Z","updated_at":"2014-07-21T01:52:22.261Z"}' + - '{"id":92009,"locale":"en","key":"register.new_organization.no_city_error","value":"Please + enter your organization''s city","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:08:55.720Z","updated_at":"2014-07-22T00:08:55.758Z"}' + - '{"id":92010,"locale":"en","key":"register.new_organization.no_street_error","value":"Please + enter your organization''s street address","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:09:13.603Z","updated_at":"2014-07-22T00:09:13.616Z"}' + - '{"id":92012,"locale":"en","key":"register.organizations.confirm_thanks.is_not_workshop_host.help","value":"","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:10:09.190Z","updated_at":"2014-07-22T00:10:09.203Z"}' + - '{"id":92013,"locale":"en","key":"register.organizations.confirm_thanks.title","value":"","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:10:13.343Z","updated_at":"2014-07-22T00:10:13.355Z"}' + - '{"id":92011,"locale":"en","key":"register.new_organization.same_email_as_attendee_error","value":"This + email needs to be different than your own personal email, we need to keep in touch + with your organization even if you''re gone in years to come.","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:09:49.895Z","updated_at":"2014-07-22T00:11:24.105Z"}' + - '{"id":92008,"locale":"en","key":"register.new_organization.no_name_error","value":"Please + tell us your organization''s name","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:06:48.248Z","updated_at":"2014-07-22T00:12:21.428Z"}' +world.ca.nb.name: + languages: + - en + pages: + - "/" + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":1487,"locale":"en","key":"world.ca.nb.name","value":"New Brunswick","interpolations":[],"is_proc":false,"created_at":"2014-05-04T05:27:41.999Z","updated_at":"2014-05-04T05:27:42.039Z"}' +form.placeholder.Enter_your_firstname: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91962,"locale":"en","key":"form.placeholder.Enter_your_firstname","value":"Francis? + Frances? Phransiz?","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:40:00.075Z","updated_at":"2014-07-21T01:53:51.732Z"}' +form.label.firstname: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91945,"locale":"en","key":"form.label.firstname","value":"First name","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:33:15.267Z","updated_at":"2014-07-21T01:33:15.278Z"}' +form.placeholder.Enter_your_lastname: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91963,"locale":"en","key":"form.placeholder.Enter_your_lastname","value":"Smith? + Ng?","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:42:51.398Z","updated_at":"2014-07-21T01:42:51.409Z"}' +form.label.lastname: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91948,"locale":"en","key":"form.label.lastname","value":"Last name","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:34:35.847Z","updated_at":"2014-07-21T01:34:35.859Z"}' +form.placeholder.Enter_your_username: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91971,"locale":"en","key":"form.placeholder.Enter_your_username","value":"How + would you like to be known?","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:48:51.318Z","updated_at":"2014-07-21T01:48:56.170Z"}' +form.label.username: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91955,"locale":"en","key":"form.label.username","value":"Preferred name","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:36:18.747Z","updated_at":"2014-07-21T01:36:18.758Z"}' +registration.primary.role_title: languages: [] pages: - - / + - "/conferences/:conference_type/:conference_slug/register(/:step)" data: [] -Conferences: +form.label.is_participant: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91946,"locale":"en","key":"form.label.is_participant","value":"A conference + participant","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:34:27.255Z","updated_at":"2014-07-21T01:34:27.267Z"}' +form.label.is_volunteer: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91947,"locale":"en","key":"form.label.is_volunteer","value":"A volunteer","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:34:33.243Z","updated_at":"2014-07-21T01:34:33.255Z"}' +cancel: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":92003,"locale":"en","key":"cancel","value":"Cancel","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:04:53.461Z","updated_at":"2014-07-22T00:04:53.473Z"}' +next: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91977,"locale":"en","key":"next","value":"next","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:51:54.465Z","updated_at":"2014-07-21T01:51:54.477Z"}' +registration.cancel.title: languages: [] pages: - - / + - "/conferences/:conference_type/:conference_slug/register(/:step)" data: [] -Organizations: +registration.cancel.help: languages: [] pages: - - / + - "/conferences/:conference_type/:conference_slug/register(/:step)" data: [] -Resources: +'no': + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +'yes': + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.cancelled.title: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.cancelled.help: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.title: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.housing: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.housing.help: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.housing_extra.title: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +form.placeholder.Enter_your_.questions.housing_extra: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91959,"locale":"en","key":"form.placeholder.Enter_your_.questions.housing_extra","value":"Preferences? + Concerns? Whatever.","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:39:27.543Z","updated_at":"2014-07-21T01:39:27.555Z"}' +registration.questions.loaner_bike: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.loaner_bike.help: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.workshop: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.questions.workshop.help: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +'Yes': + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91981,"locale":"en","key":"Yes","value":"Yes","interpolations":[],"is_proc":false,"created_at":"2014-07-21T02:03:02.555Z","updated_at":"2014-07-21T02:03:02.627Z"}' +'No': + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91978,"locale":"en","key":"No","value":"No","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:51:55.944Z","updated_at":"2014-07-21T01:51:55.955Z"}' +registration.questions.other: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +form.placeholder.Enter_your_.questions.other: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91960,"locale":"en","key":"form.placeholder.Enter_your_.questions.other","value":"Anything + else that we should know....","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:39:45.419Z","updated_at":"2014-07-21T01:39:45.431Z"}' +submit: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +register.email.registration.subject: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + vars: + - :conference_title + data: [] +register.email.registration.please_confirm: languages: [] pages: - - / + - "/conferences/:conference_type/:conference_slug/register(/:step)" + vars: + - :username data: [] -Sign_In: +register.email.registration.confirm_button: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +register.organizations.title: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +register.organizations.description: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +all_organizations: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":92002,"locale":"en","key":"all_organizations","value":"All organizations","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:04:45.086Z","updated_at":"2014-07-22T00:04:48.200Z"}' +world.ca.name: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":113,"locale":"en","key":"world.ca.name","value":"Canada","interpolations":[],"is_proc":false,"created_at":null,"updated_at":"2014-04-27T21:35:22.347Z"}' +orgnizations_filter.placeholder: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91979,"locale":"en","key":"orgnizations_filter.placeholder","value":"Organization + name or location","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:52:13.721Z","updated_at":"2014-07-21T01:52:13.732Z"}' +my_organizations: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91976,"locale":"en","key":"my_organizations","value":"My Organizations","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:51:51.454Z","updated_at":"2014-07-21T01:51:51.465Z"}' +form.label.add_new_org: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91943,"locale":"en","key":"form.label.add_new_org","value":"My organization + isn''t listed here","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:33:04.823Z","updated_at":"2014-07-21T01:33:04.834Z"}' +form.label.no_org: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":91949,"locale":"en","key":"form.label.no_org","value":"I currently do not + belong to any organization","interpolations":[],"is_proc":false,"created_at":"2014-07-21T01:35:06.287Z","updated_at":"2014-07-21T01:35:06.299Z"}' +registration.thanks.title: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.thanks.remember_to_confirm: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +registration.thanks.remember_to_confirm.help: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +resend_confirmation_email: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: [] +register.email.registration_confirmed.subject: + languages: [] + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + vars: + - :conference_title + data: [] +register.organizations.confirm_thanks.title: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":92013,"locale":"en","key":"register.organizations.confirm_thanks.title","value":"","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:10:13.343Z","updated_at":"2014-07-22T00:10:13.355Z"}' +register.organizations.confirm_thanks.is_not_workshop_host.help: + languages: + - en + pages: + - "/conferences/:conference_type/:conference_slug/register(/:step)" + data: + - '{"id":92012,"locale":"en","key":"register.organizations.confirm_thanks.is_not_workshop_host.help","value":"","interpolations":[],"is_proc":false,"created_at":"2014-07-22T00:10:09.190Z","updated_at":"2014-07-22T00:10:09.203Z"}' +register.organizations.confirm_thanks.payment_notice: languages: [] pages: - - / + - "/conferences/:conference_type/:conference_slug/register(/:step)" data: [] diff --git a/config/routes.rb b/config/routes.rb index b35a0c9..29add61 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,6 +15,10 @@ BikeBike::Application.routes.draw do #get :register, :param => 'step' #post 'register/next' => 'conferences#register_submit' match 'register(/:step)' => 'conferences#register', via: [:get, :post] + get 'register/confirm/:confirmation_token' => 'conferences#register_confirm' + match 'register/pay-registration/:confirmation_token' => 'conferences#register_pay_registration', via: [:get, :post] + get 'register/confirm-payment/:confirmation_token' => 'conferences#register_confirm_payment' + get 'register/cancel-payment/:confirmation_token' => 'conferences#register_cancel_payment' #patch 'register/step/:step' => 'conferences#register_step' #resources :registrations, :path => 'registration' do # get :form, on: :collection diff --git a/db/migrate/20140719172749_add_email_to_conference_registrations.rb b/db/migrate/20140719172749_add_email_to_conference_registrations.rb new file mode 100644 index 0000000..45f7cea --- /dev/null +++ b/db/migrate/20140719172749_add_email_to_conference_registrations.rb @@ -0,0 +1,5 @@ +class AddEmailToConferenceRegistrations < ActiveRecord::Migration + def change + add_column :conference_registrations, :email, :string + end +end diff --git a/db/migrate/20140719185914_add_is_complete_to_conference_registrations.rb b/db/migrate/20140719185914_add_is_complete_to_conference_registrations.rb new file mode 100644 index 0000000..a591bd9 --- /dev/null +++ b/db/migrate/20140719185914_add_is_complete_to_conference_registrations.rb @@ -0,0 +1,5 @@ +class AddIsCompleteToConferenceRegistrations < ActiveRecord::Migration + def change + add_column :conference_registrations, :complete, :boolean + end +end diff --git a/db/migrate/20140719204949_add_completed_to_conference_registrations.rb b/db/migrate/20140719204949_add_completed_to_conference_registrations.rb new file mode 100644 index 0000000..948736c --- /dev/null +++ b/db/migrate/20140719204949_add_completed_to_conference_registrations.rb @@ -0,0 +1,5 @@ +class AddCompletedToConferenceRegistrations < ActiveRecord::Migration + def change + add_column :conference_registrations, :completed, :boolean + end +end diff --git a/db/migrate/20140723174550_add_payment_confirmation_token_to_conference_registration.rb b/db/migrate/20140723174550_add_payment_confirmation_token_to_conference_registration.rb new file mode 100644 index 0000000..2e03699 --- /dev/null +++ b/db/migrate/20140723174550_add_payment_confirmation_token_to_conference_registration.rb @@ -0,0 +1,5 @@ +class AddPaymentConfirmationTokenToConferenceRegistration < ActiveRecord::Migration + def change + add_column :conference_registrations, :payment_confirmation_token, :string + end +end diff --git a/db/migrate/20140723174648_add_payment_info_to_conference_registration.rb b/db/migrate/20140723174648_add_payment_info_to_conference_registration.rb new file mode 100644 index 0000000..b97ec97 --- /dev/null +++ b/db/migrate/20140723174648_add_payment_info_to_conference_registration.rb @@ -0,0 +1,5 @@ +class AddPaymentInfoToConferenceRegistration < ActiveRecord::Migration + def change + add_column :conference_registrations, :payment_info, :string + end +end diff --git a/db/migrate/20140723182548_add_order_to_workshop_streams.rb b/db/migrate/20140723182548_add_order_to_workshop_streams.rb new file mode 100644 index 0000000..3b8238b --- /dev/null +++ b/db/migrate/20140723182548_add_order_to_workshop_streams.rb @@ -0,0 +1,5 @@ +class AddOrderToWorkshopStreams < ActiveRecord::Migration + def change + add_column :workshop_streams, :order, :integer + end +end diff --git a/db/migrate/20140723183557_add_order_to_workshop_presentation_styles.rb b/db/migrate/20140723183557_add_order_to_workshop_presentation_styles.rb new file mode 100644 index 0000000..b78e4bf --- /dev/null +++ b/db/migrate/20140723183557_add_order_to_workshop_presentation_styles.rb @@ -0,0 +1,5 @@ +class AddOrderToWorkshopPresentationStyles < ActiveRecord::Migration + def change + add_column :workshop_presentation_styles, :order, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 50797cc..cc812bc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140716002152) do +ActiveRecord::Schema.define(version: 20140723183557) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -66,6 +66,11 @@ ActiveRecord::Schema.define(version: 20140716002152) do t.boolean "is_volunteer" t.string "confirmation_token" t.binary "data" + t.string "email" + t.boolean "complete" + t.boolean "completed" + t.string "payment_confirmation_token" + t.string "payment_info" end create_table "conference_types", force: true do |t| @@ -267,6 +272,7 @@ ActiveRecord::Schema.define(version: 20140716002152) do t.string "info" t.datetime "created_at" t.datetime "updated_at" + t.integer "order" end create_table "workshop_requested_resources", force: true do |t| @@ -291,6 +297,7 @@ ActiveRecord::Schema.define(version: 20140716002152) do t.string "info" t.datetime "created_at" t.datetime "updated_at" + t.integer "order" end create_table "workshops", force: true do |t| diff --git a/features/landing_page.feature b/features/landing_page.feature index 88185ee..8ee7b64 100644 --- a/features/landing_page.feature +++ b/features/landing_page.feature @@ -1,9 +1,24 @@ Feature: Landing Page - As a person interested in bikebike - I want to find out about the current bikebike - In order to attend the conference + In order to learn about Bike!Bike! + As a visitor - Scenario: Read landing page content - Given I am on the landing page - Then I can read about the current bikebike - And I can register for the conference \ No newline at end of file + Scenario: See a more info link + Given There is an upcoming conference in Halifax NS + And I am on the landing page + Then I see the Bike!Bike! logo + And I see the Conferences menu item + And I see the Organizations menu item + And I see the Resources menu item + And I see Halifax + And I see More Info + + Scenario: See a register link + Given There is an upcoming conference in Halifax NS + And Registration is open + And I am on the landing page + Then I see the Bike!Bike! logo + And I see the Conferences menu item + And I see the Organizations menu item + And I see the Resources menu item + And I see Halifax + And I see a Register Now link diff --git a/features/organizations.feature b/features/organizations.feature new file mode 100644 index 0000000..e69de29 diff --git a/features/registration-two.feature b/features/registration-two.feature new file mode 100644 index 0000000..e69de29 diff --git a/features/registration.feature b/features/registration.feature new file mode 100644 index 0000000..d4d5a28 --- /dev/null +++ b/features/registration.feature @@ -0,0 +1,593 @@ +Feature: Registration + In order to register for the latest Bike!Bike! + As a visitor + + @javascript + Scenario: Register as participant with some second thoughts + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named The Bike Bush exists in Musquodoboit Harbour NS + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with shout@me.com + And I press register + + And I fill in my firstname with Joe + And I fill in my lastname with Smith + And I fill in my username with Joey + And I check is_participant + And I press cancel + + Then I should see you will lose the infomation you have submitted + Then I press no + And I should see Attending as + And firstname should be set to Joe + And lastname should be set to Smith + And username should be set to Joey + And is_participant should be checked + And is_volunteer should not be checked + + Then I press cancel + And press yes + Then I should see Your registration has been cancelled + + @javascript + Scenario: Register as participant + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named The Bike Bush exists in Musquodoboit Harbour NS + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with shout@me.com + And I press register + + And I fill in my firstname with Joe + And I fill in my lastname with Smith + And I fill in my username with Joey + And I check is_participant + And I press next + + And I see Do you require housing? + And I select couch from housing + And I fill in housing extra with I'm easy + + And I see Do you want to borrow a bike? + And I select Yes, from loaner bike + + And I see Would you like to host a workshop? + And I select No from workshop host + + And I see Anything else + And I fill in other with Nope + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + But my registration should not be confirmed + And I should get a confirm email + And I should see Who do you Represent + + But my registration is not complete + And my registration is not completed + + Then I click on The Bike Bush + And press next + And my registration is completed + + Then in the email I should see please confirm your registration + And in the email I should see a confirmation link registration + And I am not a user + + When I go to the confirmation page + And I should see Thanks for completing your registration + And my registration is confirmed + And my registration is complete + And my registration is completed + And I am a user + And I am a member of The Bike Bush + + @javascript + Scenario: Register as eager participant + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with goodgodwin@hotmail.com + And I press register + + And I fill in my firstname with Michael + And I fill in my lastname with Godwin + And I fill in my username with Godwin + And I check is_participant + And I press next + + And I see Do you require housing? + And I select bed from housing + And I fill in housing extra with I have a bad back + + And I see Do you want to borrow a bike? + And I select large from loaner bike + + And I see Would you like to host a workshop? + And I select No from workshop host + + And I see Anything else + And I fill in other with I'm coming two months early + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + And my registration should not be confirmed + And I should get a confirm email + And in the email I should see please confirm your registration + And in the email I should see a confirmation link + And I see Who do you Represent + + When I go to the confirmation page + Then I see Thanks for confirming + And I see Who do you Represent + And my registration is confirmed + But my registration is not complete + And my registration is not completed + + Then I click on Cool Cats Bikes + And press next + + Then I should see Thanks for completing your registration + And my registration is complete + And my registration is completed + But my registration is not paid + + Then I should get a Thanks email + And in the email I should see pay the registration donation + And in the email I should see a pay registration link + + When I go to the pay registration page + Then I see Thanks for completing your registration + And I see we ask that you pay + And I see payment amount + And I see submit payment + + Then I fill in payment amount with 12.34 + And press submit payment + Then I should see Your order summary + + When I finish paying + Then I should see We'll see you in Moncton + And my registration is paid + + @javascript + Scenario: Register as really eager participant + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with goodgodwin@hotmail.com + And I press register + + And I fill in my firstname with Michael + And I fill in my lastname with Godwin + And I fill in my username with Godwin + And I check is_participant + And I press next + + And I see Do you require housing? + And I select bed from housing + And I fill in housing extra with I have a bad back + + And I see Do you want to borrow a bike? + And I select large from loaner bike + + And I see Would you like to host a workshop? + And I select No from workshop host + + And I see Anything else + And I fill in other with I'm coming two months early + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + And my registration should not be confirmed + And I should get a confirm email + And in the email I should see please confirm your registration + And in the email I should see a confirmation link + And I see Who do you Represent + + When I go to the confirmation page + Then I see Thanks for confirming + And I see Who do you Represent + And my registration is confirmed + But my registration is not complete + And my registration is not completed + + Then I click on Cool Cats Bikes + And press next + + Then I should see Thanks for completing your registration + And my registration is complete + And my registration is completed + But my registration is not paid + + Then I should get a Thanks email + And in the email I should see pay the registration donation + And in the email I should see a pay registration link + + Then I should see Thanks for completing your registration + And I see we ask that you pay + And I see payment amount + And I see submit payment + + Then I fill in payment amount with 12.34 + And press submit payment + Then I should see Your order summary + + When I finish paying + Then I should see We'll see you in Moncton + And my registration is paid + + @javascript + Scenario: Register as eager with second thoughts + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with goodgodwin@hotmail.com + And I press register + + And I fill in my firstname with Michael + And I fill in my lastname with Godwin + And I fill in my username with Godwin + And I check is_participant + And I press next + + And I see Do you require housing? + And I select bed from housing + And I fill in housing extra with I have a bad back + + And I see Do you want to borrow a bike? + And I select large from loaner bike + + And I see Would you like to host a workshop? + And I select No from workshop host + + And I see Anything else + And I fill in other with I'm coming two months early + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + And my registration should not be confirmed + And I should get a confirm email + And in the email I should see please confirm your registration + And in the email I should see a confirmation link + And I see Who do you Represent + + When I go to the confirmation page + Then I see Thanks for confirming + And I see Who do you Represent + And my registration is confirmed + But my registration is not complete + And my registration is not completed + + Then I click on Cool Cats Bikes + And press next + + Then I should see Thanks for completing your registration + And my registration is complete + And my registration is completed + But my registration is not paid + + Then I should get a Thanks email + And in the email I should see pay the registration donation + And in the email I should see a pay registration link + + Then I should see Thanks for completing your registration + And I see we ask that you pay + And I see payment amount + And I see submit payment + + Then I fill in payment amount with 12.34 + And press submit payment + Then I should see Your order summary + + When I cancel the payment + Then I should see Thanks for completing your registration + And I see we ask that you pay + And my registration is not paid + + @javascript + Scenario: Register as workshop host + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named The Bike Bush exists in Musquodoboit Harbour NS + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with scream@me.com + And I press register + + And I fill in my firstname with Joe + And I fill in my lastname with Smith + And I fill in my username with Joey + And I check is_participant + And I press next + + And I see Do you require housing? + And I select couch from housing + And I fill in housing extra with I'm easy + + And I see Do you want to borrow a bike? + And I select Yes, from loaner bike + + And I see Would you like to host a workshop? + And I select Yes from workshop host + + And I see Anything else + And I fill in other with Nope + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + But my registration should not be confirmed + And I should get a confirm email + And I should see Who do you Represent + + But my registration is not complete + And my registration is not completed + + Then I click on The Bike Bush + And press next + + Then I should see Workshop Information + Then I fill in title with How make your shop more Capitalist + Then I set info to Lorem Ipsum and Stuff + Then I select organization management from stream + Then I select presentation from presentation style + Then I fill in notes with Down with all the anarchists + Then press next + + Then in the email I should see please confirm your registration + And in the email I should see a confirmation link registration + + When I go to the confirmation page + And I should see Thanks for completing your registration + And my registration is confirmed + And my registration is complete + And my registration is completed + + @javascript + Scenario: Register with new organization + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named The Bike Bush exists in Musquodoboit Harbour NS + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with example@example.com + And I press register + + And I fill in my firstname with Emma + And I fill in my lastname with Smith + And I fill in my username with Em + And I check is_participant + And I press next + + And I see Do you require housing? + And I select couch from housing + And I fill in housing extra with I'm easy + + And I see Do you want to borrow a bike? + And I select small from loaner bike + + And I see Would you like to host a workshop? + And I select No from workshop host + + And I see Anything else + And I fill in other with Nope + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + But my registration should not be confirmed + And I should get a confirm email + And I should see Who do you Represent + + But my registration is not complete + And my registration is not completed + + Then I check add new org + And I press next + + Then I should see Your Organization Information + Then I fill in name with The Bike Fridge + Then I set info to Lorem Ipsum and Stuff + Then I fill in organization email with info@bikefridge.org + Then I fill in street with 1044 Mushaboom Road + Then I fill in city with Mushaboom + Then I select ca from country + Then I select ns from territory + Then press next + + Then in the email I should see please confirm your registration + And in the email I should see a confirmation link registration + + When I go to the confirmation page + And I should see Thanks for completing your registration + And my registration is confirmed + And my registration is complete + And my registration is completed + And I am a member of The Bike Fridge + + @javascript + Scenario: Register with new organization in usa + Given There is an upcoming conference in Moncton NB + And Registration is open + And I am in San Francisco, California, USA + And an organization named The Bike Bush exists in Musquodoboit Harbour NS + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with example@example.com + And I press register + + And I fill in my firstname with Emma + And I fill in my lastname with Smith + And I fill in my username with Em + And I check is_participant + And I press next + + And I see Do you require housing? + And I select couch from housing + And I fill in housing extra with I'm easy + + And I see Do you want to borrow a bike? + And I select small from loaner bike + + And I see Would you like to host a workshop? + And I select No from workshop host + + And I see Anything else + And I fill in other with Nope + And I should not be registered for the conference + + And I press submit + + Then I should be registered for the conference + But my registration should not be confirmed + And I should get a confirm email + And I should see Who do you Represent + + But my registration is not complete + And my registration is not completed + + Then I check add new org + And I press next + + Then I should see Your Organization Information + Then I fill in name with The Bike Fridge + Then I set info to Lorem Ipsum and Stuff + Then I fill in organization email with info@bikefridge.org + Then I fill in street with 1044 Mushaboom Road + Then I fill in city with Mushaboom + Then I select us from country + Then I select ny from territory + Then press next + + Then in the email I should see please confirm your registration + And in the email I should see a confirmation link registration + + When I go to the confirmation page + And I should see Thanks for completing your registration + And my registration is confirmed + And my registration is complete + And my registration is completed + And I am a member of The Bike Fridge + + @javascript + Scenario: Lazy participant + Given There is an upcoming conference in Moncton NB + And Registration is open + And an organization named The Bike Bush exists in Musquodoboit Harbour NS + And an organization named Cool Cats Bikes exists in Sackville NB + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with example@example.com + And I press register + + And I press next + But I see please tell us your name + + Then I fill in my firstname with Emma + And I press next + But I see please tell us your name + + Then I fill in my lastname with Smith + And I press next + But I see attending the conference or volunteering + + Then I check is_participant + And I press next + + Then I select Yes from workshop host + And press submit + + Then I should be registered for the conference + But my registration should not be confirmed + And I should get a confirm email + And I should see Who do you Represent + + But my registration is not complete + And my registration is not completed + + Then I press next + But I see Please select an organization + + Then I click on The Bike Bush + And press next + + Then I should see Workshop Information + But press next + + But I should see Please give your workshop a title + Then I fill in title with Why do I have to give all this info right now? + And press next + + But I should see Please describe your workshop + Then I set info to Lorem Ipsum and Stuff + + Then I select organization management from stream + And I select presentation from presentation style + And press next + + Then I should see Thanks for submitting your registration + + Then in the email I should see please confirm your registration + And in the email I should see a confirmation link registration + + When I go to the confirmation page + And I should see Thanks for completing your registration + And my registration is confirmed + And my registration is complete + And my registration is completed + And I am a member of The Bike Bush + And My firstname should be Emma + And My lastname should be Smith + And My username should be Emma Smith diff --git a/features/step_definitions/interface_steps.rb b/features/step_definitions/interface_steps.rb index 2e97ad6..072c24b 100644 --- a/features/step_definitions/interface_steps.rb +++ b/features/step_definitions/interface_steps.rb @@ -1,13 +1,215 @@ Given(/^I am on the (.+) page$/) do |page_name| - visit path_to(page_name) + visit path_to(page_name.to_sym) end -Then(/^I can read about the current bikebike$/) do - within('#conference-name') { expect(page).to have_text 'Bike!Bike!' } - within('#conference-location') { expect(page).to have_text 'Columbus, Ohio' } - within('#conference-date') { expect(page).to have_text 'August 30 - September 1' } +Given(/^I am on the (.+) site$/) do |language| + ApplicationController::set_host (get_language_code(language) + '.bikebike.org') end -Then(/^I can register for the conference$/) do - expect(page).to have_link 'Register' +Given(/^I am in (.+)$/) do |location| + ApplicationController::set_location (location) +end + +When(/^I go to the (.+) page$/) do |page_name| + visit path_to(page_name.to_sym) +end + +When(/^(I )?(finish|cancel) (paying|(the )?payment)$/) do |a, action, b, c| + visit path_to((action == 'finish' ? 'confirm' : action) + ' payment') +end + +Given(/^There is an upcoming conference( in .+)?$/) do |location| + @last_conference = FactoryGirl.create(:upcoming_conference) + if location + @org = create_org(nil, location) + @last_conference.organizations << @org + @last_conference.save! + end +end + +Given(/^an organization( named .+)? exists( in .+)?$/) do |name, location| + if location =~ /every country/i + Carmen::World.instance.subregions.each { |country| + #puts "#{country.code}" + + if country.subregions? + country.subregions.each { |region| + org = Organization.new(name: rand(36**16).to_s(36), slug: rand(36**16).to_s(36))#create_org#(Forgery::LoremIpsum.sentence) + org.locations << Location.new(city: 'City', country: country.code, territory: region.code) + org.save! + } + else + org = Organization.new(name: rand(36**16).to_s(36), slug: rand(36**16).to_s(36))#create_org#(Forgery::LoremIpsum.sentence) + org.locations << Location.new(city: 'City', country: country.code) + org.save! + end + } + else + create_org(name ? name.gsub(/^\s*named\s+(.*?)\s*$/, '\1') : nil, location ? location.gsub(/^\s*in\s+(.*?)\s*$/, '\1') : nil) + end +end + +Given(/^Registration is (open|closed)$/) do |status| + @last_conference.registration_open = (status == 'open') + @last_conference.save! +end + +Then(/^I (should )?see (.+)$/) do | a, item | + if /(the )?Bike!Bike! logo$/ =~ item + expect(page).to have_selector('svg.logo') + elsif /(the|a)?\s?(.+) menu item$/ =~ item + within('#main-nav') { expect(page).to have_link Regexp.last_match(2) } + elsif /(the|a)?\s?(.+) image$/ =~ item + expect(page).to have_selector('#'+Regexp.last_match(2)+' img') + elsif /(the|a)?\s?(.+) link$/ =~ item + expect(page).to have_link Regexp.last_match(2) + else + expect(page).to have_text item + end +end + + +## ======= Forms ======= ## + +Then(/^(I )?click on (.+?)( button| link| which is hidden)?$/) do | a, item, type | + item = item.gsub(/^\s*(a|the)\s*(.*)$/, '\2') + if type && type.strip == 'button' + click_button(item) + elsif type && type.strip == 'link' + click_link(item) + elsif type && type =~ /hidden/ + find('[id$="' + item.gsub(/\s+/, '_') + '"]', :visible => false).click + else + page.find_link(item).trigger('click') + end +end + +Then(/^(I )?press (.+)$/) do | a, item | + click_link_or_button(locate(item)) +end + +Then(/^I (un)?check (.+)$/) do | state, item | + if state == 'un' + uncheck(locate(item)) + else + check(locate(item)) + end +end + +Then(/^I fill in (.+?) with (.+)$/) do | field, value | + field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2') + fill_in(locate(field), :with => value) + + if /email/ =~ field && !(/organization/ =~ field) + @last_email_entered = value + end +end + +Then(/^(my )?(.+)? should (not )?be set to (.+)$/) do | a, field, should, value | + field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2') + page.find('[id$="' + field.gsub(/\s+/, '_') + '"]').value.send(should.nil? ? 'should' : 'should_not', eq(value)) +end + +Then(/^(my )?(.+)? should (not )?be checked$/) do | a, field, should | + field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2') + page.find('[id$="' + field.gsub(/\s+/, '_') + '"]').send(should.nil? ? 'should' : 'should_not', be_checked) +end + +Then(/^I set (.+?) to (.+)$/) do | field, value | + field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2') + page.find('[id$="' + field.gsub(/\s+/, '_') + '"]', :visible => false).set value +end + +Then(/^(I )wait for (.+?) to appear$/) do | a, field | + count = 0 + element = nil + while element.nil? && count < 120 + begin element = page.find('[id$="' + field.gsub(/\s+/, '_') + '"]'); rescue; end + begin element ||= page.find('[id$="' + field.gsub(/\s+/, '_') + '"]', :visible => false); rescue; end + sleep(1) + count += 1 + end +end + +Then(/^show the page$/) do + print page.html + save_and_open_page +end + +Then(/^I select (.+?) from (.+)$/) do | value, field | + select(value, :from => locate(field)) +end + +## ======= Emails ======= ## + +Then(/^I should not get an email$/) do + ActionMailer::Base.deliveries.size.should eq 0 +end + +Then (/^I should get an? (.+) email$/) do |subject| + @last_email = ActionMailer::Base.deliveries.last + if @last_email_entered + @last_email.to.should include @last_email_entered + end + @last_email.subject.should include(subject) +end + +Then (/^the email should contain (.+)$/) do |value| + @last_email.parts.first.body.raw_source.should include(value) + @last_email.parts.last.body.raw_source.should include(value) +end + +Then (/^in the email I should see (.+)$/) do |value| + if /(an?|the|my) (.+) link/ =~ value + test = path_to Regexp.last_match(2) + @last_email.parts.first.body.raw_source.should include(test) + @last_email.parts.last.body.raw_source.should include(test) + else + @last_email.parts.first.body.raw_source.should include(value) + @last_email.parts.last.body.raw_source.should include(value) + end +end + +Then (/^I should (not )?be registered for the conference$/) do |state| + @last_registration = ConferenceRegistration.find_by(:email => @last_email_entered) + if state && state.strip == 'not' + @last_registration.should be_nil + else + @last_registration.should_not be_nil + end +end + +Then (/^my registration (should( not)? be|is( not)?) (confirmed|completed?|paid)$/) do |state, x, y, field| + ConferenceRegistration.find_by!(:email => @last_email_entered). + send(field == 'confirmed' ? 'is_confirmed' : (field == 'paid' ? 'payment_info' : field)). + send(state =~ / not/ ? 'should_not' : 'should', be) +end + +Then (/^I am( not)? a user$/) do |state| + User.find_by(:email => @last_email_entered). + send(state =~ / not/ ? 'should_not' : 'should', be) +end + +Then (/^I am( not)? a member of (.+)$/) do |state, org_name| + user = nil + should_be = !(state =~ / not/) + org = Organization.find_by(:name => org_name) + if should_be + org.should be + org.users.should be + elsif org.nil? || org.users.nil? + return + end + org.users.each { |u| + if u.email == @last_email_entered + user = u + end + } + user.send(should_be ? 'should' : 'should_not', be) +end + +Then (/^My (.+) should(not )? be (.+)$/) do |field, state, value| + User.find_by(:email => @last_email_entered). + send(field.gsub(/\s/, '_')). + send(state =~ / not/ ? 'should_not' : 'should', eq(value)) end diff --git a/features/support/env.rb b/features/support/env.rb index 64ddf61..f3f308d 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -5,6 +5,7 @@ # files. require 'cucumber/rails' +require 'capybara/poltergeist' # Capybara defaults to CSS3 selectors rather than XPath. # If you'd prefer to use XPath, just uncomment this line and adjust any @@ -31,11 +32,53 @@ ActionController::Base.allow_rescue = false # Remove/comment out the lines below if your app doesn't have a database. # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. begin - DatabaseCleaner.strategy = :transaction + DatabaseCleaner.strategy = :truncation + #DatabaseCleaner.clean_with(:truncation) rescue NameError - raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." + raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." end +add_translations = Array.new +Carmen::World.instance.subregions.each { |country| + add_translations << "world.#{country.code.downcase}.name" + if country.subregions? + country.subregions.each { |region| add_translations << "world.#{country.code.downcase}.#{region.code.downcase}.name" } + end +} + +I18n::Backend::BikeBike::init_tests!# add_translations + +#at_exit do +# I18n::Backend::BikeBike::end_tests! +#end + +Before('@javascript') do + ActiveRecord::Base.shared_connection = nil + ActiveRecord::Base.descendants.each do |model| + model.shared_connection = nil + end +end + +Before do + #DatabaseCleaner.start + Translation.connection.execute("INSERT INTO translations (locale, key, value) VALUES('en', 'time.formats.date', '%B %d, %Y');") + Translation.connection.execute("INSERT INTO translations (locale, key, value, is_proc) VALUES('en', 'date.month_names', '[\"~\", \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]', TRUE);") + ConferenceType.connection.execute("INSERT INTO conference_types (slug) VALUES ('bikebike'), ('regional'), ('bici-congreso')") + WorkshopStream.connection.execute("INSERT INTO workshop_streams (slug) VALUES ('mechanics'), ('leisure'), ('interorganizational_relations'), ('ethics_public_relations'), ('organization_management')") + WorkshopPresentationStyle.connection.execute("INSERT INTO workshop_presentation_styles (slug) VALUES ('discussion'), ('panel'), ('presentation'), ('hands-on'), ('other')") + #host! 'en.bikebike.org' + ApplicationController::set_host 'en.bikebike.org' + ApplicationController::set_location nil +end + +After do |scenario| + save_and_open_page if scenario.failed? +end + +#After do +# DatabaseCleaner.clean +#end + # You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios. # See the DatabaseCleaner documentation for details. Example: # @@ -54,5 +97,46 @@ end # Possible values are :truncation and :transaction # The :transaction strategy is faster, but might give you threading problems. # See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature -Cucumber::Rails::Database.javascript_strategy = :truncation +Cucumber::Rails::Database.javascript_strategy = :transaction +Capybara.register_driver :poltergeist_debug do |app| + Capybara::Poltergeist::Driver.new(app, :timeout => 120, inspector: true) +end +Capybara.javascript_driver = :poltergeist_debug +Geocoder.configure(:timeout => 60) + +def locate(id) + page.find('[id$="' + id.gsub(/\s+/, '_') + '"]')[:id] +end + +def create_org(name = nil, location = nil) + org = FactoryGirl.create(:org) + found_location = nil + if !location.nil? + l = Geocoder.search(location).first + begin + found_location = Location.new(city: l.city, territory: l.province_code, country: l.country_code, latitude: l.latitude, longitude: l.longitude) + rescue; end + if found_location.nil? + return + end + end + if !name.nil? + org.name = name + org.slug = org.generate_slug(name, found_location) + end + if !found_location.nil? + org.locations << found_location + end + org.save! + org +end +def get_language_code(language) + languages = { + 'english' => 'en', + 'french' => 'fr', + 'spanish' => 'es', + 'german' => 'de' + } + languages[language.downcase] +end diff --git a/features/support/factory_girl.rb b/features/support/factory_girl.rb new file mode 100644 index 0000000..3951634 --- /dev/null +++ b/features/support/factory_girl.rb @@ -0,0 +1,22 @@ +FactoryGirl.define do + factory :upcoming_conference, :class => 'Conference' do + title 'My Bike!Bike!' + slug 'MyBikeBike' + info 'Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.' + poster 'poster.jpg' + cover 'cover.jpg' + registration_open false + start_date Date.today - 30.days + end_date Date.today - 26.days + conference_type_id (ConferenceType.find_by(:slug => 'bikebike') || ConferenceType.create(:slug => 'bikebike')).id + end + + factory :org, :class => 'Organization' do + name 'My Organization' + info 'Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.' + avatar 'avatar.jpg' + cover 'cover.jpg' + end +end + +World(FactoryGirl::Syntax::Methods) \ No newline at end of file diff --git a/features/support/paths.rb b/features/support/paths.rb index b8adec2..f0591f1 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -1,18 +1,36 @@ module NavigationHelpers - def path_to(page_name) - case page_name - when /^landing$/i - path = 'root' - end + def path_to(page_name) + append_root = false + case page_name + when /^landing$/i + path = :root + when /^confirmation$/i + path = "/conferences/bikebike/#{@last_conference.slug}/register/confirm/#{@last_registration.confirmation_token}" + when /^pay registration$/i + path = "/conferences/bikebike/#{@last_conference.slug}/register/pay-registration/#{@last_registration.confirmation_token}" + when /^confirm payment$/i + path = "/conferences/bikebike/#{@last_conference.slug}/register/confirm-payment/#{@last_registration.payment_confirmation_token}" + when /^cancel payment$/i + path = "/conferences/bikebike/#{@last_conference.slug}/register/cancel-payment/#{@last_registration.confirmation_token}" + when /^translation list$/i + path = '/translations/' + when /^(.+) translations?$/i + path = '/translations/' + get_language_code(Regexp.last_match(1)) + when /^organization list$/i + path = '/organizations/' + end - begin - self.send((path + '_url').to_sym) - rescue Object => e - raise "Can't find mapping from \"#{page_name}\" to a path.\n" + - "#{path}_url\n" + - "Now, go and add a mapping in #{__FILE__}" - end - end + if path.is_a?(Symbol) + begin + path = self.send((path.to_s + '_url').to_sym).gsub(/^http:\/\/.+?(\/.*)$/, '\1') + rescue Object => e + raise "Can't find mapping from \"#{page_name}\" to a path.\n" + + "#{path}_url\n" + + "Now, go and add a mapping in #{__FILE__}" + end + end + path + end end World(NavigationHelpers) diff --git a/features/translations.feature b/features/translations.feature new file mode 100644 index 0000000..5c84218 --- /dev/null +++ b/features/translations.feature @@ -0,0 +1,16 @@ +Feature: Translation Pages + In order to Translate Bike!Bike! + As a visitor + + Scenario: Visit Translation List Page + Given I am on the English site + And I am on the translation list page + Then I see Translations + And I see list + And I see active + And I see inactive + + Scenario: Visit English Translation Page + Given I am on the English site + And I am on the english translations page + Then I see language translations diff --git a/features/volunteer-registration.feature b/features/volunteer-registration.feature new file mode 100644 index 0000000..6690693 --- /dev/null +++ b/features/volunteer-registration.feature @@ -0,0 +1,46 @@ +Feature: Volunteer Registration + In order to register to volunteer at the latest Bike!Bike! + As a visitor + + @javascript + Scenario: Register as volunteer + Given There is an upcoming conference in Moncton NB + And Registration is open + + When I go to the landing page + Then I see a Register Now link + And I click on the Register Now link + + And I fill in my email with example@example.com + And I press register + + And I fill in my firstname with Francis + And I fill in my lastname with Bacon + And I fill in my username with Bacon + And I check is_volunteer + And I press next + + Then I see Contact Information + And I fill in address with 1234 Some St. + And I fill in phone number with 555-555-5555 + + Then I see Do you have housing + And I fill in beds with 0 + And I fill in couch_space with 5 + And I fill in tents with 2 + + Then I see Anything else + And I fill in other with So excited! + + And I press next + + Then I should be registered for the conference + And my registration should not be confirmed + And I should get a confirm email + And in the email I should see please confirm your registration + And in the email I should see a confirmation link registration + + When I go to the confirmation page + Then I should see Thanks for completing your registration + And my registration is complete + And my registration is completed diff --git a/public/maps/Thumbs.db b/public/maps/Thumbs.db index f45eec3..8ea6334 100644 Binary files a/public/maps/Thumbs.db and b/public/maps/Thumbs.db differ diff --git a/public/registration_data/1ehptyshk26pjbe8/ba.png b/public/registration_data/1ehptyshk26pjbe8/ba.png new file mode 100644 index 0000000..2640c3c Binary files /dev/null and b/public/registration_data/1ehptyshk26pjbe8/ba.png differ diff --git a/public/registration_data/2zizzr5nokd1rh7d/Thumbs.db b/public/registration_data/2zizzr5nokd1rh7d/Thumbs.db new file mode 100644 index 0000000..8845387 Binary files /dev/null and b/public/registration_data/2zizzr5nokd1rh7d/Thumbs.db differ diff --git a/public/registration_data/2zizzr5nokd1rh7d/bikeagaindoor[1].jpg b/public/registration_data/2zizzr5nokd1rh7d/bikeagaindoor[1].jpg new file mode 100644 index 0000000..c4369ff Binary files /dev/null and b/public/registration_data/2zizzr5nokd1rh7d/bikeagaindoor[1].jpg differ diff --git a/public/registration_data/9vpeci4qzca7qs3o/Thumbs.db b/public/registration_data/9vpeci4qzca7qs3o/Thumbs.db new file mode 100644 index 0000000..152b7cb Binary files /dev/null and b/public/registration_data/9vpeci4qzca7qs3o/Thumbs.db differ diff --git a/public/registration_data/9vpeci4qzca7qs3o/bikeagaincolourlogo[1].gif b/public/registration_data/9vpeci4qzca7qs3o/bikeagaincolourlogo[1].gif new file mode 100644 index 0000000..254951c Binary files /dev/null and b/public/registration_data/9vpeci4qzca7qs3o/bikeagaincolourlogo[1].gif differ diff --git a/public/registration_data/c1g7e2jsyqrp62rv/Thumbs.db b/public/registration_data/c1g7e2jsyqrp62rv/Thumbs.db new file mode 100644 index 0000000..7a30df8 Binary files /dev/null and b/public/registration_data/c1g7e2jsyqrp62rv/Thumbs.db differ diff --git a/public/registration_data/c1g7e2jsyqrp62rv/bikeagaindoor[1].jpg b/public/registration_data/c1g7e2jsyqrp62rv/bikeagaindoor[1].jpg new file mode 100644 index 0000000..c4369ff Binary files /dev/null and b/public/registration_data/c1g7e2jsyqrp62rv/bikeagaindoor[1].jpg differ diff --git a/public/registration_data/c7evv341mlp3k4ek/Thumbs.db b/public/registration_data/c7evv341mlp3k4ek/Thumbs.db new file mode 100644 index 0000000..3b68320 Binary files /dev/null and b/public/registration_data/c7evv341mlp3k4ek/Thumbs.db differ diff --git a/public/registration_data/c7evv341mlp3k4ek/bikeagaindoor[1].jpg b/public/registration_data/c7evv341mlp3k4ek/bikeagaindoor[1].jpg new file mode 100644 index 0000000..c4369ff Binary files /dev/null and b/public/registration_data/c7evv341mlp3k4ek/bikeagaindoor[1].jpg differ diff --git a/public/registration_data/e0vs4ovunuo2i32i/ba.png b/public/registration_data/e0vs4ovunuo2i32i/ba.png new file mode 100644 index 0000000..2640c3c Binary files /dev/null and b/public/registration_data/e0vs4ovunuo2i32i/ba.png differ diff --git a/public/registration_data/lqgjjhzaew2klf7y/Thumbs.db b/public/registration_data/lqgjjhzaew2klf7y/Thumbs.db new file mode 100644 index 0000000..7c75e21 Binary files /dev/null and b/public/registration_data/lqgjjhzaew2klf7y/Thumbs.db differ diff --git a/public/registration_data/lqgjjhzaew2klf7y/bikeagaincolourlogo.gif b/public/registration_data/lqgjjhzaew2klf7y/bikeagaincolourlogo.gif new file mode 100644 index 0000000..254951c Binary files /dev/null and b/public/registration_data/lqgjjhzaew2klf7y/bikeagaincolourlogo.gif differ diff --git a/public/registration_data/qabyxh5an79d1sf1/Thumbs.db b/public/registration_data/qabyxh5an79d1sf1/Thumbs.db new file mode 100644 index 0000000..04608e0 Binary files /dev/null and b/public/registration_data/qabyxh5an79d1sf1/Thumbs.db differ diff --git a/public/registration_data/qabyxh5an79d1sf1/bikeagaindoor[1].jpg b/public/registration_data/qabyxh5an79d1sf1/bikeagaindoor[1].jpg new file mode 100644 index 0000000..c4369ff Binary files /dev/null and b/public/registration_data/qabyxh5an79d1sf1/bikeagaindoor[1].jpg differ diff --git a/public/registration_data/tlxsjj1ljiqbvoai/lb.jpg b/public/registration_data/tlxsjj1ljiqbvoai/lb.jpg new file mode 100644 index 0000000..af70161 Binary files /dev/null and b/public/registration_data/tlxsjj1ljiqbvoai/lb.jpg differ diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b69aa9b..b33f4c6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -43,6 +43,7 @@ RSpec.configure do |config| config.order = "random" config.before(:each) do + fu Translation.connection.execute("TRUNCATE TABLE translations RESTART IDENTITY;") translations = DevTranslation.connection.select_all("SELECT * FROM translations")