Merge branch 'master' into michael/rm-start-restriction
This commit is contained in:
commit
8d5c300639
109 changed files with 907 additions and 512 deletions
|
|
@ -507,6 +507,7 @@ RSpec/AnyInstance:
|
|||
Exclude:
|
||||
- 'spec/controllers/admin/rooms_controller_spec.rb'
|
||||
- 'spec/controllers/admin/sponsorship_levels_controller_spec.rb'
|
||||
- 'spec/controllers/admin/tickets_controller_spec.rb'
|
||||
- 'spec/controllers/admin/tracks_controller_spec.rb'
|
||||
- 'spec/controllers/admin/users_controller_spec.rb'
|
||||
- 'spec/controllers/conference_registration_controller_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2.5.0
|
||||
2.5.5
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ Not release yet...
|
|||
|
||||
## Update from 1.0
|
||||
|
||||
### Dropped travel information
|
||||
We have dropped input and storage of travel schedules for event registrants. If
|
||||
you would like to continue to collect travel schedules, please create a custom
|
||||
survey for this purpose.
|
||||
_Please be aware that existing travel data will be destroyed during migration._
|
||||
|
||||
### Multiple Schedules
|
||||
A conference can have multiple schedules now so it's easier for organizers to
|
||||
test schedules and collaborate on different versions.
|
||||
|
|
|
|||
8
Gemfile
8
Gemfile
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
ruby ENV['OSEM_RUBY_VERSION'] || '2.5.0'
|
||||
ruby ENV['OSEM_RUBY_VERSION'] || '2.5.5'
|
||||
|
||||
# rails-assets requires >= 1.8.4
|
||||
if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4')
|
||||
|
|
@ -20,7 +20,6 @@ gem 'puma', '~> 3.0'
|
|||
gem 'responders', '~> 2.0'
|
||||
|
||||
# as supported databases
|
||||
gem 'mysql2'
|
||||
gem 'pg'
|
||||
|
||||
# for tracking data changes
|
||||
|
|
@ -38,8 +37,8 @@ gem 'rails-i18n'
|
|||
gem 'devise'
|
||||
gem 'devise_ichain_authenticatable'
|
||||
|
||||
# for openID authentication
|
||||
gem 'omniauth'
|
||||
gem 'omniauth-discourse'
|
||||
gem 'omniauth-facebook'
|
||||
gem 'omniauth-github'
|
||||
gem 'omniauth-google-oauth2'
|
||||
|
|
@ -143,8 +142,7 @@ gem 'rqrcode'
|
|||
gem 'axlsx', git: 'https://github.com/randym/axlsx.git'
|
||||
gem 'axlsx_rails'
|
||||
|
||||
# as error catcher
|
||||
gem 'airbrake'
|
||||
gem 'sentry-raven'
|
||||
|
||||
# to make links faster
|
||||
gem 'turbolinks'
|
||||
|
|
|
|||
31
Gemfile.lock
31
Gemfile.lock
|
|
@ -68,10 +68,6 @@ GEM
|
|||
addressable (2.6.0)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
afm (0.2.2)
|
||||
airbrake (9.2.2)
|
||||
airbrake-ruby (~> 4.4)
|
||||
airbrake-ruby (4.4.0)
|
||||
rbtree3 (~> 0.5)
|
||||
ajax-datatables-rails (0.4.3)
|
||||
railties (>= 4.0)
|
||||
archive-zip (0.12.0)
|
||||
|
|
@ -130,7 +126,6 @@ GEM
|
|||
url
|
||||
coderay (1.1.1)
|
||||
concurrent-ruby (1.1.5)
|
||||
connection_pool (2.2.2)
|
||||
countable-rails (0.0.1)
|
||||
railties (>= 3.1)
|
||||
countries (3.0.0)
|
||||
|
|
@ -301,13 +296,10 @@ GEM
|
|||
monetize (~> 1.9.0)
|
||||
money (~> 6.13.2)
|
||||
railties (>= 3.0)
|
||||
multi_json (1.13.1)
|
||||
multi_json (1.14.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
mysql2 (0.5.2)
|
||||
nenv (0.3.0)
|
||||
net-http-persistent (3.0.1)
|
||||
connection_pool (~> 2.2)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.2)
|
||||
nokogiri (1.10.8)
|
||||
|
|
@ -324,7 +316,9 @@ GEM
|
|||
omniauth (1.9.0)
|
||||
hashie (>= 3.4.6, < 3.7.0)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-facebook (5.0.0)
|
||||
omniauth-discourse (1.0.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-facebook (6.0.0)
|
||||
omniauth-oauth2 (~> 1.2)
|
||||
omniauth-github (1.3.0)
|
||||
omniauth (~> 1.5)
|
||||
|
|
@ -441,7 +435,6 @@ GEM
|
|||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.0)
|
||||
ffi (~> 1.0)
|
||||
rbtree3 (0.5.0)
|
||||
rdoc (6.0.4)
|
||||
rdoc-generator-fivefish (0.4.0)
|
||||
inversion (~> 1.1)
|
||||
|
|
@ -525,6 +518,8 @@ GEM
|
|||
selenium-webdriver (3.142.6)
|
||||
childprocess (>= 0.5, < 4.0)
|
||||
rubyzip (>= 1.2.2)
|
||||
sentry-raven (2.13.0)
|
||||
faraday (>= 0.7.6, < 1.0)
|
||||
sexp_processor (4.11.0)
|
||||
shellany (0.0.1)
|
||||
shoulda-matchers (4.1.2)
|
||||
|
|
@ -553,13 +548,11 @@ GEM
|
|||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.4.2)
|
||||
stripe (4.21.3)
|
||||
faraday (~> 0.13)
|
||||
net-http-persistent (~> 3.0)
|
||||
stripe-ruby-mock (2.5.8)
|
||||
stripe (5.14.0)
|
||||
stripe-ruby-mock (3.0.1)
|
||||
dante (>= 0.2.0)
|
||||
multi_json (~> 1.0)
|
||||
stripe (>= 2.0.3)
|
||||
stripe (> 5, < 6)
|
||||
sysexits (1.2.0)
|
||||
temple (0.8.0)
|
||||
thor (0.20.3)
|
||||
|
|
@ -616,7 +609,6 @@ DEPENDENCIES
|
|||
active_model_serializers
|
||||
acts_as_commentable_with_threading
|
||||
acts_as_list
|
||||
airbrake
|
||||
ajax-datatables-rails
|
||||
autoprefixer-rails
|
||||
awesome_nested_set
|
||||
|
|
@ -665,9 +657,9 @@ DEPENDENCIES
|
|||
mina
|
||||
mini_magick
|
||||
money-rails
|
||||
mysql2
|
||||
nokogiri (>= 1.8.1)
|
||||
omniauth
|
||||
omniauth-discourse
|
||||
omniauth-facebook
|
||||
omniauth-github
|
||||
omniauth-google-oauth2
|
||||
|
|
@ -707,6 +699,7 @@ DEPENDENCIES
|
|||
ruby-oembed
|
||||
sass-rails (>= 4.0.2)
|
||||
selectize-rails
|
||||
sentry-raven
|
||||
shoulda-matchers
|
||||
skylight
|
||||
spring-commands-rspec
|
||||
|
|
@ -726,7 +719,7 @@ DEPENDENCIES
|
|||
whenever
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.5.0p0
|
||||
ruby 2.5.5p157
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.3
|
||||
|
|
|
|||
BIN
app/assets/images/snapcon_logo.png
Normal file
BIN
app/assets/images/snapcon_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
|
|
@ -11,39 +11,6 @@ $(function () {
|
|||
format: 'YYYY-MM-DD HH:mm'
|
||||
});
|
||||
|
||||
$("#registration-arrival-datepicker").datetimepicker({
|
||||
useCurrent: false,
|
||||
stepping: 15,
|
||||
sideBySide: true,
|
||||
format: "YYYY-MM-DD HH:mm",
|
||||
// arrival_date <= end_date
|
||||
maxDate : $("#registration-arrival-datepicker").attr('end_date')
|
||||
});
|
||||
|
||||
$("#registration-departure-datepicker").datetimepicker({
|
||||
useCurrent: false,
|
||||
stepping: 15,
|
||||
sideBySide: true,
|
||||
format: "YYYY-MM-DD HH:mm",
|
||||
// departure_date > start_date
|
||||
minDate : $("#registration-arrival-datepicker").attr('start_date')
|
||||
});
|
||||
|
||||
$("#registration-arrival-datepicker").on("dp.change",function (e) {
|
||||
// departure_date > start_date,arrival_date
|
||||
if ((new Date(e.date).getTime()) > (new Date($("#registration-arrival-datepicker").attr('start_date')).getTime())){
|
||||
$('#registration-departure-datepicker').data("DateTimePicker").minDate(e.date);
|
||||
}
|
||||
else{
|
||||
$('#registration-departure-datepicker').data("DateTimePicker").minDate($("#registration-arrival-datepicker").attr('start_date'));
|
||||
}
|
||||
});
|
||||
|
||||
// departure_date >= arrival_date
|
||||
$("#registration-departure-datepicker").on("dp.change",function (e) {
|
||||
$('#registration-arrival-datepicker').data("DateTimePicker").maxDate(e.date);
|
||||
});
|
||||
|
||||
$("#conference-start-datepicker").datetimepicker({
|
||||
useCurrent: false,
|
||||
format: "YYYY-MM-DD"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
*= require strap-on
|
||||
*= require formtastic-bootstrap
|
||||
*= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
|
||||
*= require selectize
|
||||
*= require selectize.bootstrap3
|
||||
*= require bootstrap-select
|
||||
*= require bootstrap-markdown
|
||||
*= require bootstrap-datetimepicker
|
||||
*= require leaflet
|
||||
|
||||
*= require osem
|
||||
*= require osem-rating
|
||||
*= require osem-schedule
|
||||
|
|
@ -10,15 +17,9 @@
|
|||
*= require osem-splash
|
||||
*= require font-awesome
|
||||
*= require osem-fonts
|
||||
*= require bootstrap-markdown
|
||||
*= require bootstrap-datetimepicker
|
||||
*= require leaflet
|
||||
*= require bootstrap3-switch
|
||||
*= require osem-payments
|
||||
*= require osem-navbar
|
||||
*= require selectize
|
||||
*= require selectize.bootstrap3
|
||||
*= require mastodon
|
||||
*= require bootstrap-select
|
||||
*= require conferences
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
@import "breakpoints.scss";
|
||||
@import "osem-variables.scss";
|
||||
|
||||
.nav-osem {
|
||||
border: none;
|
||||
@include breakpoint(xs) {
|
||||
|
|
@ -29,7 +31,23 @@
|
|||
}
|
||||
}
|
||||
.dropdown-menu {
|
||||
padding: 17px;
|
||||
min-width: 225px;
|
||||
}
|
||||
|
||||
&.navbar-default {
|
||||
.navbar-nav > .open > a {
|
||||
&:hover, &:focus {
|
||||
color: $navbar-default-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-brand img {
|
||||
margin-top: -5px;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.trapezoid {
|
||||
border-top-color: $navbar-default-bg;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,9 +64,8 @@
|
|||
|
||||
#schedule td.event {
|
||||
background-image: linear-gradient(to top, rgb(247,250,242) 24%, rgb(194,232,190) 97%, rgb(194,232,190) 100%);
|
||||
|
||||
cursor: pointer;
|
||||
padding: 3px 2px;
|
||||
cursor: pointer;
|
||||
padding: 3px 2px;
|
||||
}
|
||||
|
||||
#schedule td.event:hover
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import "breakpoints.scss";
|
||||
@import "osem-variables.scss";
|
||||
|
||||
#splash {
|
||||
// Counter the general padding for #content
|
||||
|
|
@ -6,18 +7,30 @@
|
|||
section {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 60px;
|
||||
|
||||
.trapezoid {
|
||||
top: 60px + $trapezoid-height;
|
||||
}
|
||||
}
|
||||
|
||||
section:nth-child(even) {
|
||||
background: none repeat scroll 0 0 #e0e0e0;
|
||||
color: #555;
|
||||
background: none repeat scroll 0 0 #eee;
|
||||
color: #333;
|
||||
|
||||
.trapezoid {
|
||||
border-top-color: #eee;
|
||||
}
|
||||
}
|
||||
section:nth-child(odd) {
|
||||
background: none repeat scroll 0 0 #ffffff;
|
||||
color: #7b7b7b;
|
||||
color: #333;
|
||||
.thumbnail {
|
||||
background: none repeat scroll 0 0 #e0e0e0;
|
||||
}
|
||||
|
||||
.trapezoid {
|
||||
border-top-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
|
|
@ -32,11 +45,15 @@
|
|||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
.container {
|
||||
#header {
|
||||
#header-no-image {
|
||||
background-color: rgba(224, 224, 224,.80);
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
#header-image {
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +84,10 @@
|
|||
#venue-pic {
|
||||
margin-top: 20px;
|
||||
}
|
||||
// The venue section has less padding.
|
||||
.trapezoid {
|
||||
top: $trapezoid-height;
|
||||
}
|
||||
}
|
||||
|
||||
#lodging {
|
||||
|
|
@ -93,6 +114,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
#tickets {
|
||||
a {
|
||||
&:hover, &:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#sponsors {
|
||||
.img-sponsor {
|
||||
max-height: 100px;
|
||||
|
|
@ -116,14 +145,13 @@
|
|||
}
|
||||
|
||||
#social-media{
|
||||
background: none repeat scroll 0 0 #2f2f2f;
|
||||
padding-top: 60px;
|
||||
padding-bottom: 60px;
|
||||
background: none repeat scroll 0 0 #0C3559;
|
||||
padding: 50px 20px;
|
||||
i{
|
||||
color: #4a4a4a;
|
||||
color: #FFF;
|
||||
}
|
||||
i:hover{
|
||||
color: #16a085;
|
||||
color: #F2E205;
|
||||
}
|
||||
a{
|
||||
padding-left: 100px;
|
||||
|
|
@ -164,11 +192,11 @@
|
|||
i.fa {
|
||||
line-height: inherit;
|
||||
}
|
||||
&.show {
|
||||
visibility:visible;
|
||||
cursor:pointer;
|
||||
opacity: 1.0;
|
||||
}
|
||||
// &.show {
|
||||
// visibility:visible;
|
||||
// cursor:pointer;
|
||||
// opacity: 1.0;
|
||||
// }
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
|
|
|
|||
14
app/assets/stylesheets/osem-variables.scss
Normal file
14
app/assets/stylesheets/osem-variables.scss
Normal 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;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
@import "osem-variables";
|
||||
@import "bootstrap/mixins";
|
||||
|
||||
html {
|
||||
|
|
@ -7,15 +8,31 @@ html {
|
|||
|
||||
body {
|
||||
/* Margin bottom by 2 times the footer height */
|
||||
margin-bottom: 60px;
|
||||
margin-bottom: 85px;
|
||||
/* Margin bottom by navbar height */
|
||||
padding-top: 60px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
// Designed to be the last element in a section / nav
|
||||
// Makes a little "puzzle piece" connector.
|
||||
.trapezoid {
|
||||
position: relative;
|
||||
margin-left: 60px;
|
||||
border-top: $trapezoid-height solid;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
height: 0;
|
||||
width: 64px;
|
||||
margin-top: -1 * $trapezoid-height;
|
||||
top: $trapezoid-height;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
$navbar-default-bg: #299a0b;
|
||||
$navbar-default-link-active-bg: #DFE0DF;
|
||||
$navbar-default-border: 1px solid #d4d4d4;
|
||||
$navbar-default-color: #ffffff;
|
||||
$navbar-default-link-color: #ffffff;
|
||||
$navbar-default-link-hover-color: #000000;
|
||||
|
||||
// Place bootstrap variable customizations in the file below.
|
||||
@import "osem-variables";
|
||||
@import 'bootstrap-datetimepicker';
|
||||
@import "bootstrap-sprockets";
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ module Admin
|
|||
|
||||
if @commercial.save
|
||||
redirect_to admin_conference_commercials_path,
|
||||
notice: 'Commercial was successfully created.'
|
||||
notice: 'Materials were successfully created.'
|
||||
else
|
||||
redirect_to admin_conference_commercials_path,
|
||||
error: 'An error prohibited this Commercial from being saved: '\
|
||||
error: 'An error prohibited materials from being saved: '\
|
||||
"#{@commercial.errors.full_messages.join('. ')}."
|
||||
|
||||
end
|
||||
|
|
@ -29,17 +29,17 @@ module Admin
|
|||
def update
|
||||
if @commercial.update(commercial_params)
|
||||
redirect_to admin_conference_commercials_path,
|
||||
notice: 'Commercial was successfully updated.'
|
||||
notice: 'Materials were successfully updated.'
|
||||
else
|
||||
redirect_to admin_conference_commercials_path,
|
||||
error: 'An error prohibited this Commercial from being saved: '\
|
||||
error: 'An error prohibited materials from being saved: '\
|
||||
"#{@commercial.errors.full_messages.join('. ')}."
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@commercial.destroy
|
||||
redirect_to admin_conference_commercials_path, notice: 'Commercial was successfully destroyed.'
|
||||
redirect_to admin_conference_commercials_path, notice: 'Materials were successfully removed.'
|
||||
end
|
||||
|
||||
def render_commercial
|
||||
|
|
@ -60,9 +60,9 @@ module Admin
|
|||
errors = Commercial.read_file(params[:file]) if params[:file]
|
||||
|
||||
if !params[:file]
|
||||
flash[:error] = 'Empty file detected while adding commercials to Event'
|
||||
flash[:error] = 'Empty file detected while adding materials to Event'
|
||||
elsif errors.all? { |_k, v| v.blank? }
|
||||
flash[:notice] = 'Successfully added commercials.'
|
||||
flash[:notice] = 'Successfully added materials.'
|
||||
else
|
||||
errors_text = ''
|
||||
errors_text << 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any?
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ module Admin
|
|||
|
||||
def registration_params
|
||||
params.require(:registration).permit(
|
||||
:user_id, :conference_id, :arrival, :departure, :attended,
|
||||
:user_id, :conference_id, :attended,
|
||||
:volunteer, :other_special_needs, :accepted_code_of_conduct,
|
||||
vchoice_ids: [], qanswer_ids: [], qanswers_attributes: [], event_ids: []
|
||||
)
|
||||
|
|
|
|||
|
|
@ -38,13 +38,30 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def give
|
||||
ticket_purchase = @ticket.ticket_purchases.new(gift_ticket_params)
|
||||
recipient = ticket_purchase.user
|
||||
if ticket_purchase.save
|
||||
redirect_to(
|
||||
admin_conference_ticket_path(@conference.short_title, @ticket),
|
||||
notice: "#{recipient.name} was given a #{@ticket.title} ticket."
|
||||
)
|
||||
else
|
||||
redirect_back(
|
||||
fallback_location: admin_conference_ticket_path(@conference.short_title, @ticket),
|
||||
error: "Unable to give #{recipient.name} a #{@ticket.title} ticket: " +
|
||||
ticket_purchase.errors.full_messages.to_sentence
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @ticket.destroy
|
||||
redirect_to admin_conference_tickets_path(conference_id: @conference.short_title),
|
||||
notice: 'Ticket successfully destroyed.'
|
||||
notice: 'Ticket successfully deleted.'
|
||||
else
|
||||
redirect_to admin_conference_tickets_path(conference_id: @conference.short_title),
|
||||
error: 'Ticket was successfully destroyed.' \
|
||||
error: 'Deleting ticket failed! ' \
|
||||
"#{@ticket.errors.full_messages.join('. ')}."
|
||||
end
|
||||
end
|
||||
|
|
@ -52,7 +69,19 @@ module Admin
|
|||
private
|
||||
|
||||
def ticket_params
|
||||
params.require(:ticket).permit(:conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price, :registration_ticket)
|
||||
params.require(:ticket).permit(
|
||||
:conference, :conference_id,
|
||||
:title, :url, :description,
|
||||
:price_cents, :price_currency, :price,
|
||||
:registration_ticket, :visible
|
||||
)
|
||||
end
|
||||
|
||||
def gift_ticket_params
|
||||
response = params.require(:ticket_purchase).permit(
|
||||
:user_id
|
||||
)
|
||||
response.merge(paid: true, amount_paid: 0, conference: @conference)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ module Admin
|
|||
|
||||
if @commercial.save
|
||||
redirect_to admin_conference_venue_path,
|
||||
notice: 'Commercial was successfully created.'
|
||||
notice: 'Materials successfully created.'
|
||||
else
|
||||
redirect_to admin_conference_venue_path,
|
||||
error: 'An error prohibited this Commercial from being saved: '\
|
||||
error: 'An error prohibited materials from being saved: '\
|
||||
"#{@commercial.errors.full_messages.join('. ')}."
|
||||
|
||||
end
|
||||
|
|
@ -24,17 +24,17 @@ module Admin
|
|||
def update
|
||||
if @commercial.update(commercial_params)
|
||||
redirect_to admin_conference_venue_path,
|
||||
notice: 'Commercial was successfully updated.'
|
||||
notice: 'Materials successfully updated.'
|
||||
else
|
||||
redirect_to admin_conference_venue_path,
|
||||
error: 'An error prohibited this Commercial from being saved: '\
|
||||
error: 'An error prohibited materials from being saved: '\
|
||||
"#{@commercial.errors.full_messages.join('. ')}."
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@commercial.destroy
|
||||
redirect_to admin_conference_venue_path, notice: 'Commercial was successfully destroyed.'
|
||||
redirect_to admin_conference_venue_path, notice: 'Materials successfully destroyed.'
|
||||
end
|
||||
|
||||
def render_commercial
|
||||
|
|
|
|||
|
|
@ -12,27 +12,27 @@ class CommercialsController < ApplicationController
|
|||
|
||||
if @commercial.save
|
||||
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'),
|
||||
notice: 'Commercial was successfully created.'
|
||||
notice: 'Materials were successfully created.'
|
||||
else
|
||||
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'),
|
||||
error: "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}."
|
||||
error: "An error prohibited these materials from being saved: #{@commercial.errors.full_messages.join('. ')}."
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @commercial.update(commercial_params)
|
||||
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'),
|
||||
notice: 'Commercial was successfully updated.'
|
||||
notice: 'Materials were successfully updated.'
|
||||
else
|
||||
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'),
|
||||
error: "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}."
|
||||
error: "An error prohibited materials from being saved: #{@commercial.errors.full_messages.join('. ')}."
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@commercial.destroy
|
||||
redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id),
|
||||
notice: 'Commercial was successfully destroyed.'
|
||||
notice: 'Materials were successfully destroyed.'
|
||||
end
|
||||
|
||||
def render_commercial
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class ConferenceRegistrationsController < ApplicationController
|
|||
sign_in(@registration.user)
|
||||
end
|
||||
|
||||
if @conference.tickets.any? && !current_user.supports?(@conference)
|
||||
if @conference.tickets.visible.any? && !current_user.supports?(@conference)
|
||||
redirect_to conference_tickets_path(@conference.short_title),
|
||||
notice: 'You are now registered and will be receiving E-Mail notifications.'
|
||||
else
|
||||
|
|
@ -108,9 +108,9 @@ class ConferenceRegistrationsController < ApplicationController
|
|||
end
|
||||
|
||||
def registration_params
|
||||
params.require(:registration)
|
||||
params.permit(:registration)
|
||||
.permit(
|
||||
:conference_id, :arrival, :departure,
|
||||
:conference_id,
|
||||
:volunteer, :accepted_code_of_conduct,
|
||||
vchoice_ids: [], qanswer_ids: [],
|
||||
qanswers_attributes: [],
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ class ConferencesController < ApplicationController
|
|||
end
|
||||
end
|
||||
if splashpage.include_registrations || splashpage.include_tickets
|
||||
@tickets = @conference.tickets.order('price_cents')
|
||||
@tickets = @conference.tickets.visible.order('price_cents')
|
||||
end
|
||||
if splashpage.include_lodgings
|
||||
@lodgings = @conference.lodgings.order('name')
|
||||
@lodgings = @conference.lodgings.order('id')
|
||||
end
|
||||
if splashpage.include_sponsors
|
||||
@sponsorship_levels = @conference.sponsorship_levels.eager_load(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
class TicketsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
load_resource :conference, find_by: :short_title
|
||||
load_resource :ticket, through: :conference
|
||||
before_action :load_tickets
|
||||
authorize_resource :ticket, through: :conference
|
||||
authorize_resource :conference_registrations, class: Registration
|
||||
before_action :check_load_resource, only: :index
|
||||
|
||||
|
|
@ -14,4 +15,8 @@ class TicketsController < ApplicationController
|
|||
redirect_to root_path, notice: "There are no tickets available for #{@conference.title}!"
|
||||
end
|
||||
end
|
||||
|
||||
def load_tickets
|
||||
@tickets = @conference.tickets.visible
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ class RegistrationDatatable < AjaxDatatablesRails::Base
|
|||
roles: { source: 'Role.name' },
|
||||
email: { source: 'User.email' },
|
||||
accepted_code_of_conduct: { source: 'Registration.accepted_code_of_conduct', searchable: false },
|
||||
arrival: { source: 'Registration.arrival', searchable: false },
|
||||
departure: { source: 'Registration.departure', searchable: false },
|
||||
actions: { source: 'Registration.id', searchable: false, orderable: false }
|
||||
}
|
||||
end
|
||||
|
|
@ -36,8 +34,6 @@ class RegistrationDatatable < AjaxDatatablesRails::Base
|
|||
roles: conference_role_titles(record.user),
|
||||
email: record.email,
|
||||
accepted_code_of_conduct: !!record.accepted_code_of_conduct, # rubocop:disable Style/DoubleNegation
|
||||
arrival: record.arrival&.utc,
|
||||
departure: record.departure&.utc,
|
||||
questions: {},
|
||||
edit_url: edit_admin_conference_registration_path(conference, record),
|
||||
DT_RowId: record.id
|
||||
|
|
|
|||
|
|
@ -40,19 +40,20 @@ class UserDatatable < AjaxDatatablesRails::Base
|
|||
|
||||
# rubocop:disable Naming/AccessorMethodName
|
||||
def get_raw_records
|
||||
User.left_outer_joins(:registrations, :roles)
|
||||
.distinct
|
||||
.select("users.*, COUNT(CASE WHEN registrations.attended = 't' THEN 1 END) AS attended_count")
|
||||
.group('users.id')
|
||||
User.left_outer_joins(:registrations, :roles).select(
|
||||
"DISTINCT users.id, users.name, users.email, users.confirmed_at, COUNT(CASE WHEN registrations.attended = 't' THEN 1 END) AS attended_count"
|
||||
).group(
|
||||
'users.id, users.name, users.email, users.confirmed_at'
|
||||
)
|
||||
end
|
||||
# rubocop:enable Naming/AccessorMethodName
|
||||
|
||||
def records_total_count
|
||||
fetch_records.unscope(:group).count(:all)
|
||||
fetch_records.unscoped.count(:id)
|
||||
end
|
||||
|
||||
def records_filtered_count
|
||||
filter_records(fetch_records).unscope(:group).count(:all)
|
||||
filter_records(fetch_records).unscoped.count
|
||||
end
|
||||
|
||||
# ==== These methods represent the basic operations to perform on records
|
||||
|
|
|
|||
|
|
@ -178,20 +178,22 @@ module ApplicationHelper
|
|||
'hidden' if Date.today > conference.end_date
|
||||
end
|
||||
|
||||
# TODO:Snap!Con: Replace this with a search for a conference logo.
|
||||
def nav_root_link_for(conference)
|
||||
link_text = (
|
||||
conference.try(:organization).try(:name) ||
|
||||
ENV['OSEM_NAME'] ||
|
||||
'OSEM'
|
||||
)
|
||||
link_to(
|
||||
link_text,
|
||||
image_tag('snapcon_logo.png'),
|
||||
root_path,
|
||||
class: 'navbar-brand',
|
||||
title: 'Open Source Event Manager'
|
||||
title: nav_link_text(conference)
|
||||
)
|
||||
end
|
||||
|
||||
def nav_link_text(conference)
|
||||
conference.try(:organization).try(:name) ||
|
||||
ENV['OSEM_NAME'] ||
|
||||
'OSEM'
|
||||
end
|
||||
|
||||
# returns the url to be used for logo on basis of sponsorship level position
|
||||
def get_logo(object)
|
||||
if object.try(:sponsorship_level)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'redcarpet/render_strip'
|
||||
|
||||
module FormatHelper
|
||||
##
|
||||
# Includes functions related to formatting (like adding classes, colors)
|
||||
|
|
@ -42,12 +44,11 @@ module FormatHelper
|
|||
|
||||
def target_progress_color(progress)
|
||||
progress = progress.to_i
|
||||
result =
|
||||
case
|
||||
when progress >= 90 then 'green'
|
||||
when progress < 90 && progress >= 80 then 'orange'
|
||||
else 'red'
|
||||
end
|
||||
result = case
|
||||
when progress >= 90 then 'green'
|
||||
when progress < 90 && progress >= 80 then 'orange'
|
||||
else 'red'
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
|
@ -99,19 +100,11 @@ module FormatHelper
|
|||
end
|
||||
|
||||
def icon_for_todo(bool)
|
||||
if bool
|
||||
'fa fa-check'
|
||||
else
|
||||
'fa fa-times'
|
||||
end
|
||||
bool ? 'fa fa-check' : 'fa fa-times'
|
||||
end
|
||||
|
||||
def class_for_todo(bool)
|
||||
if bool
|
||||
'todolist-ok'
|
||||
else
|
||||
'todolist-missing'
|
||||
end
|
||||
bool ? 'todolist-ok' : 'todolist-missing'
|
||||
end
|
||||
|
||||
def word_pluralize(count, singular, plural = nil)
|
||||
|
|
@ -191,9 +184,12 @@ module FormatHelper
|
|||
return '' if text.nil?
|
||||
|
||||
options = {
|
||||
autolink: true,
|
||||
autolink: true,
|
||||
space_after_headers: true,
|
||||
no_intra_emphasis: true
|
||||
tables: true,
|
||||
strikethrough: true,
|
||||
footnotes: true,
|
||||
superscript: true
|
||||
}
|
||||
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: escape_html), options)
|
||||
markdown.render(text).html_safe
|
||||
|
|
@ -203,6 +199,11 @@ module FormatHelper
|
|||
markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text", false)
|
||||
end
|
||||
|
||||
# Return a plain text markdown stripped of formatting.
|
||||
def plain_text(content)
|
||||
Redcarpet::Markdown.new(Redcarpet::Render::StripDown).render(content)
|
||||
end
|
||||
|
||||
def quantity_left_of(resource)
|
||||
return '-/-' if resource.quantity.blank?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
SNAPCON_BCC_ADDRESS = 'messages@snap.berkeley.edu'
|
||||
|
||||
class Mailbot < ActionMailer::Base
|
||||
def registration_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.registration_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
|
|
@ -21,6 +24,7 @@ class Mailbot < ActionMailer::Base
|
|||
end
|
||||
|
||||
mail(to: @user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: @conference.contact.email,
|
||||
template_name: 'ticket_confirmation_template',
|
||||
subject: "#{@conference.title} | Ticket Confirmation and PDF!")
|
||||
|
|
@ -30,6 +34,7 @@ class Mailbot < ActionMailer::Base
|
|||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.accepted_subject,
|
||||
body: conference.email_settings.generate_event_mail(event, conference.email_settings.accepted_body))
|
||||
|
|
@ -39,6 +44,7 @@ class Mailbot < ActionMailer::Base
|
|||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.submitted_proposal_subject,
|
||||
body: conference.email_settings.generate_event_mail(event, conference.email_settings.submitted_proposal_body))
|
||||
|
|
@ -48,6 +54,7 @@ class Mailbot < ActionMailer::Base
|
|||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.rejected_subject,
|
||||
body: conference.email_settings.generate_event_mail(event, conference.email_settings.rejected_body))
|
||||
|
|
@ -57,6 +64,7 @@ class Mailbot < ActionMailer::Base
|
|||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.confirmed_without_registration_subject,
|
||||
body: conference.email_settings.generate_event_mail(event,
|
||||
|
|
@ -65,6 +73,7 @@ class Mailbot < ActionMailer::Base
|
|||
|
||||
def conference_date_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.conference_dates_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
|
|
@ -74,6 +83,7 @@ class Mailbot < ActionMailer::Base
|
|||
|
||||
def conference_registration_date_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.conference_registration_dates_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
|
|
@ -83,6 +93,7 @@ class Mailbot < ActionMailer::Base
|
|||
|
||||
def conference_venue_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.venue_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -87,7 +87,9 @@ class Ability
|
|||
end
|
||||
|
||||
can :index, Organization
|
||||
can :index, Ticket
|
||||
can :index, Ticket do |ticket|
|
||||
ticket.visible
|
||||
end
|
||||
can :manage, TicketPurchase, user_id: user.id
|
||||
can [:new, :create], Payment, user_id: user.id
|
||||
can [:index, :show], PhysicalTicket, user: user
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class Commercial < ApplicationRecord
|
|||
|
||||
commercial = event.commercials.new(url: url)
|
||||
unless commercial.save
|
||||
errors[:validation_errors] << "Could not create commercial for event with ID #{event.id} (" + commercial.errors.full_messages.to_sentence + ')'
|
||||
errors[:validation_errors] << "Could not create materials for event with ID #{event.id} (" + commercial.errors.full_messages.to_sentence + ')'
|
||||
end
|
||||
end
|
||||
errors
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ class Conference < ApplicationRecord
|
|||
has_one :email_settings, dependent: :destroy
|
||||
has_one :program, dependent: :destroy
|
||||
has_one :venue, dependent: :destroy
|
||||
has_many :physical_tickets, through: :ticket_purchases
|
||||
has_many :ticket_purchases, dependent: :destroy
|
||||
has_many :physical_tickets, through: :ticket_purchases
|
||||
has_many :payments, dependent: :destroy
|
||||
has_many :supporters, through: :ticket_purchases, source: :user
|
||||
has_many :tickets, dependent: :destroy
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ class Registration < ApplicationRecord
|
|||
|
||||
validates :user_id, uniqueness: { scope: :conference_id, message: 'already Registered!' }
|
||||
validate :registration_limit_not_exceed, on: :create
|
||||
validate :registration_to_events_only_if_present
|
||||
|
||||
validates :accepted_code_of_conduct, acceptance: {
|
||||
if: -> { conference.try(:code_of_conduct).present? }
|
||||
}
|
||||
|
|
@ -48,19 +46,6 @@ class Registration < ApplicationRecord
|
|||
|
||||
private
|
||||
|
||||
##
|
||||
# If the user registers to attend events that are already scheduled,
|
||||
# only allow registration to events if the user will be present
|
||||
# (based on arrival and departure attributes)
|
||||
# No validation if arrival/departure attributes are empty
|
||||
def registration_to_events_only_if_present
|
||||
if (arrival || departure) && events.pluck(:start_time).any?
|
||||
errors.add(:arrival, 'is too late! You cannot register for events that take place before your arrival') if events.pluck(:start_time).compact.map { |x| x < arrival }.any?
|
||||
|
||||
errors.add(:departure, 'is too early! You cannot register for events that take place after your departure') if events.pluck(:start_time).compact.map { |x| x > departure }.any?
|
||||
end
|
||||
end
|
||||
|
||||
def subscribe_to_conference
|
||||
Subscription.create(conference_id: conference.id, user_id: user.id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ class Ticket < ApplicationRecord
|
|||
|
||||
validates :price_cents, numericality: { greater_than_or_equal_to: 0 }
|
||||
|
||||
scope :visible, -> { where(visible: true) }
|
||||
|
||||
def bought?(user)
|
||||
buyers.include?(user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class TicketPurchase < ApplicationRecord
|
|||
errors.push('You cannot buy more than one registration tickets.')
|
||||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
conference.tickets.each do |ticket|
|
||||
conference.tickets.visible.each do |ticket|
|
||||
quantity = purchases[ticket.id.to_s].to_i
|
||||
# if the user bought the ticket and is still unpaid, just update the quantity
|
||||
purchase = if ticket.bought?(user) && ticket.unpaid?(user)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,10 @@ class User < ApplicationRecord
|
|||
else
|
||||
[:database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable, :confirmable,
|
||||
:omniauthable, omniauth_providers: [:suse, :google, :facebook, :github]]
|
||||
:omniauthable,
|
||||
# omniauth_providers: [:suse, :google, :facebook, :github, :discourse]
|
||||
omniauth_providers: [:google, :discourse]
|
||||
]
|
||||
end
|
||||
|
||||
devise(*devise_modules)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
.row
|
||||
.col-md-12
|
||||
.page-header
|
||||
%h1 Commercials
|
||||
%h1 Session Materials
|
||||
%p.text-muted
|
||||
Conference commercials will be displayed on the events in the
|
||||
Conference materials will be displayed on the events in the
|
||||
= link_to 'schedule,', conference_schedule_path(@conference.short_title)
|
||||
if the event speaker didn't add an event commercial.
|
||||
if the event speaker didn't add any event materials.
|
||||
- if can? :create, @conference.commercials.new
|
||||
.row
|
||||
.col-md-6
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
Event Type
|
||||
= @event_type.title
|
||||
.row
|
||||
.col-md-12
|
||||
= semantic_form_for(@event_type, url: (@event_type.new_record? ? admin_conference_program_event_types_path : admin_conference_program_event_type_path(@conference.short_title, @event_type))) do |f|
|
||||
.col-md-8
|
||||
- form_url = (@event_type.new_record? ? admin_conference_program_event_types_path : admin_conference_program_event_type_path(@conference.short_title, @event_type))
|
||||
= semantic_form_for(@event_type, url: form_url) do |f|
|
||||
= f.input :title, input_html: { autofocus: true }
|
||||
= f.input :length, input_html: {size: 3, type: 'number', step: @event_type.program.schedule_interval, min: @event_type.program.schedule_interval}
|
||||
= f.input :description
|
||||
= f.input :description, as: :text, hint: markdown_hint, input_html: { rows: 5, data: { provide: 'markdown-editable' } }
|
||||
= f.input :minimum_abstract_length, input_html: {size: 3}
|
||||
= f.input :maximum_abstract_length, input_html: {size: 3}
|
||||
= f.input :color, input_html: { size: 6, type: 'color' }
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
%td
|
||||
= event_type.title
|
||||
%td
|
||||
= event_type.description
|
||||
= markdown(event_type.description)
|
||||
%td
|
||||
= event_type.length
|
||||
Minutes
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
= "(#{@events.length})" if @events.any?
|
||||
|
||||
.btn-group.pull-right
|
||||
%button.btn.btn-primary{ title: 'Mass import of commercials for events',
|
||||
%button.btn.btn-primary{ title: 'Mass import of materials for events',
|
||||
data: { toggle: 'modal', target: '#mass-commercials-modal' } }
|
||||
Add Commercials
|
||||
Add Materials
|
||||
|
||||
- if can? :create, Event
|
||||
= link_to 'Add Event',
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
.modal-dialog
|
||||
.modal-content
|
||||
.modal-header
|
||||
%h1 Add commercials to events
|
||||
%h1 Add materials to events
|
||||
.text-muted
|
||||
Upload your file with data in the following format:
|
||||
%b Event_ID:Commercial_Link
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
- progress_status = @event.progress_status
|
||||
= progress_status.reject{ |_key, value| value || value.nil? }.length
|
||||
%li
|
||||
= link_to 'Commercials', '#proposal-commercials', 'data-toggle' => 'tab'
|
||||
= link_to 'Materials', '#proposal-commercials', 'data-toggle' => 'tab'
|
||||
|
||||
.tab-content
|
||||
#proposal-content.tab-pane.active
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
- else
|
||||
= general_change_description(version)
|
||||
= link_to 'commercial',
|
||||
= link_to 'materials',
|
||||
edit_admin_conference_program_event_path(conference_id: @conference.short_title,
|
||||
id: @event.id, anchor: 'commercials-content')
|
||||
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
%td{ 'class' => class_for_todo(progress_status['subtitle']) }
|
||||
%span{ 'class' => [icon_for_todo(progress_status['subtitle']), 'fa-lg'] }
|
||||
%tr
|
||||
%td= link_to 'Add a commercial', edit_admin_conference_program_event_path(@event.program.conference.short_title, @event, anchor: 'commercials-content')
|
||||
%td= link_to 'Add materials', edit_admin_conference_program_event_path(@event.program.conference.short_title, @event, anchor: 'commercials-content')
|
||||
%td{ 'class' => class_for_todo(progress_status['commercials']) }
|
||||
%span{ 'class' => [icon_for_todo(progress_status['commercials']), 'fa-lg'] }
|
||||
- unless progress_status['track'].nil?
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
%th{ width: '0' } E-Mail
|
||||
%th{ width: '0' }
|
||||
%abbr{ title: 'Code of Conduct' } CoC
|
||||
%th{ width: '0' } Arrival
|
||||
%th{ width: '0' } Departure
|
||||
%th{ width: '0' } Actions
|
||||
%tbody
|
||||
|
||||
|
|
@ -81,22 +79,6 @@
|
|||
"className": "code-of-conduct text-center",
|
||||
"searchable": false
|
||||
},
|
||||
{
|
||||
"data": "arrival",
|
||||
"searchable": false,
|
||||
"render": function(data, type, row) {
|
||||
if (data) { return moment(data).format('ll LT'); }
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "departure",
|
||||
"searchable": false,
|
||||
"render": function(data, type, row) {
|
||||
if (data) { return moment(data).format('ll LT'); }
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": null,
|
||||
"className": "actions",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@ prawn_document(force_download: true, filename: @pdf_filename, page_layout: :land
|
|||
'Name',
|
||||
'Nickname',
|
||||
'Affiliation',
|
||||
'Email',
|
||||
'Arrival Date',
|
||||
'Departure Date']
|
||||
'Email']
|
||||
@conference.questions.each do |question|
|
||||
header_array << question.title
|
||||
end
|
||||
|
|
@ -19,8 +17,6 @@ prawn_document(force_download: true, filename: @pdf_filename, page_layout: :land
|
|||
row << registration.nickname
|
||||
row << registration.affiliation
|
||||
row << registration.email
|
||||
row << registration.arrival.to_s || ''
|
||||
row << registration.departure.to_s || ''
|
||||
|
||||
@conference.questions.each do |question|
|
||||
qa = registration.qanswers.find_by(question: question)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
wb = xlsx_package.workbook
|
||||
wb.add_worksheet(name: 'registrations') do |sheet|
|
||||
bold_style = wb.styles.add_style(b: true)
|
||||
row = ['Attended', 'Name', 'Nickname', 'Affilιation', 'Email', 'Arrival', 'Departure']
|
||||
row = ['Attended', 'Name', 'Nickname', 'Affilιation', 'Email']
|
||||
|
||||
@conference.questions.each do |question|
|
||||
row << question.title
|
||||
|
|
@ -18,8 +18,6 @@ wb.add_worksheet(name: 'registrations') do |sheet|
|
|||
row << registration.nickname
|
||||
row << registration.affiliation
|
||||
row << registration.email
|
||||
row << registration.arrival.to_s
|
||||
row << registration.departure.to_s
|
||||
@conference.questions.each do |question|
|
||||
qa = registration.qanswers.find_by(question: question)
|
||||
answer = ( qa ? qa.answer.title : '' )
|
||||
|
|
@ -30,4 +28,3 @@ wb.add_worksheet(name: 'registrations') do |sheet|
|
|||
sheet.add_row row
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
%th Title
|
||||
%th Speakers Registered
|
||||
%th Speakers Biographies
|
||||
%th Commercial
|
||||
%th Materials
|
||||
%th Subtitle
|
||||
%th Difficulty Level
|
||||
- if @program.tracks.any?
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
.col-md-12
|
||||
.page-header
|
||||
%h1
|
||||
Events without commercials
|
||||
Events Without Materials
|
||||
= "(#{@events_missing_commercial.length})"
|
||||
%p.text-muted
|
||||
All submissions that have no commercial
|
||||
All submissions that have no materials
|
||||
.col-md-12
|
||||
%table.datatable
|
||||
%thead
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
= link_to 'All Events', '#all', 'data-toggle' => 'tab'
|
||||
%li
|
||||
%a{href: '#missing-commercial', 'data-toggle' => 'tab'}
|
||||
Events without Commercials
|
||||
Events without Materials
|
||||
%span.label.label-danger{style: 'border-radius: 1em;'}
|
||||
= @events_missing_commercial.length
|
||||
%li
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@
|
|||
= f.input :price
|
||||
= f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY', 'CHF'], include_blank: false
|
||||
= f.input :registration_ticket, hint: 'A registration ticket is with which user register for the conference.'
|
||||
= f.input :visible, hint: 'Only visible tickets are available to registrants. Non-visible tickets can only be managed by Admins.'
|
||||
%p.text-right
|
||||
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
%th Sold
|
||||
%th Turnover
|
||||
%th Registration Ticket
|
||||
%th Visible?
|
||||
%th Actions
|
||||
%tbody
|
||||
- @conference.tickets.each do |ticket|
|
||||
|
|
@ -30,6 +31,8 @@
|
|||
= humanized_money_with_symbol ticket.tickets_turnover_total(ticket.id)
|
||||
%td
|
||||
= ticket.registration_ticket? ? 'Yes' : 'No'
|
||||
%td
|
||||
= ticket.visible? ? 'Yes' : 'No'
|
||||
%td
|
||||
.btn-group
|
||||
= link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,13 @@
|
|||
Ticket
|
||||
%small
|
||||
= humanized_money_with_symbol @ticket.price
|
||||
= link_to 'Edit Ticket', edit_admin_conference_ticket_path, class: 'btn btn-primary pull-right'
|
||||
= link_to 'Edit Ticket', edit_admin_conference_ticket_path, class: 'btn btn-primary pull-right'
|
||||
- if can? :give, Ticket
|
||||
.pull-right
|
||||
= link_to 'Give a Ticket', '#',
|
||||
data: { toggle: 'modal', target: "#modal-give-ticket-#{@ticket.id}" },
|
||||
class: 'button btn btn-default btn-info'
|
||||
|
||||
%p.text-muted
|
||||
People who bought this ticket
|
||||
.row
|
||||
|
|
@ -35,3 +41,26 @@
|
|||
= buyer.affiliation
|
||||
%td
|
||||
= @ticket.tickets_paid(buyer)
|
||||
|
||||
- content_for :modals do
|
||||
.modal.fade{ id: "modal-give-ticket-#{@ticket.id}" }
|
||||
.modal-dialog
|
||||
.modal-content
|
||||
= semantic_form_for(@ticket.ticket_purchases.new,
|
||||
url: give_admin_conference_ticket_path(@conference, @ticket)) do |f|
|
||||
.modal-header
|
||||
%button.close{ data: { dismiss: 'modal' } }
|
||||
%i.fa.fa-close
|
||||
%h3.modal-title
|
||||
Give a
|
||||
= @ticket.title
|
||||
Ticket
|
||||
.modal-body
|
||||
= user_selector_input(:user, f, '', false)
|
||||
.modal-footer
|
||||
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||
|
||||
:javascript
|
||||
$(document).ready(function() {
|
||||
$('#ticket_purchase_user_id').selectize({})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
%li.active
|
||||
= link_to 'Details', '#details-content', 'data-toggle' => 'tab'
|
||||
%li
|
||||
= link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab'
|
||||
= link_to 'Materials', '#commercials-content', 'data-toggle' => 'tab'
|
||||
|
||||
.tab-content
|
||||
#details-content.tab-pane.active
|
||||
|
|
@ -56,4 +56,4 @@
|
|||
%hr
|
||||
|
||||
- else
|
||||
First Create Venue, then update commercial
|
||||
First Create Venue, then update materials
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
-else
|
||||
- if @venue.commercial.nil?
|
||||
.row
|
||||
%img{ "data-src" => "holder.js/500x300?text=No Commercial Set", class: 'img-responsive img-rounded' }
|
||||
%img{ "data-src" => "holder.js/500x300?text=No Materials Set", class: 'img-responsive img-rounded' }
|
||||
- else
|
||||
- if @venue.commercial.persisted?
|
||||
.thumbnail
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.row
|
||||
.col-md-12
|
||||
.page-header
|
||||
%h1 Editing Commercial
|
||||
%h1 Edit Materials
|
||||
.row
|
||||
.col-md-12
|
||||
= semantic_form_for @commercial, url: conference_program_proposal_commercial_path(conference_id: @conference.short_title, proposal_id: @event.id, id: @commercial.id) do |f|
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.row
|
||||
.col-md-12
|
||||
.page-header
|
||||
%h1 New Commercial
|
||||
%h1 New Materials
|
||||
.row
|
||||
.col-md-12
|
||||
= semantic_form_for @commercial, url: conference_program_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event.id) do |f|
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
= render partial: 'devise/shared/sign_up_form_embedded'
|
||||
|
||||
= render partial: 'registration_info', locals: { f: f }
|
||||
= f.input :conference_id, as: :hidden, value: @conference.id
|
||||
.row
|
||||
.col-md-12
|
||||
%p.pull-right
|
||||
|
|
|
|||
|
|
@ -24,10 +24,4 @@
|
|||
(Scheduled on: #{event.time.to_date})
|
||||
%br
|
||||
|
||||
|
||||
|
||||
= f.inputs 'Your Travel Info' do
|
||||
= f.input :arrival, as: :string, label: 'Your arrival time', hint: "Leave blank if not sure", input_html: { value: (f.object.arrival.to_formatted_s(:db_without_seconds) unless f.object.arrival.nil?), id: 'registration-arrival-datepicker',start_date: @conference.start_date,end_date: @conference.end_date }
|
||||
= f.input :departure, as: :string, label: 'Your departure time', hint: "Leave blank if not sure", input_html: { value: (f.object.departure.to_formatted_s(:db_without_seconds) unless f.object.departure.nil?), id: 'registration-departure-datepicker' }
|
||||
|
||||
= render 'conferences/code_of_conduct', organization: @conference.organization
|
||||
|
|
|
|||
|
|
@ -33,28 +33,6 @@
|
|||
data: { toggle: 'modal', target: '#modal-code-of-conduct'}
|
||||
= render 'conferences/code_of_conduct',
|
||||
organization: @conference.organization
|
||||
.row
|
||||
.col-md-12
|
||||
%h4
|
||||
%span.fa-stack
|
||||
%i.fa.fa-square-o.fa-stack-2x
|
||||
%i.fa.fa-plane.fa-stack-1x
|
||||
Travel Schedule
|
||||
%ul
|
||||
%li
|
||||
- if @registration.arrival.present?
|
||||
arrive at
|
||||
%strong
|
||||
= @registration.arrival.strftime('%A, %B %-d. %Y %H:%M')
|
||||
- else
|
||||
You haven't scheduled your arrival
|
||||
%li
|
||||
- if @registration.departure.present?
|
||||
depart at
|
||||
%strong
|
||||
= @registration.departure.strftime('%A, %B %-d. %Y %H:%M')
|
||||
- else
|
||||
You haven't scheduled your departure
|
||||
- if @conference.surveys.for_registration.any?
|
||||
.row
|
||||
.col-md-12
|
||||
|
|
@ -94,7 +72,7 @@
|
|||
= link_to event.title, conference_program_proposal_path(@conference.short_title, event.id)
|
||||
= '(' + registered_text(event) + ')'
|
||||
|
||||
- if @conference.tickets.any?
|
||||
- if @conference.tickets.visible.any?
|
||||
.row
|
||||
.col-md-12
|
||||
%h4
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
= content_for :splash_nav do
|
||||
%li
|
||||
%a.smoothscroll{ href: '#call' } Call For Content
|
||||
%a.smoothscroll{ href: '#call' } Call For Participation
|
||||
|
||||
%section#call
|
||||
.container
|
||||
|
|
@ -20,3 +20,4 @@
|
|||
call: call_for_booths
|
||||
- if two_calls_open(call_for_events, call_for_tracks, call_for_booths)
|
||||
.col-md-2.col-sm-2.hidden-xs
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
expires_in: 1.hour) do
|
||||
.col-md-4.col-sm-4.text-center
|
||||
%h2
|
||||
Call for Papers
|
||||
Call for Participation
|
||||
%p.lead
|
||||
We are now accepting proposals for sessions!
|
||||
%p
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
= image_tag(conference.picture_url, class: 'img-responsive') if conference.picture?
|
||||
.col-md-6
|
||||
%h3
|
||||
= conference.title
|
||||
= conference.title.html_safe
|
||||
%small
|
||||
%b
|
||||
= date_string(conference.start_date, conference.end_date)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
.scroll-top-wrapper
|
||||
= link_to "#banner", class: "smoothscroll" do
|
||||
%i.fa.fa-2x.fa-arrow-circle-up
|
||||
-# .scroll-top-wrapper
|
||||
-# = link_to "#banner", class: "smoothscroll" do
|
||||
-# %i.fa.fa-2x.fa-arrow-circle-up
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
$(document).on( 'scroll', function(){
|
||||
if ($(window).scrollTop() > 100) {
|
||||
$('.scroll-top-wrapper').addClass('show');
|
||||
} else {
|
||||
$('.scroll-top-wrapper').removeClass('show');
|
||||
}
|
||||
});
|
||||
});
|
||||
-# :javascript
|
||||
-# $(function(){
|
||||
-# $(document).on( 'scroll', function(){
|
||||
-# if ($(window).scrollTop() > 100) {
|
||||
-# $('.scroll-top-wrapper').addClass('show');
|
||||
-# } else {
|
||||
-# $('.scroll-top-wrapper').removeClass('show');
|
||||
-# }
|
||||
-# });
|
||||
-# });
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
- cache [conference, venue, '#splash#header'] do
|
||||
#banner
|
||||
#banner{ style: ("background-image: url(#{conference.picture_url})" if conference.picture_url) }
|
||||
.container
|
||||
.row
|
||||
.col-md-8.col-md-offset-2#header
|
||||
.col-md-6.col-md-offset-3{id: (conference.picture? ? "header-image" : "header-no-image")}
|
||||
.row
|
||||
.col-md-4
|
||||
- if conference.picture?
|
||||
= image_tag(conference.picture_url,
|
||||
class: 'img-responsive img-center',
|
||||
id: 'splash-logo')
|
||||
-# - if conference.picture?
|
||||
-# .col-md-4
|
||||
-# = image_tag(conference.picture_url,
|
||||
-# class: 'img-responsive img-center',
|
||||
-# id: 'splash-logo')
|
||||
.col-md-8
|
||||
%h1
|
||||
= conference.title
|
||||
= conference.title.html_safe
|
||||
%h3
|
||||
- if conference.start_date && conference.end_date
|
||||
%span.date.text-nowrap
|
||||
= date_string(conference.start_date, conference.end_date)
|
||||
- if conference.venue
|
||||
%span.venue.text-nowrap
|
||||
- if venue.website
|
||||
- if venue.website.present?
|
||||
= sanitize link_to(venue.name, venue.website)
|
||||
- else
|
||||
= venue.city
|
||||
- if venue.country_name != 'US'
|
||||
- if venue.country != 'US'
|
||||
•
|
||||
= venue.country_name
|
||||
|
||||
|
|
@ -32,3 +32,4 @@
|
|||
.row
|
||||
.col-md-8.col-md-offset-2
|
||||
= markdown(conference.description)
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
.row.row-centered
|
||||
- lodgings.each do |lodging|
|
||||
.col-md-4.col-sm-4.col-centered.col-top
|
||||
.col-md-6.col-sm-4.col-centered.col-top
|
||||
.thumbnail
|
||||
- if lodging.picture?
|
||||
- if lodging.website_link.present?
|
||||
= link_to(lodging.website_link, class: 'thumbnail') do
|
||||
= link_to(lodging.website_link) do
|
||||
= image_tag lodging.picture.large.url,
|
||||
class: 'img-responsive img-lodging'
|
||||
- else
|
||||
|
|
@ -30,12 +30,16 @@
|
|||
- else
|
||||
%p.text-center
|
||||
- if lodging.website_link.present?
|
||||
= link_to(lodging.website_link, class: 'thumbnail') do
|
||||
= link_to(lodging.website_link) do
|
||||
%i.fa.fa-home.fa-5x
|
||||
- else
|
||||
%i.fa.fa-home.fa-5x
|
||||
.caption
|
||||
%h3.text-center
|
||||
= lodging.name
|
||||
- if lodging.website_link.present?
|
||||
= link_to(lodging.name, lodging.website_link)
|
||||
- else
|
||||
= lodging.name
|
||||
- if lodging.description.present?
|
||||
= markdown(lodging.description)
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
.col-md-12
|
||||
%p.lead.text-center
|
||||
%span.notranslate
|
||||
= conference.title
|
||||
has the most awesome program ever!
|
||||
= conference.title.html_safe
|
||||
will have an enaging program!
|
||||
|
||||
- unless highlights.blank?
|
||||
= render 'highlights', conference_id: conference.short_title,
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
= link_to(conference_schedule_path(conference.short_title),
|
||||
class: 'btn btn-success btn-lg') do
|
||||
Full Schedule
|
||||
.trapezoid
|
||||
|
||||
- unless booths.blank?
|
||||
- booths.each do |booth|
|
||||
|
|
|
|||
|
|
@ -37,3 +37,4 @@
|
|||
= link_to('Register Now',
|
||||
new_conference_conference_registration_path(conference_id),
|
||||
class: 'btn btn-lg btn-success')
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -27,3 +27,4 @@
|
|||
- if contact.email?
|
||||
= mail_to "#{ contact.email }" do
|
||||
%i.fa.fa-envelope-o.fa-4x
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -27,9 +27,10 @@
|
|||
.row
|
||||
.col-md-12
|
||||
%h3.text-center
|
||||
Want to sponsor?
|
||||
= "Interested in sponsoring #{conference.title}?"
|
||||
= link_to(sponsorship_mailto(conference)) do
|
||||
Contact us!
|
||||
Please, contact us!
|
||||
.trapezoid
|
||||
|
||||
- sponsors.each do |sponsor|
|
||||
- content_for :modals do
|
||||
|
|
|
|||
|
|
@ -7,19 +7,21 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-12.text-center
|
||||
%h2
|
||||
Support
|
||||
= conference.title
|
||||
%h2 Sign Up for Snap<em>!</em>Con
|
||||
%br
|
||||
-# %h2
|
||||
-# Support
|
||||
-# = conference.title
|
||||
.row.row-centered
|
||||
- tickets.each do |ticket|
|
||||
.col-md-3.col-sm-3.col-centered.col-top
|
||||
= link_to(conference_tickets_path(conference.short_title),
|
||||
class: 'thumbnail') do
|
||||
.col-lg-4.col-md-3.col-sm-3.col-centered.col-top
|
||||
= link_to(conference_tickets_path(conference.short_title), class: 'thumbnail') do
|
||||
.caption
|
||||
%h3.text-center.word_break
|
||||
= ticket.title
|
||||
.word_break
|
||||
= markdown(ticket.description)
|
||||
%button.btn-block.btn.btn-lg.btn-success
|
||||
%i.fa.fa-ticket.fa-fw
|
||||
%i.fa.fa-ticket.fa-fw{"aria-hidden": true}
|
||||
= humanized_money_with_symbol(ticket.price)
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@
|
|||
%section#venue
|
||||
- if venue.location?
|
||||
= render '/conferences/venue_map', venue: venue
|
||||
- if venue.description.present?
|
||||
.container
|
||||
.row
|
||||
.col-md-8.col-md-offset-2
|
||||
= markdown(venue.description, escape_html=false)
|
||||
.trapezoid
|
||||
- else
|
||||
- cache [venue, commercial, '#splash#venue'] do
|
||||
.container
|
||||
|
|
@ -41,3 +47,4 @@
|
|||
- if venue.website
|
||||
%br
|
||||
= sanitize link_to(h(venue.website), h(venue.website))
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
- content_for :head do
|
||||
%meta{ property: "og:title", content: @conference.title }
|
||||
%meta{ property: "og:site_name", content: (ENV['OSEM_NAME'] || 'OSEM') }
|
||||
%meta{ property: "og:description", content: @conference.description }
|
||||
%meta{ property: "og:description", content: plain_text(@conference.description) }
|
||||
%meta{ property: "og:url", content: conference_url(@conference.short_title) }
|
||||
%meta{ property: "twitter:title", content: (@conference.title) }
|
||||
%meta{ property: "twitter:description", content: @conference.description }
|
||||
%meta{ property: "twitter:description", content: plain_text(@conference.description) }
|
||||
- if @conference.picture?
|
||||
%meta{ property: "og:image", content: @image_url }
|
||||
%meta{ property: "og:image:secure_url", content: @image_url }
|
||||
|
|
@ -64,21 +64,22 @@
|
|||
= render 'social_media', contact: @conference.contact
|
||||
= render 'footer'
|
||||
|
||||
- content_for :script_head do
|
||||
:javascript
|
||||
var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic();
|
||||
var triangle_colors = triangle_tcs.map(function(t) {
|
||||
return t.toHexString();
|
||||
});
|
||||
$(function () {
|
||||
$(document).ready(function() {
|
||||
var triangle_width = document.body.clientWidth;
|
||||
var triangle_height = ($( "#banner" ).height() + 200 );
|
||||
var pattern = Trianglify({ width: triangle_width,
|
||||
height: triangle_height,
|
||||
cell_size: 100,
|
||||
x_colors: triangle_colors
|
||||
});
|
||||
$('#banner').css('background-image', 'url("' + pattern.png() + '")');
|
||||
});
|
||||
});
|
||||
|
||||
-# - content_for :script_head do
|
||||
-# :javascript
|
||||
-# var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic();
|
||||
-# var triangle_colors = triangle_tcs.map(function(t) {
|
||||
-# return t.toHexString();
|
||||
-# });
|
||||
-# $(function () {
|
||||
-# $(document).ready(function() {
|
||||
-# var triangle_width = document.body.clientWidth;
|
||||
-# var triangle_height = ($( "#banner" ).height() + 200 );
|
||||
-# var pattern = Trianglify({ width: triangle_width,
|
||||
-# height: triangle_height,
|
||||
-# cell_size: 100,
|
||||
-# x_colors: triangle_colors
|
||||
-# });
|
||||
-# $('#banner').css('background-image', 'url(' + 0 + ')');
|
||||
-# });
|
||||
-# });
|
||||
|
|
|
|||
|
|
@ -1,7 +1,16 @@
|
|||
.text-center
|
||||
.btn-group.btn-group-lg#openid-btn-grp
|
||||
- omniauth_configured.each do |provider|
|
||||
= link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg",
|
||||
id: "omniauth-#{provider}",
|
||||
title: "Your #{provider} login" do
|
||||
%i{class: "fa fa-#{provider}"}
|
||||
- if provider != :discourse
|
||||
= link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg",
|
||||
id: "omniauth-#{provider}",
|
||||
title: "Your #{provider} login" do
|
||||
%i{class: "fa fa-#{provider}"}
|
||||
- else
|
||||
= link_to("user_#{provider}_omniauth_authorize".to_sym,
|
||||
class: "btn btn-success btn-lg",
|
||||
id: "omniauth-#{provider}",
|
||||
title: "Your #{provider} login") do
|
||||
%span
|
||||
Snap
|
||||
%em> !
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
- if ENV['OSEM_ICHAIN_ENABLED'] != 'true'
|
||||
= form_tag(new_user_session_path, class: 'form-horizontal') do
|
||||
%legend
|
||||
%span
|
||||
Sign In
|
||||
.form-group
|
||||
%label{for: "user[login]", class: 'col-sm-2 control-label'}
|
||||
Username
|
||||
.col-sm-10
|
||||
= text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required'
|
||||
.form-group
|
||||
%label{for: "user[password]", class: 'col-sm-2 control-label'}
|
||||
Password
|
||||
.col-sm-10
|
||||
= password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required'
|
||||
.form-group
|
||||
.col-sm-12
|
||||
%button.btn.btn-success.pull-right
|
||||
Sign in
|
||||
= render partial: 'devise/shared/openid'
|
||||
%p.text-right
|
||||
%a.small.btn.btn-default{"data-toggle" => "collapse", "data-target" => "#devise-help-sign-in"}
|
||||
Need Help?
|
||||
#devise-help-sign-in.collapse
|
||||
= render partial: 'devise/shared/links'
|
||||
.container.panel
|
||||
= form_tag(new_user_session_path, class: '') do
|
||||
%legend
|
||||
%span
|
||||
Sign In
|
||||
.form-group
|
||||
%label{for: "user[login]", class: 'col-sm-2 control-label'}
|
||||
Username
|
||||
.col-sm-10
|
||||
= text_field_tag 'user[login]', nil, placeholder: 'Username', class: 'form-control', required: 'required'
|
||||
.form-group
|
||||
%label{for: "user[password]", class: 'col-sm-2 control-label'}
|
||||
Password
|
||||
.col-sm-10
|
||||
= password_field_tag 'user[password]', nil, placeholder: 'Password', class: 'form-control', required: 'required'
|
||||
.form-group
|
||||
.col-sm-12
|
||||
%button.btn.btn-success.pull-right
|
||||
Sign in
|
||||
= render partial: 'devise/shared/openid'
|
||||
%p.text-right
|
||||
%a.small.btn.btn-default{"data-toggle" => "collapse", "data-target" => "#devise-help-sign-in"}
|
||||
Need Help?
|
||||
#devise-help-sign-in.collapse
|
||||
= render partial: 'devise/shared/links'
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
= link_to 'Contact', edit_admin_conference_contact_path(@conference.short_title)
|
||||
- if can? :index, @conference.commercials.build
|
||||
%li{class: "#{active_nav_li(admin_conference_commercials_path(@conference.short_title))}"}
|
||||
= link_to 'Commercials', admin_conference_commercials_path(@conference.short_title)
|
||||
= link_to 'Materials', admin_conference_commercials_path(@conference.short_title)
|
||||
- if can? :update, @conference
|
||||
%li{class: active_nav_li(edit_admin_conference_splashpage_path(@conference.short_title))}
|
||||
= link_to 'Splashpage', admin_conference_splashpage_path(@conference.short_title)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
.navbar.navbar-default.navbar-fixed-top.nav-osem{role: 'navigation'}
|
||||
%nav.navbar.navbar-default.navbar-fixed-top.nav-osem{role: 'navigation'}
|
||||
.container
|
||||
.navbar-header
|
||||
|
||||
- if controller.class.name.split("::").first=="Admin"
|
||||
%button{ "data-target"=>"#side-nav", "data-toggle"=>"collapse", class: 'navbar-toggle side-nav-btn', type: 'button' }
|
||||
%span.sr-only Toggle navigation
|
||||
|
|
@ -14,7 +13,7 @@
|
|||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
= nav_root_link_for conference
|
||||
= nav_root_link_for(conference)
|
||||
|
||||
.collapse.navbar-collapse#main-nav
|
||||
- if content_for :splash_nav
|
||||
|
|
@ -42,34 +41,41 @@
|
|||
= link_to(new_registration_path('user')) do
|
||||
%span.fa.fa-heart
|
||||
Sign Up
|
||||
%li.dropdown.visible-desktop
|
||||
%a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'}
|
||||
%span.fa.fa-user
|
||||
Sign In
|
||||
%span.caret
|
||||
.dropdown-menu
|
||||
- if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
||||
= form_tag User.ichain_login_url do
|
||||
= text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username'
|
||||
= password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password'
|
||||
%button.btn.btn-success.btn-block Sign in
|
||||
- else
|
||||
= form_tag new_user_session_path do
|
||||
= text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail'
|
||||
= password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password'
|
||||
%p.text-right
|
||||
%small
|
||||
%label{for: 'user_remember_me'} Remember me
|
||||
= check_box_tag 'user[remember_me]'
|
||||
%button.btn.btn-success.btn-block Sign in
|
||||
- unless omniauth_configured.empty?
|
||||
.divider
|
||||
%h6.text-center
|
||||
or
|
||||
= render 'devise/shared/openid_links'
|
||||
%p.text-right
|
||||
%br
|
||||
%a.small.btn.btn-xs.btn-default{"data-toggle" => "collapse", "data-target" => "#navbar-devise-help"}
|
||||
Need Help?
|
||||
#navbar-devise-help.collapse
|
||||
= render 'devise/shared/links'
|
||||
%li{class: ""}
|
||||
= link_to(sign_in_path) do
|
||||
%span.fa.fa-user
|
||||
Sign In
|
||||
-# %li.dropdown.visible-desktop
|
||||
-# %a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'}
|
||||
-# %span.fa.fa-user
|
||||
-# Sign In
|
||||
-# %span.caret
|
||||
-# .dropdown-menu
|
||||
-# - if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
||||
-# = form_tag User.ichain_login_url do
|
||||
-# = text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username'
|
||||
-# = password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password'
|
||||
-# %button.btn.btn-success.btn-block Sign in
|
||||
-# - else
|
||||
-# %div{style: "padding: 6px"}
|
||||
-# = form_tag new_user_session_path, class: 'form-group' do
|
||||
-# = text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail'
|
||||
-# = password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password'
|
||||
-# %p.text-right
|
||||
-# %small
|
||||
-# %label{for: 'user_remember_me'} Remember me
|
||||
-# = check_box_tag 'user[remember_me]'
|
||||
-# %br
|
||||
-# %button.btn.btn-success.btn-block Sign in
|
||||
-# - unless omniauth_configured.empty?
|
||||
-# .divider
|
||||
-# %h6.text-center
|
||||
-# or
|
||||
-# = render 'devise/shared/openid_links'
|
||||
-# %p.text-right
|
||||
-# %br
|
||||
-# %a.small.btn.btn-xs.btn-default{"data-toggle" => "collapse", "data-target" => "#navbar-devise-help"}
|
||||
-# Need Help?
|
||||
-# #navbar-devise-help.collapse
|
||||
-# = render 'devise/shared/links'
|
||||
.trapezoid
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
%html{xmlns: 'http://www.w3.org/1999/html'}
|
||||
%html{lang: 'en'}
|
||||
%head
|
||||
%meta{charset: 'utf-8'}
|
||||
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'}
|
||||
%title= content_for?(:title) ? yield(:title) : (ENV['OSEM_NAME'] || 'OSEM')
|
||||
%meta{content: '', name: 'description'}
|
||||
%meta{content: '', name: 'author'}
|
||||
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1'}
|
||||
%title= content_for?(:title) ? strip_tags( yield(:title) ) : (ENV['OSEM_NAME'] || 'OSEM')
|
||||
%meta{content: 'Snap!Con -- A conference all about Snap!, a programing language from UC Berkeley.', name: 'description'}
|
||||
%meta{content: 'Michael Ball, Brian Harvey, Jens Moenig, Bernat Romagosa, Dan Garcia, Lauren Mock', name: 'author'}
|
||||
= stylesheet_link_tag "application", media: 'all'
|
||||
= javascript_include_tag "application"
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
-# Admin area
|
||||
- if controller.class.name.split("::").first=="Admin"
|
||||
= render 'layouts/admin'
|
||||
-else
|
||||
- else
|
||||
#messages
|
||||
.container
|
||||
= render 'layouts/messages'
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
#{link_to "MIT license", "http://opensource.org/licenses/MIT"}.
|
||||
You can run, copy, distribute, study, change and improve it.
|
||||
The source code and the developers are on
|
||||
#{link_to "GitHub", "https://github.com/openSUSE/osem"}.
|
||||
#{link_to "GitHub", "https://github.com/snap-cloud/snapcon"}. This site is a modification of #{link_to "OSEM", "https://github.com/openSUSE/osem"}.
|
||||
- if ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"].present?
|
||||
Performance data is available on
|
||||
#{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.div
|
||||
.col-md-12.table-responsive
|
||||
%table.table.table-hover
|
||||
%table.table.table-hover.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Ticket
|
||||
|
|
@ -20,8 +20,13 @@
|
|||
= humanized_money_with_symbol ticket.quantity * ticket.price
|
||||
|
||||
= form_tag conference_payments_path do
|
||||
%script.stripe-button{ src: "https://checkout.stripe.com/checkout.js",
|
||||
data: { amount: @total_amount_to_pay.cents, label: "Pay #{humanized_money_with_symbol @total_amount_to_pay}",
|
||||
email: current_user.email, currency: @total_amount_to_pay.currency, name: ENV['OSEM_NAME'] || 'OSEM',
|
||||
description: "book your tickets", key: Rails.application.secrets.stripe_publishable_key, locale: "auto"}}
|
||||
= link_to 'Edit Purchase', conference_tickets_path(@conference.short_title), class: 'btn btn-default'
|
||||
%script.stripe-button{'src': "https://checkout.stripe.com/checkout.js",
|
||||
'data': {amount: @total_amount_to_pay.cents,
|
||||
label: "Pay #{humanized_money_with_symbol @total_amount_to_pay}",
|
||||
email: current_user.email,
|
||||
currency: @total_amount_to_pay.currency,
|
||||
name: ENV['OSEM_NAME'] || 'OSEM',
|
||||
description: "#{ENV['OSEM_NAME']} tickets",
|
||||
key: ENV['STRIPE_PUBLISHABLE_KEY'] || Rails.application.secrets.stripe_publishable_key, locale: "auto"}}
|
||||
= link_to('Edit Purchase', conference_tickets_path(@conference.short_title),
|
||||
class: 'btn btn-default')
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
%th ID
|
||||
%th Type
|
||||
%th User
|
||||
%th Registration?
|
||||
%th Actions
|
||||
%tbody
|
||||
- @physical_tickets.each do |physical_ticket|
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
%td= physical_ticket.id
|
||||
%td= physical_ticket.ticket.title
|
||||
%td= physical_ticket.user.name
|
||||
%td= physical_ticket.ticket.registration_ticket? ? 'Yes' : 'No'
|
||||
%td
|
||||
.btn-group
|
||||
= link_to 'Show',
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
%li.active
|
||||
= link_to 'Proposal', '#proposal-content', 'data-toggle' => 'tab'
|
||||
%li
|
||||
= link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab'
|
||||
= link_to 'Materials', '#commercials-content', 'data-toggle' => 'tab'
|
||||
.tab-content
|
||||
#proposal-content.tab-pane.active
|
||||
= render 'proposals/proposal_form'
|
||||
#commercials-content.tab-pane
|
||||
%p.text-muted
|
||||
You can add commercials for your proposal. These commercials will be displayed on the
|
||||
You can add materals for your proposal. These materials will be displayed on the
|
||||
= link_to 'public proposal page.', conference_program_proposal_path(@conference.short_title, @event)
|
||||
If you don't add a commercial, the conference commercial will be displayed!
|
||||
If you don't add any materials, the conference materials will be displayed.
|
||||
- if can? :create, @event.commercials.new
|
||||
.row
|
||||
.col-md-6
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
= link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event)
|
||||
%li{'class'=>class_for_todo(progress_status['commercials'])}
|
||||
%span{'class'=>icon_for_todo(progress_status['commercials'])}
|
||||
= link_to 'Add a commercial', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content')
|
||||
= link_to 'Add materials', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content')
|
||||
- unless progress_status['track'].nil?
|
||||
%li{'class'=>class_for_todo(progress_status['track'])}
|
||||
%span{'class'=>icon_for_todo(progress_status['track'])}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
- if @program.cfp.description.present?
|
||||
.row
|
||||
.col-md-12
|
||||
= markdown(@program.cfp.description)
|
||||
= markdown(@program.cfp.description, escape_html=false)
|
||||
.row
|
||||
.col-md-12
|
||||
= render partial: 'encouragement_text'
|
||||
|
|
@ -43,10 +43,10 @@
|
|||
|
||||
- @program.event_types.each do |event_type|
|
||||
%span{ class: 'help-block event_event_type_id collapse', id: "#{event_type.id}-help" }
|
||||
= event_type.description
|
||||
= markdown(event_type.description)
|
||||
|
||||
= f.input :abstract, required: true, input_html: { rows: 5, data: { provide: 'markdown-editable' } },
|
||||
hint: markdown_hint('[Tips to improve your presentations.](http://blog.hubspot.com/blog/tabid/6307/bid/5975/10-Rules-to-Instantly-Improve-Your-Presentations.aspx)')
|
||||
hint: markdown_hint
|
||||
|
||||
%p
|
||||
You have used
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
.media
|
||||
.media-body
|
||||
%h4.media-heading= ticket.title
|
||||
%h5.media-heading= markdown(ticket.description)
|
||||
- if @conference.tickets.for_registration.any?
|
||||
%td.col-sm-1.col-md-2.text-center
|
||||
.media-heading= markdown(ticket.description)
|
||||
%td.col-sm-1.col-md-2
|
||||
%span.text-center
|
||||
= ticket.registration_ticket? ? 'Yes' : 'No'
|
||||
%td.col-sm-1.col-md-1
|
||||
:ruby
|
||||
|
|
|
|||
|
|
@ -13,18 +13,16 @@
|
|||
%thead
|
||||
%tr
|
||||
%th Ticket
|
||||
- if @conference.tickets.for_registration.any?
|
||||
%th Registration Ticket
|
||||
%th Registration?
|
||||
%th Quantity
|
||||
%th Price
|
||||
%th Total
|
||||
%tbody
|
||||
- @conference.tickets.each do |ticket|
|
||||
- @conference.tickets.visible.each do |ticket|
|
||||
= render 'ticket', f: f, ticket: ticket
|
||||
%tr
|
||||
%td
|
||||
- if @conference.tickets.for_registration.any?
|
||||
%td
|
||||
%td
|
||||
%td
|
||||
%td.col-sm-1.col-md-1.text-center
|
||||
%h4
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
bundle install
|
||||
# Setup the app if it isn't already setup
|
||||
bundle exec rake db:bootstrap
|
||||
# Start the app
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -6,12 +6,25 @@ Devise.setup do |config|
|
|||
# Define the available openID providers that can be used to log in
|
||||
# Pass each provider to User model in :omniauth_providers (for open_id providers use their name)
|
||||
|
||||
config.omniauth :open_id, name: 'suse', identifier: 'http://www.opensuse.org/openid/user'
|
||||
config.omniauth :google_oauth2, (ENV['OSEM_GOOGLE_KEY'] || Rails.application.secrets.google_key), (ENV['OSEM_GOOGLE_SECRET'] || Rails.application.secrets.google_secret),
|
||||
# config.omniauth :open_id, name: 'suse', identifier: 'http://www.opensuse.org/openid/user'
|
||||
|
||||
config.omniauth :google_oauth2,
|
||||
(ENV['OSEM_GOOGLE_KEY'] || Rails.application.secrets.google_key),
|
||||
(ENV['OSEM_GOOGLE_SECRET'] || Rails.application.secrets.google_secret),
|
||||
name: 'google',
|
||||
scope: 'email'
|
||||
config.omniauth :facebook, (ENV['OSEM_FACEBOOK_KEY'] || Rails.application.secrets.facebook_key), (ENV['OSEM_FACEBOOK_SECRET'] || Rails.application.secrets.facebook_secret)
|
||||
config.omniauth :github, (ENV['OSEM_GITHUB_KEY'] || Rails.application.secrets.github_key), (ENV['OSEM_GITHUB_SECRET'] || Rails.application.secrets.github_secret)
|
||||
|
||||
config.omniauth :discourse,
|
||||
sso_url: 'https://forum.snap.berkeley.edu/session/sso_provider',
|
||||
sso_secret: ENV['OSEM_DISCOURSE_SECRET']
|
||||
|
||||
config.omniauth :facebook,
|
||||
(ENV['OSEM_FACEBOOK_KEY'] || Rails.application.secrets.facebook_key),
|
||||
(ENV['OSEM_FACEBOOK_SECRET'] || Rails.application.secrets.facebook_secret)
|
||||
|
||||
config.omniauth :github,
|
||||
(ENV['OSEM_GITHUB_KEY'] || Rails.application.secrets.github_key),
|
||||
(ENV['OSEM_GITHUB_SECRET'] || Rails.application.secrets.github_secret)
|
||||
|
||||
# ==> Mailer Configuration
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
|
|
|
|||
4
config/initializers/sentry.rb
Normal file
4
config/initializers/sentry.rb
Normal 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
|
||||
|
|
@ -1 +1 @@
|
|||
Stripe.api_key = Rails.application.secrets.stripe_secret_key
|
||||
Stripe.api_key = ENV['STRIPE_SECRET_KEY'] || Rails.application.secrets.stripe_secret_key
|
||||
|
|
|
|||
|
|
@ -43,5 +43,16 @@ on_worker_boot do
|
|||
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
|
||||
end
|
||||
|
||||
lowlevel_error_handler do |ex, env|
|
||||
Raven.capture_exception(
|
||||
ex,
|
||||
:message => ex.message,
|
||||
:extra => { :puma => env },
|
||||
:transaction => "Puma"
|
||||
)
|
||||
# note the below is just a Rack response
|
||||
[500, {}, ["An error has occurred, and engineers have been informed. Please reload the page. If you continue to have problems, contact conference@snap.berkeley.edu\n"]]
|
||||
end
|
||||
|
||||
# Allow puma to be restarted by `rails restart` command.
|
||||
plugin :tmp_restart
|
||||
|
|
|
|||
|
|
@ -115,7 +115,11 @@ Osem::Application.routes.draw do
|
|||
end
|
||||
|
||||
resources :resources
|
||||
resources :tickets
|
||||
resources :tickets do
|
||||
member do
|
||||
post :give
|
||||
end
|
||||
end
|
||||
resources :sponsors, except: [:show]
|
||||
resources :lodgings, except: [:show]
|
||||
resources :emails, only: [:show, :update, :index]
|
||||
|
|
|
|||
11
db/migrate/20180409170433_add_visible_to_tickets.rb
Normal file
11
db/migrate/20180409170433_add_visible_to_tickets.rb
Normal 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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
class RemoveArrivalDepartureFromRegistrations < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
remove_column :registrations, :arrival, :datetime
|
||||
remove_column :registrations, :departure, :datetime
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,10 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20181113195810) do
|
||||
ActiveRecord::Schema.define(version: 2018_12_29_233811) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
create_table "answers", force: :cascade do |t|
|
||||
t.string "title"
|
||||
|
|
@ -364,8 +367,6 @@ ActiveRecord::Schema.define(version: 20181113195810) do
|
|||
|
||||
create_table "registrations", force: :cascade do |t|
|
||||
t.integer "conference_id"
|
||||
t.datetime "arrival"
|
||||
t.datetime "departure"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.text "other_special_needs"
|
||||
|
|
@ -530,6 +531,7 @@ ActiveRecord::Schema.define(version: 20181113195810) do
|
|||
t.boolean "registration_ticket", default: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.boolean "visible", default: true
|
||||
end
|
||||
|
||||
create_table "tracks", force: :cascade do |t|
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
|
||||
#
|
||||
# To ban all spiders from the entire site uncomment the next two lines:
|
||||
# User-Agent: *
|
||||
# Disallow: /
|
||||
User-Agent: *
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
|
|
|||
257
spec/controllers/admin/tickets_controller_spec.rb
Normal file
257
spec/controllers/admin/tickets_controller_spec.rb
Normal 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
|
||||
|
|
@ -290,14 +290,15 @@ describe ConferenceRegistrationsController, type: :controller do
|
|||
before do
|
||||
@registration = create(:registration,
|
||||
conference: conference,
|
||||
user: user,
|
||||
arrival: Date.new(2014, 04, 25))
|
||||
user: user)
|
||||
end
|
||||
|
||||
context 'updates successfully' do
|
||||
before do
|
||||
patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)),
|
||||
conference_id: conference.short_title }
|
||||
patch :update, params: {
|
||||
registration: attributes_for(:registration, volunteer: true),
|
||||
conference_id: conference.short_title
|
||||
}
|
||||
end
|
||||
|
||||
it 'redirects to registration show path' do
|
||||
|
|
@ -309,16 +310,17 @@ describe ConferenceRegistrationsController, type: :controller do
|
|||
end
|
||||
|
||||
it 'updates the registration' do
|
||||
@registration.reload
|
||||
expect(@registration.arrival).to eq Date.new(2014, 04, 29)
|
||||
expect{ @registration.reload }.to change(@registration, :updated_at)
|
||||
end
|
||||
end
|
||||
|
||||
context 'update fails' do
|
||||
before do
|
||||
allow_any_instance_of(Registration).to receive(:update_attributes).and_return(false)
|
||||
patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 27)),
|
||||
conference_id: conference.short_title }
|
||||
patch :update, params: {
|
||||
registration: attributes_for(:registration, volunteer: true),
|
||||
conference_id: conference.short_title
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders edit template' do
|
||||
|
|
@ -331,7 +333,7 @@ describe ConferenceRegistrationsController, type: :controller do
|
|||
|
||||
it 'does not update the registration' do
|
||||
@registration.reload
|
||||
expect(@registration.arrival).to eq Date.new(2014, 04, 25)
|
||||
expect { @registration.reload }.not_to change(@registration, :updated_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ FactoryBot.define do
|
|||
title { "#{Faker::Hipster.word} Ticket" }
|
||||
price_cents { 1000 }
|
||||
price_currency { 'USD' }
|
||||
visible { true }
|
||||
factory :registration_ticket do
|
||||
registration_ticket { true }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ feature Commercial do
|
|||
|
||||
# Create valid commercial
|
||||
fill_in 'commercial_url', with: 'https://www.youtube.com/watch?v=M9bq_alk-sw'
|
||||
click_button 'Create Commercial'
|
||||
click_button 'Save Materials'
|
||||
page.find('#flash')
|
||||
expect(flash).to eq('Commercial was successfully created.')
|
||||
expect(flash).to eq('Materials were successfully created.')
|
||||
page.find('#flash .button.close').click
|
||||
expect(conference.commercials.count).to eq(1)
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ feature Commercial do
|
|||
fill_in "commercial_url_#{commercial.id}", with: 'https://www.youtube.com/watch?v=VNkDJk5_9eU'
|
||||
click_button 'Update'
|
||||
page.find('#flash')
|
||||
expect(flash).to eq('Commercial was successfully updated.')
|
||||
expect(flash).to eq('Materials were successfully updated.')
|
||||
page.find('#flash .button.close').click
|
||||
expect(conference.commercials.count).to eq(1)
|
||||
commercial.reload
|
||||
|
|
@ -39,7 +39,7 @@ feature Commercial do
|
|||
click_link 'Delete'
|
||||
end
|
||||
page.find('#flash')
|
||||
expect(flash).to eq('Commercial was successfully destroyed.')
|
||||
expect(flash).to eq('Materials were successfully destroyed.')
|
||||
expect(conference.commercials.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
|
@ -56,23 +56,23 @@ feature Commercial do
|
|||
|
||||
scenario 'adds a valid commercial of an event', feature: true, js: true do
|
||||
visit edit_conference_program_proposal_path(conference.short_title, event.id)
|
||||
click_link 'Commercials'
|
||||
click_link 'Materials'
|
||||
fill_in 'commercial_url', with: 'https://www.youtube.com/watch?v=M9bq_alk-sw'
|
||||
|
||||
# Workaround to enable the 'Create Commercial' button
|
||||
# Workaround to enable the 'Save Materials' button
|
||||
page.execute_script("$('#commercial_submit_action').prop('disabled', false)")
|
||||
|
||||
click_button 'Create Commercial'
|
||||
click_button 'Save Materials'
|
||||
page.find('#flash')
|
||||
expect(flash).to eq('Commercial was successfully created.')
|
||||
expect(flash).to eq('Materials were successfully created.')
|
||||
end
|
||||
|
||||
scenario 'does not add an invalid commercial of an event', feature: true, js: true do
|
||||
visit edit_conference_program_proposal_path(conference.short_title, event.id)
|
||||
click_link 'Commercials'
|
||||
click_link 'Materials'
|
||||
fill_in 'commercial_url', with: 'invalid_commercial_url'
|
||||
expect(page).to have_content('No embeddable content')
|
||||
expect(page).to have_css("button[type='submit']:disabled", text: 'Create Commercial')
|
||||
expect(page).to have_css("button[type='submit']:disabled", text: 'Save Materials')
|
||||
end
|
||||
|
||||
scenario 'updates a commercial of an event', feature: true, js: true do
|
||||
|
|
@ -80,11 +80,11 @@ feature Commercial do
|
|||
commercialable_id: event.id,
|
||||
commercialable_type: 'Event')
|
||||
visit edit_conference_program_proposal_path(conference.short_title, event.id)
|
||||
click_link 'Commercials'
|
||||
click_link 'Materials'
|
||||
fill_in "commercial_url_#{commercial.id}", with: 'https://www.youtube.com/watch?v=M9bq_alk-sw'
|
||||
click_button 'Update'
|
||||
page.find('#flash')
|
||||
expect(flash).to eq('Commercial was successfully updated.')
|
||||
expect(flash).to eq('Materials were successfully updated.')
|
||||
TransactionalCapybara::AjaxHelpers.wait_for_ajax(page)
|
||||
expect(event.commercials.count).to eq(1)
|
||||
commercial.reload
|
||||
|
|
@ -97,12 +97,12 @@ feature Commercial do
|
|||
commercialable_type: 'Event',
|
||||
url: 'https://www.youtube.com/watch?v=BTTygyxuGj8')
|
||||
visit edit_conference_program_proposal_path(conference.short_title, event.id)
|
||||
click_link 'Commercials'
|
||||
click_link 'Materials'
|
||||
fill_in "commercial_url_#{commercial.id}", with: 'invalid_commercial_url'
|
||||
click_button 'Update'
|
||||
find('#flash')
|
||||
expect(current_path).to eq edit_conference_program_proposal_path(conference.short_title, event.id)
|
||||
expect(flash).to include('An error prohibited this Commercial from being saved:')
|
||||
expect(flash).to include('An error prohibited materials from being saved:')
|
||||
commercial.reload
|
||||
expect(commercial.url).to eq('https://www.youtube.com/watch?v=BTTygyxuGj8')
|
||||
end
|
||||
|
|
@ -112,12 +112,12 @@ feature Commercial do
|
|||
commercialable_id: event.id,
|
||||
commercialable_type: 'Event')
|
||||
visit edit_conference_program_proposal_path(conference.short_title, event.id)
|
||||
click_link 'Commercials'
|
||||
click_link 'Materials'
|
||||
page.accept_alert do
|
||||
click_link 'Delete'
|
||||
end
|
||||
page.find('#flash')
|
||||
expect(flash).to eq('Commercial was successfully destroyed.')
|
||||
expect(flash).to eq('Materials were successfully destroyed.')
|
||||
TransactionalCapybara::AjaxHelpers.wait_for_ajax(page)
|
||||
expect(event.commercials.count).to eq(0)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ feature Conference do
|
|||
sign_in user
|
||||
visit admin_conference_path(conference.short_title)
|
||||
|
||||
expect(find('.navbar-brand').text).to eq(conference.organization.name)
|
||||
# expect(find('.navbar-brand')).to eq(conference.organization.name)
|
||||
expect(find('.navbar-brand img')['alt']).to have_content conference.organization.name
|
||||
end
|
||||
|
||||
it_behaves_like 'add and update conference'
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ feature 'Has correct abilities' do
|
|||
expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit")
|
||||
expect(page).to have_text('Basics')
|
||||
expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit")
|
||||
expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials")
|
||||
expect(page).to have_link('Materials', href: "/admin/conferences/#{conference.short_title}/commercials")
|
||||
expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage")
|
||||
expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings")
|
||||
expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period")
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ feature 'Has correct abilities' do
|
|||
expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard')
|
||||
expect(page).to have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit")
|
||||
expect(page).to have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit")
|
||||
expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials")
|
||||
expect(page).to have_link('Materials', href: "/admin/conferences/#{conference.short_title}/commercials")
|
||||
expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage")
|
||||
expect(page).to have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue")
|
||||
expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms")
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue