Merge branch 'master' into michael/rm-start-restriction

This commit is contained in:
Michael Ball 2020-06-02 02:08:33 -07:00 committed by GitHub
commit 8d5c300639
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
109 changed files with 907 additions and 512 deletions

View file

@ -507,6 +507,7 @@ RSpec/AnyInstance:
Exclude: Exclude:
- 'spec/controllers/admin/rooms_controller_spec.rb' - 'spec/controllers/admin/rooms_controller_spec.rb'
- 'spec/controllers/admin/sponsorship_levels_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/tracks_controller_spec.rb'
- 'spec/controllers/admin/users_controller_spec.rb' - 'spec/controllers/admin/users_controller_spec.rb'
- 'spec/controllers/conference_registration_controller_spec.rb' - 'spec/controllers/conference_registration_controller_spec.rb'

View file

@ -1 +1 @@
2.5.0 2.5.5

View file

@ -4,6 +4,12 @@ Not release yet...
## Update from 1.0 ## 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 ### Multiple Schedules
A conference can have multiple schedules now so it's easier for organizers to A conference can have multiple schedules now so it's easier for organizers to
test schedules and collaborate on different versions. test schedules and collaborate on different versions.

View file

@ -2,7 +2,7 @@
source 'https://rubygems.org' 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 # rails-assets requires >= 1.8.4
if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('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' gem 'responders', '~> 2.0'
# as supported databases # as supported databases
gem 'mysql2'
gem 'pg' gem 'pg'
# for tracking data changes # for tracking data changes
@ -38,8 +37,8 @@ gem 'rails-i18n'
gem 'devise' gem 'devise'
gem 'devise_ichain_authenticatable' gem 'devise_ichain_authenticatable'
# for openID authentication
gem 'omniauth' gem 'omniauth'
gem 'omniauth-discourse'
gem 'omniauth-facebook' gem 'omniauth-facebook'
gem 'omniauth-github' gem 'omniauth-github'
gem 'omniauth-google-oauth2' gem 'omniauth-google-oauth2'
@ -143,8 +142,7 @@ gem 'rqrcode'
gem 'axlsx', git: 'https://github.com/randym/axlsx.git' gem 'axlsx', git: 'https://github.com/randym/axlsx.git'
gem 'axlsx_rails' gem 'axlsx_rails'
# as error catcher gem 'sentry-raven'
gem 'airbrake'
# to make links faster # to make links faster
gem 'turbolinks' gem 'turbolinks'

View file

@ -68,10 +68,6 @@ GEM
addressable (2.6.0) addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0) public_suffix (>= 2.0.2, < 4.0)
afm (0.2.2) 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) ajax-datatables-rails (0.4.3)
railties (>= 4.0) railties (>= 4.0)
archive-zip (0.12.0) archive-zip (0.12.0)
@ -130,7 +126,6 @@ GEM
url url
coderay (1.1.1) coderay (1.1.1)
concurrent-ruby (1.1.5) concurrent-ruby (1.1.5)
connection_pool (2.2.2)
countable-rails (0.0.1) countable-rails (0.0.1)
railties (>= 3.1) railties (>= 3.1)
countries (3.0.0) countries (3.0.0)
@ -301,13 +296,10 @@ GEM
monetize (~> 1.9.0) monetize (~> 1.9.0)
money (~> 6.13.2) money (~> 6.13.2)
railties (>= 3.0) railties (>= 3.0)
multi_json (1.13.1) multi_json (1.14.1)
multi_xml (0.6.0) multi_xml (0.6.0)
multipart-post (2.1.1) multipart-post (2.1.1)
mysql2 (0.5.2)
nenv (0.3.0) nenv (0.3.0)
net-http-persistent (3.0.1)
connection_pool (~> 2.2)
netrc (0.11.0) netrc (0.11.0)
nio4r (2.5.2) nio4r (2.5.2)
nokogiri (1.10.8) nokogiri (1.10.8)
@ -324,7 +316,9 @@ GEM
omniauth (1.9.0) omniauth (1.9.0)
hashie (>= 3.4.6, < 3.7.0) hashie (>= 3.4.6, < 3.7.0)
rack (>= 1.6.2, < 3) 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-oauth2 (~> 1.2)
omniauth-github (1.3.0) omniauth-github (1.3.0)
omniauth (~> 1.5) omniauth (~> 1.5)
@ -441,7 +435,6 @@ GEM
rb-fsevent (0.10.3) rb-fsevent (0.10.3)
rb-inotify (0.10.0) rb-inotify (0.10.0)
ffi (~> 1.0) ffi (~> 1.0)
rbtree3 (0.5.0)
rdoc (6.0.4) rdoc (6.0.4)
rdoc-generator-fivefish (0.4.0) rdoc-generator-fivefish (0.4.0)
inversion (~> 1.1) inversion (~> 1.1)
@ -525,6 +518,8 @@ GEM
selenium-webdriver (3.142.6) selenium-webdriver (3.142.6)
childprocess (>= 0.5, < 4.0) childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2) rubyzip (>= 1.2.2)
sentry-raven (2.13.0)
faraday (>= 0.7.6, < 1.0)
sexp_processor (4.11.0) sexp_processor (4.11.0)
shellany (0.0.1) shellany (0.0.1)
shoulda-matchers (4.1.2) shoulda-matchers (4.1.2)
@ -553,13 +548,11 @@ GEM
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sqlite3 (1.4.2) sqlite3 (1.4.2)
stripe (4.21.3) stripe (5.14.0)
faraday (~> 0.13) stripe-ruby-mock (3.0.1)
net-http-persistent (~> 3.0)
stripe-ruby-mock (2.5.8)
dante (>= 0.2.0) dante (>= 0.2.0)
multi_json (~> 1.0) multi_json (~> 1.0)
stripe (>= 2.0.3) stripe (> 5, < 6)
sysexits (1.2.0) sysexits (1.2.0)
temple (0.8.0) temple (0.8.0)
thor (0.20.3) thor (0.20.3)
@ -616,7 +609,6 @@ DEPENDENCIES
active_model_serializers active_model_serializers
acts_as_commentable_with_threading acts_as_commentable_with_threading
acts_as_list acts_as_list
airbrake
ajax-datatables-rails ajax-datatables-rails
autoprefixer-rails autoprefixer-rails
awesome_nested_set awesome_nested_set
@ -665,9 +657,9 @@ DEPENDENCIES
mina mina
mini_magick mini_magick
money-rails money-rails
mysql2
nokogiri (>= 1.8.1) nokogiri (>= 1.8.1)
omniauth omniauth
omniauth-discourse
omniauth-facebook omniauth-facebook
omniauth-github omniauth-github
omniauth-google-oauth2 omniauth-google-oauth2
@ -707,6 +699,7 @@ DEPENDENCIES
ruby-oembed ruby-oembed
sass-rails (>= 4.0.2) sass-rails (>= 4.0.2)
selectize-rails selectize-rails
sentry-raven
shoulda-matchers shoulda-matchers
skylight skylight
spring-commands-rspec spring-commands-rspec
@ -726,7 +719,7 @@ DEPENDENCIES
whenever whenever
RUBY VERSION RUBY VERSION
ruby 2.5.0p0 ruby 2.5.5p157
BUNDLED WITH BUNDLED WITH
1.17.3 1.17.3

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -11,39 +11,6 @@ $(function () {
format: 'YYYY-MM-DD HH:mm' 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({ $("#conference-start-datepicker").datetimepicker({
useCurrent: false, useCurrent: false,
format: "YYYY-MM-DD" format: "YYYY-MM-DD"

View file

@ -2,6 +2,13 @@
*= require strap-on *= require strap-on
*= require formtastic-bootstrap *= require formtastic-bootstrap
*= require dataTables/bootstrap/3/jquery.dataTables.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
*= require osem-rating *= require osem-rating
*= require osem-schedule *= require osem-schedule
@ -10,15 +17,9 @@
*= require osem-splash *= require osem-splash
*= require font-awesome *= require font-awesome
*= require osem-fonts *= require osem-fonts
*= require bootstrap-markdown
*= require bootstrap-datetimepicker
*= require leaflet
*= require bootstrap3-switch *= require bootstrap3-switch
*= require osem-payments *= require osem-payments
*= require osem-navbar *= require osem-navbar
*= require selectize
*= require selectize.bootstrap3
*= require mastodon *= require mastodon
*= require bootstrap-select
*= require conferences *= require conferences
*/ */

View file

@ -1,4 +1,6 @@
@import "breakpoints.scss"; @import "breakpoints.scss";
@import "osem-variables.scss";
.nav-osem { .nav-osem {
border: none; border: none;
@include breakpoint(xs) { @include breakpoint(xs) {
@ -29,7 +31,23 @@
} }
} }
.dropdown-menu { .dropdown-menu {
padding: 17px;
min-width: 225px; 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;
}
} }

View file

@ -64,9 +64,8 @@
#schedule td.event { #schedule td.event {
background-image: linear-gradient(to top, rgb(247,250,242) 24%, rgb(194,232,190) 97%, rgb(194,232,190) 100%); background-image: linear-gradient(to top, rgb(247,250,242) 24%, rgb(194,232,190) 97%, rgb(194,232,190) 100%);
cursor: pointer;
cursor: pointer; padding: 3px 2px;
padding: 3px 2px;
} }
#schedule td.event:hover #schedule td.event:hover

View file

@ -1,4 +1,5 @@
@import "breakpoints.scss"; @import "breakpoints.scss";
@import "osem-variables.scss";
#splash { #splash {
// Counter the general padding for #content // Counter the general padding for #content
@ -6,18 +7,30 @@
section { section {
padding-top: 60px; padding-top: 60px;
padding-bottom: 60px; padding-bottom: 60px;
.trapezoid {
top: 60px + $trapezoid-height;
}
} }
section:nth-child(even) { section:nth-child(even) {
background: none repeat scroll 0 0 #e0e0e0; background: none repeat scroll 0 0 #eee;
color: #555; color: #333;
.trapezoid {
border-top-color: #eee;
}
} }
section:nth-child(odd) { section:nth-child(odd) {
background: none repeat scroll 0 0 #ffffff; background: none repeat scroll 0 0 #ffffff;
color: #7b7b7b; color: #333;
.thumbnail { .thumbnail {
background: none repeat scroll 0 0 #e0e0e0; background: none repeat scroll 0 0 #e0e0e0;
} }
.trapezoid {
border-top-color: #fff;
}
} }
.cta-button { .cta-button {
@ -32,11 +45,15 @@
padding-top: 100px; padding-top: 100px;
padding-bottom: 100px; padding-bottom: 100px;
.container { .container {
#header { #header-no-image {
background-color: rgba(224, 224, 224,.80); background-color: rgba(224, 224, 224,.80);
padding-top: 20px; padding-top: 20px;
padding-bottom: 20px; padding-bottom: 20px;
} }
#header-image {
color: #FFF;
}
} }
} }
@ -67,6 +84,10 @@
#venue-pic { #venue-pic {
margin-top: 20px; margin-top: 20px;
} }
// The venue section has less padding.
.trapezoid {
top: $trapezoid-height;
}
} }
#lodging { #lodging {
@ -93,6 +114,14 @@
} }
} }
#tickets {
a {
&:hover, &:focus {
text-decoration: none;
}
}
}
#sponsors { #sponsors {
.img-sponsor { .img-sponsor {
max-height: 100px; max-height: 100px;
@ -116,14 +145,13 @@
} }
#social-media{ #social-media{
background: none repeat scroll 0 0 #2f2f2f; background: none repeat scroll 0 0 #0C3559;
padding-top: 60px; padding: 50px 20px;
padding-bottom: 60px;
i{ i{
color: #4a4a4a; color: #FFF;
} }
i:hover{ i:hover{
color: #16a085; color: #F2E205;
} }
a{ a{
padding-left: 100px; padding-left: 100px;
@ -164,11 +192,11 @@
i.fa { i.fa {
line-height: inherit; line-height: inherit;
} }
&.show { // &.show {
visibility:visible; // visibility:visible;
cursor:pointer; // cursor:pointer;
opacity: 1.0; // opacity: 1.0;
} // }
a { a {
color: white; color: white;
} }

View file

@ -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;

View file

@ -1,3 +1,4 @@
@import "osem-variables";
@import "bootstrap/mixins"; @import "bootstrap/mixins";
html { html {
@ -7,15 +8,31 @@ html {
body { body {
/* Margin bottom by 2 times the footer height */ /* Margin bottom by 2 times the footer height */
margin-bottom: 60px; margin-bottom: 85px;
/* Margin bottom by navbar height */ /* Margin bottom by navbar height */
padding-top: 60px; padding-top: 60px;
font-size: 16px;
} }
#content { #content {
padding-bottom: 60px; 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 { #footer {
position: absolute; position: absolute;
bottom: 0; bottom: 0;

View file

@ -1,10 +1,5 @@
$navbar-default-bg: #299a0b; // Place bootstrap variable customizations in the file below.
$navbar-default-link-active-bg: #DFE0DF; @import "osem-variables";
$navbar-default-border: 1px solid #d4d4d4;
$navbar-default-color: #ffffff;
$navbar-default-link-color: #ffffff;
$navbar-default-link-hover-color: #000000;
@import 'bootstrap-datetimepicker'; @import 'bootstrap-datetimepicker';
@import "bootstrap-sprockets"; @import "bootstrap-sprockets";

View file

@ -17,10 +17,10 @@ module Admin
if @commercial.save if @commercial.save
redirect_to admin_conference_commercials_path, redirect_to admin_conference_commercials_path,
notice: 'Commercial was successfully created.' notice: 'Materials were successfully created.'
else else
redirect_to admin_conference_commercials_path, 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('. ')}." "#{@commercial.errors.full_messages.join('. ')}."
end end
@ -29,17 +29,17 @@ module Admin
def update def update
if @commercial.update(commercial_params) if @commercial.update(commercial_params)
redirect_to admin_conference_commercials_path, redirect_to admin_conference_commercials_path,
notice: 'Commercial was successfully updated.' notice: 'Materials were successfully updated.'
else else
redirect_to admin_conference_commercials_path, 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('. ')}." "#{@commercial.errors.full_messages.join('. ')}."
end end
end end
def destroy def destroy
@commercial.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 end
def render_commercial def render_commercial
@ -60,9 +60,9 @@ module Admin
errors = Commercial.read_file(params[:file]) if params[:file] errors = Commercial.read_file(params[:file]) if 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? } elsif errors.all? { |_k, v| v.blank? }
flash[:notice] = 'Successfully added commercials.' flash[:notice] = 'Successfully added materials.'
else else
errors_text = '' errors_text = ''
errors_text << 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any? errors_text << 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any?

View file

@ -82,7 +82,7 @@ module Admin
def registration_params def registration_params
params.require(:registration).permit( params.require(:registration).permit(
:user_id, :conference_id, :arrival, :departure, :attended, :user_id, :conference_id, :attended,
:volunteer, :other_special_needs, :accepted_code_of_conduct, :volunteer, :other_special_needs, :accepted_code_of_conduct,
vchoice_ids: [], qanswer_ids: [], qanswers_attributes: [], event_ids: [] vchoice_ids: [], qanswer_ids: [], qanswers_attributes: [], event_ids: []
) )

View file

@ -38,13 +38,30 @@ module Admin
end end
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 def destroy
if @ticket.destroy if @ticket.destroy
redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), redirect_to admin_conference_tickets_path(conference_id: @conference.short_title),
notice: 'Ticket successfully destroyed.' notice: 'Ticket successfully deleted.'
else else
redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), 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('. ')}." "#{@ticket.errors.full_messages.join('. ')}."
end end
end end
@ -52,7 +69,19 @@ module Admin
private private
def ticket_params 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 end
end end

