diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a7514f19..0dc492c9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -507,6 +507,7 @@ RSpec/AnyInstance: Exclude: - 'spec/controllers/admin/rooms_controller_spec.rb' - 'spec/controllers/admin/sponsorship_levels_controller_spec.rb' + - 'spec/controllers/admin/tickets_controller_spec.rb' - 'spec/controllers/admin/tracks_controller_spec.rb' - 'spec/controllers/admin/users_controller_spec.rb' - 'spec/controllers/conference_registration_controller_spec.rb' diff --git a/.ruby-version b/.ruby-version index 437459cd..0cadbc1e 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.0 +2.5.5 diff --git a/CHANGES.md b/CHANGES.md index db20a234..432cdcdf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,12 @@ Not release yet... ## Update from 1.0 +### Dropped travel information +We have dropped input and storage of travel schedules for event registrants. If +you would like to continue to collect travel schedules, please create a custom +survey for this purpose. +_Please be aware that existing travel data will be destroyed during migration._ + ### Multiple Schedules A conference can have multiple schedules now so it's easier for organizers to test schedules and collaborate on different versions. diff --git a/Gemfile b/Gemfile index b281e1aa..ad32fc93 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' -ruby ENV['OSEM_RUBY_VERSION'] || '2.5.0' +ruby ENV['OSEM_RUBY_VERSION'] || '2.5.5' # rails-assets requires >= 1.8.4 if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4') @@ -20,7 +20,6 @@ gem 'puma', '~> 3.0' gem 'responders', '~> 2.0' # as supported databases -gem 'mysql2' gem 'pg' # for tracking data changes @@ -38,8 +37,8 @@ gem 'rails-i18n' gem 'devise' gem 'devise_ichain_authenticatable' -# for openID authentication gem 'omniauth' +gem 'omniauth-discourse' gem 'omniauth-facebook' gem 'omniauth-github' gem 'omniauth-google-oauth2' @@ -143,8 +142,7 @@ gem 'rqrcode' gem 'axlsx', git: 'https://github.com/randym/axlsx.git' gem 'axlsx_rails' -# as error catcher -gem 'airbrake' +gem 'sentry-raven' # to make links faster gem 'turbolinks' diff --git a/Gemfile.lock b/Gemfile.lock index 81a6be64..4eb23f40 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,10 +68,6 @@ GEM addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) afm (0.2.2) - airbrake (9.2.2) - airbrake-ruby (~> 4.4) - airbrake-ruby (4.4.0) - rbtree3 (~> 0.5) ajax-datatables-rails (0.4.3) railties (>= 4.0) archive-zip (0.12.0) @@ -130,7 +126,6 @@ GEM url coderay (1.1.1) concurrent-ruby (1.1.5) - connection_pool (2.2.2) countable-rails (0.0.1) railties (>= 3.1) countries (3.0.0) @@ -301,13 +296,10 @@ GEM monetize (~> 1.9.0) money (~> 6.13.2) railties (>= 3.0) - multi_json (1.13.1) + multi_json (1.14.1) multi_xml (0.6.0) multipart-post (2.1.1) - mysql2 (0.5.2) nenv (0.3.0) - net-http-persistent (3.0.1) - connection_pool (~> 2.2) netrc (0.11.0) nio4r (2.5.2) nokogiri (1.10.8) @@ -324,7 +316,9 @@ GEM omniauth (1.9.0) hashie (>= 3.4.6, < 3.7.0) rack (>= 1.6.2, < 3) - omniauth-facebook (5.0.0) + omniauth-discourse (1.0.0) + omniauth (~> 1.0) + omniauth-facebook (6.0.0) omniauth-oauth2 (~> 1.2) omniauth-github (1.3.0) omniauth (~> 1.5) @@ -441,7 +435,6 @@ GEM rb-fsevent (0.10.3) rb-inotify (0.10.0) ffi (~> 1.0) - rbtree3 (0.5.0) rdoc (6.0.4) rdoc-generator-fivefish (0.4.0) inversion (~> 1.1) @@ -525,6 +518,8 @@ GEM selenium-webdriver (3.142.6) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) + sentry-raven (2.13.0) + faraday (>= 0.7.6, < 1.0) sexp_processor (4.11.0) shellany (0.0.1) shoulda-matchers (4.1.2) @@ -553,13 +548,11 @@ GEM activesupport (>= 4.0) sprockets (>= 3.0.0) sqlite3 (1.4.2) - stripe (4.21.3) - faraday (~> 0.13) - net-http-persistent (~> 3.0) - stripe-ruby-mock (2.5.8) + stripe (5.14.0) + stripe-ruby-mock (3.0.1) dante (>= 0.2.0) multi_json (~> 1.0) - stripe (>= 2.0.3) + stripe (> 5, < 6) sysexits (1.2.0) temple (0.8.0) thor (0.20.3) @@ -616,7 +609,6 @@ DEPENDENCIES active_model_serializers acts_as_commentable_with_threading acts_as_list - airbrake ajax-datatables-rails autoprefixer-rails awesome_nested_set @@ -665,9 +657,9 @@ DEPENDENCIES mina mini_magick money-rails - mysql2 nokogiri (>= 1.8.1) omniauth + omniauth-discourse omniauth-facebook omniauth-github omniauth-google-oauth2 @@ -707,6 +699,7 @@ DEPENDENCIES ruby-oembed sass-rails (>= 4.0.2) selectize-rails + sentry-raven shoulda-matchers skylight spring-commands-rspec @@ -726,7 +719,7 @@ DEPENDENCIES whenever RUBY VERSION - ruby 2.5.0p0 + ruby 2.5.5p157 BUNDLED WITH 1.17.3 diff --git a/app/assets/images/snapcon_logo.png b/app/assets/images/snapcon_logo.png new file mode 100644 index 00000000..cec0ed9b Binary files /dev/null and b/app/assets/images/snapcon_logo.png differ diff --git a/app/assets/javascripts/osem-datepickers.js b/app/assets/javascripts/osem-datepickers.js index 1408a26c..8b808b63 100644 --- a/app/assets/javascripts/osem-datepickers.js +++ b/app/assets/javascripts/osem-datepickers.js @@ -11,39 +11,6 @@ $(function () { format: 'YYYY-MM-DD HH:mm' }); - $("#registration-arrival-datepicker").datetimepicker({ - useCurrent: false, - stepping: 15, - sideBySide: true, - format: "YYYY-MM-DD HH:mm", - // arrival_date <= end_date - maxDate : $("#registration-arrival-datepicker").attr('end_date') - }); - - $("#registration-departure-datepicker").datetimepicker({ - useCurrent: false, - stepping: 15, - sideBySide: true, - format: "YYYY-MM-DD HH:mm", - // departure_date > start_date - minDate : $("#registration-arrival-datepicker").attr('start_date') - }); - - $("#registration-arrival-datepicker").on("dp.change",function (e) { - // departure_date > start_date,arrival_date - if ((new Date(e.date).getTime()) > (new Date($("#registration-arrival-datepicker").attr('start_date')).getTime())){ - $('#registration-departure-datepicker').data("DateTimePicker").minDate(e.date); - } - else{ - $('#registration-departure-datepicker').data("DateTimePicker").minDate($("#registration-arrival-datepicker").attr('start_date')); - } - }); - - // departure_date >= arrival_date - $("#registration-departure-datepicker").on("dp.change",function (e) { - $('#registration-arrival-datepicker').data("DateTimePicker").maxDate(e.date); - }); - $("#conference-start-datepicker").datetimepicker({ useCurrent: false, format: "YYYY-MM-DD" diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 567fa050..0b80bc19 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -2,6 +2,13 @@ *= require strap-on *= require formtastic-bootstrap *= require dataTables/bootstrap/3/jquery.dataTables.bootstrap + *= require selectize + *= require selectize.bootstrap3 + *= require bootstrap-select + *= require bootstrap-markdown + *= require bootstrap-datetimepicker + *= require leaflet + *= require osem *= require osem-rating *= require osem-schedule @@ -10,15 +17,9 @@ *= require osem-splash *= require font-awesome *= require osem-fonts - *= require bootstrap-markdown - *= require bootstrap-datetimepicker - *= require leaflet *= require bootstrap3-switch *= require osem-payments *= require osem-navbar - *= require selectize - *= require selectize.bootstrap3 *= require mastodon - *= require bootstrap-select *= require conferences */ diff --git a/app/assets/stylesheets/osem-navbar.scss b/app/assets/stylesheets/osem-navbar.scss index 011ebc89..89aa2dce 100644 --- a/app/assets/stylesheets/osem-navbar.scss +++ b/app/assets/stylesheets/osem-navbar.scss @@ -1,4 +1,6 @@ @import "breakpoints.scss"; +@import "osem-variables.scss"; + .nav-osem { border: none; @include breakpoint(xs) { @@ -29,7 +31,23 @@ } } .dropdown-menu { - padding: 17px; min-width: 225px; } + + &.navbar-default { + .navbar-nav > .open > a { + &:hover, &:focus { + color: $navbar-default-link-color; + } + } + } + + .navbar-brand img { + margin-top: -5px; + max-height: 100%; + } + + .trapezoid { + border-top-color: $navbar-default-bg; + } } diff --git a/app/assets/stylesheets/osem-schedule.scss b/app/assets/stylesheets/osem-schedule.scss index 1cf1efec..b7c4e3ac 100644 --- a/app/assets/stylesheets/osem-schedule.scss +++ b/app/assets/stylesheets/osem-schedule.scss @@ -64,9 +64,8 @@ #schedule td.event { background-image: linear-gradient(to top, rgb(247,250,242) 24%, rgb(194,232,190) 97%, rgb(194,232,190) 100%); - -cursor: pointer; -padding: 3px 2px; + cursor: pointer; + padding: 3px 2px; } #schedule td.event:hover diff --git a/app/assets/stylesheets/osem-splash.scss b/app/assets/stylesheets/osem-splash.scss index ce0418d6..e2bdda65 100644 --- a/app/assets/stylesheets/osem-splash.scss +++ b/app/assets/stylesheets/osem-splash.scss @@ -1,4 +1,5 @@ @import "breakpoints.scss"; +@import "osem-variables.scss"; #splash { // Counter the general padding for #content @@ -6,18 +7,30 @@ section { padding-top: 60px; padding-bottom: 60px; + + .trapezoid { + top: 60px + $trapezoid-height; + } } section:nth-child(even) { - background: none repeat scroll 0 0 #e0e0e0; - color: #555; + background: none repeat scroll 0 0 #eee; + color: #333; + + .trapezoid { + border-top-color: #eee; + } } section:nth-child(odd) { background: none repeat scroll 0 0 #ffffff; - color: #7b7b7b; + color: #333; .thumbnail { background: none repeat scroll 0 0 #e0e0e0; } + + .trapezoid { + border-top-color: #fff; + } } .cta-button { @@ -32,11 +45,15 @@ padding-top: 100px; padding-bottom: 100px; .container { - #header { + #header-no-image { background-color: rgba(224, 224, 224,.80); padding-top: 20px; padding-bottom: 20px; } + + #header-image { + color: #FFF; + } } } @@ -67,6 +84,10 @@ #venue-pic { margin-top: 20px; } + // The venue section has less padding. + .trapezoid { + top: $trapezoid-height; + } } #lodging { @@ -93,6 +114,14 @@ } } + #tickets { + a { + &:hover, &:focus { + text-decoration: none; + } + } + } + #sponsors { .img-sponsor { max-height: 100px; @@ -116,14 +145,13 @@ } #social-media{ - background: none repeat scroll 0 0 #2f2f2f; - padding-top: 60px; - padding-bottom: 60px; + background: none repeat scroll 0 0 #0C3559; + padding: 50px 20px; i{ - color: #4a4a4a; + color: #FFF; } i:hover{ - color: #16a085; + color: #F2E205; } a{ padding-left: 100px; @@ -164,11 +192,11 @@ i.fa { line-height: inherit; } - &.show { - visibility:visible; - cursor:pointer; - opacity: 1.0; - } + // &.show { + // visibility:visible; + // cursor:pointer; + // opacity: 1.0; + // } a { color: white; } diff --git a/app/assets/stylesheets/osem-variables.scss b/app/assets/stylesheets/osem-variables.scss new file mode 100644 index 00000000..1ae23c03 --- /dev/null +++ b/app/assets/stylesheets/osem-variables.scss @@ -0,0 +1,14 @@ +// This file is included *early* in CSS order! +// These variables change bootstrap defaults. + +$navbar-default-bg: #0C3559; +$navbar-default-link-active-bg: rgb(8,8,8); +$navbar-default-border: 1px solid #d4d4d4; +$navbar-default-color: #FFF; +$navbar-default-link-color: #FFF; +$navbar-default-link-hover-color: #F2E205; +$navbar-default-link-active-hover-color: #FFF; + + +// The hiegh of the section tabs that are like Snap! blocks. +$trapezoid-height: 14px; diff --git a/app/assets/stylesheets/osem.scss b/app/assets/stylesheets/osem.scss index 04da1a37..bcf37d4f 100644 --- a/app/assets/stylesheets/osem.scss +++ b/app/assets/stylesheets/osem.scss @@ -1,3 +1,4 @@ +@import "osem-variables"; @import "bootstrap/mixins"; html { @@ -7,15 +8,31 @@ html { body { /* Margin bottom by 2 times the footer height */ - margin-bottom: 60px; + margin-bottom: 85px; /* Margin bottom by navbar height */ padding-top: 60px; + font-size: 16px; } #content { padding-bottom: 60px; } +// Designed to be the last element in a section / nav +// Makes a little "puzzle piece" connector. +.trapezoid { + position: relative; + margin-left: 60px; + border-top: $trapezoid-height solid; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + height: 0; + width: 64px; + margin-top: -1 * $trapezoid-height; + top: $trapezoid-height; + z-index: 1000; +} + #footer { position: absolute; bottom: 0; diff --git a/app/assets/stylesheets/strap-on.scss b/app/assets/stylesheets/strap-on.scss index 571161e6..69538d2e 100644 --- a/app/assets/stylesheets/strap-on.scss +++ b/app/assets/stylesheets/strap-on.scss @@ -1,10 +1,5 @@ -$navbar-default-bg: #299a0b; -$navbar-default-link-active-bg: #DFE0DF; -$navbar-default-border: 1px solid #d4d4d4; -$navbar-default-color: #ffffff; -$navbar-default-link-color: #ffffff; -$navbar-default-link-hover-color: #000000; - +// Place bootstrap variable customizations in the file below. +@import "osem-variables"; @import 'bootstrap-datetimepicker'; @import "bootstrap-sprockets"; diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb index e361086d..ee8cee00 100644 --- a/app/controllers/admin/commercials_controller.rb +++ b/app/controllers/admin/commercials_controller.rb @@ -17,10 +17,10 @@ module Admin if @commercial.save redirect_to admin_conference_commercials_path, - notice: 'Commercial was successfully created.' + notice: 'Materials were successfully created.' else redirect_to admin_conference_commercials_path, - error: 'An error prohibited this Commercial from being saved: '\ + error: 'An error prohibited materials from being saved: '\ "#{@commercial.errors.full_messages.join('. ')}." end @@ -29,17 +29,17 @@ module Admin def update if @commercial.update(commercial_params) redirect_to admin_conference_commercials_path, - notice: 'Commercial was successfully updated.' + notice: 'Materials were successfully updated.' else redirect_to admin_conference_commercials_path, - error: 'An error prohibited this Commercial from being saved: '\ + error: 'An error prohibited materials from being saved: '\ "#{@commercial.errors.full_messages.join('. ')}." end end def destroy @commercial.destroy - redirect_to admin_conference_commercials_path, notice: 'Commercial was successfully destroyed.' + redirect_to admin_conference_commercials_path, notice: 'Materials were successfully removed.' end def render_commercial @@ -60,9 +60,9 @@ module Admin errors = Commercial.read_file(params[:file]) if params[:file] if !params[:file] - flash[:error] = 'Empty file detected while adding commercials to Event' + flash[:error] = 'Empty file detected while adding materials to Event' elsif errors.all? { |_k, v| v.blank? } - flash[:notice] = 'Successfully added commercials.' + flash[:notice] = 'Successfully added materials.' else errors_text = '' errors_text << 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any? diff --git a/app/controllers/admin/registrations_controller.rb b/app/controllers/admin/registrations_controller.rb index 89c4d069..ef94ae2e 100644 --- a/app/controllers/admin/registrations_controller.rb +++ b/app/controllers/admin/registrations_controller.rb @@ -82,7 +82,7 @@ module Admin def registration_params params.require(:registration).permit( - :user_id, :conference_id, :arrival, :departure, :attended, + :user_id, :conference_id, :attended, :volunteer, :other_special_needs, :accepted_code_of_conduct, vchoice_ids: [], qanswer_ids: [], qanswers_attributes: [], event_ids: [] ) diff --git a/app/controllers/admin/tickets_controller.rb b/app/controllers/admin/tickets_controller.rb index 6635ed29..3426d2aa 100644 --- a/app/controllers/admin/tickets_controller.rb +++ b/app/controllers/admin/tickets_controller.rb @@ -38,13 +38,30 @@ module Admin end end + def give + ticket_purchase = @ticket.ticket_purchases.new(gift_ticket_params) + recipient = ticket_purchase.user + if ticket_purchase.save + redirect_to( + admin_conference_ticket_path(@conference.short_title, @ticket), + notice: "#{recipient.name} was given a #{@ticket.title} ticket." + ) + else + redirect_back( + fallback_location: admin_conference_ticket_path(@conference.short_title, @ticket), + error: "Unable to give #{recipient.name} a #{@ticket.title} ticket: " + + ticket_purchase.errors.full_messages.to_sentence + ) + end + end + def destroy if @ticket.destroy redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), - notice: 'Ticket successfully destroyed.' + notice: 'Ticket successfully deleted.' else redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), - error: 'Ticket was successfully destroyed.' \ + error: 'Deleting ticket failed! ' \ "#{@ticket.errors.full_messages.join('. ')}." end end @@ -52,7 +69,19 @@ module Admin private def ticket_params - params.require(:ticket).permit(:conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price, :registration_ticket) + params.require(:ticket).permit( + :conference, :conference_id, + :title, :url, :description, + :price_cents, :price_currency, :price, + :registration_ticket, :visible + ) + end + + def gift_ticket_params + response = params.require(:ticket_purchase).permit( + :user_id + ) + response.merge(paid: true, amount_paid: 0, conference: @conference) end end end diff --git a/app/controllers/admin/venue_commercials_controller.rb b/app/controllers/admin/venue_commercials_controller.rb index ddd13aa9..10a46de6 100644 --- a/app/controllers/admin/venue_commercials_controller.rb +++ b/app/controllers/admin/venue_commercials_controller.rb @@ -12,10 +12,10 @@ module Admin if @commercial.save redirect_to admin_conference_venue_path, - notice: 'Commercial was successfully created.' + notice: 'Materials successfully created.' else redirect_to admin_conference_venue_path, - error: 'An error prohibited this Commercial from being saved: '\ + error: 'An error prohibited materials from being saved: '\ "#{@commercial.errors.full_messages.join('. ')}." end @@ -24,17 +24,17 @@ module Admin def update if @commercial.update(commercial_params) redirect_to admin_conference_venue_path, - notice: 'Commercial was successfully updated.' + notice: 'Materials successfully updated.' else redirect_to admin_conference_venue_path, - error: 'An error prohibited this Commercial from being saved: '\ + error: 'An error prohibited materials from being saved: '\ "#{@commercial.errors.full_messages.join('. ')}." end end def destroy @commercial.destroy - redirect_to admin_conference_venue_path, notice: 'Commercial was successfully destroyed.' + redirect_to admin_conference_venue_path, notice: 'Materials successfully destroyed.' end def render_commercial diff --git a/app/controllers/commercials_controller.rb b/app/controllers/commercials_controller.rb index aa48a406..9b5e2110 100644 --- a/app/controllers/commercials_controller.rb +++ b/app/controllers/commercials_controller.rb @@ -12,27 +12,27 @@ class CommercialsController < ApplicationController if @commercial.save redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), - notice: 'Commercial was successfully created.' + notice: 'Materials were successfully created.' else redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), - error: "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." + error: "An error prohibited these materials from being saved: #{@commercial.errors.full_messages.join('. ')}." end end def update if @commercial.update(commercial_params) redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), - notice: 'Commercial was successfully updated.' + notice: 'Materials were successfully updated.' else redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), - error: "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." + error: "An error prohibited materials from being saved: #{@commercial.errors.full_messages.join('. ')}." end end def destroy @commercial.destroy redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id), - notice: 'Commercial was successfully destroyed.' + notice: 'Materials were successfully destroyed.' end def render_commercial diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index 5c17d8dc..d0dad229 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -57,7 +57,7 @@ class ConferenceRegistrationsController < ApplicationController sign_in(@registration.user) end - if @conference.tickets.any? && !current_user.supports?(@conference) + if @conference.tickets.visible.any? && !current_user.supports?(@conference) redirect_to conference_tickets_path(@conference.short_title), notice: 'You are now registered and will be receiving E-Mail notifications.' else @@ -108,9 +108,9 @@ class ConferenceRegistrationsController < ApplicationController end def registration_params - params.require(:registration) + params.permit(:registration) .permit( - :conference_id, :arrival, :departure, + :conference_id, :volunteer, :accepted_code_of_conduct, vchoice_ids: [], qanswer_ids: [], qanswers_attributes: [], diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 035ab366..e7d196d5 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -51,10 +51,10 @@ class ConferencesController < ApplicationController end end if splashpage.include_registrations || splashpage.include_tickets - @tickets = @conference.tickets.order('price_cents') + @tickets = @conference.tickets.visible.order('price_cents') end if splashpage.include_lodgings - @lodgings = @conference.lodgings.order('name') + @lodgings = @conference.lodgings.order('id') end if splashpage.include_sponsors @sponsorship_levels = @conference.sponsorship_levels.eager_load( diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index c62afc06..7766d006 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -3,7 +3,8 @@ class TicketsController < ApplicationController before_action :authenticate_user! load_resource :conference, find_by: :short_title - load_resource :ticket, through: :conference + before_action :load_tickets + authorize_resource :ticket, through: :conference authorize_resource :conference_registrations, class: Registration before_action :check_load_resource, only: :index @@ -14,4 +15,8 @@ class TicketsController < ApplicationController redirect_to root_path, notice: "There are no tickets available for #{@conference.title}!" end end + + def load_tickets + @tickets = @conference.tickets.visible + end end diff --git a/app/datatables/registration_datatable.rb b/app/datatables/registration_datatable.rb index bdd97e72..a20fe3af 100644 --- a/app/datatables/registration_datatable.rb +++ b/app/datatables/registration_datatable.rb @@ -10,8 +10,6 @@ class RegistrationDatatable < AjaxDatatablesRails::Base roles: { source: 'Role.name' }, email: { source: 'User.email' }, accepted_code_of_conduct: { source: 'Registration.accepted_code_of_conduct', searchable: false }, - arrival: { source: 'Registration.arrival', searchable: false }, - departure: { source: 'Registration.departure', searchable: false }, actions: { source: 'Registration.id', searchable: false, orderable: false } } end @@ -36,8 +34,6 @@ class RegistrationDatatable < AjaxDatatablesRails::Base roles: conference_role_titles(record.user), email: record.email, accepted_code_of_conduct: !!record.accepted_code_of_conduct, # rubocop:disable Style/DoubleNegation - arrival: record.arrival&.utc, - departure: record.departure&.utc, questions: {}, edit_url: edit_admin_conference_registration_path(conference, record), DT_RowId: record.id diff --git a/app/datatables/user_datatable.rb b/app/datatables/user_datatable.rb index ab0e877f..a01e7e12 100644 --- a/app/datatables/user_datatable.rb +++ b/app/datatables/user_datatable.rb @@ -40,19 +40,20 @@ class UserDatatable < AjaxDatatablesRails::Base # rubocop:disable Naming/AccessorMethodName def get_raw_records - User.left_outer_joins(:registrations, :roles) - .distinct - .select("users.*, COUNT(CASE WHEN registrations.attended = 't' THEN 1 END) AS attended_count") - .group('users.id') + User.left_outer_joins(:registrations, :roles).select( + "DISTINCT users.id, users.name, users.email, users.confirmed_at, COUNT(CASE WHEN registrations.attended = 't' THEN 1 END) AS attended_count" + ).group( + 'users.id, users.name, users.email, users.confirmed_at' + ) end # rubocop:enable Naming/AccessorMethodName def records_total_count - fetch_records.unscope(:group).count(:all) + fetch_records.unscoped.count(:id) end def records_filtered_count - filter_records(fetch_records).unscope(:group).count(:all) + filter_records(fetch_records).unscoped.count end # ==== These methods represent the basic operations to perform on records diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9e27c1a5..78dbc652 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -178,20 +178,22 @@ module ApplicationHelper 'hidden' if Date.today > conference.end_date end + # TODO:Snap!Con: Replace this with a search for a conference logo. def nav_root_link_for(conference) - link_text = ( - conference.try(:organization).try(:name) || - ENV['OSEM_NAME'] || - 'OSEM' - ) link_to( - link_text, + image_tag('snapcon_logo.png'), root_path, class: 'navbar-brand', - title: 'Open Source Event Manager' + title: nav_link_text(conference) ) end + def nav_link_text(conference) + conference.try(:organization).try(:name) || + ENV['OSEM_NAME'] || + 'OSEM' + end + # returns the url to be used for logo on basis of sponsorship level position def get_logo(object) if object.try(:sponsorship_level) diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb index b0691518..6aa198d6 100644 --- a/app/helpers/format_helper.rb +++ b/app/helpers/format_helper.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'redcarpet/render_strip' + module FormatHelper ## # Includes functions related to formatting (like adding classes, colors) @@ -42,12 +44,11 @@ module FormatHelper def target_progress_color(progress) progress = progress.to_i - result = - case - when progress >= 90 then 'green' - when progress < 90 && progress >= 80 then 'orange' - else 'red' - end + result = case + when progress >= 90 then 'green' + when progress < 90 && progress >= 80 then 'orange' + else 'red' + end result end @@ -99,19 +100,11 @@ module FormatHelper end def icon_for_todo(bool) - if bool - 'fa fa-check' - else - 'fa fa-times' - end + bool ? 'fa fa-check' : 'fa fa-times' end def class_for_todo(bool) - if bool - 'todolist-ok' - else - 'todolist-missing' - end + bool ? 'todolist-ok' : 'todolist-missing' end def word_pluralize(count, singular, plural = nil) @@ -191,9 +184,12 @@ module FormatHelper return '' if text.nil? options = { - autolink: true, + autolink: true, space_after_headers: true, - no_intra_emphasis: true + tables: true, + strikethrough: true, + footnotes: true, + superscript: true } markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: escape_html), options) markdown.render(text).html_safe @@ -203,6 +199,11 @@ module FormatHelper markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text", false) end + # Return a plain text markdown stripped of formatting. + def plain_text(content) + Redcarpet::Markdown.new(Redcarpet::Render::StripDown).render(content) + end + def quantity_left_of(resource) return '-/-' if resource.quantity.blank? diff --git a/app/mailers/mailbot.rb b/app/mailers/mailbot.rb index 52e15b80..c535f4aa 100644 --- a/app/mailers/mailbot.rb +++ b/app/mailers/mailbot.rb @@ -1,8 +1,11 @@ # frozen_string_literal: true +SNAPCON_BCC_ADDRESS = 'messages@snap.berkeley.edu' + class Mailbot < ActionMailer::Base def registration_mail(conference, user) mail(to: user.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.registration_subject, body: conference.email_settings.generate_email_on_conf_updates(conference, @@ -21,6 +24,7 @@ class Mailbot < ActionMailer::Base end mail(to: @user.email, + bcc: SNAPCON_BCC_ADDRESS, from: @conference.contact.email, template_name: 'ticket_confirmation_template', subject: "#{@conference.title} | Ticket Confirmation and PDF!") @@ -30,6 +34,7 @@ class Mailbot < ActionMailer::Base conference = event.program.conference mail(to: event.submitter.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.accepted_subject, body: conference.email_settings.generate_event_mail(event, conference.email_settings.accepted_body)) @@ -39,6 +44,7 @@ class Mailbot < ActionMailer::Base conference = event.program.conference mail(to: event.submitter.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.submitted_proposal_subject, body: conference.email_settings.generate_event_mail(event, conference.email_settings.submitted_proposal_body)) @@ -48,6 +54,7 @@ class Mailbot < ActionMailer::Base conference = event.program.conference mail(to: event.submitter.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.rejected_subject, body: conference.email_settings.generate_event_mail(event, conference.email_settings.rejected_body)) @@ -57,6 +64,7 @@ class Mailbot < ActionMailer::Base conference = event.program.conference mail(to: event.submitter.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.confirmed_without_registration_subject, body: conference.email_settings.generate_event_mail(event, @@ -65,6 +73,7 @@ class Mailbot < ActionMailer::Base def conference_date_update_mail(conference, user) mail(to: user.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.conference_dates_updated_subject, body: conference.email_settings.generate_email_on_conf_updates(conference, @@ -74,6 +83,7 @@ class Mailbot < ActionMailer::Base def conference_registration_date_update_mail(conference, user) mail(to: user.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.conference_registration_dates_updated_subject, body: conference.email_settings.generate_email_on_conf_updates(conference, @@ -83,6 +93,7 @@ class Mailbot < ActionMailer::Base def conference_venue_update_mail(conference, user) mail(to: user.email, + bcc: SNAPCON_BCC_ADDRESS, from: conference.contact.email, subject: conference.email_settings.venue_updated_subject, body: conference.email_settings.generate_email_on_conf_updates(conference, diff --git a/app/models/.gitkeep b/app/models/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/.lodging.rb.swp b/app/models/.lodging.rb.swp deleted file mode 100644 index 70c3567d..00000000 Binary files a/app/models/.lodging.rb.swp and /dev/null differ diff --git a/app/models/ability.rb b/app/models/ability.rb index caf8f2a4..e4d30311 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -87,7 +87,9 @@ class Ability end can :index, Organization - can :index, Ticket + can :index, Ticket do |ticket| + ticket.visible + end can :manage, TicketPurchase, user_id: user.id can [:new, :create], Payment, user_id: user.id can [:index, :show], PhysicalTicket, user: user diff --git a/app/models/commercial.rb b/app/models/commercial.rb index 7bb2a081..4d28330c 100644 --- a/app/models/commercial.rb +++ b/app/models/commercial.rb @@ -39,7 +39,7 @@ class Commercial < ApplicationRecord commercial = event.commercials.new(url: url) unless commercial.save - errors[:validation_errors] << "Could not create commercial for event with ID #{event.id} (" + commercial.errors.full_messages.to_sentence + ')' + errors[:validation_errors] << "Could not create materials for event with ID #{event.id} (" + commercial.errors.full_messages.to_sentence + ')' end end errors diff --git a/app/models/conference.rb b/app/models/conference.rb index be3c36ad..c48dcf02 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -25,8 +25,8 @@ class Conference < ApplicationRecord has_one :email_settings, dependent: :destroy has_one :program, dependent: :destroy has_one :venue, dependent: :destroy - has_many :physical_tickets, through: :ticket_purchases has_many :ticket_purchases, dependent: :destroy + has_many :physical_tickets, through: :ticket_purchases has_many :payments, dependent: :destroy has_many :supporters, through: :ticket_purchases, source: :user has_many :tickets, dependent: :destroy diff --git a/app/models/registration.rb b/app/models/registration.rb index 84a9aba0..759003fd 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -28,8 +28,6 @@ class Registration < ApplicationRecord validates :user_id, uniqueness: { scope: :conference_id, message: 'already Registered!' } validate :registration_limit_not_exceed, on: :create - validate :registration_to_events_only_if_present - validates :accepted_code_of_conduct, acceptance: { if: -> { conference.try(:code_of_conduct).present? } } @@ -48,19 +46,6 @@ class Registration < ApplicationRecord private - ## - # If the user registers to attend events that are already scheduled, - # only allow registration to events if the user will be present - # (based on arrival and departure attributes) - # No validation if arrival/departure attributes are empty - def registration_to_events_only_if_present - if (arrival || departure) && events.pluck(:start_time).any? - errors.add(:arrival, 'is too late! You cannot register for events that take place before your arrival') if events.pluck(:start_time).compact.map { |x| x < arrival }.any? - - errors.add(:departure, 'is too early! You cannot register for events that take place after your departure') if events.pluck(:start_time).compact.map { |x| x > departure }.any? - end - end - def subscribe_to_conference Subscription.create(conference_id: conference.id, user_id: user.id) end diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 677ef90f..ca686115 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -20,6 +20,8 @@ class Ticket < ApplicationRecord validates :price_cents, numericality: { greater_than_or_equal_to: 0 } + scope :visible, -> { where(visible: true) } + def bought?(user) buyers.include?(user) end diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb index 129d7916..a3dfd1cd 100644 --- a/app/models/ticket_purchase.rb +++ b/app/models/ticket_purchase.rb @@ -32,7 +32,7 @@ class TicketPurchase < ApplicationRecord errors.push('You cannot buy more than one registration tickets.') else ActiveRecord::Base.transaction do - conference.tickets.each do |ticket| + conference.tickets.visible.each do |ticket| quantity = purchases[ticket.id.to_s].to_i # if the user bought the ticket and is still unpaid, just update the quantity purchase = if ticket.bought?(user) && ticket.unpaid?(user) diff --git a/app/models/user.rb b/app/models/user.rb index 7c764fa1..f6d62de3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -50,7 +50,10 @@ class User < ApplicationRecord else [:database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, - :omniauthable, omniauth_providers: [:suse, :google, :facebook, :github]] + :omniauthable, + # omniauth_providers: [:suse, :google, :facebook, :github, :discourse] + omniauth_providers: [:google, :discourse] + ] end devise(*devise_modules) diff --git a/app/views/admin/commercials/index.html.haml b/app/views/admin/commercials/index.html.haml index 095ddad2..2dbe10a2 100644 --- a/app/views/admin/commercials/index.html.haml +++ b/app/views/admin/commercials/index.html.haml @@ -1,11 +1,11 @@ .row .col-md-12 .page-header - %h1 Commercials + %h1 Session Materials %p.text-muted - Conference commercials will be displayed on the events in the + Conference materials will be displayed on the events in the = link_to 'schedule,', conference_schedule_path(@conference.short_title) - if the event speaker didn't add an event commercial. + if the event speaker didn't add any event materials. - if can? :create, @conference.commercials.new .row .col-md-6 diff --git a/app/views/admin/event_types/_form.html.haml b/app/views/admin/event_types/_form.html.haml index 29fac398..91533877 100644 --- a/app/views/admin/event_types/_form.html.haml +++ b/app/views/admin/event_types/_form.html.haml @@ -7,11 +7,12 @@ Event Type = @event_type.title .row - .col-md-12 - = semantic_form_for(@event_type, url: (@event_type.new_record? ? admin_conference_program_event_types_path : admin_conference_program_event_type_path(@conference.short_title, @event_type))) do |f| + .col-md-8 + - form_url = (@event_type.new_record? ? admin_conference_program_event_types_path : admin_conference_program_event_type_path(@conference.short_title, @event_type)) + = semantic_form_for(@event_type, url: form_url) do |f| = f.input :title, input_html: { autofocus: true } = f.input :length, input_html: {size: 3, type: 'number', step: @event_type.program.schedule_interval, min: @event_type.program.schedule_interval} - = f.input :description + = f.input :description, as: :text, hint: markdown_hint, input_html: { rows: 5, data: { provide: 'markdown-editable' } } = f.input :minimum_abstract_length, input_html: {size: 3} = f.input :maximum_abstract_length, input_html: {size: 3} = f.input :color, input_html: { size: 6, type: 'color' } diff --git a/app/views/admin/event_types/index.html.haml b/app/views/admin/event_types/index.html.haml index 4d3c27b8..e18cceeb 100644 --- a/app/views/admin/event_types/index.html.haml +++ b/app/views/admin/event_types/index.html.haml @@ -20,7 +20,7 @@ %td = event_type.title %td - = event_type.description + = markdown(event_type.description) %td = event_type.length Minutes diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 4944d946..c766a7a6 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -6,9 +6,9 @@ = "(#{@events.length})" if @events.any? .btn-group.pull-right - %button.btn.btn-primary{ title: 'Mass import of commercials for events', + %button.btn.btn-primary{ title: 'Mass import of materials for events', data: { toggle: 'modal', target: '#mass-commercials-modal' } } - Add Commercials + Add Materials - if can? :create, Event = link_to 'Add Event', @@ -28,7 +28,7 @@ .modal-dialog .modal-content .modal-header - %h1 Add commercials to events + %h1 Add materials to events .text-muted Upload your file with data in the following format: %b Event_ID:Commercial_Link diff --git a/app/views/admin/events/show.html.haml b/app/views/admin/events/show.html.haml index 4b764838..525e4c93 100644 --- a/app/views/admin/events/show.html.haml +++ b/app/views/admin/events/show.html.haml @@ -11,7 +11,7 @@ - progress_status = @event.progress_status = progress_status.reject{ |_key, value| value || value.nil? }.length %li - = link_to 'Commercials', '#proposal-commercials', 'data-toggle' => 'tab' + = link_to 'Materials', '#proposal-commercials', 'data-toggle' => 'tab' .tab-content #proposal-content.tab-pane.active @@ -42,7 +42,7 @@ - else = general_change_description(version) - = link_to 'commercial', + = link_to 'materials', edit_admin_conference_program_event_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content') @@ -82,7 +82,7 @@ %td{ 'class' => class_for_todo(progress_status['subtitle']) } %span{ 'class' => [icon_for_todo(progress_status['subtitle']), 'fa-lg'] } %tr - %td= link_to 'Add a commercial', edit_admin_conference_program_event_path(@event.program.conference.short_title, @event, anchor: 'commercials-content') + %td= link_to 'Add materials', edit_admin_conference_program_event_path(@event.program.conference.short_title, @event, anchor: 'commercials-content') %td{ 'class' => class_for_todo(progress_status['commercials']) } %span{ 'class' => [icon_for_todo(progress_status['commercials']), 'fa-lg'] } - unless progress_status['track'].nil? diff --git a/app/views/admin/registrations/index.html.haml b/app/views/admin/registrations/index.html.haml index 8ea544d8..09f674e9 100644 --- a/app/views/admin/registrations/index.html.haml +++ b/app/views/admin/registrations/index.html.haml @@ -30,8 +30,6 @@ %th{ width: '0' } E-Mail %th{ width: '0' } %abbr{ title: 'Code of Conduct' } CoC - %th{ width: '0' } Arrival - %th{ width: '0' } Departure %th{ width: '0' } Actions %tbody @@ -81,22 +79,6 @@ "className": "code-of-conduct text-center", "searchable": false }, - { - "data": "arrival", - "searchable": false, - "render": function(data, type, row) { - if (data) { return moment(data).format('ll LT'); } - return ''; - } - }, - { - "data": "departure", - "searchable": false, - "render": function(data, type, row) { - if (data) { return moment(data).format('ll LT'); } - return ''; - } - }, { "data": null, "className": "actions", diff --git a/app/views/admin/registrations/index.pdf.prawn b/app/views/admin/registrations/index.pdf.prawn index d7c97ef2..3edebf04 100644 --- a/app/views/admin/registrations/index.pdf.prawn +++ b/app/views/admin/registrations/index.pdf.prawn @@ -4,9 +4,7 @@ prawn_document(force_download: true, filename: @pdf_filename, page_layout: :land 'Name', 'Nickname', 'Affiliation', - 'Email', - 'Arrival Date', - 'Departure Date'] + 'Email'] @conference.questions.each do |question| header_array << question.title end @@ -19,8 +17,6 @@ prawn_document(force_download: true, filename: @pdf_filename, page_layout: :land row << registration.nickname row << registration.affiliation row << registration.email - row << registration.arrival.to_s || '' - row << registration.departure.to_s || '' @conference.questions.each do |question| qa = registration.qanswers.find_by(question: question) diff --git a/app/views/admin/registrations/index.xlsx.axlsx b/app/views/admin/registrations/index.xlsx.axlsx index ee49eb4d..a95c163e 100644 --- a/app/views/admin/registrations/index.xlsx.axlsx +++ b/app/views/admin/registrations/index.xlsx.axlsx @@ -3,7 +3,7 @@ wb = xlsx_package.workbook wb.add_worksheet(name: 'registrations') do |sheet| bold_style = wb.styles.add_style(b: true) - row = ['Attended', 'Name', 'Nickname', 'Affilιation', 'Email', 'Arrival', 'Departure'] + row = ['Attended', 'Name', 'Nickname', 'Affilιation', 'Email'] @conference.questions.each do |question| row << question.title @@ -18,8 +18,6 @@ wb.add_worksheet(name: 'registrations') do |sheet| row << registration.nickname row << registration.affiliation row << registration.email - row << registration.arrival.to_s - row << registration.departure.to_s @conference.questions.each do |question| qa = registration.qanswers.find_by(question: question) answer = ( qa ? qa.answer.title : '' ) @@ -30,4 +28,3 @@ wb.add_worksheet(name: 'registrations') do |sheet| sheet.add_row row end end - diff --git a/app/views/admin/reports/_all_events.html.haml b/app/views/admin/reports/_all_events.html.haml index 712d4ad7..0eb6b829 100644 --- a/app/views/admin/reports/_all_events.html.haml +++ b/app/views/admin/reports/_all_events.html.haml @@ -14,7 +14,7 @@ %th Title %th Speakers Registered %th Speakers Biographies - %th Commercial + %th Materials %th Subtitle %th Difficulty Level - if @program.tracks.any? diff --git a/app/views/admin/reports/_events_without_commercials.html.haml b/app/views/admin/reports/_events_without_commercials.html.haml index 8f26cb99..77020191 100644 --- a/app/views/admin/reports/_events_without_commercials.html.haml +++ b/app/views/admin/reports/_events_without_commercials.html.haml @@ -2,10 +2,10 @@ .col-md-12 .page-header %h1 - Events without commercials + Events Without Materials = "(#{@events_missing_commercial.length})" %p.text-muted - All submissions that have no commercial + All submissions that have no materials .col-md-12 %table.datatable %thead diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index 6bbb8886..db6480f3 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -4,7 +4,7 @@ = link_to 'All Events', '#all', 'data-toggle' => 'tab' %li %a{href: '#missing-commercial', 'data-toggle' => 'tab'} - Events without Commercials + Events without Materials %span.label.label-danger{style: 'border-radius: 1em;'} = @events_missing_commercial.length %li diff --git a/app/views/admin/tickets/_form.html.haml b/app/views/admin/tickets/_form.html.haml index f66cea51..73c93229 100644 --- a/app/views/admin/tickets/_form.html.haml +++ b/app/views/admin/tickets/_form.html.haml @@ -14,5 +14,6 @@ = f.input :price = f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY', 'CHF'], include_blank: false = f.input :registration_ticket, hint: 'A registration ticket is with which user register for the conference.' + = f.input :visible, hint: 'Only visible tickets are available to registrants. Non-visible tickets can only be managed by Admins.' %p.text-right = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } diff --git a/app/views/admin/tickets/index.html.haml b/app/views/admin/tickets/index.html.haml index 020cc1c7..ac7f97b5 100644 --- a/app/views/admin/tickets/index.html.haml +++ b/app/views/admin/tickets/index.html.haml @@ -15,6 +15,7 @@ %th Sold %th Turnover %th Registration Ticket + %th Visible? %th Actions %tbody - @conference.tickets.each do |ticket| @@ -30,6 +31,8 @@ = humanized_money_with_symbol ticket.tickets_turnover_total(ticket.id) %td = ticket.registration_ticket? ? 'Yes' : 'No' + %td + = ticket.visible? ? 'Yes' : 'No' %td .btn-group = link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id), diff --git a/app/views/admin/tickets/show.html.haml b/app/views/admin/tickets/show.html.haml index d80b040b..629bed8c 100644 --- a/app/views/admin/tickets/show.html.haml +++ b/app/views/admin/tickets/show.html.haml @@ -7,7 +7,13 @@ Ticket %small = humanized_money_with_symbol @ticket.price - = link_to 'Edit Ticket', edit_admin_conference_ticket_path, class: 'btn btn-primary pull-right' + = link_to 'Edit Ticket', edit_admin_conference_ticket_path, class: 'btn btn-primary pull-right' + - if can? :give, Ticket + .pull-right + = link_to 'Give a Ticket', '#', + data: { toggle: 'modal', target: "#modal-give-ticket-#{@ticket.id}" }, + class: 'button btn btn-default btn-info' + %p.text-muted People who bought this ticket .row @@ -35,3 +41,26 @@ = buyer.affiliation %td = @ticket.tickets_paid(buyer) + +- content_for :modals do + .modal.fade{ id: "modal-give-ticket-#{@ticket.id}" } + .modal-dialog + .modal-content + = semantic_form_for(@ticket.ticket_purchases.new, + url: give_admin_conference_ticket_path(@conference, @ticket)) do |f| + .modal-header + %button.close{ data: { dismiss: 'modal' } } + %i.fa.fa-close + %h3.modal-title + Give a + = @ticket.title + Ticket + .modal-body + = user_selector_input(:user, f, '', false) + .modal-footer + = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } + +:javascript + $(document).ready(function() { + $('#ticket_purchase_user_id').selectize({}) + }); diff --git a/app/views/admin/venues/_form.html.haml b/app/views/admin/venues/_form.html.haml index 6674305b..e19325da 100644 --- a/app/views/admin/venues/_form.html.haml +++ b/app/views/admin/venues/_form.html.haml @@ -7,7 +7,7 @@ %li.active = link_to 'Details', '#details-content', 'data-toggle' => 'tab' %li - = link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab' + = link_to 'Materials', '#commercials-content', 'data-toggle' => 'tab' .tab-content #details-content.tab-pane.active @@ -56,4 +56,4 @@ %hr - else - First Create Venue, then update commercial + First Create Venue, then update materials diff --git a/app/views/admin/venues/show.html.haml b/app/views/admin/venues/show.html.haml index 36906e05..de29c4e3 100644 --- a/app/views/admin/venues/show.html.haml +++ b/app/views/admin/venues/show.html.haml @@ -12,7 +12,7 @@ -else - if @venue.commercial.nil? .row - %img{ "data-src" => "holder.js/500x300?text=No Commercial Set", class: 'img-responsive img-rounded' } + %img{ "data-src" => "holder.js/500x300?text=No Materials Set", class: 'img-responsive img-rounded' } - else - if @venue.commercial.persisted? .thumbnail diff --git a/app/views/commercials/edit.html.haml b/app/views/commercials/edit.html.haml index 174a1a60..359f27a8 100644 --- a/app/views/commercials/edit.html.haml +++ b/app/views/commercials/edit.html.haml @@ -2,7 +2,7 @@ .row .col-md-12 .page-header - %h1 Editing Commercial + %h1 Edit Materials .row .col-md-12 = semantic_form_for @commercial, url: conference_program_proposal_commercial_path(conference_id: @conference.short_title, proposal_id: @event.id, id: @commercial.id) do |f| diff --git a/app/views/commercials/new.html.haml b/app/views/commercials/new.html.haml index da726e89..4152ff88 100644 --- a/app/views/commercials/new.html.haml +++ b/app/views/commercials/new.html.haml @@ -2,7 +2,7 @@ .row .col-md-12 .page-header - %h1 New Commercial + %h1 New Materials .row .col-md-12 = semantic_form_for @commercial, url: conference_program_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event.id) do |f| diff --git a/app/views/conference_registrations/_form.html.haml b/app/views/conference_registrations/_form.html.haml index 971a613f..1dd5f175 100644 --- a/app/views/conference_registrations/_form.html.haml +++ b/app/views/conference_registrations/_form.html.haml @@ -22,6 +22,7 @@ = render partial: 'devise/shared/sign_up_form_embedded' = render partial: 'registration_info', locals: { f: f } + = f.input :conference_id, as: :hidden, value: @conference.id .row .col-md-12 %p.pull-right diff --git a/app/views/conference_registrations/_registration_info.html.haml b/app/views/conference_registrations/_registration_info.html.haml index a81f385d..5fdd9bf4 100644 --- a/app/views/conference_registrations/_registration_info.html.haml +++ b/app/views/conference_registrations/_registration_info.html.haml @@ -24,10 +24,4 @@ (Scheduled on: #{event.time.to_date}) %br - - -= f.inputs 'Your Travel Info' do - = f.input :arrival, as: :string, label: 'Your arrival time', hint: "Leave blank if not sure", input_html: { value: (f.object.arrival.to_formatted_s(:db_without_seconds) unless f.object.arrival.nil?), id: 'registration-arrival-datepicker',start_date: @conference.start_date,end_date: @conference.end_date } - = f.input :departure, as: :string, label: 'Your departure time', hint: "Leave blank if not sure", input_html: { value: (f.object.departure.to_formatted_s(:db_without_seconds) unless f.object.departure.nil?), id: 'registration-departure-datepicker' } - = render 'conferences/code_of_conduct', organization: @conference.organization diff --git a/app/views/conference_registrations/show.html.haml b/app/views/conference_registrations/show.html.haml index afb5b9e0..a5663ef1 100644 --- a/app/views/conference_registrations/show.html.haml +++ b/app/views/conference_registrations/show.html.haml @@ -33,28 +33,6 @@ data: { toggle: 'modal', target: '#modal-code-of-conduct'} = render 'conferences/code_of_conduct', organization: @conference.organization - .row - .col-md-12 - %h4 - %span.fa-stack - %i.fa.fa-square-o.fa-stack-2x - %i.fa.fa-plane.fa-stack-1x - Travel Schedule - %ul - %li - - if @registration.arrival.present? - arrive at - %strong - = @registration.arrival.strftime('%A, %B %-d. %Y %H:%M') - - else - You haven't scheduled your arrival - %li - - if @registration.departure.present? - depart at - %strong - = @registration.departure.strftime('%A, %B %-d. %Y %H:%M') - - else - You haven't scheduled your departure - if @conference.surveys.for_registration.any? .row .col-md-12 @@ -94,7 +72,7 @@ = link_to event.title, conference_program_proposal_path(@conference.short_title, event.id) = '(' + registered_text(event) + ')' - - if @conference.tickets.any? + - if @conference.tickets.visible.any? .row .col-md-12 %h4 diff --git a/app/views/conferences/_call_for_content.haml b/app/views/conferences/_call_for_content.haml index 8287e911..57cd9dc8 100644 --- a/app/views/conferences/_call_for_content.haml +++ b/app/views/conferences/_call_for_content.haml @@ -1,6 +1,6 @@ = content_for :splash_nav do %li - %a.smoothscroll{ href: '#call' } Call For Content + %a.smoothscroll{ href: '#call' } Call For Participation %section#call .container @@ -20,3 +20,4 @@ call: call_for_booths - if two_calls_open(call_for_events, call_for_tracks, call_for_booths) .col-md-2.col-sm-2.hidden-xs + .trapezoid diff --git a/app/views/conferences/_call_for_papers.haml b/app/views/conferences/_call_for_papers.haml index 4847a992..d0d513ff 100644 --- a/app/views/conferences/_call_for_papers.haml +++ b/app/views/conferences/_call_for_papers.haml @@ -2,7 +2,7 @@ expires_in: 1.hour) do .col-md-4.col-sm-4.text-center %h2 - Call for Papers + Call for Participation %p.lead We are now accepting proposals for sessions! %p diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml index 08b73023..02e54c29 100644 --- a/app/views/conferences/_conference_details.html.haml +++ b/app/views/conferences/_conference_details.html.haml @@ -6,7 +6,7 @@ = image_tag(conference.picture_url, class: 'img-responsive') if conference.picture? .col-md-6 %h3 - = conference.title + = conference.title.html_safe %small %b = date_string(conference.start_date, conference.end_date) diff --git a/app/views/conferences/_footer.haml b/app/views/conferences/_footer.haml index 5b24fd92..6b66478a 100644 --- a/app/views/conferences/_footer.haml +++ b/app/views/conferences/_footer.haml @@ -1,14 +1,14 @@ -.scroll-top-wrapper - = link_to "#banner", class: "smoothscroll" do - %i.fa.fa-2x.fa-arrow-circle-up +-# .scroll-top-wrapper +-# = link_to "#banner", class: "smoothscroll" do +-# %i.fa.fa-2x.fa-arrow-circle-up -:javascript - $(function(){ - $(document).on( 'scroll', function(){ - if ($(window).scrollTop() > 100) { - $('.scroll-top-wrapper').addClass('show'); - } else { - $('.scroll-top-wrapper').removeClass('show'); - } - }); - }); +-# :javascript +-# $(function(){ +-# $(document).on( 'scroll', function(){ +-# if ($(window).scrollTop() > 100) { +-# $('.scroll-top-wrapper').addClass('show'); +-# } else { +-# $('.scroll-top-wrapper').removeClass('show'); +-# } +-# }); +-# }); diff --git a/app/views/conferences/_header.haml b/app/views/conferences/_header.haml index c3a75bbc..7edf2afd 100644 --- a/app/views/conferences/_header.haml +++ b/app/views/conferences/_header.haml @@ -1,28 +1,28 @@ - cache [conference, venue, '#splash#header'] do - #banner + #banner{ style: ("background-image: url(#{conference.picture_url})" if conference.picture_url) } .container .row - .col-md-8.col-md-offset-2#header + .col-md-6.col-md-offset-3{id: (conference.picture? ? "header-image" : "header-no-image")} .row - .col-md-4 - - if conference.picture? - = image_tag(conference.picture_url, - class: 'img-responsive img-center', - id: 'splash-logo') + -# - if conference.picture? + -# .col-md-4 + -# = image_tag(conference.picture_url, + -# class: 'img-responsive img-center', + -# id: 'splash-logo') .col-md-8 %h1 - = conference.title + = conference.title.html_safe %h3 - if conference.start_date && conference.end_date %span.date.text-nowrap = date_string(conference.start_date, conference.end_date) - if conference.venue %span.venue.text-nowrap - - if venue.website + - if venue.website.present? = sanitize link_to(venue.name, venue.website) - else = venue.city - - if venue.country_name != 'US' + - if venue.country != 'US' • = venue.country_name @@ -32,3 +32,4 @@ .row .col-md-8.col-md-offset-2 = markdown(conference.description) + .trapezoid diff --git a/app/views/conferences/_lodging.haml b/app/views/conferences/_lodging.haml index 724e78ca..fcffbff8 100644 --- a/app/views/conferences/_lodging.haml +++ b/app/views/conferences/_lodging.haml @@ -17,11 +17,11 @@ .row.row-centered - lodgings.each do |lodging| - .col-md-4.col-sm-4.col-centered.col-top + .col-md-6.col-sm-4.col-centered.col-top .thumbnail - if lodging.picture? - if lodging.website_link.present? - = link_to(lodging.website_link, class: 'thumbnail') do + = link_to(lodging.website_link) do = image_tag lodging.picture.large.url, class: 'img-responsive img-lodging' - else @@ -30,12 +30,16 @@ - else %p.text-center - if lodging.website_link.present? - = link_to(lodging.website_link, class: 'thumbnail') do + = link_to(lodging.website_link) do %i.fa.fa-home.fa-5x - else %i.fa.fa-home.fa-5x .caption %h3.text-center - = lodging.name + - if lodging.website_link.present? + = link_to(lodging.name, lodging.website_link) + - else + = lodging.name - if lodging.description.present? = markdown(lodging.description) + .trapezoid diff --git a/app/views/conferences/_program.haml b/app/views/conferences/_program.haml index 2ab2ef70..2998c2f0 100644 --- a/app/views/conferences/_program.haml +++ b/app/views/conferences/_program.haml @@ -9,8 +9,8 @@ .col-md-12 %p.lead.text-center %span.notranslate - = conference.title - has the most awesome program ever! + = conference.title.html_safe + will have an enaging program! - unless highlights.blank? = render 'highlights', conference_id: conference.short_title, @@ -31,6 +31,7 @@ = link_to(conference_schedule_path(conference.short_title), class: 'btn btn-success btn-lg') do Full Schedule + .trapezoid - unless booths.blank? - booths.each do |booth| diff --git a/app/views/conferences/_registration.haml b/app/views/conferences/_registration.haml index 51258f15..468b8b38 100644 --- a/app/views/conferences/_registration.haml +++ b/app/views/conferences/_registration.haml @@ -37,3 +37,4 @@ = link_to('Register Now', new_conference_conference_registration_path(conference_id), class: 'btn btn-lg btn-success') + .trapezoid diff --git a/app/views/conferences/_social_media.haml b/app/views/conferences/_social_media.haml index ea5c481d..ebbfb8e1 100644 --- a/app/views/conferences/_social_media.haml +++ b/app/views/conferences/_social_media.haml @@ -27,3 +27,4 @@ - if contact.email? = mail_to "#{ contact.email }" do %i.fa.fa-envelope-o.fa-4x + .trapezoid diff --git a/app/views/conferences/_sponsors.haml b/app/views/conferences/_sponsors.haml index 5d7bbaa9..0bd5edb0 100644 --- a/app/views/conferences/_sponsors.haml +++ b/app/views/conferences/_sponsors.haml @@ -27,9 +27,10 @@ .row .col-md-12 %h3.text-center - Want to sponsor? + = "Interested in sponsoring #{conference.title}?" = link_to(sponsorship_mailto(conference)) do - Contact us! + Please, contact us! + .trapezoid - sponsors.each do |sponsor| - content_for :modals do diff --git a/app/views/conferences/_tickets.haml b/app/views/conferences/_tickets.haml index 5f0da517..8b37582a 100644 --- a/app/views/conferences/_tickets.haml +++ b/app/views/conferences/_tickets.haml @@ -7,19 +7,21 @@ .container .row .col-md-12.text-center - %h2 - Support - = conference.title + %h2 Sign Up for Snap!Con + %br + -# %h2 + -# Support + -# = conference.title .row.row-centered - tickets.each do |ticket| - .col-md-3.col-sm-3.col-centered.col-top - = link_to(conference_tickets_path(conference.short_title), - class: 'thumbnail') do + .col-lg-4.col-md-3.col-sm-3.col-centered.col-top + = link_to(conference_tickets_path(conference.short_title), class: 'thumbnail') do .caption %h3.text-center.word_break = ticket.title .word_break = markdown(ticket.description) %button.btn-block.btn.btn-lg.btn-success - %i.fa.fa-ticket.fa-fw + %i.fa.fa-ticket.fa-fw{"aria-hidden": true} = humanized_money_with_symbol(ticket.price) + .trapezoid diff --git a/app/views/conferences/_venue.haml b/app/views/conferences/_venue.haml index fbdcde48..aae6b43d 100644 --- a/app/views/conferences/_venue.haml +++ b/app/views/conferences/_venue.haml @@ -5,6 +5,12 @@ %section#venue - if venue.location? = render '/conferences/venue_map', venue: venue + - if venue.description.present? + .container + .row + .col-md-8.col-md-offset-2 + = markdown(venue.description, escape_html=false) + .trapezoid - else - cache [venue, commercial, '#splash#venue'] do .container @@ -41,3 +47,4 @@ - if venue.website %br = sanitize link_to(h(venue.website), h(venue.website)) + .trapezoid diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml index e8f64db3..f067fe2d 100644 --- a/app/views/conferences/show.html.haml +++ b/app/views/conferences/show.html.haml @@ -1,10 +1,10 @@ - content_for :head do %meta{ property: "og:title", content: @conference.title } %meta{ property: "og:site_name", content: (ENV['OSEM_NAME'] || 'OSEM') } - %meta{ property: "og:description", content: @conference.description } + %meta{ property: "og:description", content: plain_text(@conference.description) } %meta{ property: "og:url", content: conference_url(@conference.short_title) } %meta{ property: "twitter:title", content: (@conference.title) } - %meta{ property: "twitter:description", content: @conference.description } + %meta{ property: "twitter:description", content: plain_text(@conference.description) } - if @conference.picture? %meta{ property: "og:image", content: @image_url } %meta{ property: "og:image:secure_url", content: @image_url } @@ -64,21 +64,22 @@ = render 'social_media', contact: @conference.contact = render 'footer' -- content_for :script_head do - :javascript - var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic(); - var triangle_colors = triangle_tcs.map(function(t) { - return t.toHexString(); - }); - $(function () { - $(document).ready(function() { - var triangle_width = document.body.clientWidth; - var triangle_height = ($( "#banner" ).height() + 200 ); - var pattern = Trianglify({ width: triangle_width, - height: triangle_height, - cell_size: 100, - x_colors: triangle_colors - }); - $('#banner').css('background-image', 'url("' + pattern.png() + '")'); - }); - }); + +-# - content_for :script_head do +-# :javascript +-# var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic(); +-# var triangle_colors = triangle_tcs.map(function(t) { +-# return t.toHexString(); +-# }); +-# $(function () { +-# $(document).ready(function() { +-# var triangle_width = document.body.clientWidth; +-# var triangle_height = ($( "#banner" ).height() + 200 ); +-# var pattern = Trianglify({ width: triangle_width, +-# height: triangle_height, +-# cell_size: 100, +-# x_colors: triangle_colors +-# }); +-# $('#banner').css('background-image', 'url(' + 0 + ')'); +-# }); +-# }); diff --git a/app/views/devise/shared/_openid_links.html.haml b/app/views/devise/shared/_openid_links.html.haml index 09c7a7ea..2e7916b3 100644 --- a/app/views/devise/shared/_openid_links.html.haml +++ b/app/views/devise/shared/_openid_links.html.haml @@ -1,7 +1,16 @@ .text-center .btn-group.btn-group-lg#openid-btn-grp - omniauth_configured.each do |provider| - = link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg", - id: "omniauth-#{provider}", - title: "Your #{provider} login" do - %i{class: "fa fa-#{provider}"} + - if provider != :discourse + = link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg", + id: "omniauth-#{provider}", + title: "Your #{provider} login" do + %i{class: "fa fa-#{provider}"} + - else + = link_to("user_#{provider}_omniauth_authorize".to_sym, + class: "btn btn-success btn-lg", + id: "omniauth-#{provider}", + title: "Your #{provider} login") do + %span + Snap + %em> ! diff --git a/app/views/devise/shared/_sign_in_form_embedded.html.haml b/app/views/devise/shared/_sign_in_form_embedded.html.haml index 362fc695..9a82b188 100644 --- a/app/views/devise/shared/_sign_in_form_embedded.html.haml +++ b/app/views/devise/shared/_sign_in_form_embedded.html.haml @@ -1,25 +1,26 @@ - if ENV['OSEM_ICHAIN_ENABLED'] != 'true' - = form_tag(new_user_session_path, class: 'form-horizontal') do - %legend - %span - Sign In - .form-group - %label{for: "user[login]", class: 'col-sm-2 control-label'} - Username - .col-sm-10 - = text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required' - .form-group - %label{for: "user[password]", class: 'col-sm-2 control-label'} - Password - .col-sm-10 - = password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required' - .form-group - .col-sm-12 - %button.btn.btn-success.pull-right - Sign in - = render partial: 'devise/shared/openid' - %p.text-right - %a.small.btn.btn-default{"data-toggle" => "collapse", "data-target" => "#devise-help-sign-in"} - Need Help? - #devise-help-sign-in.collapse - = render partial: 'devise/shared/links' + .container.panel + = form_tag(new_user_session_path, class: '') do + %legend + %span + Sign In + .form-group + %label{for: "user[login]", class: 'col-sm-2 control-label'} + Username + .col-sm-10 + = text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required' + .form-group + %label{for: "user[password]", class: 'col-sm-2 control-label'} + Password + .col-sm-10 + = password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required' + .form-group + .col-sm-12 + %button.btn.btn-success.pull-right + Sign in + = render partial: 'devise/shared/openid' + %p.text-right + %a.small.btn.btn-default{"data-toggle" => "collapse", "data-target" => "#devise-help-sign-in"} + Need Help? + #devise-help-sign-in.collapse + = render partial: 'devise/shared/links' diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index 78523bc7..78b6da07 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.html.haml @@ -43,7 +43,7 @@ = link_to 'Contact', edit_admin_conference_contact_path(@conference.short_title) - if can? :index, @conference.commercials.build %li{class: "#{active_nav_li(admin_conference_commercials_path(@conference.short_title))}"} - = link_to 'Commercials', admin_conference_commercials_path(@conference.short_title) + = link_to 'Materials', admin_conference_commercials_path(@conference.short_title) - if can? :update, @conference %li{class: active_nav_li(edit_admin_conference_splashpage_path(@conference.short_title))} = link_to 'Splashpage', admin_conference_splashpage_path(@conference.short_title) diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index deea4f09..ddc8634a 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,7 +1,6 @@ -.navbar.navbar-default.navbar-fixed-top.nav-osem{role: 'navigation'} +%nav.navbar.navbar-default.navbar-fixed-top.nav-osem{role: 'navigation'} .container .navbar-header - - if controller.class.name.split("::").first=="Admin" %button{ "data-target"=>"#side-nav", "data-toggle"=>"collapse", class: 'navbar-toggle side-nav-btn', type: 'button' } %span.sr-only Toggle navigation @@ -14,7 +13,7 @@ %span.icon-bar %span.icon-bar %span.icon-bar - = nav_root_link_for conference + = nav_root_link_for(conference) .collapse.navbar-collapse#main-nav - if content_for :splash_nav @@ -42,34 +41,41 @@ = link_to(new_registration_path('user')) do %span.fa.fa-heart Sign Up - %li.dropdown.visible-desktop - %a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'} - %span.fa.fa-user - Sign In - %span.caret - .dropdown-menu - - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - = form_tag User.ichain_login_url do - = text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username' - = password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password' - %button.btn.btn-success.btn-block Sign in - - else - = form_tag new_user_session_path do - = text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail' - = password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password' - %p.text-right - %small - %label{for: 'user_remember_me'} Remember me - = check_box_tag 'user[remember_me]' - %button.btn.btn-success.btn-block Sign in - - unless omniauth_configured.empty? - .divider - %h6.text-center - or - = render 'devise/shared/openid_links' - %p.text-right - %br - %a.small.btn.btn-xs.btn-default{"data-toggle" => "collapse", "data-target" => "#navbar-devise-help"} - Need Help? - #navbar-devise-help.collapse - = render 'devise/shared/links' + %li{class: ""} + = link_to(sign_in_path) do + %span.fa.fa-user + Sign In + -# %li.dropdown.visible-desktop + -# %a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'} + -# %span.fa.fa-user + -# Sign In + -# %span.caret + -# .dropdown-menu + -# - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + -# = form_tag User.ichain_login_url do + -# = text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username' + -# = password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password' + -# %button.btn.btn-success.btn-block Sign in + -# - else + -# %div{style: "padding: 6px"} + -# = form_tag new_user_session_path, class: 'form-group' do + -# = text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail' + -# = password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password' + -# %p.text-right + -# %small + -# %label{for: 'user_remember_me'} Remember me + -# = check_box_tag 'user[remember_me]' + -# %br + -# %button.btn.btn-success.btn-block Sign in + -# - unless omniauth_configured.empty? + -# .divider + -# %h6.text-center + -# or + -# = render 'devise/shared/openid_links' + -# %p.text-right + -# %br + -# %a.small.btn.btn-xs.btn-default{"data-toggle" => "collapse", "data-target" => "#navbar-devise-help"} + -# Need Help? + -# #navbar-devise-help.collapse + -# = render 'devise/shared/links' + .trapezoid diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index d4c194b9..86eafac9 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,10 +1,10 @@ -%html{xmlns: 'http://www.w3.org/1999/html'} +%html{lang: 'en'} %head %meta{charset: 'utf-8'} - %meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'} - %title= content_for?(:title) ? yield(:title) : (ENV['OSEM_NAME'] || 'OSEM') - %meta{content: '', name: 'description'} - %meta{content: '', name: 'author'} + %meta{name: 'viewport', content: 'width=device-width, initial-scale=1'} + %title= content_for?(:title) ? strip_tags( yield(:title) ) : (ENV['OSEM_NAME'] || 'OSEM') + %meta{content: 'Snap!Con -- A conference all about Snap!, a programing language from UC Berkeley.', name: 'description'} + %meta{content: 'Michael Ball, Brian Harvey, Jens Moenig, Bernat Romagosa, Dan Garcia, Lauren Mock', name: 'author'} = stylesheet_link_tag "application", media: 'all' = javascript_include_tag "application" @@ -26,7 +26,7 @@ -# Admin area - if controller.class.name.split("::").first=="Admin" = render 'layouts/admin' - -else + - else #messages .container = render 'layouts/messages' @@ -45,7 +45,7 @@ #{link_to "MIT license", "http://opensource.org/licenses/MIT"}. You can run, copy, distribute, study, change and improve it. The source code and the developers are on - #{link_to "GitHub", "https://github.com/openSUSE/osem"}. + #{link_to "GitHub", "https://github.com/snap-cloud/snapcon"}. This site is a modification of #{link_to "OSEM", "https://github.com/openSUSE/osem"}. - if ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"].present? Performance data is available on #{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}. diff --git a/app/views/payments/_payment.html.haml b/app/views/payments/_payment.html.haml index 56af80f7..440f9985 100644 --- a/app/views/payments/_payment.html.haml +++ b/app/views/payments/_payment.html.haml @@ -1,6 +1,6 @@ .div .col-md-12.table-responsive - %table.table.table-hover + %table.table.table-hover.table-striped %thead %tr %th Ticket @@ -20,8 +20,13 @@ = humanized_money_with_symbol ticket.quantity * ticket.price = form_tag conference_payments_path do - %script.stripe-button{ src: "https://checkout.stripe.com/checkout.js", - data: { amount: @total_amount_to_pay.cents, label: "Pay #{humanized_money_with_symbol @total_amount_to_pay}", - email: current_user.email, currency: @total_amount_to_pay.currency, name: ENV['OSEM_NAME'] || 'OSEM', - description: "book your tickets", key: Rails.application.secrets.stripe_publishable_key, locale: "auto"}} - = link_to 'Edit Purchase', conference_tickets_path(@conference.short_title), class: 'btn btn-default' + %script.stripe-button{'src': "https://checkout.stripe.com/checkout.js", + 'data': {amount: @total_amount_to_pay.cents, + label: "Pay #{humanized_money_with_symbol @total_amount_to_pay}", + email: current_user.email, + currency: @total_amount_to_pay.currency, + name: ENV['OSEM_NAME'] || 'OSEM', + description: "#{ENV['OSEM_NAME']} tickets", + key: ENV['STRIPE_PUBLISHABLE_KEY'] || Rails.application.secrets.stripe_publishable_key, locale: "auto"}} + = link_to('Edit Purchase', conference_tickets_path(@conference.short_title), + class: 'btn btn-default') diff --git a/app/views/physical_tickets/index.html.haml b/app/views/physical_tickets/index.html.haml index 2ded8115..e8adbc80 100644 --- a/app/views/physical_tickets/index.html.haml +++ b/app/views/physical_tickets/index.html.haml @@ -16,6 +16,7 @@ %th ID %th Type %th User + %th Registration? %th Actions %tbody - @physical_tickets.each do |physical_ticket| @@ -23,6 +24,7 @@ %td= physical_ticket.id %td= physical_ticket.ticket.title %td= physical_ticket.user.name + %td= physical_ticket.ticket.registration_ticket? ? 'Yes' : 'No' %td .btn-group = link_to 'Show', diff --git a/app/views/proposals/_form.html.haml b/app/views/proposals/_form.html.haml index fe966ed1..7f6716d5 100644 --- a/app/views/proposals/_form.html.haml +++ b/app/views/proposals/_form.html.haml @@ -3,15 +3,15 @@ %li.active = link_to 'Proposal', '#proposal-content', 'data-toggle' => 'tab' %li - = link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab' + = link_to 'Materials', '#commercials-content', 'data-toggle' => 'tab' .tab-content #proposal-content.tab-pane.active = render 'proposals/proposal_form' #commercials-content.tab-pane %p.text-muted - You can add commercials for your proposal. These commercials will be displayed on the + You can add materals for your proposal. These materials will be displayed on the = link_to 'public proposal page.', conference_program_proposal_path(@conference.short_title, @event) - If you don't add a commercial, the conference commercial will be displayed! + If you don't add any materials, the conference materials will be displayed. - if can? :create, @event.commercials.new .row .col-md-6 diff --git a/app/views/proposals/_tooltip.html.haml b/app/views/proposals/_tooltip.html.haml index b10b5a7a..2220451d 100644 --- a/app/views/proposals/_tooltip.html.haml +++ b/app/views/proposals/_tooltip.html.haml @@ -20,7 +20,7 @@ = link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event) %li{'class'=>class_for_todo(progress_status['commercials'])} %span{'class'=>icon_for_todo(progress_status['commercials'])} - = link_to 'Add a commercial', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content') + = link_to 'Add materials', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content') - unless progress_status['track'].nil? %li{'class'=>class_for_todo(progress_status['track'])} %span{'class'=>icon_for_todo(progress_status['track'])} diff --git a/app/views/proposals/new.html.haml b/app/views/proposals/new.html.haml index 7885f990..bab6eebd 100644 --- a/app/views/proposals/new.html.haml +++ b/app/views/proposals/new.html.haml @@ -7,7 +7,7 @@ - if @program.cfp.description.present? .row .col-md-12 - = markdown(@program.cfp.description) + = markdown(@program.cfp.description, escape_html=false) .row .col-md-12 = render partial: 'encouragement_text' @@ -43,10 +43,10 @@ - @program.event_types.each do |event_type| %span{ class: 'help-block event_event_type_id collapse', id: "#{event_type.id}-help" } - = event_type.description + = markdown(event_type.description) = f.input :abstract, required: true, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, - hint: markdown_hint('[Tips to improve your presentations.](http://blog.hubspot.com/blog/tabid/6307/bid/5975/10-Rules-to-Instantly-Improve-Your-Presentations.aspx)') + hint: markdown_hint %p You have used diff --git a/app/views/tickets/_ticket.html.haml b/app/views/tickets/_ticket.html.haml index 501e4151..052bc9e9 100644 --- a/app/views/tickets/_ticket.html.haml +++ b/app/views/tickets/_ticket.html.haml @@ -3,9 +3,9 @@ .media .media-body %h4.media-heading= ticket.title - %h5.media-heading= markdown(ticket.description) - - if @conference.tickets.for_registration.any? - %td.col-sm-1.col-md-2.text-center + .media-heading= markdown(ticket.description) + %td.col-sm-1.col-md-2 + %span.text-center = ticket.registration_ticket? ? 'Yes' : 'No' %td.col-sm-1.col-md-1 :ruby diff --git a/app/views/tickets/index.html.haml b/app/views/tickets/index.html.haml index e157d75e..2128aa19 100644 --- a/app/views/tickets/index.html.haml +++ b/app/views/tickets/index.html.haml @@ -13,18 +13,16 @@ %thead %tr %th Ticket - - if @conference.tickets.for_registration.any? - %th Registration Ticket + %th Registration? %th Quantity %th Price %th Total %tbody - - @conference.tickets.each do |ticket| + - @conference.tickets.visible.each do |ticket| = render 'ticket', f: f, ticket: ticket %tr %td - - if @conference.tickets.for_registration.any? - %td + %td %td %td.col-sm-1.col-md-1.text-center %h4 diff --git a/bin/osem-init.sh b/bin/osem-init.sh index b7d05dca..4a43081d 100755 --- a/bin/osem-init.sh +++ b/bin/osem-init.sh @@ -1,4 +1,5 @@ #!/bin/bash +bundle install # Setup the app if it isn't already setup bundle exec rake db:bootstrap # Start the app diff --git a/config/initializers/airbrake.rb b/config/initializers/airbrake.rb deleted file mode 100644 index e3c96dfc..00000000 --- a/config/initializers/airbrake.rb +++ /dev/null @@ -1,22 +0,0 @@ -Airbrake.configure do |config| - # Change this to some sensible data for your errbit instance - config.project_id = ENV['OSEM_ERRBIT_ID'] || Rails.application.secrets.errbit_id || '' - config.project_key = ENV['OSEM_ERRBIT_KEY'] || Rails.application.secrets.errbit_key || '' - config.host = ENV['OSEM_ERRBIT_HOST'] - config.environment = Rails.env - if config.project_key.blank? || config.host.blank? - config.ignore_environments = [:production, :development, :test] - else - config.ignore_environments = [:development, :test] - end -end - -Airbrake.add_filter do |notice| - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'ActiveRecord::RecordNotFound' } - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'ActionController::InvalidAuthenticityToken' } - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'ActionController::UnknownAction' } - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'AbstractController::ActionNotFound' } - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'ActionView::MissingTemplate' } - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'ActionController::UnknownFormat' } - notice.ignore! if notice[:errors].any? { |error| error[:type] == 'ActionController::RoutingError' && error[:message] =~ %r{\[GET\]} } -end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index a533ffe2..101f0c3d 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -6,12 +6,25 @@ Devise.setup do |config| # Define the available openID providers that can be used to log in # Pass each provider to User model in :omniauth_providers (for open_id providers use their name) - config.omniauth :open_id, name: 'suse', identifier: 'http://www.opensuse.org/openid/user' - config.omniauth :google_oauth2, (ENV['OSEM_GOOGLE_KEY'] || Rails.application.secrets.google_key), (ENV['OSEM_GOOGLE_SECRET'] || Rails.application.secrets.google_secret), + # config.omniauth :open_id, name: 'suse', identifier: 'http://www.opensuse.org/openid/user' + + config.omniauth :google_oauth2, + (ENV['OSEM_GOOGLE_KEY'] || Rails.application.secrets.google_key), + (ENV['OSEM_GOOGLE_SECRET'] || Rails.application.secrets.google_secret), name: 'google', scope: 'email' - config.omniauth :facebook, (ENV['OSEM_FACEBOOK_KEY'] || Rails.application.secrets.facebook_key), (ENV['OSEM_FACEBOOK_SECRET'] || Rails.application.secrets.facebook_secret) - config.omniauth :github, (ENV['OSEM_GITHUB_KEY'] || Rails.application.secrets.github_key), (ENV['OSEM_GITHUB_SECRET'] || Rails.application.secrets.github_secret) + + config.omniauth :discourse, + sso_url: 'https://forum.snap.berkeley.edu/session/sso_provider', + sso_secret: ENV['OSEM_DISCOURSE_SECRET'] + + config.omniauth :facebook, + (ENV['OSEM_FACEBOOK_KEY'] || Rails.application.secrets.facebook_key), + (ENV['OSEM_FACEBOOK_SECRET'] || Rails.application.secrets.facebook_secret) + + config.omniauth :github, + (ENV['OSEM_GITHUB_KEY'] || Rails.application.secrets.github_key), + (ENV['OSEM_GITHUB_SECRET'] || Rails.application.secrets.github_secret) # ==> Mailer Configuration # Configure the e-mail address which will be shown in Devise::Mailer, diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb new file mode 100644 index 00000000..b504df81 --- /dev/null +++ b/config/initializers/sentry.rb @@ -0,0 +1,4 @@ +Raven.configure do |config| + config.dsn = ENV['SENTRY_DSN'] + config.sanitize_fields = Rails.application.config.filter_parameters.map(&:to_s) +end diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb index 555cc16f..b89159b4 100644 --- a/config/initializers/stripe.rb +++ b/config/initializers/stripe.rb @@ -1 +1 @@ -Stripe.api_key = Rails.application.secrets.stripe_secret_key +Stripe.api_key = ENV['STRIPE_SECRET_KEY'] || Rails.application.secrets.stripe_secret_key diff --git a/config/puma.rb b/config/puma.rb index 9886e1e5..1d43c487 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -43,5 +43,16 @@ on_worker_boot do ActiveRecord::Base.establish_connection if defined?(ActiveRecord) end +lowlevel_error_handler do |ex, env| + Raven.capture_exception( + ex, + :message => ex.message, + :extra => { :puma => env }, + :transaction => "Puma" + ) + # note the below is just a Rack response + [500, {}, ["An error has occurred, and engineers have been informed. Please reload the page. If you continue to have problems, contact conference@snap.berkeley.edu\n"]] +end + # Allow puma to be restarted by `rails restart` command. plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb index 57bfa630..8849e0b2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -115,7 +115,11 @@ Osem::Application.routes.draw do end resources :resources - resources :tickets + resources :tickets do + member do + post :give + end + end resources :sponsors, except: [:show] resources :lodgings, except: [:show] resources :emails, only: [:show, :update, :index] diff --git a/db/migrate/20180409170433_add_visible_to_tickets.rb b/db/migrate/20180409170433_add_visible_to_tickets.rb new file mode 100644 index 00000000..199f7a48 --- /dev/null +++ b/db/migrate/20180409170433_add_visible_to_tickets.rb @@ -0,0 +1,11 @@ +class AddVisibleToTickets < ActiveRecord::Migration[5.0] + def up + add_column :tickets, :visible, :boolean, default: true + Ticket.reset_column_information + Ticket.update_all(visible: true) # rubocop:disable Rails/SkipsModelValidations + end + + def down + remove_column :tickets, :visible + end +end diff --git a/db/migrate/20181229233811_remove_arrival_departure_from_registrations.rb b/db/migrate/20181229233811_remove_arrival_departure_from_registrations.rb new file mode 100644 index 00000000..18f1398d --- /dev/null +++ b/db/migrate/20181229233811_remove_arrival_departure_from_registrations.rb @@ -0,0 +1,6 @@ +class RemoveArrivalDepartureFromRegistrations < ActiveRecord::Migration[5.0] + def change + remove_column :registrations, :arrival, :datetime + remove_column :registrations, :departure, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 2cb9ac88..4c2bc28e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20181113195810) do +ActiveRecord::Schema.define(version: 2018_12_29_233811) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" create_table "answers", force: :cascade do |t| t.string "title" @@ -364,8 +367,6 @@ ActiveRecord::Schema.define(version: 20181113195810) do create_table "registrations", force: :cascade do |t| t.integer "conference_id" - t.datetime "arrival" - t.datetime "departure" t.datetime "created_at" t.datetime "updated_at" t.text "other_special_needs" @@ -530,6 +531,7 @@ ActiveRecord::Schema.define(version: 20181113195810) do t.boolean "registration_ticket", default: false t.datetime "created_at" t.datetime "updated_at" + t.boolean "visible", default: true end create_table "tracks", force: :cascade do |t| diff --git a/public/robots.txt b/public/robots.txt index 085187fa..0e16a116 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,5 +1,6 @@ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # # To ban all spiders from the entire site uncomment the next two lines: -# User-Agent: * -# Disallow: / +User-Agent: * +Allow: / +Disallow: /admin diff --git a/spec/controllers/admin/tickets_controller_spec.rb b/spec/controllers/admin/tickets_controller_spec.rb new file mode 100644 index 00000000..6f09070c --- /dev/null +++ b/spec/controllers/admin/tickets_controller_spec.rb @@ -0,0 +1,257 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Admin::TicketsController do + let(:admin) { create(:admin) } + let(:conference) { create(:conference) } + let!(:ticket) { create(:ticket, conference: conference) } + let(:new_title) { Faker::Hipster.sentence } + + context 'admin is signed in' do + before { sign_in admin } + + describe 'GET #index' do + before { get :index, params: { conference_id: conference } } + + it 'assigns conference and tickets variables via cancancan' do + expect(assigns(:conference)).to eq conference + expect(assigns(:tickets)).to eq conference.tickets + end + + it 'renders index template' do + expect(response).to render_template('index') + end + end + + describe 'GET #edit' do + before { get :edit, params: { conference_id: conference, id: ticket } } + + it 'assigns ticket variable via cancancan' do + expect(assigns(:ticket)).to eq ticket + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + end + + describe 'GET #new' do + before { get :new, params: { conference_id: conference } } + + it 'assigns ticket variable' do + expect(assigns(:ticket)).to be_instance_of(Ticket) + end + + it 'renders new template' do + expect(response).to render_template('new') + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before(:each, run: true) do + post :create, params: { conference_id: conference, ticket: attributes_for(:ticket) } + end + + let!(:ticket_count) { conference.tickets.count } + + it 'redirects to index path', run: true do + expect(response).to redirect_to( + admin_conference_tickets_path(conference_id: conference) + ) + end + + it 'shows success message in flash notice', run: true do + expect(flash[:notice]).to match('Ticket successfully created.') + end + + it 'creates new ticket' do + expect do + post :create, params: { + ticket: attributes_for(:ticket), + conference_id: conference + } + end.to change{ conference.tickets.count }.from(ticket_count).to(ticket_count + 1) + end + end + + context 'save fails' do + before do + allow_any_instance_of(Ticket).to receive(:save).and_return(false) + post :create, params: { conference_id: conference, ticket: attributes_for(:ticket) } + end + + let!(:ticket_count) { conference.tickets.count } + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating Ticket failed: #{ticket.errors.full_messages.join('. ')}.") + end + + it 'does not create new ticket' do + expect(conference.tickets.count).to eq ticket_count + end + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before do + patch :update, params: { + conference_id: conference, id: ticket, + ticket: attributes_for(:ticket, title: new_title) + } + end + + it 'redirects to index path' do + expect(response).to redirect_to( + admin_conference_tickets_path(conference_id: conference) + ) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Ticket successfully updated.') + end + + it 'updates the ticket' do + ticket.reload + expect(ticket.title).to eq(new_title) + end + end + + context 'update fails' do + before do + allow_any_instance_of(Ticket).to receive(:save).and_return(false) + patch :update, params: { + conference_id: conference, id: ticket, + ticket: attributes_for(:ticket, title: new_title) + } + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Ticket update failed: #{ticket.errors.full_messages.join('. ')}.") + end + + it 'does not update ticket' do + ticket.reload + expect(ticket.title).not_to eq(new_title) + end + end + end + + describe 'DELETE #destroy' do + context 'deletes successfully' do + before(:each, run: true) do + delete :destroy, params: { conference_id: conference, id: ticket } + end + + let!(:ticket_count) { conference.tickets.count } + + it 'redirects to index path', run: true do + expect(response).to redirect_to( + admin_conference_tickets_path(conference_id: conference) + ) + end + + it 'shows success message in flash notice', run: true do + expect(flash[:notice]).to match('Ticket successfully deleted.') + end + + it 'deletes the ticket' do + expect do + delete :destroy, params: { conference_id: conference, id: ticket } + end.to change{ conference.tickets.count }.from(ticket_count).to(ticket_count - 1) + end + end + + context 'delete fails' do + let!(:ticket_count) { conference.tickets.count } + + before do + allow_any_instance_of(Ticket).to receive(:destroy).and_return(false) + delete :destroy, params: { conference_id: conference, id: ticket } + end + + it 'redirects to index path' do + expect(response).to redirect_to( + admin_conference_tickets_path(conference_id: conference) + ) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Deleting ticket failed! #{ticket.errors.full_messages.join('. ')}.") + end + + it 'does not delete ticket' do + expect(conference.tickets.count).to eq(ticket_count) + end + end + end + + describe 'POST #give' do + context 'grants a ticket purchase to a user' do + let!(:purchase_count) { admin.ticket_purchases.count } + + before do + post :give, params: { + conference_id: conference, id: ticket, + ticket_purchase: { user_id: admin.id } + } + end + + it 'redirects to ticket' do + expect(response).to redirect_to( + admin_conference_ticket_path(conference_id: conference, id: ticket) + ) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match( + "#{admin.name} was given a #{ticket.title} ticket." + ) + end + + it 'creates a ticket purchase' do + expect(admin.ticket_purchases.count).to eq(purchase_count + 1) + expect(admin.ticket_purchases.last.ticket).to eq(ticket) + end + end + + context 'giving fails' do + before do + allow_any_instance_of(TicketPurchase).to receive(:save).and_return(false) + post :give, params: { + conference_id: conference, id: ticket, + ticket_purchase: { user_id: admin.id } + } + end + + let(:purchase_count) { admin.ticket_purchases.count } + + it 'redirects to ticket' do + expect(response).to redirect_to( + admin_conference_ticket_path(conference_id: conference, id: ticket) + ) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match( + "Unable to give #{admin.name} a #{ticket.title} ticket: " + ) + end + + it 'does not create a ticket purchase' do + expect(admin.ticket_purchases.count).to eq(purchase_count) + end + end + end + end +end diff --git a/spec/controllers/conference_registration_controller_spec.rb b/spec/controllers/conference_registration_controller_spec.rb index f2849c27..964acaac 100644 --- a/spec/controllers/conference_registration_controller_spec.rb +++ b/spec/controllers/conference_registration_controller_spec.rb @@ -290,14 +290,15 @@ describe ConferenceRegistrationsController, type: :controller do before do @registration = create(:registration, conference: conference, - user: user, - arrival: Date.new(2014, 04, 25)) + user: user) end context 'updates successfully' do before do - patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)), - conference_id: conference.short_title } + patch :update, params: { + registration: attributes_for(:registration, volunteer: true), + conference_id: conference.short_title + } end it 'redirects to registration show path' do @@ -309,16 +310,17 @@ describe ConferenceRegistrationsController, type: :controller do end it 'updates the registration' do - @registration.reload - expect(@registration.arrival).to eq Date.new(2014, 04, 29) + expect{ @registration.reload }.to change(@registration, :updated_at) end end context 'update fails' do before do allow_any_instance_of(Registration).to receive(:update_attributes).and_return(false) - patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 27)), - conference_id: conference.short_title } + patch :update, params: { + registration: attributes_for(:registration, volunteer: true), + conference_id: conference.short_title + } end it 'renders edit template' do @@ -331,7 +333,7 @@ describe ConferenceRegistrationsController, type: :controller do it 'does not update the registration' do @registration.reload - expect(@registration.arrival).to eq Date.new(2014, 04, 25) + expect { @registration.reload }.not_to change(@registration, :updated_at) end end end diff --git a/spec/factories/tickets.rb b/spec/factories/tickets.rb index e71b898f..42d877d0 100644 --- a/spec/factories/tickets.rb +++ b/spec/factories/tickets.rb @@ -5,6 +5,7 @@ FactoryBot.define do title { "#{Faker::Hipster.word} Ticket" } price_cents { 1000 } price_currency { 'USD' } + visible { true } factory :registration_ticket do registration_ticket { true } end diff --git a/spec/features/commercials_spec.rb b/spec/features/commercials_spec.rb index a0710f86..5ddb08b2 100644 --- a/spec/features/commercials_spec.rb +++ b/spec/features/commercials_spec.rb @@ -17,9 +17,9 @@ feature Commercial do # Create valid commercial fill_in 'commercial_url', with: 'https://www.youtube.com/watch?v=M9bq_alk-sw' - click_button 'Create Commercial' + click_button 'Save Materials' page.find('#flash') - expect(flash).to eq('Commercial was successfully created.') + expect(flash).to eq('Materials were successfully created.') page.find('#flash .button.close').click expect(conference.commercials.count).to eq(1) @@ -28,7 +28,7 @@ feature Commercial do fill_in "commercial_url_#{commercial.id}", with: 'https://www.youtube.com/watch?v=VNkDJk5_9eU' click_button 'Update' page.find('#flash') - expect(flash).to eq('Commercial was successfully updated.') + expect(flash).to eq('Materials were successfully updated.') page.find('#flash .button.close').click expect(conference.commercials.count).to eq(1) commercial.reload @@ -39,7 +39,7 @@ feature Commercial do click_link 'Delete' end page.find('#flash') - expect(flash).to eq('Commercial was successfully destroyed.') + expect(flash).to eq('Materials were successfully destroyed.') expect(conference.commercials.count).to eq(0) end end @@ -56,23 +56,23 @@ feature Commercial do scenario 'adds a valid commercial of an event', feature: true, js: true do visit edit_conference_program_proposal_path(conference.short_title, event.id) - click_link 'Commercials' + click_link 'Materials' fill_in 'commercial_url', with: 'https://www.youtube.com/watch?v=M9bq_alk-sw' - # Workaround to enable the 'Create Commercial' button + # Workaround to enable the 'Save Materials' button page.execute_script("$('#commercial_submit_action').prop('disabled', false)") - click_button 'Create Commercial' + click_button 'Save Materials' page.find('#flash') - expect(flash).to eq('Commercial was successfully created.') + expect(flash).to eq('Materials were successfully created.') end scenario 'does not add an invalid commercial of an event', feature: true, js: true do visit edit_conference_program_proposal_path(conference.short_title, event.id) - click_link 'Commercials' + click_link 'Materials' fill_in 'commercial_url', with: 'invalid_commercial_url' expect(page).to have_content('No embeddable content') - expect(page).to have_css("button[type='submit']:disabled", text: 'Create Commercial') + expect(page).to have_css("button[type='submit']:disabled", text: 'Save Materials') end scenario 'updates a commercial of an event', feature: true, js: true do @@ -80,11 +80,11 @@ feature Commercial do commercialable_id: event.id, commercialable_type: 'Event') visit edit_conference_program_proposal_path(conference.short_title, event.id) - click_link 'Commercials' + click_link 'Materials' fill_in "commercial_url_#{commercial.id}", with: 'https://www.youtube.com/watch?v=M9bq_alk-sw' click_button 'Update' page.find('#flash') - expect(flash).to eq('Commercial was successfully updated.') + expect(flash).to eq('Materials were successfully updated.') TransactionalCapybara::AjaxHelpers.wait_for_ajax(page) expect(event.commercials.count).to eq(1) commercial.reload @@ -97,12 +97,12 @@ feature Commercial do commercialable_type: 'Event', url: 'https://www.youtube.com/watch?v=BTTygyxuGj8') visit edit_conference_program_proposal_path(conference.short_title, event.id) - click_link 'Commercials' + click_link 'Materials' fill_in "commercial_url_#{commercial.id}", with: 'invalid_commercial_url' click_button 'Update' find('#flash') expect(current_path).to eq edit_conference_program_proposal_path(conference.short_title, event.id) - expect(flash).to include('An error prohibited this Commercial from being saved:') + expect(flash).to include('An error prohibited materials from being saved:') commercial.reload expect(commercial.url).to eq('https://www.youtube.com/watch?v=BTTygyxuGj8') end @@ -112,12 +112,12 @@ feature Commercial do commercialable_id: event.id, commercialable_type: 'Event') visit edit_conference_program_proposal_path(conference.short_title, event.id) - click_link 'Commercials' + click_link 'Materials' page.accept_alert do click_link 'Delete' end page.find('#flash') - expect(flash).to eq('Commercial was successfully destroyed.') + expect(flash).to eq('Materials were successfully destroyed.') TransactionalCapybara::AjaxHelpers.wait_for_ajax(page) expect(event.commercials.count).to eq(0) end diff --git a/spec/features/conference_spec.rb b/spec/features/conference_spec.rb index 95f422bc..45f59e78 100644 --- a/spec/features/conference_spec.rb +++ b/spec/features/conference_spec.rb @@ -98,7 +98,8 @@ feature Conference do sign_in user visit admin_conference_path(conference.short_title) - expect(find('.navbar-brand').text).to eq(conference.organization.name) + # expect(find('.navbar-brand')).to eq(conference.organization.name) + expect(find('.navbar-brand img')['alt']).to have_content conference.organization.name end it_behaves_like 'add and update conference' diff --git a/spec/features/info_desk_ability_spec.rb b/spec/features/info_desk_ability_spec.rb index 066c95b8..95367ebb 100644 --- a/spec/features/info_desk_ability_spec.rb +++ b/spec/features/info_desk_ability_spec.rb @@ -21,7 +21,7 @@ feature 'Has correct abilities' do expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit") expect(page).to have_text('Basics') expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials") + expect(page).to have_link('Materials', href: "/admin/conferences/#{conference.short_title}/commercials") expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage") expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings") expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb index 5765d97f..3f9e32f8 100644 --- a/spec/features/organization_admin_ability_spec.rb +++ b/spec/features/organization_admin_ability_spec.rb @@ -32,7 +32,7 @@ feature 'Has correct abilities' do expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') expect(page).to have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit") expect(page).to have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials") + expect(page).to have_link('Materials', href: "/admin/conferences/#{conference.short_title}/commercials") expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage") expect(page).to have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue") expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 6339b6fa..27935824 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -35,7 +35,7 @@ feature 'Has correct abilities' do expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') expect(page).to have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit") expect(page).to have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials") + expect(page).to have_link('Materials', href: "/admin/conferences/#{conference.short_title}/commercials") expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage") expect(page).to have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue") expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") diff --git a/spec/features/tickets_spec.rb b/spec/features/tickets_spec.rb index 161d64d2..13f5a24b 100644 --- a/spec/features/tickets_spec.rb +++ b/spec/features/tickets_spec.rb @@ -15,7 +15,7 @@ feature Ticket do sign_out end - scenario 'add a valid ticket', feature: true, js: true do + scenario 'add a valid ticket', feature: true do visit admin_conference_tickets_path(conference.short_title) click_link 'Add Ticket' @@ -29,7 +29,7 @@ feature Ticket do expect(Ticket.count).to eq(2) end - scenario 'add a invalid ticket', feature: true, js: true do + scenario 'add a invalid ticket', feature: true do visit admin_conference_tickets_path(conference.short_title) click_link 'Add Ticket' @@ -42,10 +42,26 @@ feature Ticket do expect(Ticket.count).to eq(1) end + scenario 'add a hidden ticket', feature: true do + visit admin_conference_tickets_path(conference.short_title) + click_link 'Add Ticket' + + fill_in 'ticket_title', with: 'Hidden Ticket' + fill_in 'ticket_description', with: 'The hidden ticket' + fill_in 'ticket_price', with: '100' + uncheck 'ticket_visible' + + click_button 'Create Ticket' + page.find('#flash') + expect(flash).to eq('Ticket successfully created.') + expect(Ticket.count).to eq(2) + expect(Ticket.visible.count).to eq(1) + end + context 'Ticket already created' do let!(:ticket) { create(:ticket, title: 'Business Ticket', price: 100, conference_id: conference.id) } - scenario 'edit valid ticket', feature: true, js: true do + scenario 'edit valid ticket', feature: true do visit admin_conference_tickets_path(conference.short_title) click_link('Edit', href: edit_admin_conference_ticket_path(conference.short_title, ticket.id)) @@ -63,7 +79,7 @@ feature Ticket do expect(Ticket.count).to eq(2) end - scenario 'edit invalid ticket', feature: true, js: true do + scenario 'edit invalid ticket', feature: true do visit admin_conference_tickets_path(conference.short_title) click_link('Edit', href: edit_admin_conference_ticket_path(conference.short_title, ticket.id)) @@ -86,7 +102,7 @@ feature Ticket do click_link('Delete', href: admin_conference_ticket_path(conference.short_title, ticket.id)) page.accept_alert page.find('#flash') - expect(flash).to eq('Ticket successfully destroyed.') + expect(flash).to eq('Ticket successfully deleted.') expect(Ticket.count).to eq(1) end end diff --git a/spec/features/track_organizer_ability_spec.rb b/spec/features/track_organizer_ability_spec.rb index ec2ffdf1..1107f777 100644 --- a/spec/features/track_organizer_ability_spec.rb +++ b/spec/features/track_organizer_ability_spec.rb @@ -23,7 +23,7 @@ feature 'Has correct abilities' do expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit") expect(page).to have_text('Basics') expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials") + expect(page).to have_link('Materials', href: "/admin/conferences/#{conference.short_title}/commercials") expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage") expect(page).to_not have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue") expect(page).to_not have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") diff --git a/spec/features/versions_spec.rb b/spec/features/versions_spec.rb index ec443fd0..cf0c49ed 100644 --- a/spec/features/versions_spec.rb +++ b/spec/features/versions_spec.rb @@ -277,9 +277,9 @@ feature 'Version' do conference_commercial.destroy visit admin_revision_history_path - expect(page).to have_text("Someone (probably via the console) created new commercial in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) updated url of commercial in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) deleted commercial in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) created new materials in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) updated url of materials in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) deleted materials in conference #{conference.short_title}") end scenario 'display changes in event commercials', feature: true, versioning: true, js: true do @@ -288,9 +288,9 @@ feature 'Version' do event_commercial.destroy visit admin_revision_history_path - expect(page).to have_text("Someone (probably via the console) created new commercial in event #{event_with_commercial.title} in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) updated url of commercial in event #{event_with_commercial.title} in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) deleted commercial in event #{event_with_commercial.title} in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) created new materals in event #{event_with_commercial.title} in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) updated url of materials in event #{event_with_commercial.title} in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) deleted materials in event #{event_with_commercial.title} in conference #{conference.short_title}") end scenario 'display changes in event commercials in event history', feature: true, versioning: true, js: true do @@ -299,10 +299,10 @@ feature 'Version' do visit admin_conference_program_event_path(conference.short_title, event_with_commercial) click_link 'History' - expect(page).to have_text('Someone (probably via the console) created new commercial') + expect(page).to have_text('Someone (probably via the console) created new materials') visit admin_conference_program_event_path(conference.short_title, event_without_commercial) click_link 'History' - expect(page).to have_no_text('Someone (probably via the console) created new commercial') + expect(page).to have_no_text('Someone (probably via the console) created new materials') end scenario 'display changes in organization', feature: true, versioning: true, js: true do diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index cc0caeb9..edadc869 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -65,16 +65,19 @@ describe ApplicationHelper, type: :helper do describe 'navigation title link' do it 'should default to OSEM' do ENV.delete('OSEM_NAME') - expect(nav_root_link_for(nil)).to match 'OSEM' + # TODO:Snap!Con: expect(nav_root_link_for(nil)).to match 'OSEM' + expect(nav_root_link_for(nil)).to match image_tag('snapcon_logo.png') end it 'should use the environment variable' do ENV['OSEM_NAME'] = Faker::Company.name + "'" - expect(nav_root_link_for(nil)).to match h(ENV['OSEM_NAME']) + # expect(nav_root_link_for(nil)).to match h(ENV['OSEM_NAME']) + expect(nav_root_link_for(nil)).to match image_tag('snapcon_logo.png') end it 'should use the conference organization name' do - expect(nav_root_link_for(conference)).to match h(conference.organization.name) + # expect(nav_root_link_for(conference)).to match h(conference.organization.name) + expect(nav_root_link_for(nil)).to match image_tag('snapcon_logo.png') end end end diff --git a/spec/helpers/format_helper_spec.rb b/spec/helpers/format_helper_spec.rb index 0eb4d055..9d611ccb 100644 --- a/spec/helpers/format_helper_spec.rb +++ b/spec/helpers/format_helper_spec.rb @@ -11,7 +11,15 @@ describe FormatHelper, type: :helper do it 'should return HTML for header markdown' do expect(Redcarpet::Markdown).to receive(:new) - .with(Redcarpet::Render::HTML, autolink: true, space_after_headers: true, no_intra_emphasis: true) + .with( + Redcarpet::Render::HTML, + autolink: true, + space_after_headers: true, + tables: true, + strikethrough: true, + footnotes: true, + superscript: true + ) .and_call_original expect(markdown('# this is my header')).to eq "