diff --git a/Gemfile b/Gemfile index b6fd6c0..35a2251 100644 --- a/Gemfile +++ b/Gemfile @@ -35,7 +35,7 @@ gem 'geocoder' gem 'paper_trail', '~> 3.0.5' gem 'sitemap_generator' gem 'activerecord-session_store' -gem 'paypal-express'#, '0.7.1' +gem 'paypal-express', '0.7.1' gem 'sass-json-vars' gem 'premailer-rails' gem 'redcarpet' diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index af59252..982285e 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -136,7 +136,7 @@ } window.initNodeFunctions = [ function(node) { - forEachElement('.number-field,.email-field,.text-field', function(field) { + forEachElement('.number-field,.email-field,.text-field,.password-field', function(field) { var input = field.querySelector('input'); var positionLabel = function(input) { field.classList[input.value ? 'remove' : 'add']('empty'); diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss index ac10e75..3953d17 100644 --- a/app/assets/stylesheets/_application.scss +++ b/app/assets/stylesheets/_application.scss @@ -333,6 +333,7 @@ input { .number-field, .email-field, .telephone-field, +.password-field, .text-field { position: relative; margin-bottom: 2em; @@ -402,6 +403,7 @@ input { } .number-field, .email-field, +.password-field, .telephone-field, .text-field, .text-area-field { @@ -605,10 +607,8 @@ input { content: '+'; border: 0; font-size: 2.5em; - // top: 0;//-0.25em; - // left: 0.175em; - top: -0.15em; - left: 0.05em; + top: -0.025em; + left: 0.175em; line-height: 1em; color: #FFF; height: 1em; @@ -641,6 +641,13 @@ input { display: block; margin: 0 2em 5em; font-size: 0.75em; + + input[type="radio"] + label { + @include after { + top: -0.15em; + left: 0.05em; + } + } } .check-box-field.inline { @@ -2285,7 +2292,7 @@ html :focus { #main .skip { button { - background-color: #CCC; + background-color: #888; } } @@ -3175,6 +3182,13 @@ html[data-lingua-franca-example="html"] { width: 100%; margin-bottom: 2em; } + + &.inline-label { + label { + float: left; + margin-right: 0.5em; + } + } } .toggleable { @@ -3468,67 +3482,6 @@ html[data-ontop] { @include _(box-shadow, 0 0 2em -0.5em rgba(0, 0, 0, 0.5)); } } - - .flow-steps { - #registration-steps { - li { - display: inline-block; - text-align: center; - float: left; - - @include after { - content: ''; - top: 1.125em; - left: auto; - right: -0.25em; - @include _(transform, rotate(45deg)); - } - - /*&.enabled:hover, - &.enabled:hover ~ li { - @include after { - @include _(transform, rotate(-135deg)); - background-color: transparent; - } - }*/ - - &:first-child { - @include _(border-radius, 0.15em 0 0 0.15em); - } - - &:last-child { - @include _(border-radius, 0); - } - } - } - - #post-registration-steps { - margin-bottom: -2em; - - li { - &:last-child { - @include _(border-bottom-right-radius, 0.15em); - @include _(border-bottom-left-radius, 0.15em); - } - - &:first-child { - @include _(border-top-right-radius, 0.15em); - @include _(border-bottom-left-radius, 0); - } - } - } - - ul { - display: inline-block; - text-align: left; - margin-top: -4em; - vertical-align: top; - } - - li { - text-align: center; - } - } #registration-admin-menu { a { @@ -3698,6 +3651,61 @@ html[data-ontop] { } } +@media (min-width: 825px) { + .flow-steps { + #registration-steps { + li { + display: inline-block; + text-align: center; + float: left; + + @include after { + content: ''; + top: 1.125em; + left: auto; + right: -0.25em; + @include _(transform, rotate(45deg)); + } + + &:first-child { + @include _(border-radius, 0.15em 0 0 0.15em); + } + + &:last-child { + @include _(border-radius, 0); + } + } + } + + #post-registration-steps { + margin-bottom: -2em; + + li { + &:last-child { + @include _(border-bottom-right-radius, 0.15em); + @include _(border-bottom-left-radius, 0.15em); + } + + &:first-child { + @include _(border-top-right-radius, 0.15em); + @include _(border-bottom-left-radius, 0); + } + } + } + + ul { + display: inline-block; + text-align: left; + margin-top: -4em; + vertical-align: top; + } + + li { + text-align: center; + } + } +} + @include breakpoint(large) { #main-nav { .nav { @@ -3759,8 +3767,7 @@ html[data-ontop] { overflow: visible; padding: 0; width: 100%; - margin-bottom: 1em; - //height: 4.5em; + margin-bottom: 2.5em; footer { max-width: $row-width; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 96aeaeb..87939ec 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -235,12 +235,20 @@ class ApplicationController < LinguaFrancaApplicationController end expiry ||= (Time.now + 12.hours) session[:confirm_uid] = user.id + + # send the confirmation email and make sure it get sent as quickly as possible UserMailer.send_mail! :email_confirmation do EmailConfirmation.create(user_id: user.id, expiry: expiry, url: url) end end def user_settings + @conferences = Array.new + if logged_in? + Conference.all.each do | conference | + @conferences << conference if conference.host? current_user + end + end @main_title = @page_title = 'page_titles.user_settings.Your_Account' end diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 17764fe..339877b 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -594,6 +594,32 @@ class ConferencesController < ApplicationController availability: [ params[:first_day], params[:last_day] ], notes: params[:notes] } + when :questions + @registration.housing = params[:housing] + @registration.arrival = params[:arrival] + @registration.departure = params[:departure] + @registration.bike = params[:bike] + @registration.food = params[:food] + @registration.allergies = params[:allergies] + @registration.other = params[:other] + when :payment + amount = params[:amount].to_f + + if amount > 0 + @registration.payment_confirmation_token = ENV['RAILS_ENV'] == 'test' ? 'token' : Digest::SHA256.hexdigest(rand(Time.now.to_f * 1000000).to_i.to_s) + # @registration.save + + host = "#{request.protocol}#{request.host_with_port}" + response = PayPal!.setup( + PayPalRequest(amount), + register_paypal_confirm_url(@this_conference.slug, :paypal_confirm, @registration.payment_confirmation_token), + register_paypal_confirm_url(@this_conference.slug, :paypal_cancel, @registration.payment_confirmation_token) + ) + if ENV['RAILS_ENV'] != 'test' + redirect_to response.redirect_uri + end + return + end end if @errors.present? @@ -1126,7 +1152,7 @@ class ConferencesController < ApplicationController def admin_update set_conference - set_conference_registration + # set_conference_registration return do_403 unless @this_conference.host? current_user # set the page title in case we render instead of redirecting @@ -1138,11 +1164,16 @@ class ConferencesController < ApplicationController when 'edit' case params[:button] when 'save' + @this_conference.registration_status = params[:registration_status] @this_conference.info = LinguaFranca::ActiveRecord::UntranslatedValue.new(params[:info]) unless @this_conference.info! == params[:info] params[:info_translations].each do | locale, value | - @this_conference.set_column_for_locale(:info, locale, value, current_user.id) unless value = @this_conference._info(locale) + @this_conference.set_column_for_locale(:info, locale, value, current_user.id) unless value == @this_conference._info(locale) end + @this_conference.paypal_email_address = params[:paypal_email_address] + @this_conference.paypal_username = params[:paypal_username] + @this_conference.paypal_password = params[:paypal_password] + @this_conference.paypal_signature = params[:paypal_signature] @this_conference.save return redirect_to register_step_path(@this_conference.slug, :administration) when 'add_member' @@ -2096,21 +2127,21 @@ class ConferencesController < ApplicationController def registration_steps(conference = nil) conference ||= @this_conference || @conference status = conference.registration_status - return [] unless status == :pre || status == :open + # return [] unless status == :pre || status == :open - steps = [ + steps = status == :pre || status == :open ? [ :policy, :contact_info, :questions, :hosting, :payment, - :workshops, - :administration - ] + :workshops + ] : [] - steps -= [:questions, :payment] unless status == :open + steps -= [:questions] unless status == :open + steps -= [:payment] unless status == :open && conference.paypal_email_address.present? && conference.paypal_username.present? && conference.paypal_password.present? && conference.paypal_signature.present? if @registration.present? - if view_context.same_city?(@registration.city, @conference.location) + if view_context.same_city?(@registration.city, conference.location) steps -= [:questions] else steps -= [:hosting] @@ -2119,13 +2150,13 @@ class ConferencesController < ApplicationController steps -= [:hosting, :questions] end - steps -= [:administration] unless @registration.present? && @conference.host?(current_user) + steps += [:administration] if conference.host?(current_user) return steps end def required_steps(conference = nil) - # return the intersection of current steps and reuired steps + # return the intersection of current steps and required steps registration_steps(conference || @this_conference || @conference) & # current steps [:policy, :contact_info, :hosting, :questions] # all required steps end @@ -2349,9 +2380,9 @@ class ConferencesController < ApplicationController def PayPal! Paypal::Express::Request.new( - :username => @this_conference.paypal_username, - :password => @this_conference.paypal_password, - :signature => @this_conference.paypal_signature + username: @this_conference.paypal_username, + password: @this_conference.paypal_password, + signature: @this_conference.paypal_signature ) end @@ -2363,7 +2394,7 @@ class ConferencesController < ApplicationController :amount => amount.to_f, # item value :custom_fields => { CARTBORDERCOLOR: "00ADEF", - LOGOIMG: "https://cdn.bikebike.org/assets/bblogo-paypal.png" + LOGOIMG: "https://en.bikebike.org/assets/bblogo-paypal.png" } ) end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ac193d5..7886722 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -754,6 +754,18 @@ module ApplicationHelper return days end + def registration_status_options_list(conference = nil) + conference ||= @this_conference || @conference + return [] unless conference + + options = Array.new + [:closed, :pre, :open].each do | opt | + options << [(_"forms.labels.generic.registration_statuses.#{opt}"), opt] + end + + return options + end + def day_select(value = nil, args = {}) selectfield :day, value, conference_days_options_list(:during, nil, args[:format]), args end @@ -823,7 +835,7 @@ module ApplicationHelper def registration_step_menu steps = current_registration_steps(@registration) - return '' unless steps.present? + return '' unless steps.present? && steps.length > 1 pre_registration_steps = '' post_registration_steps = '' @@ -889,7 +901,7 @@ module ApplicationHelper steps = '' admin_steps.each do | step | steps += content_tag(:li, class: (step.to_s == @admin_step ? :current : nil)) do - link_to _("menu.submenu.admin.#{step.to_s.titlecase}"), step == :edit ? + link_to _("menu.submenu.admin.#{step.to_s.titlecase.gsub(/\s/, '_')}"), step == :edit ? register_step_path(@this_conference.slug, :administration) : administration_step_path(@this_conference.slug, step.to_s) end @@ -1082,6 +1094,10 @@ module ApplicationHelper textfield(name, value, options.merge({type: :email})) end + def passwordfield(name, value, options = {}) + textfield(name, value, options.merge({type: :password})) + end + def textfield(name, value, options = {}) html = '' id = name.to_s.gsub('[', '_').gsub(']', '') @@ -1127,6 +1143,8 @@ module ApplicationHelper input_options[:autocomplete] = 'email' when :phone input_options[:autocomplete] = 'tel' + when :paypal_email_address, :paypal_username, :paypal_password, :paypal_signature + input_options[:autocomplete] = 'false' end case options[:type] @@ -1140,12 +1158,14 @@ module ApplicationHelper class: [ "#{(options[:type] || :text).to_s}-field", 'input-field', + value.present? ? nil : 'empty', options[:big] ? 'big' : nil, options[:small] ? 'small' : nil, options[:stretch] ? 'stretch-item' : nil, options[:full] ? 'full' : nil, + options[:inline_label] ? 'inline-label' : nil, (@errors || {})[name].present? ? 'has-error' : nil - ]) + ].compact) html += _original_content(options[:original_value], options[:original_lang]) if options[:original_value].present? diff --git a/app/views/application/user_settings.html.haml b/app/views/application/user_settings.html.haml index ee07852..cab5782 100644 --- a/app/views/application/user_settings.html.haml +++ b/app/views/application/user_settings.html.haml @@ -7,6 +7,11 @@ - if @conference.present? && (@conference.registration_status == :pre || @conference.registration_status == :open) %p=_'articles.user_settings.paragraphs.conference_registration', :t = link_to (_'actions.conference.edit_registration'), register_path(@conference.slug), class: :button + - if @conferences.present? + %h3=_'articles.user_settings.headings.Your_Conferences' + - @conferences.each do | conference | + = link_to (_!conference.title), administration_step_path(conference.slug, :edit), class: :button + = form_tag update_settings_path do = textfield :name, current_user.name, required: true, heading: 'articles.conference_registration.headings.name', big: true diff --git a/app/views/conferences/_questions.html.haml b/app/views/conferences/_questions.html.haml index 50231d1..e98ec2d 100644 --- a/app/views/conferences/_questions.html.haml +++ b/app/views/conferences/_questions.html.haml @@ -13,4 +13,4 @@ = columns(medium: 12) do = textfield :allergies, @registration.allergies, heading: 'articles.conference_registration.headings.allergies' = textarea :other, @registration.other, plain: true, heading: 'articles.conference_registration.headings.other' - = button_tag :register, :value => :save + = button_tag :register, :value => :questions diff --git a/app/views/conferences/admin/_edit.html.haml b/app/views/conferences/admin/_edit.html.haml index f50f0f1..7e505e0 100644 --- a/app/views/conferences/admin/_edit.html.haml +++ b/app/views/conferences/admin/_edit.html.haml @@ -1,8 +1,15 @@ = form_tag administration_update_path(@this_conference.slug, :edit) do + = selectfield :registration_status, @this_conference.registration_status || 'closed', registration_status_options_list, small: true, inline_label: true = textarea :info, @this_conference.info!, heading: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', lang: @this_conference.locale, edit_on: :focus - I18n.backend.enabled_locales.each do | locale | - if locale.to_s != @this_conference.locale.to_s = textarea "info_translations[#{locale.to_s}]", @this_conference._info(locale), label: 'translate.pages.Locale_Translation', vars: { language: _("languages.#{locale}") }, lang: locale, edit_on: :focus + %h4=_'articles.admin.edit.headings.paypal_info', :t + %p=(_'articles.admin.edit.paragraphs.paypal_info', :p).html_safe + = emailfield :paypal_email_address, @this_conference.paypal_email_address || @this_conference.email_address || (@this_conference.organizations.present? && @this_conference.organizations.first.present? ? @this_conference.organizations.first.email_address : nil) + = textfield :paypal_username, @this_conference.paypal_username + = passwordfield :paypal_password, @this_conference.paypal_password + = textfield :paypal_signature, @this_conference.paypal_signature .actions.right = button_tag :save, value: :save %h4=_'articles.admin.edit.headings.host_organizations' diff --git a/config/environments/development.rb b/config/environments/development.rb index 0aeda92..2e1bda6 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -58,5 +58,5 @@ BikeBike::Application.configure do # to deliver to the browser instead of email config.action_mailer.delivery_method = :letter_opener - # Paypal.sandbox! + Paypal.sandbox! end diff --git a/config/locales/en.yml b/config/locales/en.yml index ad3bc9a..6c09f1b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5302,6 +5302,13 @@ en: amenities: Amenities edit_event: Edit Event edit_location: Edit Location + edit: + headings: + host_organizations: Host Organizations + members: Organization Members + paypal_info: PayPal Info + paragraphs: + paypal_info: PayPal info is used for donations and fee payments. You must enter all fields to enable online fee payments, see the PayPal API credential guide for more information. contact: headings: contact: Send us a question or a complement @@ -5365,8 +5372,8 @@ en: preferred_language: What is your preferred language? location: Where are you coming from? name: What is your name? - Payment: Payment - payment: Payment + Payment: Registration Fees + payment: Donation Allergies: Allergies Stats: Stats Workshops: Workshops @@ -5388,12 +5395,16 @@ en: Verify_Account: Verify your account Hosting: Hosting can_provide_housing: Can you provide housing to attendees visiting the city? + questions: Your Visit host: considerations: Special Considerations space: Available Space availability: Availability address: Address notes: Notes + admin: + edit: + info: 'Conference Info' paragraphs: Policy_Agreement: Ensuring that all attendees feel welcome, safe, and respected at all times is especially important to us all. Please ensure that you have fully read and understand our safer spaces policy below, if you have any questions or concerns you can reach out to the organizers at any time. Confirm_Agreement: By clicking the "I Agree" button, you are pledging to do @@ -5642,6 +5653,15 @@ en: reasons: website: Something about the website conference: Something about the conference + paypal_email_address: PayPal Email Address + paypal_username: PayPal API Username + paypal_password: PayPal API Password + paypal_signature: PayPal Signature + registration_statuses: + closed: Closed + open: Open + pre: Pre-Registration + registration_status: Registration Status actions: generic: login: Sign In @@ -5673,6 +5693,7 @@ en: set_host: Set Host add_comment: Add Comment reply: Reply + add_member: Add aria: remove_interest: Click if you are no longer interested in this workshop show_interest: Click if you are interested in this workshop @@ -5748,6 +5769,7 @@ en: Meals: Meals Events: Events Schedule: Schedule + Workshop_Times: Workshop Times actions: workshops: create: New Workshop