View file

@ -12,10 +12,10 @@ module Admin
if @commercial.save if @commercial.save
redirect_to admin_conference_venue_path, redirect_to admin_conference_venue_path,
notice: 'Commercial was successfully created.' notice: 'Materials successfully created.'
else else
redirect_to admin_conference_venue_path, 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('. ')}." "#{@commercial.errors.full_messages.join('. ')}."
end end
@ -24,17 +24,17 @@ module Admin
def update def update
if @commercial.update(commercial_params) if @commercial.update(commercial_params)
redirect_to admin_conference_venue_path, redirect_to admin_conference_venue_path,
notice: 'Commercial was successfully updated.' notice: 'Materials successfully updated.'
else else
redirect_to admin_conference_venue_path, 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('. ')}." "#{@commercial.errors.full_messages.join('. ')}."
end end
end end
def destroy def destroy
@commercial.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 end
def render_commercial def render_commercial

View file

@ -12,27 +12,27 @@ class CommercialsController < ApplicationController
if @commercial.save if @commercial.save
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), 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 else
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), 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
end end
def update def update
if @commercial.update(commercial_params) if @commercial.update(commercial_params)
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), 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 else
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), 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
end end
def destroy def destroy
@commercial.destroy @commercial.destroy
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id), 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 end
def render_commercial def render_commercial

View file

@ -57,7 +57,7 @@ class ConferenceRegistrationsController < ApplicationController
sign_in(@registration.user) sign_in(@registration.user)
end 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), redirect_to conference_tickets_path(@conference.short_title),
notice: 'You are now registered and will be receiving E-Mail notifications.' notice: 'You are now registered and will be receiving E-Mail notifications.'
else else
@ -108,9 +108,9 @@ class ConferenceRegistrationsController < ApplicationController
end end
def registration_params def registration_params
params.require(:registration) params.permit(:registration)
.permit( .permit(
:conference_id, :arrival, :departure, :conference_id,
:volunteer, :accepted_code_of_conduct, :volunteer, :accepted_code_of_conduct,
vchoice_ids: [], qanswer_ids: [], vchoice_ids: [], qanswer_ids: [],
qanswers_attributes: [], qanswers_attributes: [],

View file

@ -51,10 +51,10 @@ class ConferencesController < ApplicationController
end end
end end
if splashpage.include_registrations || splashpage.include_tickets if splashpage.include_registrations || splashpage.include_tickets
@tickets = @conference.tickets.order('price_cents') @tickets = @conference.tickets.visible.order('price_cents')
end end
if splashpage.include_lodgings if splashpage.include_lodgings
@lodgings = @conference.lodgings.order('name') @lodgings = @conference.lodgings.order('id')
end end
if splashpage.include_sponsors if splashpage.include_sponsors
@sponsorship_levels = @conference.sponsorship_levels.eager_load( @sponsorship_levels = @conference.sponsorship_levels.eager_load(

View file

@ -3,7 +3,8 @@
class TicketsController < ApplicationController class TicketsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
load_resource :conference, find_by: :short_title 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 authorize_resource :conference_registrations, class: Registration
before_action :check_load_resource, only: :index 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}!" redirect_to root_path, notice: "There are no tickets available for #{@conference.title}!"
end end
end end
def load_tickets
@tickets = @conference.tickets.visible
end
end end

View file

@ -10,8 +10,6 @@ class RegistrationDatatable < AjaxDatatablesRails::Base
roles: { source: 'Role.name' }, roles: { source: 'Role.name' },
email: { source: 'User.email' }, email: { source: 'User.email' },
accepted_code_of_conduct: { source: 'Registration.accepted_code_of_conduct', searchable: false }, 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 } actions: { source: 'Registration.id', searchable: false, orderable: false }
} }
end end
@ -36,8 +34,6 @@ class RegistrationDatatable < AjaxDatatablesRails::Base
roles: conference_role_titles(record.user), roles: conference_role_titles(record.user),
email: record.email, email: record.email,
accepted_code_of_conduct: !!record.accepted_code_of_conduct, # rubocop:disable Style/DoubleNegation accepted_code_of_conduct: !!record.accepted_code_of_conduct, # rubocop:disable Style/DoubleNegation
arrival: record.arrival&.utc,
departure: record.departure&.utc,
questions: {}, questions: {},
edit_url: edit_admin_conference_registration_path(conference, record), edit_url: edit_admin_conference_registration_path(conference, record),
DT_RowId: record.id DT_RowId: record.id

View file

@ -40,19 +40,20 @@ class UserDatatable < AjaxDatatablesRails::Base
# rubocop:disable Naming/AccessorMethodName # rubocop:disable Naming/AccessorMethodName
def get_raw_records def get_raw_records
User.left_outer_joins(:registrations, :roles) User.left_outer_joins(:registrations, :roles).select(
.distinct "DISTINCT users.id, users.name, users.email, users.confirmed_at, COUNT(CASE WHEN registrations.attended = 't' THEN 1 END) AS attended_count"
.select("users.*, COUNT(CASE WHEN registrations.attended = 't' THEN 1 END) AS attended_count") ).group(
.group('users.id') 'users.id, users.name, users.email, users.confirmed_at'
)
end end
# rubocop:enable Naming/AccessorMethodName # rubocop:enable Naming/AccessorMethodName
def records_total_count def records_total_count
fetch_records.unscope(:group).count(:all) fetch_records.unscoped.count(:id)
end end
def records_filtered_count def records_filtered_count
filter_records(fetch_records).unscope(:group).count(:all) filter_records(fetch_records).unscoped.count
end end
# ==== These methods represent the basic operations to perform on records # ==== These methods represent the basic operations to perform on records

View file

@ -178,20 +178,22 @@ module ApplicationHelper
'hidden' if Date.today > conference.end_date 'hidden' if Date.today > conference.end_date
end end
# TODO:Snap!Con: Replace this with a search for a conference logo.
def nav_root_link_for(conference) def nav_root_link_for(conference)
link_text = (
conference.try(:organization).try(:name) ||
ENV['OSEM_NAME'] ||
'OSEM'
)
link_to( link_to(
link_text, image_tag('snapcon_logo.png'),
root_path, root_path,
class: 'navbar-brand', class: 'navbar-brand',
title: 'Open Source Event Manager' title: nav_link_text(conference)
) )
end 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 # returns the url to be used for logo on basis of sponsorship level position
def get_logo(object) def get_logo(object)
if object.try(:sponsorship_level) if object.try(:sponsorship_level)

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'redcarpet/render_strip'
module FormatHelper module FormatHelper
## ##
# Includes functions related to formatting (like adding classes, colors) # Includes functions related to formatting (like adding classes, colors)
@ -42,12 +44,11 @@ module FormatHelper
def target_progress_color(progress) def target_progress_color(progress)
progress = progress.to_i progress = progress.to_i
result = result = case
case when progress >= 90 then 'green'
when progress >= 90 then 'green' when progress < 90 && progress >= 80 then 'orange'
when progress < 90 && progress >= 80 then 'orange' else 'red'
else 'red' end
end
result result
end end
@ -99,19 +100,11 @@ module FormatHelper
end end
def icon_for_todo(bool) def icon_for_todo(bool)
if bool bool ? 'fa fa-check' : 'fa fa-times'
'fa fa-check'
else
'fa fa-times'
end
end end
def class_for_todo(bool) def class_for_todo(bool)
if bool bool ? 'todolist-ok' : 'todolist-missing'
'todolist-ok'
else
'todolist-missing'
end
end end
def word_pluralize(count, singular, plural = nil) def word_pluralize(count, singular, plural = nil)
@ -191,9 +184,12 @@ module FormatHelper
return '' if text.nil? return '' if text.nil?
options = { options = {
autolink: true, autolink: true,
space_after_headers: 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 = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: escape_html), options)
markdown.render(text).html_safe 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) markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text", false)
end 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) def quantity_left_of(resource)
return '-/-' if resource.quantity.blank? return '-/-' if resource.quantity.blank?

View file

@ -1,8 +1,11 @@
# frozen_string_literal: true # frozen_string_literal: true
SNAPCON_BCC_ADDRESS = 'messages@snap.berkeley.edu'
class Mailbot < ActionMailer::Base class Mailbot < ActionMailer::Base
def registration_mail(conference, user) def registration_mail(conference, user)
mail(to: user.email, mail(to: user.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.registration_subject, subject: conference.email_settings.registration_subject,
body: conference.email_settings.generate_email_on_conf_updates(conference, body: conference.email_settings.generate_email_on_conf_updates(conference,
@ -21,6 +24,7 @@ class Mailbot < ActionMailer::Base
end end
mail(to: @user.email, mail(to: @user.email,
bcc: SNAPCON_BCC_ADDRESS,
from: @conference.contact.email, from: @conference.contact.email,
template_name: 'ticket_confirmation_template', template_name: 'ticket_confirmation_template',
subject: "#{@conference.title} | Ticket Confirmation and PDF!") subject: "#{@conference.title} | Ticket Confirmation and PDF!")
@ -30,6 +34,7 @@ class Mailbot < ActionMailer::Base
conference = event.program.conference conference = event.program.conference
mail(to: event.submitter.email, mail(to: event.submitter.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.accepted_subject, subject: conference.email_settings.accepted_subject,
body: conference.email_settings.generate_event_mail(event, conference.email_settings.accepted_body)) 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 conference = event.program.conference
mail(to: event.submitter.email, mail(to: event.submitter.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.submitted_proposal_subject, subject: conference.email_settings.submitted_proposal_subject,
body: conference.email_settings.generate_event_mail(event, conference.email_settings.submitted_proposal_body)) 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 conference = event.program.conference
mail(to: event.submitter.email, mail(to: event.submitter.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.rejected_subject, subject: conference.email_settings.rejected_subject,
body: conference.email_settings.generate_event_mail(event, conference.email_settings.rejected_body)) 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 conference = event.program.conference
mail(to: event.submitter.email, mail(to: event.submitter.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.confirmed_without_registration_subject, subject: conference.email_settings.confirmed_without_registration_subject,
body: conference.email_settings.generate_event_mail(event, body: conference.email_settings.generate_event_mail(event,
@ -65,6 +73,7 @@ class Mailbot < ActionMailer::Base
def conference_date_update_mail(conference, user) def conference_date_update_mail(conference, user)
mail(to: user.email, mail(to: user.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.conference_dates_updated_subject, subject: conference.email_settings.conference_dates_updated_subject,
body: conference.email_settings.generate_email_on_conf_updates(conference, 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) def conference_registration_date_update_mail(conference, user)
mail(to: user.email, mail(to: user.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.conference_registration_dates_updated_subject, subject: conference.email_settings.conference_registration_dates_updated_subject,
body: conference.email_settings.generate_email_on_conf_updates(conference, 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) def conference_venue_update_mail(conference, user)
mail(to: user.email, mail(to: user.email,
bcc: SNAPCON_BCC_ADDRESS,
from: conference.contact.email, from: conference.contact.email,
subject: conference.email_settings.venue_updated_subject, subject: conference.email_settings.venue_updated_subject,
body: conference.email_settings.generate_email_on_conf_updates(conference, body: conference.email_settings.generate_email_on_conf_updates(conference,

View file

Binary file not shown.

View file

@ -87,7 +87,9 @@ class Ability
end end
can :index, Organization can :index, Organization
can :index, Ticket can :index, Ticket do |ticket|
ticket.visible
end
can :manage, TicketPurchase, user_id: user.id can :manage, TicketPurchase, user_id: user.id
can [:new, :create], Payment, user_id: user.id can [:new, :create], Payment, user_id: user.id
can [:index, :show], PhysicalTicket, user: user can [:index, :show], PhysicalTicket, user: user

View file

@ -39,7 +39,7 @@ class Commercial < ApplicationRecord
commercial = event.commercials.new(url: url) commercial = event.commercials.new(url: url)
unless commercial.save 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
end end
errors errors

View file

@ -25,8 +25,8 @@ class Conference < ApplicationRecord
has_one :email_settings, dependent: :destroy has_one :email_settings, dependent: :destroy
has_one :program, dependent: :destroy has_one :program, dependent: :destroy
has_one :venue, dependent: :destroy has_one :venue, dependent: :destroy
has_many :physical_tickets, through: :ticket_purchases
has_many :ticket_purchases, dependent: :destroy has_many :ticket_purchases, dependent: :destroy
has_many :physical_tickets, through: :ticket_purchases
has_many :payments, dependent: :destroy has_many :payments, dependent: :destroy
has_many :supporters, through: :ticket_purchases, source: :user has_many :supporters, through: :ticket_purchases, source: :user
has_many :tickets, dependent: :destroy has_many :tickets, dependent: :destroy

View file

@ -28,8 +28,6 @@ class Registration < ApplicationRecord
validates :user_id, uniqueness: { scope: :conference_id, message: 'already Registered!' } validates :user_id, uniqueness: { scope: :conference_id, message: 'already Registered!' }
validate :registration_limit_not_exceed, on: :create validate :registration_limit_not_exceed, on: :create
validate :registration_to_events_only_if_present
validates :accepted_code_of_conduct, acceptance: { validates :accepted_code_of_conduct, acceptance: {
if: -> { conference.try(:code_of_conduct).present? } if: -> { conference.try(:code_of_conduct).present? }
} }
@ -48,19 +46,6 @@ class Registration < ApplicationRecord
private 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 def subscribe_to_conference
Subscription.create(conference_id: conference.id, user_id: user.id) Subscription.create(conference_id: conference.id, user_id: user.id)
end end

View file

@ -20,6 +20,8 @@ class Ticket < ApplicationRecord
validates :price_cents, numericality: { greater_than_or_equal_to: 0 } validates :price_cents, numericality: { greater_than_or_equal_to: 0 }
scope :visible, -> { where(visible: true) }
def bought?(user) def bought?(user)
buyers.include?(user) buyers.include?(user)
end end

View file

@ -32,7 +32,7 @@ class TicketPurchase < ApplicationRecord
errors.push('You cannot buy more than one registration tickets.') errors.push('You cannot buy more than one registration tickets.')
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
conference.tickets.each do |ticket| conference.tickets.visible.each do |ticket|
quantity = purchases[ticket.id.to_s].to_i quantity = purchases[ticket.id.to_s].to_i
# if the user bought the ticket and is still unpaid, just update the quantity # if the user bought the ticket and is still unpaid, just update the quantity
purchase = if ticket.bought?(user) && ticket.unpaid?(user) purchase = if ticket.bought?(user) && ticket.unpaid?(user)

View file

@ -50,7 +50,10 @@ class User < ApplicationRecord
else else
[:database_authenticatable, :registerable, [:database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :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 end
devise(*devise_modules) devise(*devise_modules)

View file

@ -1,11 +1,11 @@
.row .row
.col-md-12 .col-md-12
.page-header .page-header
%h1 Commercials %h1 Session Materials
%p.text-muted %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) = 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 - if can? :create, @conference.commercials.new
.row .row
.col-md-6 .col-md-6

View file

@ -7,11 +7,12 @@
Event Type Event Type
= @event_type.title = @event_type.title
.row .row
.col-md-12 .col-md-8
= 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| - 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 :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 :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 :minimum_abstract_length, input_html: {size: 3}
= f.input :maximum_abstract_length, input_html: {size: 3} = f.input :maximum_abstract_length, input_html: {size: 3}
= f.input :color, input_html: { size: 6, type: 'color' } = f.input :color, input_html: { size: 6, type: 'color' }

View file

@ -20,7 +20,7 @@
%td %td
= event_type.title = event_type.title
%td %td
= event_type.description = markdown(event_type.description)
%td %td
= event_type.length = event_type.length
Minutes Minutes

View file

@ -6,9 +6,9 @@
= "(#{@events.length})" if @events.any? = "(#{@events.length})" if @events.any?
.btn-group.pull-right .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' } } data: { toggle: 'modal', target: '#mass-commercials-modal' } }
Add Commercials Add Materials
- if can? :create, Event - if can? :create, Event
= link_to 'Add Event', = link_to 'Add Event',
@ -28,7 +28,7 @@
.modal-dialog .modal-dialog
.modal-content .modal-content
.modal-header .modal-header
%h1 Add commercials to events %h1 Add materials to events
.text-muted .text-muted
Upload your file with data in the following format: Upload your file with data in the following format:
%b Event_ID:Commercial_Link %b Event_ID:Commercial_Link

View file

@ -11,7 +11,7 @@
- progress_status = @event.progress_status - progress_status = @event.progress_status
= progress_status.reject{ |_key, value| value || value.nil? }.length = progress_status.reject{ |_key, value| value || value.nil? }.length
%li %li
= link_to 'Commercials', '#proposal-commercials', 'data-toggle' => 'tab' = link_to 'Materials', '#proposal-commercials', 'data-toggle' => 'tab'
.tab-content .tab-content
#proposal-content.tab-pane.active #proposal-content.tab-pane.active
@ -42,7 +42,7 @@
- else - else
= general_change_description(version) = general_change_description(version)
= link_to 'commercial', = link_to 'materials',
edit_admin_conference_program_event_path(conference_id: @conference.short_title, edit_admin_conference_program_event_path(conference_id: @conference.short_title,
id: @event.id, anchor: 'commercials-content') id: @event.id, anchor: 'commercials-content')
@ -82,7 +82,7 @@
%td{ 'class' => class_for_todo(progress_status['subtitle']) } %td{ 'class' => class_for_todo(progress_status['subtitle']) }
%span{ 'class' => [icon_for_todo(progress_status['subtitle']), 'fa-lg'] } %span{ 'class' => [icon_for_todo(progress_status['subtitle']), 'fa-lg'] }
%tr %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']) } %td{ 'class' => class_for_todo(progress_status['commercials']) }
%span{ 'class' => [icon_for_todo(progress_status['commercials']), 'fa-lg'] } %span{ 'class' => [icon_for_todo(progress_status['commercials']), 'fa-lg'] }
- unless progress_status['track'].nil? - unless progress_status['track'].nil?

View file

@ -30,8 +30,6 @@
%th{ width: '0' } E-Mail %th{ width: '0' } E-Mail
%th{ width: '0' } %th{ width: '0' }
%abbr{ title: 'Code of Conduct' } CoC %abbr{ title: 'Code of Conduct' } CoC
%th{ width: '0' } Arrival
%th{ width: '0' } Departure
%th{ width: '0' } Actions %th{ width: '0' } Actions
%tbody %tbody
@ -81,22 +79,6 @@
"className": "code-of-conduct text-center", "className": "code-of-conduct text-center",
"searchable": false "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, "data": null,
"className": "actions", "className": "actions",

View file

@ -4,9 +4,7 @@ prawn_document(force_download: true, filename: @pdf_filename, page_layout: :land
'Name', 'Name',
'Nickname', 'Nickname',
'Affiliation', 'Affiliation',
'Email', 'Email']
'Arrival Date',
'Departure Date']
@conference.questions.each do |question| @conference.questions.each do |question|
header_array << question.title header_array << question.title
end end
@ -19,8 +17,6 @@ prawn_document(force_download: true, filename: @pdf_filename, page_layout: :land
row << registration.nickname row << registration.nickname
row << registration.affiliation row << registration.affiliation
row << registration.email row << registration.email
row << registration.arrival.to_s || ''
row << registration.departure.to_s || ''
@conference.questions.each do |question| @conference.questions.each do |question|
qa = registration.qanswers.find_by(question: question) qa = registration.qanswers.find_by(question: question)

View file

@ -3,7 +3,7 @@
wb = xlsx_package.workbook wb = xlsx_package.workbook
wb.add_worksheet(name: 'registrations') do |sheet| wb.add_worksheet(name: 'registrations') do |sheet|
bold_style = wb.styles.add_style(b: true) 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| @conference.questions.each do |question|
row << question.title row << question.title
@ -18,8 +18,6 @@ wb.add_worksheet(name: 'registrations') do |sheet|
row << registration.nickname row << registration.nickname
row << registration.affiliation row << registration.affiliation
row << registration.email row << registration.email
row << registration.arrival.to_s
row << registration.departure.to_s
@conference.questions.each do |question| @conference.questions.each do |question|
qa = registration.qanswers.find_by(question: question) qa = registration.qanswers.find_by(question: question)
answer = ( qa ? qa.answer.title : '' ) answer = ( qa ? qa.answer.title : '' )
@ -30,4 +28,3 @@ wb.add_worksheet(name: 'registrations') do |sheet|
sheet.add_row row sheet.add_row row
end end
end end

View file

@ -14,7 +14,7 @@
%th Title %th Title
%th Speakers Registered %th Speakers Registered
%th Speakers Biographies %th Speakers Biographies
%th Commercial %th Materials
%th Subtitle %th Subtitle
%th Difficulty Level %th Difficulty Level
- if @program.tracks.any? - if @program.tracks.any?

View file

@ -2,10 +2,10 @@
.col-md-12 .col-md-12
.page-header .page-header
%h1 %h1
Events without commercials Events Without Materials
= "(#{@events_missing_commercial.length})" = "(#{@events_missing_commercial.length})"
%p.text-muted %p.text-muted
All submissions that have no commercial All submissions that have no materials
.col-md-12 .col-md-12
%table.datatable %table.datatable
%thead %thead

View file

@ -4,7 +4,7 @@
= link_to 'All Events', '#all', 'data-toggle' => 'tab' = link_to 'All Events', '#all', 'data-toggle' => 'tab'
%li %li
%a{href: '#missing-commercial', 'data-toggle' => 'tab'} %a{href: '#missing-commercial', 'data-toggle' => 'tab'}
Events without Commercials Events without Materials
%span.label.label-danger{style: 'border-radius: 1em;'} %span.label.label-danger{style: 'border-radius: 1em;'}
= @events_missing_commercial.length = @events_missing_commercial.length
%li %li

View file

@ -14,5 +14,6 @@
= f.input :price = f.input :price
= f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY', 'CHF'], include_blank: false = 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 :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 %p.text-right
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -15,6 +15,7 @@
%th Sold %th Sold
%th Turnover %th Turnover
%th Registration Ticket %th Registration Ticket
%th Visible?
%th Actions %th Actions
%tbody %tbody
- @conference.tickets.each do |ticket| - @conference.tickets.each do |ticket|
@ -30,6 +31,8 @@
= humanized_money_with_symbol ticket.tickets_turnover_total(ticket.id) = humanized_money_with_symbol ticket.tickets_turnover_total(ticket.id)
%td %td
= ticket.registration_ticket? ? 'Yes' : 'No' = ticket.registration_ticket? ? 'Yes' : 'No'
%td
= ticket.visible? ? 'Yes' : 'No'
%td %td
.btn-group .btn-group
= link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id), = link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id),

View file

@ -7,7 +7,13 @@
Ticket Ticket
%small %small
= humanized_money_with_symbol @ticket.price = 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 %p.text-muted
People who bought this ticket People who bought this ticket
.row .row
@ -35,3 +41,26 @@
= buyer.affiliation = buyer.affiliation
%td %td
= @ticket.tickets_paid(buyer) = @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({})
});

View file

@ -7,7 +7,7 @@
%li.active %li.active
= link_to 'Details', '#details-content', 'data-toggle' => 'tab' = link_to 'Details', '#details-content', 'data-toggle' => 'tab'
%li %li
= link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab' = link_to 'Materials', '#commercials-content', 'data-toggle' => 'tab'
.tab-content .tab-content
#details-content.tab-pane.active #details-content.tab-pane.active
@ -56,4 +56,4 @@
%hr %hr
- else - else
First Create Venue, then update commercial First Create Venue, then update materials

View file

@ -12,7 +12,7 @@
-else -else
- if @venue.commercial.nil? - if @venue.commercial.nil?
.row .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 - else
- if @venue.commercial.persisted? - if @venue.commercial.persisted?
.thumbnail .thumbnail

View file

@ -2,7 +2,7 @@
.row .row
.col-md-12 .col-md-12
.page-header .page-header
%h1 Editing Commercial %h1 Edit Materials
.row .row
.col-md-12 .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| = semantic_form_for @commercial, url: conference_program_proposal_commercial_path(conference_id: @conference.short_title, proposal_id: @event.id, id: @commercial.id) do |f|

View file

@ -2,7 +2,7 @@
.row .row
.col-md-12 .col-md-12
.page-header .page-header
%h1 New Commercial %h1 New Materials
.row .row
.col-md-12 .col-md-12
= semantic_form_for @commercial, url: conference_program_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event.id) do |f| = semantic_form_for @commercial, url: conference_program_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event.id) do |f|

View file

@ -22,6 +22,7 @@
= render partial: 'devise/shared/sign_up_form_embedded' = render partial: 'devise/shared/sign_up_form_embedded'
= render partial: 'registration_info', locals: { f: f } = render partial: 'registration_info', locals: { f: f }
= f.input :conference_id, as: :hidden, value: @conference.id
.row .row
.col-md-12 .col-md-12
%p.pull-right %p.pull-right

View file

@ -24,10 +24,4 @@
(Scheduled on: #{event.time.to_date}) (Scheduled on: #{event.time.to_date})
%br %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 = render 'conferences/code_of_conduct', organization: @conference.organization

View file

@ -33,28 +33,6 @@
data: { toggle: 'modal', target: '#modal-code-of-conduct'} data: { toggle: 'modal', target: '#modal-code-of-conduct'}
= render 'conferences/code_of_conduct', = render 'conferences/code_of_conduct',
organization: @conference.organization 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? - if @conference.surveys.for_registration.any?
.row .row
.col-md-12 .col-md-12
@ -94,7 +72,7 @@
= link_to event.title, conference_program_proposal_path(@conference.short_title, event.id) = link_to event.title, conference_program_proposal_path(@conference.short_title, event.id)
= '(' + registered_text(event) + ')' = '(' + registered_text(event) + ')'
- if @conference.tickets.any? - if @conference.tickets.visible.any?
.row .row
.col-md-12 .col-md-12
%h4 %h4

View file

@ -1,6 +1,6 @@
= content_for :splash_nav do = content_for :splash_nav do
%li %li
%a.smoothscroll{ href: '#call' } Call For Content %a.smoothscroll{ href: '#call' } Call For Participation
%section#call %section#call
.container .container
@ -20,3 +20,4 @@
call: call_for_booths call: call_for_booths
- if two_calls_open(call_for_events, call_for_tracks, call_for_booths) - if two_calls_open(call_for_events, call_for_tracks, call_for_booths)
.col-md-2.col-sm-2.hidden-xs &nbsp; .col-md-2.col-sm-2.hidden-xs &nbsp;
.trapezoid

View file

@ -2,7 +2,7 @@
expires_in: 1.hour) do expires_in: 1.hour) do
.col-md-4.col-sm-4.text-center .col-md-4.col-sm-4.text-center
%h2 %h2
Call for Papers Call for Participation
%p.lead %p.lead
We are now accepting proposals for sessions! We are now accepting proposals for sessions!
%p %p

View file

@ -6,7 +6,7 @@
= image_tag(conference.picture_url, class: 'img-responsive') if conference.picture? = image_tag(conference.picture_url, class: 'img-responsive') if conference.picture?
.col-md-6 .col-md-6
%h3 %h3
= conference.title = conference.title.html_safe
%small %small
%b %b
= date_string(conference.start_date, conference.end_date) = date_string(conference.start_date, conference.end_date)

View file

@ -1,14 +1,14 @@
.scroll-top-wrapper -# .scroll-top-wrapper
= link_to "#banner", class: "smoothscroll" do -# = link_to "#banner", class: "smoothscroll" do
%i.fa.fa-2x.fa-arrow-circle-up -# %i.fa.fa-2x.fa-arrow-circle-up
:javascript -# :javascript
$(function(){ -# $(function(){
$(document).on( 'scroll', function(){ -# $(document).on( 'scroll', function(){
if ($(window).scrollTop() > 100) { -# if ($(window).scrollTop() > 100) {
$('.scroll-top-wrapper').addClass('show'); -# $('.scroll-top-wrapper').addClass('show');
} else { -# } else {
$('.scroll-top-wrapper').removeClass('show'); -# $('.scroll-top-wrapper').removeClass('show');
} -# }
}); -# });
}); -# });

View file

@ -1,28 +1,28 @@
- cache [conference, venue, '#splash#header'] do - cache [conference, venue, '#splash#header'] do
#banner #banner{ style: ("background-image: url(#{conference.picture_url})" if conference.picture_url) }
.container .container
.row .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 .row
.col-md-4 -# - if conference.picture?
- if conference.picture? -# .col-md-4
= image_tag(conference.picture_url, -# = image_tag(conference.picture_url,
class: 'img-responsive img-center', -# class: 'img-responsive img-center',
id: 'splash-logo') -# id: 'splash-logo')
.col-md-8 .col-md-8
%h1 %h1
= conference.title = conference.title.html_safe
%h3 %h3
- if conference.start_date && conference.end_date - if conference.start_date && conference.end_date
%span.date.text-nowrap %span.date.text-nowrap
= date_string(conference.start_date, conference.end_date) = date_string(conference.start_date, conference.end_date)
- if conference.venue - if conference.venue
%span.venue.text-nowrap %span.venue.text-nowrap
- if venue.website - if venue.website.present?
= sanitize link_to(venue.name, venue.website) = sanitize link_to(venue.name, venue.website)
- else - else
= venue.city = venue.city
- if venue.country_name != 'US' - if venue.country != 'US'
&bull; &bull;
= venue.country_name = venue.country_name
@ -32,3 +32,4 @@
.row .row
.col-md-8.col-md-offset-2 .col-md-8.col-md-offset-2
= markdown(conference.description) = markdown(conference.description)
.trapezoid

View file

@ -17,11 +17,11 @@
.row.row-centered .row.row-centered
- lodgings.each do |lodging| - 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 .thumbnail
- if lodging.picture? - if lodging.picture?
- if lodging.website_link.present? - 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, = image_tag lodging.picture.large.url,
class: 'img-responsive img-lodging' class: 'img-responsive img-lodging'
- else - else
@ -30,12 +30,16 @@
- else - else
%p.text-center %p.text-center
- if lodging.website_link.present? - 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 %i.fa.fa-home.fa-5x
- else - else
%i.fa.fa-home.fa-5x %i.fa.fa-home.fa-5x
.caption .caption
%h3.text-center %h3.text-center
= lodging.name - if lodging.website_link.present?
= link_to(lodging.name, lodging.website_link)
- else
= lodging.name
- if lodging.description.present? - if lodging.description.present?
= markdown(lodging.description) = markdown(lodging.description)
.trapezoid

View file

@ -9,8 +9,8 @@
.col-md-12 .col-md-12
%p.lead.text-center %p.lead.text-center
%span.notranslate %span.notranslate
= conference.title = conference.title.html_safe
has the most awesome program ever! will have an enaging program!
- unless highlights.blank? - unless highlights.blank?
= render 'highlights', conference_id: conference.short_title, = render 'highlights', conference_id: conference.short_title,
@ -31,6 +31,7 @@
= link_to(conference_schedule_path(conference.short_title), = link_to(conference_schedule_path(conference.short_title),
class: 'btn btn-success btn-lg') do class: 'btn btn-success btn-lg') do
Full Schedule Full Schedule
.trapezoid
- unless booths.blank? - unless booths.blank?
- booths.each do |booth| - booths.each do |booth|

View file

@ -37,3 +37,4 @@
= link_to('Register Now', = link_to('Register Now',
new_conference_conference_registration_path(conference_id), new_conference_conference_registration_path(conference_id),
class: 'btn btn-lg btn-success') class: 'btn btn-lg btn-success')
.trapezoid

View file

@ -27,3 +27,4 @@
- if contact.email? - if contact.email?
= mail_to "#{ contact.email }" do = mail_to "#{ contact.email }" do
%i.fa.fa-envelope-o.fa-4x %i.fa.fa-envelope-o.fa-4x
.trapezoid

View file

@ -27,9 +27,10 @@
.row .row
.col-md-12 .col-md-12
%h3.text-center %h3.text-center
Want to sponsor? = "Interested in sponsoring #{conference.title}?"
= link_to(sponsorship_mailto(conference)) do = link_to(sponsorship_mailto(conference)) do
Contact us! Please, contact us!
.trapezoid
- sponsors.each do |sponsor| - sponsors.each do |sponsor|
- content_for :modals do - content_for :modals do

View file

@ -7,19 +7,21 @@
.container .container
.row .row
.col-md-12.text-center .col-md-12.text-center
%h2 %h2 Sign Up for Snap<em>!</em>Con
Support %br
= conference.title -# %h2
-# Support
-# = conference.title
.row.row-centered .row.row-centered
- tickets.each do |ticket| - tickets.each do |ticket|
.col-md-3.col-sm-3.col-centered.col-top .col-lg-4.col-md-3.col-sm-3.col-centered.col-top
= link_to(conference_tickets_path(conference.short_title), = link_to(conference_tickets_path(conference.short_title), class: 'thumbnail') do
class: 'thumbnail') do
.caption .caption
%h3.text-center.word_break %h3.text-center.word_break
= ticket.title = ticket.title
.word_break .word_break
= markdown(ticket.description) = markdown(ticket.description)
%button.btn-block.btn.btn-lg.btn-success %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) = humanized_money_with_symbol(ticket.price)
.trapezoid

View file

@ -5,6 +5,12 @@
%section#venue %section#venue
- if venue.location? - if venue.location?
= render '/conferences/venue_map', venue: venue = 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 - else
- cache [venue, commercial, '#splash#venue'] do - cache [venue, commercial, '#splash#venue'] do
.container .container
@ -41,3 +47,4 @@
- if venue.website - if venue.website
%br %br
= sanitize link_to(h(venue.website), h(venue.website)) = sanitize link_to(h(venue.website), h(venue.website))
.trapezoid

View file

@ -1,10 +1,10 @@
- content_for :head do - content_for :head do
%meta{ property: "og:title", content: @conference.title } %meta{ property: "og:title", content: @conference.title }
%meta{ property: "og:site_name", content: (ENV['OSEM_NAME'] || 'OSEM') } %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: "og:url", content: conference_url(@conference.short_title) }
%meta{ property: "twitter:title", content: (@conference.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? - if @conference.picture?
%meta{ property: "og:image", content: @image_url } %meta{ property: "og:image", content: @image_url }
%meta{ property: "og:image:secure_url", content: @image_url } %meta{ property: "og:image:secure_url", content: @image_url }
@ -64,21 +64,22 @@
= render 'social_media', contact: @conference.contact = render 'social_media', contact: @conference.contact
= render 'footer' = render 'footer'
- content_for :script_head do
:javascript -# - content_for :script_head do
var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic(); -# :javascript
var triangle_colors = triangle_tcs.map(function(t) { -# var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic();
return t.toHexString(); -# var triangle_colors = triangle_tcs.map(function(t) {
}); -# return t.toHexString();
$(function () { -# });
$(document).ready(function() { -# $(function () {
var triangle_width = document.body.clientWidth; -# $(document).ready(function() {
var triangle_height = ($( "#banner" ).height() + 200 ); -# var triangle_width = document.body.clientWidth;
var pattern = Trianglify({ width: triangle_width, -# var triangle_height = ($( "#banner" ).height() + 200 );
height: triangle_height, -# var pattern = Trianglify({ width: triangle_width,
cell_size: 100, -# height: triangle_height,
x_colors: triangle_colors -# cell_size: 100,
}); -# x_colors: triangle_colors
$('#banner').css('background-image', 'url("' + pattern.png() + '")'); -# });
}); -# $('#banner').css('background-image', 'url(' + 0 + ')');
}); -# });
-# });

View file

@ -1,7 +1,16 @@
.text-center .text-center
.btn-group.btn-group-lg#openid-btn-grp .btn-group.btn-group-lg#openid-btn-grp
- omniauth_configured.each do |provider| - omniauth_configured.each do |provider|
= link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg", - if provider != :discourse
id: "omniauth-#{provider}", = link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg",
title: "Your #{provider} login" do id: "omniauth-#{provider}",
%i{class: "fa fa-#{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> !

View file

@ -1,25 +1,26 @@
- if ENV['OSEM_ICHAIN_ENABLED'] != 'true' - if ENV['OSEM_ICHAIN_ENABLED'] != 'true'
= form_tag(new_user_session_path, class: 'form-horizontal') do .container.panel
%legend = form_tag(new_user_session_path, class: '') do
%span %legend
Sign In %span
.form-group Sign In
%label{for: "user[login]", class: 'col-sm-2 control-label'} .form-group
Username %label{for: "user[login]", class: 'col-sm-2 control-label'}
.col-sm-10 Username
= text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required' .col-sm-10
.form-group = text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required'
%label{for: "user[password]", class: 'col-sm-2 control-label'} .form-group
Password %label{for: "user[password]", class: 'col-sm-2 control-label'}
.col-sm-10 Password
= password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required' .col-sm-10
.form-group = password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required'
.col-sm-12 .form-group
%button.btn.btn-success.pull-right .col-sm-12
Sign in %button.btn.btn-success.pull-right
= render partial: 'devise/shared/openid' Sign in
%p.text-right = render partial: 'devise/shared/openid'
%a.small.btn.btn-default{"data-toggle" => "collapse", "data-target" => "#devise-help-sign-in"} %p.text-right
Need Help? %a.small.btn.btn-default{"data-toggle" => "collapse", "data-target" => "#devise-help-sign-in"}
#devise-help-sign-in.collapse Need Help?
= render partial: 'devise/shared/links' #devise-help-sign-in.collapse
= render partial: 'devise/shared/links'

View file

@ -43,7 +43,7 @@
= link_to 'Contact', edit_admin_conference_contact_path(@conference.short_title) = link_to 'Contact', edit_admin_conference_contact_path(@conference.short_title)
- if can? :index, @conference.commercials.build - if can? :index, @conference.commercials.build
%li{class: "#{active_nav_li(admin_conference_commercials_path(@conference.short_title))}"} %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 - if can? :update, @conference
%li{class: active_nav_li(edit_admin_conference_splashpage_path(@conference.short_title))} %li{class: active_nav_li(edit_admin_conference_splashpage_path(@conference.short_title))}
= link_to 'Splashpage', admin_conference_splashpage_path(@conference.short_title) = link_to 'Splashpage', admin_conference_splashpage_path(@conference.short_title)

View file

@ -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 .container
.navbar-header .navbar-header
- if controller.class.name.split("::").first=="Admin" - if controller.class.name.split("::").first=="Admin"
%button{ "data-target"=>"#side-nav", "data-toggle"=>"collapse", class: 'navbar-toggle side-nav-btn', type: 'button' } %button{ "data-target"=>"#side-nav", "data-toggle"=>"collapse", class: 'navbar-toggle side-nav-btn', type: 'button' }
%span.sr-only Toggle navigation %span.sr-only Toggle navigation
@ -14,7 +13,7 @@
%span.icon-bar %span.icon-bar
%span.icon-bar %span.icon-bar
%span.icon-bar %span.icon-bar
= nav_root_link_for conference = nav_root_link_for(conference)
.collapse.navbar-collapse#main-nav .collapse.navbar-collapse#main-nav
- if content_for :splash_nav - if content_for :splash_nav
@ -42,34 +41,41 @@
= link_to(new_registration_path('user')) do = link_to(new_registration_path('user')) do
%span.fa.fa-heart %span.fa.fa-heart
Sign Up Sign Up
%li.dropdown.visible-desktop %li{class: ""}
%a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'} = link_to(sign_in_path) do
%span.fa.fa-user %span.fa.fa-user
Sign In Sign In
%span.caret -# %li.dropdown.visible-desktop
.dropdown-menu -# %a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'}
- if ENV['OSEM_ICHAIN_ENABLED'] == 'true' -# %span.fa.fa-user
= form_tag User.ichain_login_url do -# Sign In
= text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username' -# %span.caret
= password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password' -# .dropdown-menu
%button.btn.btn-success.btn-block Sign in -# - if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
- else -# = form_tag User.ichain_login_url do
= form_tag new_user_session_path do -# = text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username'
= text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail' -# = password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password'
= password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password' -# %button.btn.btn-success.btn-block Sign in
%p.text-right -# - else
%small -# %div{style: "padding: 6px"}
%label{for: 'user_remember_me'} Remember me -# = form_tag new_user_session_path, class: 'form-group' do
= check_box_tag 'user[remember_me]' -# = text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail'
%button.btn.btn-success.btn-block Sign in -# = password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password'
- unless omniauth_configured.empty? -# %p.text-right
.divider -# %small
%h6.text-center -# %label{for: 'user_remember_me'} Remember me
or -# = check_box_tag 'user[remember_me]'
= render 'devise/shared/openid_links' -# %br
%p.text-right -# %button.btn.btn-success.btn-block Sign in
%br -# - unless omniauth_configured.empty?
%a.small.btn.btn-xs.btn-default{"data-toggle" => "collapse", "data-target" => "#navbar-devise-help"} -# .divider
Need Help? -# %h6.text-center
#navbar-devise-help.collapse -# or
= render 'devise/shared/links' -# = 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

View file

@ -1,10 +1,10 @@
%html{xmlns: 'http://www.w3.org/1999/html'} %html{lang: 'en'}
%head %head
%meta{charset: 'utf-8'} %meta{charset: 'utf-8'}
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'} %meta{name: 'viewport', content: 'width=device-width, initial-scale=1'}
%title= content_for?(:title) ? yield(:title) : (ENV['OSEM_NAME'] || 'OSEM') %title= content_for?(:title) ? strip_tags( yield(:title) ) : (ENV['OSEM_NAME'] || 'OSEM')
%meta{content: '', name: 'description'} %meta{content: 'Snap!Con -- A conference all about Snap!, a programing language from UC Berkeley.', name: 'description'}
%meta{content: '', name: 'author'} %meta{content: 'Michael Ball, Brian Harvey, Jens Moenig, Bernat Romagosa, Dan Garcia, Lauren Mock', name: 'author'}
= stylesheet_link_tag "application", media: 'all' = stylesheet_link_tag "application", media: 'all'
= javascript_include_tag "application" = javascript_include_tag "application"
@ -26,7 +26,7 @@
-# Admin area -# Admin area
- if controller.class.name.split("::").first=="Admin" - if controller.class.name.split("::").first=="Admin"
= render 'layouts/admin' = render 'layouts/admin'
-else - else
#messages #messages
.container .container
= render 'layouts/messages' = render 'layouts/messages'
@ -45,7 +45,7 @@
#{link_to "MIT license", "http://opensource.org/licenses/MIT"}. #{link_to "MIT license", "http://opensource.org/licenses/MIT"}.
You can run, copy, distribute, study, change and improve it. You can run, copy, distribute, study, change and improve it.
The source code and the developers are on 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? - if ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"].present?
Performance data is available on Performance data is available on
#{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}. #{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}.

View file

@ -1,6 +1,6 @@
.div .div
.col-md-12.table-responsive .col-md-12.table-responsive
%table.table.table-hover %table.table.table-hover.table-striped
%thead %thead
%tr %tr
%th Ticket %th Ticket
@ -20,8 +20,13 @@
= humanized_money_with_symbol ticket.quantity * ticket.price = humanized_money_with_symbol ticket.quantity * ticket.price
= form_tag conference_payments_path do = form_tag conference_payments_path do
%script.stripe-button{ src: "https://checkout.stripe.com/checkout.js", %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}", 'data': {amount: @total_amount_to_pay.cents,
email: current_user.email, currency: @total_amount_to_pay.currency, name: ENV['OSEM_NAME'] || 'OSEM', label: "Pay #{humanized_money_with_symbol @total_amount_to_pay}",
description: "book your tickets", key: Rails.application.secrets.stripe_publishable_key, locale: "auto"}} email: current_user.email,
= link_to 'Edit Purchase', conference_tickets_path(@conference.short_title), class: 'btn btn-default' 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')

View file

@ -16,6 +16,7 @@
%th ID %th ID
%th Type %th Type
%th User %th User
%th Registration?
%th Actions %th Actions
%tbody %tbody
- @physical_tickets.each do |physical_ticket| - @physical_tickets.each do |physical_ticket|
@ -23,6 +24,7 @@
%td= physical_ticket.id %td= physical_ticket.id
%td= physical_ticket.ticket.title %td= physical_ticket.ticket.title
%td= physical_ticket.user.name %td= physical_ticket.user.name
%td= physical_ticket.ticket.registration_ticket? ? 'Yes' : 'No'
%td %td
.btn-group .btn-group
= link_to 'Show', = link_to 'Show',

View file

@ -3,15 +3,15 @@
%li.active %li.active
= link_to 'Proposal', '#proposal-content', 'data-toggle' => 'tab' = link_to 'Proposal', '#proposal-content', 'data-toggle' => 'tab'
%li %li
= link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab' = link_to 'Materials', '#commercials-content', 'data-toggle' => 'tab'
.tab-content .tab-content
#proposal-content.tab-pane.active #proposal-content.tab-pane.active
= render 'proposals/proposal_form' = render 'proposals/proposal_form'
#commercials-content.tab-pane #commercials-content.tab-pane
%p.text-muted %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) = 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 - if can? :create, @event.commercials.new
.row .row
.col-md-6 .col-md-6

View file

@ -20,7 +20,7 @@
= link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event) = link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event)
%li{'class'=>class_for_todo(progress_status['commercials'])} %li{'class'=>class_for_todo(progress_status['commercials'])}
%span{'class'=>icon_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? - unless progress_status['track'].nil?
%li{'class'=>class_for_todo(progress_status['track'])} %li{'class'=>class_for_todo(progress_status['track'])}
%span{'class'=>icon_for_todo(progress_status['track'])} %span{'class'=>icon_for_todo(progress_status['track'])}

View file

@ -7,7 +7,7 @@
- if @program.cfp.description.present? - if @program.cfp.description.present?
.row .row
.col-md-12 .col-md-12
= markdown(@program.cfp.description) = markdown(@program.cfp.description, escape_html=false)
.row .row
.col-md-12 .col-md-12
= render partial: 'encouragement_text' = render partial: 'encouragement_text'
@ -43,10 +43,10 @@
- @program.event_types.each do |event_type| - @program.event_types.each do |event_type|
%span{ class: 'help-block event_event_type_id collapse', id: "#{event_type.id}-help" } %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' } }, = 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 %p
You have used You have used

View file

@ -3,9 +3,9 @@
.media .media
.media-body .media-body
%h4.media-heading= ticket.title %h4.media-heading= ticket.title
%h5.media-heading= markdown(ticket.description) .media-heading= markdown(ticket.description)
- if @conference.tickets.for_registration.any? %td.col-sm-1.col-md-2
%td.col-sm-1.col-md-2.text-center %span.text-center
= ticket.registration_ticket? ? 'Yes' : 'No' = ticket.registration_ticket? ? 'Yes' : 'No'
%td.col-sm-1.col-md-1 %td.col-sm-1.col-md-1
:ruby :ruby

View file

@ -13,18 +13,16 @@
%thead %thead
%tr %tr
%th Ticket %th Ticket
- if @conference.tickets.for_registration.any? %th Registration?
%th Registration Ticket
%th Quantity %th Quantity
%th Price %th Price
%th Total %th Total
%tbody %tbody
- @conference.tickets.each do |ticket| - @conference.tickets.visible.each do |ticket|
= render 'ticket', f: f, ticket: ticket = render 'ticket', f: f, ticket: ticket
%tr %tr
%td %td
- if @conference.tickets.for_registration.any? %td
%td
%td %td
%td.col-sm-1.col-md-1.text-center %td.col-sm-1.col-md-1.text-center
%h4 %h4

View file

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
bundle install
# Setup the app if it isn't already setup # Setup the app if it isn't already setup
bundle exec rake db:bootstrap bundle exec rake db:bootstrap
# Start the app # Start the app

View file

@ -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

View file

@ -6,12 +6,25 @@ Devise.setup do |config|
# Define the available openID providers that can be used to log in # 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) # 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 :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 :google_oauth2,
(ENV['OSEM_GOOGLE_KEY'] || Rails.application.secrets.google_key),
(ENV['OSEM_GOOGLE_SECRET'] || Rails.application.secrets.google_secret),
name: 'google', name: 'google',
scope: 'email' 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 # ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer, # Configure the e-mail address which will be shown in Devise::Mailer,

View file

@ -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

View file

@ -1 +1 @@
Stripe.api_key = Rails.application.secrets.stripe_secret_key Stripe.api_key = ENV['STRIPE_SECRET_KEY'] || Rails.application.secrets.stripe_secret_key

View file

@ -43,5 +43,16 @@ on_worker_boot do
ActiveRecord::Base.establish_connection if defined?(ActiveRecord) ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
end 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. # Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart plugin :tmp_restart

View file

@ -115,7 +115,11 @@ Osem::Application.routes.draw do
end end
resources :resources resources :resources
resources :tickets resources :tickets do
member do
post :give
end
end
resources :sponsors, except: [:show] resources :sponsors, except: [:show]
resources :lodgings, except: [:show] resources :lodgings, except: [:show]
resources :emails, only: [:show, :update, :index] resources :emails, only: [:show, :update, :index]

View file

@ -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

View file

@ -0,0 +1,6 @@
class RemoveArrivalDepartureFromRegistrations < ActiveRecord::Migration[5.0]
def change
remove_column :registrations, :arrival, :datetime
remove_column :registrations, :departure, :datetime
end
end

View file

@ -10,7 +10,10 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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| create_table "answers", force: :cascade do |t|
t.string "title" t.string "title"
@ -364,8 +367,6 @@ ActiveRecord::Schema.define(version: 20181113195810) do
create_table "registrations", force: :cascade do |t| create_table "registrations", force: :cascade do |t|
t.integer "conference_id" t.integer "conference_id"
t.datetime "arrival"
t.datetime "departure"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.text "other_special_needs" t.text "other_special_needs"
@ -530,6 +531,7 @@ ActiveRecord::Schema.define(version: 20181113195810) do
t.boolean "registration_ticket", default: false t.boolean "registration_ticket", default: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "visible", default: true
end end
create_table "tracks", force: :cascade do |t| create_table "tracks", force: :cascade do |t|

View file

@ -1,5 +1,6 @@
# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # 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: # To ban all spiders from the entire site uncomment the next two lines:
# User-Agent: * User-Agent: *
# Disallow: / Allow: /
Disallow: /admin

View file

@ -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

View file

@ -290,14 +290,15 @@ describe ConferenceRegistrationsController, type: :controller do
before do before do
@registration = create(:registration, @registration = create(:registration,
conference: conference, conference: conference,
user: user, user: user)
arrival: Date.new(2014, 04, 25))
end end
context 'updates successfully' do context 'updates successfully' do
before do before do
patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)), patch :update, params: {
conference_id: conference.short_title } registration: attributes_for(:registration, volunteer: true),
conference_id: conference.short_title
}
end end
it 'redirects to registration show path' do it 'redirects to registration show path' do
@ -309,16 +310,17 @@ describe ConferenceRegistrationsController, type: :controller do
end end
it 'updates the registration' do it 'updates the registration' do
@registration.reload expect{ @registration.reload }.to change(@registration, :updated_at)
expect(@registration.arrival).to eq Date.new(2014, 04, 29)
end end
end end
context 'update fails' do context 'update fails' do
before do before do
allow_any_instance_of(Registration).to receive(:update_attributes).and_return(false) 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)), patch :update, params: {
conference_id: conference.short_title } registration: attributes_for(:registration, volunteer: true),
conference_id: conference.short_title
}
end end
it 'renders edit template' do it 'renders edit template' do
@ -331,7 +333,7 @@ describe ConferenceRegistrationsController, type: :controller do
it 'does not update the registration' do it 'does not update the registration' do
@registration.reload @registration.reload
expect(@registration.arrival).to eq Date.new(2014, 04, 25) expect { @registration.reload }.not_to change(@registration, :updated_at)
end end
end end
end end

View file

@ -5,6 +5,7 @@ FactoryBot.define do
title { "#{Faker::Hipster.word} Ticket" } title { "#{Faker::Hipster.word} Ticket" }
price_cents { 1000 } price_cents { 1000 }
price_currency { 'USD' } price_currency { 'USD' }
visible { true }
factory :registration_ticket do factory :registration_ticket do
registration_ticket { true } registration_ticket { true }
end end

View file

@ -17,9 +17,9 @@ feature Commercial do
# Create valid commercial # Create valid commercial
fill_in 'commercial_url', with: 'https://www.youtube.com/watch?v=M9bq_alk-sw' 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') 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 page.find('#flash .button.close').click
expect(conference.commercials.count).to eq(1) 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' fill_in "commercial_url_#{commercial.id}", with: 'https://www.youtube.com/watch?v=VNkDJk5_9eU'
click_button 'Update' click_button 'Update'
page.find('#flash') 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 page.find('#flash .button.close').click
expect(conference.commercials.count).to eq(1) expect(conference.commercials.count).to eq(1)
commercial.reload commercial.reload
@ -39,7 +39,7 @@ feature Commercial do
click_link 'Delete' click_link 'Delete'
end end
page.find('#flash') 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) expect(conference.commercials.count).to eq(0)
end end
end end
@ -56,23 +56,23 @@ feature Commercial do
scenario 'adds a valid commercial of an event', feature: true, js: true 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) 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' 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)") page.execute_script("$('#commercial_submit_action').prop('disabled', false)")
click_button 'Create Commercial' click_button 'Save Materials'
page.find('#flash') page.find('#flash')
expect(flash).to eq('Commercial was successfully created.') expect(flash).to eq('Materials were successfully created.')
end end
scenario 'does not add an invalid commercial of an event', feature: true, js: true do 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) 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' fill_in 'commercial_url', with: 'invalid_commercial_url'
expect(page).to have_content('No embeddable content') 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 end
scenario 'updates a commercial of an event', feature: true, js: true do scenario 'updates a commercial of an event', feature: true, js: true do
@ -80,11 +80,11 @@ feature Commercial do
commercialable_id: event.id, commercialable_id: event.id,
commercialable_type: 'Event') commercialable_type: 'Event')
visit edit_conference_program_proposal_path(conference.short_title, event.id) 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' fill_in "commercial_url_#{commercial.id}", with: 'https://www.youtube.com/watch?v=M9bq_alk-sw'
click_button 'Update' click_button 'Update'
page.find('#flash') 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) TransactionalCapybara::AjaxHelpers.wait_for_ajax(page)
expect(event.commercials.count).to eq(1) expect(event.commercials.count).to eq(1)
commercial.reload commercial.reload
@ -97,12 +97,12 @@ feature Commercial do
commercialable_type: 'Event', commercialable_type: 'Event',
url: 'https://www.youtube.com/watch?v=BTTygyxuGj8') url: 'https://www.youtube.com/watch?v=BTTygyxuGj8')
visit edit_conference_program_proposal_path(conference.short_title, event.id) 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' fill_in "commercial_url_#{commercial.id}", with: 'invalid_commercial_url'
click_button 'Update' click_button 'Update'
find('#flash') find('#flash')
expect(current_path).to eq edit_conference_program_proposal_path(conference.short_title, event.id) 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 commercial.reload
expect(commercial.url).to eq('https://www.youtube.com/watch?v=BTTygyxuGj8') expect(commercial.url).to eq('https://www.youtube.com/watch?v=BTTygyxuGj8')
end end
@ -112,12 +112,12 @@ feature Commercial do
commercialable_id: event.id, commercialable_id: event.id,
commercialable_type: 'Event') commercialable_type: 'Event')
visit edit_conference_program_proposal_path(conference.short_title, event.id) visit edit_conference_program_proposal_path(conference.short_title, event.id)
click_link 'Commercials' click_link 'Materials'
page.accept_alert do page.accept_alert do
click_link 'Delete' click_link 'Delete'
end end
page.find('#flash') 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) TransactionalCapybara::AjaxHelpers.wait_for_ajax(page)
expect(event.commercials.count).to eq(0) expect(event.commercials.count).to eq(0)
end end

View file

@ -98,7 +98,8 @@ feature Conference do
sign_in user sign_in user
visit admin_conference_path(conference.short_title) 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 end
it_behaves_like 'add and update conference' it_behaves_like 'add and update conference'

View file

@ -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_not have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit")
expect(page).to have_text('Basics') expect(page).to have_text('Basics')
expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit") 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('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('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings")
expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period")

View file

@ -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_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('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('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('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('Venue', href: "/admin/conferences/#{conference.short_title}/venue")
expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms")

Some files were not shown because too many files have changed in this diff Show more