Merge branch 'master' into master

This commit is contained in:
James Mason 2017-12-22 11:15:47 -08:00 • committed by GitHub
commit fb96655741
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
98 changed files with 1198 additions and 755 deletions

15
.github/ISSUE_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,15 @@
**I'm submitting a ..**
- [ ] Bug Report
- [ ] Feature Request
**Current behavior:**
<!-- Describe the bug -->
**Expected correct behavior:**
<!-- Describe what should happen, without the bug. -->
**Steps to reproduce:**
<!-- If you are able to illustrate the bug or feature request with an example, please provide steps to reproduce it. -->
**Other information:**
<!-- List any other information that is relevant to your issue. Stack traces, related issues, suggestions on how to fix, Stack Overflow links, forum links, etc. -->

19
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,19 @@
**Checklist**
- [ ] I have read the [Contribution & Best practices Guide](https://github.com/openSUSE/osem/blob/master/CONTRIBUTING.md).
- [ ] My branch is up-to-date with the upstream `master` branch.
- [ ] The tests pass locally with my changes.
- [ ] I have added tests that prove my fix is effective or that my feature works(if appropriate).
- [ ] I have added necessary documentation (if appropriate).
**Short description of what this resolves/which [issues](https://github.com/openSUSE/osem/issues) does this fix?:**
<!-- List the issue number resolved with this change; if there is no open issue, describe the problem this request solves -->
-
**Changes proposed in this pull request:**
<!-- Summarize the changes, using declarative language. -->
-

View file

@ -121,20 +121,9 @@ linters:
- "app/views/conference_registrations/_registration_info.html.haml" - "app/views/conference_registrations/_registration_info.html.haml"
- "app/views/conference_registrations/_volunteer.html.haml" - "app/views/conference_registrations/_volunteer.html.haml"
- "app/views/conference_registrations/show.html.haml" - "app/views/conference_registrations/show.html.haml"
- "app/views/conferences/_booths.html.haml"
- "app/views/conferences/_call_for_paper.html.haml"
- "app/views/conferences/_conference_details.html.haml" - "app/views/conferences/_conference_details.html.haml"
- "app/views/conferences/_gallery.html.haml" - "app/views/conferences/_gallery.html.haml"
- "app/views/conferences/_lodging.html.haml"
- "app/views/conferences/_program.html.haml"
- "app/views/conferences/_registration.html.haml"
- "app/views/conferences/_schedule_splashpage.html.haml"
- "app/views/conferences/_sponsors.html.haml"
- "app/views/conferences/_tickets.html.haml"
- "app/views/conferences/_venue.html.haml"
- "app/views/conferences/_venue_map.html.haml"
- "app/views/conferences/index.html.haml" - "app/views/conferences/index.html.haml"
- "app/views/conferences/show.html.haml"
- "app/views/devise/confirmations/new.html.haml" - "app/views/devise/confirmations/new.html.haml"
- "app/views/devise/ichain_sessions/new.html.haml" - "app/views/devise/ichain_sessions/new.html.haml"
- "app/views/devise/ichain_sessions/new_test.html.haml" - "app/views/devise/ichain_sessions/new_test.html.haml"

View file

@ -376,15 +376,6 @@ Naming/VariableNumber:
Exclude: Exclude:
- 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_purchase_spec.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect.
Performance/HashEachMethods:
Exclude:
- 'app/controllers/admin/conferences_controller.rb'
- 'app/helpers/application_helper.rb'
- 'db/migrate/20140701123203_add_events_per_week_to_conference.rb'
- 'spec/factories/event_users.rb'
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
@ -422,6 +413,7 @@ Style/DateTime:
- 'app/models/conference.rb' - 'app/models/conference.rb'
- 'app/models/program.rb' - 'app/models/program.rb'
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
- 'spec/models/program_spec.rb'
# Offense count: 488 # Offense count: 488
Style/Documentation: Style/Documentation:

View file

@ -82,7 +82,7 @@ You can read through current enabled rules in `.rubocop.yml` file. Explanations
Additionally you can read through the [ruby style-guide](https://github.com/bbatsov/ruby-style-guide) to better understand core principles. Additionally you can read through the [ruby style-guide](https://github.com/bbatsov/ruby-style-guide) to better understand core principles.
### Test Suite ### Test Suite
We are using [rspec](http://rspec.info/)+[capybara](http://jnicklas.github.io/capybara/)+[factory girl](https://github.com/thoughtbot/factory_girl) as a test suite. You can run it locally We are using [rspec](http://rspec.info/)+[capybara](http://teamcapybara.github.io/capybara/)+[factory girl](https://github.com/thoughtbot/factory_girl) as a test suite. You can run it locally
```shell ```shell
vagrant exec bundle exec rspec vagrant exec bundle exec rspec

View file

@ -179,7 +179,7 @@ gem 'acts_as_list'
gem 'bootstrap-switch-rails', '~> 3.0.0' gem 'bootstrap-switch-rails', '~> 3.0.0'
# for parsing OEmbed data # for parsing OEmbed data
gem 'ruby-oembed' gem 'ruby-oembed', '~>0.12.0'
# for uploading images to the cloud # for uploading images to the cloud
gem 'cloudinary' gem 'cloudinary'
@ -214,6 +214,9 @@ gem 'selectize-rails'
# CVE-2017-9049, CVE-2017-9050 # CVE-2017-9049, CVE-2017-9050
gem 'nokogiri', '>= 1.8.1' gem 'nokogiri', '>= 1.8.1'
# memcached binary connector
gem 'dalli'
# Use guard and spring for testing in development # Use guard and spring for testing in development
group :development do group :development do
# to launch specs when files are modified # to launch specs when files are modified

View file

@ -145,6 +145,7 @@ GEM
safe_yaml (~> 1.0.0) safe_yaml (~> 1.0.0)
currencies (0.4.2) currencies (0.4.2)
daemons (1.1.9) daemons (1.1.9)
dalli (2.7.6)
dante (0.2.0) dante (0.2.0)
database_cleaner (1.3.0) database_cleaner (1.3.0)
debug_inspector (0.0.3) debug_inspector (0.0.3)
@ -292,7 +293,7 @@ GEM
multi_json (1.12.1) multi_json (1.12.1)
multi_xml (0.5.5) multi_xml (0.5.5)
multipart-post (2.0.0) multipart-post (2.0.0)
mysql2 (0.4.9) mysql2 (0.4.10)
nenv (0.3.0) nenv (0.3.0)
netrc (0.11.0) netrc (0.11.0)
nio4r (2.1.0) nio4r (2.1.0)
@ -479,7 +480,7 @@ GEM
rainbow (>= 2.2.2, < 3.0) rainbow (>= 2.2.2, < 3.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1) unicode-display_width (~> 1.0, >= 1.0.1)
ruby-oembed (0.8.14) ruby-oembed (0.12.0)
ruby-openid (2.5.0) ruby-openid (2.5.0)
ruby-progressbar (1.9.0) ruby-progressbar (1.9.0)
ruby_dep (1.5.0) ruby_dep (1.5.0)
@ -597,6 +598,7 @@ DEPENDENCIES
country_select country_select
coveralls coveralls
daemons daemons
dalli
database_cleaner database_cleaner
delayed_job_active_record delayed_job_active_record
devise devise
@ -662,7 +664,7 @@ DEPENDENCIES
rspec-activemodel-mocks rspec-activemodel-mocks
rspec-rails (~> 3.5, >= 3.5.2) rspec-rails (~> 3.5, >= 3.5.2)
rubocop (~> 0.51.0) rubocop (~> 0.51.0)
ruby-oembed ruby-oembed (~> 0.12.0)
sass-rails (>= 4.0.2) sass-rails (>= 4.0.2)
selectize-rails selectize-rails
shoulda-matchers shoulda-matchers

View file

@ -98,6 +98,9 @@ $(function () {
$("#registration-period-start-datepicker").on("dp.change",function (e) { $("#registration-period-start-datepicker").on("dp.change",function (e) {
$('#registration-period-end-datepicker').data("DateTimePicker").setMinDate(e.date); $('#registration-period-end-datepicker').data("DateTimePicker").setMinDate(e.date);
if (!$('#registration-period-end-datepicker').val()) {
$('#registration-period-end-datepicker').data("DateTimePicker").setDate(e.date);
}
}); });
$("#registration-period-end-datepicker").on("dp.change",function (e) { $("#registration-period-end-datepicker").on("dp.change",function (e) {
$('#registration-period-start-datepicker').data("DateTimePicker").setMaxDate(e.date); $('#registration-period-start-datepicker').data("DateTimePicker").setMaxDate(e.date);

View file

@ -2,20 +2,20 @@
@if $class == xs { @if $class == xs {
@media (max-width: 767px) { @content; } @media (max-width: 767px) { @content; }
} }
@else if $class == sm { @else if $class == sm {
@media (min-width: 750px) { @content; } @media (min-width: 768px) and (max-width: 991px) { @content; }
} }
@else if $class == md { @else if $class == md {
@media (min-width: 992px) { @content; } @media (min-width: 992px) and (max-width: 1199px) { @content; }
} }
@else if $class == lg { @else if $class == lg {
@media (min-width: 1200px) { @content; } @media (min-width: 1200px) { @content; }
} }
@else { @else {
@warn "Breakpoint mixin supports: xs, sm, md, lg"; @warn "Breakpoint mixin supports: xs, sm, md, lg";
} }
} }

View file

@ -49,6 +49,26 @@ module Admin
end end
end end
##
# Received a file from user
# Reads file and creates commercial for event
# File content example:
# EventID:MyURL
def mass_upload
errors = Commercial.read_file(params[:file]) if params[:file]
if errors.all? { |_k, v| v.blank? }
flash[:notice] = 'Successfully added commercials.'
else
errors_text = ''
errors_text << 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any?
errors_text << 'There were some errors: ' + errors[:validation_errors].join('. ') if errors[:validation_errors].any?
flash[:error] = errors_text
end
redirect_to :back
end
private private
def commercial_params def commercial_params

View file

@ -155,7 +155,7 @@ module Admin
# Set line color using a hash function # Set line color using a hash function
@tickets = [] @tickets = []
@tickets_data.keys.each do |title| @tickets_data.each_key do |title|
@tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}") @tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}")
end end

View file

@ -124,6 +124,15 @@ module Admin
def cancel def cancel
update_state(:cancel, 'Event canceled!') update_state(:cancel, 'Event canceled!')
selected_schedule = @event.program.selected_schedule
event_schedule = EventSchedule.unscoped.where(event: @event).find_by(schedule: selected_schedule) if selected_schedule
Rails.logger.debug "schedule: #{selected_schedule.inspect} and event_schedule #{event_schedule.inspect}"
if selected_schedule && event_schedule
event_schedule.enabled = false
event_schedule.save
else
@event.event_schedules.destroy_all
end
end end
def reject def reject

View file

@ -9,19 +9,58 @@ class ConferencesController < ApplicationController
end end
def show def show
@conference = if params[:id] # load conference with header content
Conference.find_by_short_title(params[:id]) @conference = Conference.unscoped.eager_load(
else :splashpage,
load_conference_by_domain :program,
end :registration_period,
authorize! :show, @conference :contact,
@program = @conference.program venue: :commercial
).find_by(conference_finder_conditions)
authorize! :show, @conference # TODO: reduce the 10 queries performed here
splashpage = @conference.splashpage
if splashpage.include_cfp
cfps = @conference.program.cfps
@call_for_events = cfps.find { |call| call.cfp_type == 'events' }
if @call_for_events.try(:open?)
@event_types = @conference.event_types.pluck(:title)
@track_names = @conference.confirmed_tracks.pluck(:name).sort
end
@call_for_tracks = cfps.find { |call| call.cfp_type == 'tracks' }
end
if splashpage.include_program
@highlights = @conference.highlighted_events.eager_load(:speakers)
if splashpage.include_tracks
@tracks = @conference.confirmed_tracks.eager_load(
:room
).order('tracks.name')
end
if splashpage.include_booths
@booths = @conference.confirmed_booths.order('title')
end
end
if splashpage.include_registrations || splashpage.include_tickets
@tickets = @conference.tickets.order('price_cents')
end
if splashpage.include_lodgings
@lodgings = @conference.lodgings.order('name')
end
if splashpage.include_sponsors
@sponsorship_levels = @conference.sponsorship_levels.eager_load(
:sponsors
).order('sponsorship_levels.position ASC', 'sponsors.name')
end
end end
private private
def load_conference_by_domain def conference_finder_conditions
Conference.find_by(custom_domain: request.domain) if params[:id]
{ short_title: params[:id] }
else
{ custom_domain: request.domain }
end
end end
def respond_to_options def respond_to_options

View file

@ -91,6 +91,15 @@ class ProposalsController < ApplicationController
begin begin
@event.withdraw @event.withdraw
selected_schedule = @event.program.selected_schedule
event_schedule = @event.event_schedules.find_by(schedule: selected_schedule) if selected_schedule
Rails.logger.debug "schedule: #{selected_schedule.inspect} and event_schedule #{event_schedule.inspect}"
if selected_schedule && event_schedule
event_schedule.enabled = false
event_schedule.save
else
@event.event_schedules.destroy_all
end
rescue Transitions::InvalidTransition rescue Transitions::InvalidTransition
redirect_to :back, error: "Event can't be withdrawn" redirect_to :back, error: "Event can't be withdrawn"
return return

View file

@ -11,6 +11,11 @@ module Users
def handle(provider) def handle(provider)
auth_hash = request.env['omniauth.auth'] auth_hash = request.env['omniauth.auth']
unless auth_hash.info.email.present?
flash[:error] = "Email field is missing in your #{provider} account"
redirect_to new_user_registration_path
return
end
username = auth_hash.info.email.split('@')[0] username = auth_hash.info.email.split('@')[0]
openid = Openid.find_for_oauth(auth_hash) # Get or create openid openid = Openid.find_for_oauth(auth_hash) # Get or create openid
# If openid exists and is associated with a user, sign in with associated user, # If openid exists and is associated with a user, sign in with associated user,

View file

@ -56,17 +56,7 @@ module ApplicationHelper
end end
def tracks(conference) def tracks(conference)
all = conference.program.tracks.confirmed.cfp_active.pluck(:name) conference.confirmed_tracks.collect(&:name).to_sentence
first = all[0...-1]
last = all[-1]
ts = ''
if all.length > 1
ts << first.join(', ')
ts << " and #{last}"
else
ts = all.join
end
ts
end end
def difficulty_levels(conference) def difficulty_levels(conference)
@ -99,7 +89,7 @@ module ApplicationHelper
end end
def normalize_array_length(hashmap, length) def normalize_array_length(hashmap, length)
hashmap.each do |_, value| hashmap.each_value do |value|
if value.length < length if value.length < length
value.fill(value[-1], value.length...length) value.fill(value[-1], value.length...length)
end end
@ -151,8 +141,8 @@ module ApplicationHelper
hint: 'The people responsible for the booth. You can only select existing users.' hint: 'The people responsible for the booth. You can only select existing users.'
end end
def event_types(conference) def event_types_sentence(conference)
conference.program.event_types.map { |et| et.title.pluralize }.to_sentence conference.event_types.map { |et| et.title.pluralize }.to_sentence
end end
def sign_in_path def sign_in_path
@ -191,4 +181,19 @@ module ApplicationHelper
title: 'Open Source Event Manager' title: 'Open Source Event Manager'
) )
end end
# returns the url to be used for logo on basis of sponsorship level position
def get_logo(object)
if object.try(:sponsorship_level)
if object.sponsorship_level.position == 1
object.picture.first.url
elsif object.sponsorship_level.position == 2
object.picture.second.url
else
object.picture.others.url
end
else
object.picture.large.url
end
end
end end

View file

@ -0,0 +1,17 @@
module ConferenceHelper
# Return true if only call_for_papers or call_for_tracks is open
def one_call_open(*calls)
calls.one? { |call| call.try(:open?) }
end
# URL for sponsorship emails
def sponsorship_mailto(conference)
[
'mailto:',
conference.contact.sponsor_email,
'?subject=',
url_encode(conference.short_title),
'%20Sponsorship'
].join
end
end

View file

@ -1,12 +0,0 @@
module SponsorsHelper
# returns the url to be used for logo on basis of sponsorship level position
def get_logo(sponsor)
if sponsor.sponsorship_level.position == 1
sponsor.picture.first.url
elsif sponsor.sponsorship_level.position == 2
sponsor.picture.second.url
else
sponsor.picture.others.url
end
end
end

View file

@ -5,7 +5,7 @@ class Commercial < ApplicationRecord
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id } has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
validates :url, presence: true validates :url, presence: true, uniqueness: { scope: :commercialable }
validates :url, format: URI::regexp(%w(http https)) validates :url, format: URI::regexp(%w(http https))
validate :valid_url validate :valid_url
@ -20,6 +20,29 @@ class Commercial < ApplicationRecord
end end
end end
def self.read_file(file)
errors = {}
errors[:no_event] = []
errors[:validation_errors] = []
file.read.each_line do |line|
# Get the event id (text before :)
id = line.match(/:/).pre_match.to_i
# Get the commercial url (text after :)
url = line.match(/:/).post_match
event = Event.find_by(id: id)
# Go to next event, if the event is not found
errors[:no_event] << id && next unless event
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 + ')'
end
end
errors
end
private private
def valid_url def valid_url

View file

@ -33,6 +33,7 @@ class Conference < ApplicationRecord
end end
has_many :resources, dependent: :destroy has_many :resources, dependent: :destroy
has_many :booths, dependent: :destroy has_many :booths, dependent: :destroy
has_many :confirmed_booths, -> { where(state: 'confirmed') }, class_name: 'Booth'
has_many :lodgings, dependent: :destroy has_many :lodgings, dependent: :destroy
has_many :registrations, dependent: :destroy has_many :registrations, dependent: :destroy
@ -45,7 +46,15 @@ class Conference < ApplicationRecord
has_many :campaigns, dependent: :destroy has_many :campaigns, dependent: :destroy
has_many :commercials, as: :commercialable, dependent: :destroy has_many :commercials, as: :commercialable, dependent: :destroy
has_many :subscriptions, dependent: :destroy has_many :subscriptions, dependent: :destroy
has_one :call_for_events, -> { where(cfp_type: 'events') }, through: :program, source: :cfps
has_one :call_for_booths, -> { where(cfp_type: 'booths') }, through: :program, source: :cfps
has_one :call_for_tracks, -> { where(cfp_type: 'tracks') }, through: :program, source: :cfps
has_many :confirmed_tracks, -> { where(state: 'confirmed') }, through: :program, source: :tracks
has_many :highlighted_events,
-> { where(state: :confirmed, is_highlight: true) },
through: :program,
source: :events
has_many :event_types, through: :program
accepts_nested_attributes_for :venue accepts_nested_attributes_for :venue
accepts_nested_attributes_for :tickets, allow_destroy: true accepts_nested_attributes_for :tickets, allow_destroy: true
accepts_nested_attributes_for :sponsorship_levels, allow_destroy: true accepts_nested_attributes_for :sponsorship_levels, allow_destroy: true

View file

@ -197,6 +197,14 @@ class Event < ApplicationRecord
send(transition) send(transition)
end end
save save
# If the event was previously scheduled, and then withdrawn or cancelled
# its event_schedule will have enabled set to false
# If the event is now confirmed again, we want it to be available for scheduling
Rails.logger.debug "transition is #{transition}"
if transition == :confirm
Rails.logger.debug "schedules #{EventSchedule.unscoped.where(event: self, enabled: false)}"
EventSchedule.unscoped.where(event: self, enabled: false).destroy_all
end
rescue Transitions::InvalidTransition => e rescue Transitions::InvalidTransition => e
alert = "Update state failed. #{e.message}" alert = "Update state failed. #{e.message}"
end end

View file

@ -1,4 +1,5 @@
class EventSchedule < ApplicationRecord class EventSchedule < ApplicationRecord
default_scope { where(enabled: true) }
belongs_to :schedule belongs_to :schedule
belongs_to :event belongs_to :event
belongs_to :room belongs_to :room
@ -33,7 +34,7 @@ class EventSchedule < ApplicationRecord
# Returns event schedules that are scheduled in the same room and start_time as event # Returns event schedules that are scheduled in the same room and start_time as event
# #
def intersecting_event_schedules def intersecting_event_schedules
room.event_schedules.where(start_time: start_time, schedule: schedule).where.not(id: id) EventSchedule.unscoped.where(room: room, start_time: start_time, schedule: schedule).where.not(id: id)
end end
def replacement? def replacement?

View file

@ -1,6 +1,6 @@
class Openid < ApplicationRecord class Openid < ApplicationRecord
belongs_to :user belongs_to :user
validates :provider, :uid, presence: true validates :provider, :uid, :email, presence: true
# Searches for openid based on provider and uid. # Searches for openid based on provider and uid.
# Returns found openid or a new openid. # Returns found openid or a new openid.

View file

@ -165,7 +165,7 @@ class Program < ApplicationRecord
# * +False+ -> If there is not any event for the given date # * +False+ -> If there is not any event for the given date
def any_event_for_this_date?(date) def any_event_for_this_date?(date)
parsed_date = DateTime.parse("#{date} 00:00").utc parsed_date = DateTime.parse("#{date} 00:00").utc
EventSchedule.where(schedule: selected_schedule).where(start_time: parsed_date..(parsed_date + 1)).any? EventSchedule.where(schedule: selected_schedule).where(start_time: parsed_date..(parsed_date + 1.day)).any?
end end
## ##

View file

@ -45,8 +45,8 @@ class User < ApplicationRecord
attr_accessor :login attr_accessor :login
has_many :event_users, dependent: :destroy has_many :event_users, dependent: :destroy
has_many :events, -> { uniq }, through: :event_users has_many :events, -> { distinct }, through: :event_users
has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).uniq }, through: :event_users, source: :event has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).distinct }, through: :event_users, source: :event
has_many :registrations, dependent: :destroy do has_many :registrations, dependent: :destroy do
def for_conference conference def for_conference conference
where(conference: conference).first where(conference: conference).first
@ -216,7 +216,7 @@ class User < ApplicationRecord
end end
def proposals(conference) def proposals(conference)
events.where('program_id = ? AND event_users.event_role=?', conference.program.id, 'submitter') events.where('program_id = ? AND (event_users.event_role=? OR event_users.event_role=?)', conference.program.id, 'submitter', 'speaker')
end end
def proposal_count(conference) def proposal_count(conference)

View file

@ -1,3 +1,5 @@
require 'open-uri'
class TicketPdf < Prawn::Document class TicketPdf < Prawn::Document
def initialize(conference, user, physical_ticket, ticket_layout, file_name) def initialize(conference, user, physical_ticket, ticket_layout, file_name)
super(page_layout: ticket_layout, page_size: 'A4', filename: file_name) super(page_layout: ticket_layout, page_size: 'A4', filename: file_name)
@ -43,11 +45,17 @@ class TicketPdf < Prawn::Document
def draw_second_square def draw_second_square
move_up 150 move_up 150
if @conference.picture? if @conference.picture?
if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height] conference_image = case @conference.picture.ticket.url[0, 4]
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], width: 120 when 'http', 'ftp:' # CDNs
else open(@conference.picture.ticket.url)
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], height: 70 when '/sys' # local storage
end open([
Rails.root,
'/public',
@conference.picture.ticket.url
].join)
end
image conference_image, at: [@mid_horizontal + 30, cursor]
else else
image "#{Rails.root}/public/img/osem-logo.png", at: [@mid_horizontal + 30, cursor], height: 70 image "#{Rails.root}/public/img/osem-logo.png", at: [@mid_horizontal + 30, cursor], height: 70
end end

View file

@ -52,10 +52,6 @@ class PictureUploader < CarrierWave::Uploader::Base
"system/#{object_class_name}/#{mounted_as}/#{model.id}" "system/#{object_class_name}/#{mounted_as}/#{model.id}"
end end
def image
@image ||= MiniMagick::Image.open(file.file)
end
# Create different versions of your uploaded files: # Create different versions of your uploaded files:
version :large do version :large do
process resize_to_fit: [300, 300] process resize_to_fit: [300, 300]
@ -80,6 +76,11 @@ class PictureUploader < CarrierWave::Uploader::Base
process resize_and_pad: [320, 120, 'white'] process resize_and_pad: [320, 120, 'white']
end end
version :ticket, if: :conference?
version :ticket do
process resize_and_pad: [120, 70]
end
# Add a white list of extensions which are allowed to be uploaded. # Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this: # For images you might use something like this:
def extension_white_list def extension_white_list
@ -95,4 +96,8 @@ class PictureUploader < CarrierWave::Uploader::Base
def sponsor?(_picture) def sponsor?(_picture)
object_class_name == 'sponsors' object_class_name == 'sponsors'
end end
def conference?(_picture)
object_class_name == 'conferences'
end
end end

View file

@ -21,7 +21,7 @@
%dt %dt
Event types: Event types:
%dd %dd
= event_types(@conference) = event_types_sentence(@conference)
%dt %dt
Tracks: Tracks:
%dd %dd

View file

@ -4,37 +4,60 @@
%h1 %h1
Events Events
= "(#{@events.length})" if @events.any? = "(#{@events.length})" if @events.any?
.pull-right
.btn-group.pull-right
%button.btn.btn-primary{ 'data-toggle' => 'modal', 'data-target' => '#mass-commercials-modal', title: 'Mass import of commercials for events' }
Add Commercials
- if can? :create, Event - if can? :create, Event
=link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info' = link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info'
- if can? :read, Event - if can? :read, Event
.btn-group .btn-group
.btn-group %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' } Export PDF
Export PDF %span.caret
%span.caret %ul.dropdown-menu{ role: 'menu' }
%ul.dropdown-menu{ role: 'menu' } %li= link_to 'All Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all')
%li= link_to 'All Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all') %li= link_to 'Confirmed Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'confirmed')
%li= link_to 'Confirmed Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'confirmed') %li= link_to 'All Events with Comments', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all_with_comments')
%li= link_to 'All Events with Comments', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all_with_comments') .btn-group
.btn-group %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' } Export CSV
Export CSV %span.caret
%span.caret %ul.dropdown-menu{ role: 'menu' }
%ul.dropdown-menu{ role: 'menu' } %li= link_to 'All', admin_conference_program_events_path(@conference.short_title, format: :csv, event_export_option: 'all')
%li= link_to 'All', admin_conference_program_events_path(@conference.short_title, format: :csv, event_export_option: 'all') %li= link_to 'Confirmed', admin_conference_program_events_path(@conference.short_title, format: :csv, event_export_option: 'confirmed')
%li= link_to 'Confirmed', admin_conference_program_events_path(@conference.short_title, format: :csv, event_export_option: 'confirmed') %li= link_to 'All with Comments', admin_conference_program_events_path(@conference.short_title, format: :csv, event_export_option: 'all_with_comments')
%li= link_to 'All with Comments', admin_conference_program_events_path(@conference.short_title, format: :csv, event_export_option: 'all_with_comments') .btn-group
.btn-group %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' } Export XLS
Export XLS %span.caret
%span.caret %ul.dropdown-menu{ role: 'menu' }
%ul.dropdown-menu{ role: 'menu' } %li= link_to 'All', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'all')
%li= link_to 'All', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'all') %li= link_to 'Confirmed', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'confirmed')
%li= link_to 'Confirmed', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'confirmed') %li= link_to 'All with Comments', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'all_with_comments')
%li= link_to 'All with Comments', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'all_with_comments')
%p.text-muted %p.text-muted
All the submissions of your speakers All the submissions of your speakers
.modal#mass-commercials-modal
.modal-dialog
.modal-content
.modal-header
%h1 Add commercials to events
.text-muted
Upload your file with data in the following format:
%b Event_ID:Commercial_Link
, eg.
%br
%b 11:https://youtube.com/myvideo
.modal-body
= semantic_form_for '', url: mass_upload_commercials_admin_conference_program_path(@conference.short_title), method: :post do |f|
= f.input 'file', as: :file
.modal-footer
= f.submit 'Add', class: 'btn btn-primary'
.row .row
.col-md-4 .col-md-4
= render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Events state', data: @event_distribution } = render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Events state', data: @event_distribution }

View file

@ -22,7 +22,7 @@
%dt %dt
Event types: Event types:
%dd %dd
= event_types(@conference) = event_types_sentence(@conference)
%dt %dt
Tracks: Tracks:
%dd %dd

View file

@ -2,21 +2,46 @@
.col-md-12 .col-md-12
.page-header .page-header
%h1 Splashpage %h1 Splashpage
.row
.col-md-8 = semantic_form_for(@splashpage, url: admin_conference_splashpage_path(@conference.short_title)) do |f|
= semantic_form_for(@splashpage, url: admin_conference_splashpage_path(@conference.short_title)) do |f| .row
.col-md-12
= f.inputs name: 'Components' do = f.inputs name: 'Components' do
= f.input :include_tracks, label: 'Display tracks', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tracks) } %ul.fa-ul
= f.input :include_program, label: 'Display program', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_program) } %li
= f.input :include_cfp, label: 'Display call for papers information on splashpage, while cfp is open', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_cfp) } = f.input :include_cfp, label: 'Display call for papers and call for tracks, while open', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_cfp) }
= f.input :include_venue, label: 'Display venue', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_venue) } %li
= f.input :include_registrations, label: 'Display the registration period', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_registrations) } = f.input :include_program, label: 'Display the program', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_program) }
= f.input :include_tickets, label: 'Display tickets', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tickets) }
= f.input :include_lodgings, label: 'Display the lodgings', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_lodgings) } %ul.fa-ul
= f.input :include_sponsors, label: 'Display sponsors', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_sponsors) } %li
= f.input :include_booths, label: 'Display confirmed booths', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) } = f.input :include_tracks, label: 'Include confirmed tracks', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tracks) }
= f.input :include_social_media, label: 'Display social media', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_social_media) } %li
= f.input :include_booths, label: 'Include confirmed booths', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) }
%li
= f.input :include_registrations, label: 'Display the registration period', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_registrations) }
%li
= f.input :include_tickets, label: 'Display tickets', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tickets) }
%li
= f.input :include_venue, label: 'Display the venue', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_venue) }
%li
= f.input :include_lodgings, label: 'Display the lodgings', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_lodgings) }
%li
= f.input :include_sponsors, label: 'Display sponsors', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_sponsors) }
%li
= f.input :include_social_media, label: 'Display social media links', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_social_media) }
= f.inputs name: 'Access' do = f.inputs name: 'Access' do
= f.input :public, label: 'Make splash page public?' %ul.fa-ul
%li
= f.input :public, label: 'Make splash page public?'
.row
.col-md-12
%p.text-right %p.text-right
= f.submit 'Save Splashpage', class: 'btn btn-primary' = f.submit 'Save Changes', class: 'btn btn-primary'

View file

@ -8,92 +8,47 @@
with all the information for your conference with all the information for your conference
- if @splashpage - if @splashpage
.row .row
.col-md-8 .col-md-12
%dl.dl-horizontal %ul.fa-ul
%dt %li
Include Tracks: %i{ class: "fa-li #{icon_for_todo @splashpage.include_cfp?}" }
%dd Display call for papers and call for tracks, while open
- if @splashpage.include_tracks %li
Yes %i{ class: "fa-li #{icon_for_todo @splashpage.include_program?}" }
- else Display the program
No %ul.fa-ul
%dt %li
Include Program: %i{ class: "fa-li #{icon_for_todo @splashpage.include_program?}" }
%dd Include confirmed tracks
- if @splashpage.include_program %li
Yes %i{ class: "fa-li #{icon_for_todo @splashpage.include_booths?}" }
- else Include confirmed booths
No %li
%dt %i{ class: "fa-li #{icon_for_todo @splashpage.include_registrations?}" }
Include CFP: Display the registration period
%dd %li
- if @splashpage.include_cfp %i{ class: "fa-li #{icon_for_todo @splashpage.include_tickets?}" }
Yes Display tickets
- else %li
No %i{ class: "fa-li #{icon_for_todo @splashpage.include_venue?}" }
%dt Display the venue
Include Venue: %li
%dd %i{ class: "fa-li #{icon_for_todo @splashpage.include_lodgings?}" }
-if @splashpage.include_venue Display the lodgings
Yes %li
-else %i{ class: "fa-li #{icon_for_todo @splashpage.include_sponsors?}" }
No Display sponsors
%dt %li
Include Registrations: %i{ class: "fa-li #{icon_for_todo @splashpage.include_social_media?}" }
%dd Display social media links
- if @splashpage.include_registrations
Yes
- else
No
%dt
Include Tickets:
%dd
- if @splashpage.include_tickets
Yes
- else
No
%dt
Include Lodgins
%dd
-if @splashpage.include_lodgings
Yes
-else
No
%dt
Include Sponsors:
%dd
- if @splashpage.include_sponsors
Yes
- else
No
%dt
Include Booths
%dd
- if @splashpage.include_booths
Yes
- else
No
%dt
Include Social Media:
%dd
- if @splashpage.include_social_media
Yes
- else
No
%dt
Public
%dd
- if @splashpage.public
Yes
- else
No
.row .row
.col-md-12 .col-md-12
- if can? :update, @splashpage - if can? :update, @splashpage
= link_to 'Edit', edit_admin_conference_splashpage_path, class: 'btn btn-primary' = link_to 'Edit', edit_admin_conference_splashpage_path, class: 'btn btn-primary'
- if can? :destroy, @splashpage - if can? :destroy, @splashpage
= link_to 'Delete', admin_conference_splashpage_path, = link_to 'Delete', admin_conference_splashpage_path,
method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger'
- else - else
.row .row
.col-md-12.text-right .col-md-12.text-right

View file

@ -9,8 +9,8 @@
.row .row
.col-md-8 .col-md-8
= semantic_form_for(@ticket, url: (@ticket.new_record? ? admin_conference_tickets_path : admin_conference_ticket_path(@conference.short_title, @ticket))) do |f| = semantic_form_for(@ticket, url: (@ticket.new_record? ? admin_conference_tickets_path : admin_conference_ticket_path(@conference.short_title, @ticket))) do |f|
= f.input :title = f.input :title, input_html: { autofocus: true }
= f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } } = f.input :description, input_html: { rows: 5, data: { provide: 'markdown-editable' } }
= f.input :price = f.input :price
= f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY', 'CHF'], include_blank: false = f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY', 'CHF'], include_blank: false
= f.input :registration_ticket, hint: 'A registration ticket is with which user register for the conference.' = f.input :registration_ticket, hint: 'A registration ticket is with which user register for the conference.'

View file

@ -14,7 +14,7 @@
= f.input :color, input_html: {size: 6, type: 'color'}, required: true = f.input :color, input_html: {size: 6, type: 'color'}, required: true
= f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? } = f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? }
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? } = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? }
- if @conference.venue.try(:rooms) - if @conference.venue.try(:rooms).present?
= f.input :room, as: :select, collection: (@conference.venue.rooms).map {|room| ["#{room.name}", room.id]}, include_blank: true, label: 'Room', input_html: { class: 'select-help-toggle', required: @track.self_organized_and_accepted_or_confirmed? } = f.input :room, as: :select, collection: (@conference.venue.rooms).map {|room| ["#{room.name}", room.id]}, include_blank: true, label: 'Room', input_html: { class: 'select-help-toggle', required: @track.self_organized_and_accepted_or_confirmed? }
- else - else
%b %b

View file

@ -234,6 +234,12 @@
= link_to_organization(version.conference_id) = link_to_organization(version.conference_id)
- else - else
(Organization Deleted) (Organization Deleted)
- elsif version.item_type == 'Commercial'
- commercial = current_or_last_object_state(version.item_type, version.item_id)
- commercialable = current_or_last_object_state(commercial.commercialable_type, commercial.commercialable_id)
- unless commercial.commercialable_type == 'Conference'
in conference
= link_to_conference(version.conference_id)
- else - else
in conference in conference
= link_to_conference(version.conference_id) = link_to_conference(version.conference_id)

View file

@ -104,7 +104,9 @@
= humanized_money @total_price_per_ticket[ticket_id] = humanized_money @total_price_per_ticket[ticket_id]
%br %br
- if @tickets.any? - if @tickets.any?
= link_to 'Get more tickets', conference_tickets_path(@conference.short_title), class: "btn btn-default" .btn-group
= link_to 'View all tickets', conference_physical_tickets_path(@conference.short_title), class: "btn btn-success"
= link_to 'Get more tickets', conference_tickets_path(@conference.short_title), class: "btn btn-default"
- else - else
You haven't bought any tickets. You haven't bought any tickets.
= link_to 'Please get some tickets to support us!', conference_tickets_path(@conference.short_title) = link_to 'Please get some tickets to support us!', conference_tickets_path(@conference.short_title)

View file

@ -0,0 +1,15 @@
.row
.col-md-12
%h3.text-center Booths
.row.row-centered
- booths.each do |booth|
.col-md-2.col-sm-2.col-centered.col-top.booth
%a.thumbnail{ href: '#',
data: { toggle: 'modal', target: "#modal-booth-#{booth.id}" } }
- if booth.picture?
= image_tag get_logo(booth),
class: ['img-responsive', 'img-rounded'],
title: booth.title
- else
.caption
%h3.text-center= booth.title

View file

@ -1,24 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#booths' } Booths
.container
.row
.col-md-12.text-center
%h2 Booths
- @conference.booths.confirmed.each_slice(3).with_index do |slice, index_for_row|
.row.row-centered
- slice.each.with_index do |booth, index_for_column|
.col-md-4.col-sm-4.col-xs-10.col-centered.col-top
.thumbnail
- if booth.logo_link
= link_to booth.website_url, class: 'thumbnail' do
= image_tag booth.picture.large.url
.caption
%h3.text-center
= booth.title
%p.text-center.text-muted
= link_to "#show_descrition_#{index_for_row}_#{index_for_column}", "data-toggle"=>"collapse" do
learn more
.collapse{ id: "show_descrition_#{index_for_row}_#{index_for_column}" }
= markdown(booth.description)

View file

@ -0,0 +1,16 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#call' } Call For Content
%section#call
.container
.row
- if one_call_open(call_for_events, call_for_tracks)
.col-md-3.col-sm-3.hidden-xs &nbsp;
- if call_for_events.try(:open?)
= render 'call_for_papers', conference_id: conference.short_title,
call: call_for_events, event_types: event_types, tracks: tracks
.col-md-2.col-sm-2 &nbsp;
- if call_for_tracks.try(:open?)
= render 'call_for_tracks', conference_id: conference.short_title,
call: call_for_tracks

View file

@ -1,43 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#callforpapers' } Call For Papers
.container
.row
.col-md-12.text-center
%h2
Call for Papers
%p.lead
We are ready to accept your proposals for sessions!
.row
.col-md-6.col-md-offset-3.col-sm-10.col-sm-offset-1
%p
- if @conference.program.event_types.any?
You can submit proposals for
%span.notranslate
= "#{event_types(@conference)}."
- if @conference.program.tracks.any?
Proposals should fit in one of the
%span.notranslate
= "#{pluralize(@conference.program.tracks.count, 'track')}:"
= "#{tracks(@conference)}."
The submission period has begun
%em.notranslate
= @conference.program.cfp.start_date.strftime('%A, %B %-d. %Y')
and closes
%em.notranslate
= @conference.program.cfp.end_date.strftime('%A, %B %-d. %Y.')
- if @conference.program.cfp_open?
That means you have only
%b.notranslate= pluralize(@conference.program.cfp.remaining_days, 'day')
left!
Remember
%span.notranslate
= @conference.short_title
will only be as good as the sessions you present. Submit early, submit often!
- else
The submission period is closed.
.row
.col-md-12.text-center
%p.cta-button
= link_to "Submit your paper now", conference_program_proposals_path(@conference.short_title), class: 'btn btn-success btn-lg text-center'

View file

@ -0,0 +1,27 @@
- cache [conference_id, call, event_types, tracks, '#splash#callforpapers'] do
.col-md-5.col-sm-5.text-center
%h2
Call for Papers
%p.lead
We are now accepting proposals for sessions!
%p
- if event_types.any?
You can submit proposals for
%span.notranslate
= event_types.map(&:pluralize).to_sentence + '.'
- if tracks.any?
Proposals should fit in one of the
%span.notranslate
= pluralize(tracks.length, 'track') + ':'
= tracks.to_sentence + '.'
The submission period is open
%em.notranslate
= date_string(call.start_date, call.end_date) + '.'
%b
You have
= pluralize(call.remaining_days, 'day')
left!
%p.cta-button
= link_to "Submit your proposal now",
conference_program_proposals_path(conference_id),
class: 'btn btn-success btn-lg text-center'

View file

@ -0,0 +1,19 @@
- cache [conference_id, call, '#splash#callfortracks'] do
.col-md-5.col-sm-5.text-center
%h2
Call for Tracks
%p.lead
We are now accepting custom track requests!
%p
Would you like to host a mini-summit, sub-conference, or hack space?
The submission period for track requests is open
%em
= date_string(call.start_date, call.end_date) + '.'
%b
You have
= pluralize(call.remaining_days, 'day')
left!
%p.cta-button
= link_to("Submit your request for track",
conference_program_tracks_path(conference_id),
class: 'btn btn-success btn-lg text-center')

View file

@ -1,30 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#callfortracks' } Call For Tracks
.container
.row
.col-md-12.text-center
%h2
Call for Tracks
%p.lead
We are ready to accept requests for tracks!
.row
.col-md-6.col-md-offset-3.col-sm-10.col-sm-offset-1
%p
The submission period for track requests has begun
%em.notranslate
= @conference.program.cfps.for_tracks.start_date.strftime('%A, %B %-d. %Y')
and closes
%em.notranslate
= @conference.program.cfps.for_tracks.end_date.strftime('%A, %B %-d. %Y.')
- if @conference.program.cfps.for_tracks.try(:open?)
That means you have only
%b.notranslate= pluralize(@conference.program.cfps.for_tracks.remaining_days, 'day')
left!
- else
The submission period for track requests is closed.
.row
.col-md-12.text-center
%p.cta-button
= link_to "Submit your request for track", conference_program_tracks_path(@conference.short_title), class: 'btn btn-success btn-lg text-center'

View file

@ -0,0 +1,35 @@
- cache [conference, venue, '#splash#header'] do
#banner
.container
.row
.col-md-8.col-md-offset-2#header
.row
.col-md-4
- if conference.picture?
= image_tag(conference.picture_url,
class: 'img-responsive img-center',
id: 'splash-logo')
.col-md-8
%h1
= conference.title
%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
= sanitize link_to(venue.name, venue.website)
- else
= venue.city
- if venue.country_name != 'US'
&bull;
= venue.country_name
- unless conference.description.blank?
%section#about
.container
.row
.col-md-8.col-md-offset-2
%h3.text-center
= markdown(conference.description)

View file

@ -0,0 +1,19 @@
.row
.col-md-12
%h3.text-center
Program Highlights
.row
.col-md-12
.row.row-centered
- highlights.each do |event|
- speaker = event.speakers_ordered.first
.col-md-3.col-sm-3.col-centered.col-top.highlights
= link_to(conference_program_proposal_path(conference_id,
event),
class: 'thumbnail') do
= image_tag speaker.gravatar_url(size: 300),
class: ['img-responsive', 'img-circle'],
title: speaker.name
.caption
%h3.text-center= speaker.name
%h4.text-center= event.title

View file

@ -0,0 +1,41 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#lodging' } Lodging
- cache [venue, lodgings, '#splash#lodging'] do
%section#lodging
.container
.row
.col-md-12.text-center
%h2
Where to stay
- if venue
in
= venue.city
%p.lead
We recommend the following accommodations for your visit.
.row.row-centered
- lodgings.each do |lodging|
.col-md-4.col-sm-4.col-centered.col-top
.thumbnail
- if lodging.picture?
- if lodging.website_link.present?
= link_to(lodging.website_link, class: 'thumbnail') do
= image_tag lodging.picture.large.url,
class: 'img-responsive img-lodging'
- else
= image_tag lodging.picture.large.url,
class: 'img-responsive img-lodging'
- else
%p.text-center
- if lodging.website_link.present?
= link_to(lodging.website_link, class: 'thumbnail') do
%i.fa.fa-home.fa-5x
- else
%i.fa.fa-home.fa-5x
.caption
%h3.text-center
= lodging.name
- if lodging.description.present?
= markdown(lodging.description)

View file

@ -1,37 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#lodging' } Lodging
.container
.row
.col-md-12.text-center
%h2
Where to stay
- if @conference.venue
in
= @conference.venue.city
%p.lead
We recommend these affordable lodging accommodations for your visit.
.row.row-centered{ style:"display: flex; flex-wrap: wrap" }
- @conference.lodgings.each do |lodging|
.col-md-4.col-sm-4.col-centered.col-top{ style:"display:flex;" }
.thumbnail
- if lodging.picture?
-if lodging.website_link.present?
= link_to(lodging.website_link, class: 'thumbnail') do
= image_tag lodging.picture.large.url, class: 'img-responsive img-lodging'
- else
= image_tag lodging.picture.large.url, class: 'img-responsive img-lodging'
- else
%p.text-center
-if lodging.website_link.present?
= link_to(lodging.website_link, class: 'thumbnail') do
%i.fa.fa-home.fa-5x
- else
%i.fa.fa-home.fa-5x
.caption
%h3.text-center
= lodging.name
-if lodging.description.present?
= markdown(lodging.description)

View file

@ -0,0 +1,22 @@
- content_for :modals do
- cache [object, '#modal'] do
.modal.fade{ id: "modal-#{object.class.name.downcase}-#{object.id}" }
.modal-dialog
.modal-content
.modal-header
%button.close{ data: { dismiss: 'modal' } }
%i.fa.fa-close
%h3.modal-title
= object.try(:title) || object.try(:name)
.modal-body
%p.logo
= link_to object.website_url || '#', target: '_blank' do
- img_classes = ['img-responsive center-block']
- if object.is_a? Sponsor
- img_classes << ['img-sponsor',
"img-sponsor-#{object.sponsorship_level.position}"]
= image_tag get_logo(object), class: img_classes
%p.description
= object.description
.modal-footer
= link_to nil, object.website_url, target: '_blank'

View file

@ -0,0 +1,38 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#program' } Program
- cache [conference, highlights, tracks, booths, '#splash#program'] do
%section#program
.container
.row
.col-md-12
%p.lead.text-center
%span.notranslate
= conference.title
has the most awesome program ever!
- unless highlights.blank?
= render 'highlights', conference_id: conference.short_title,
highlights: highlights
- if conference.splashpage.include_tracks
- unless tracks.blank?
= render 'tracks', tracks: tracks
- if conference.splashpage.include_booths
- unless booths.blank?
= render 'booths', booths: booths
- if conference.program.try(:schedule_public?)
.row
.col-md-12
%p.cta-button.text-center
= link_to(conference_schedule_path(conference.short_title),
class: 'btn btn-success btn-lg') do
Full Schedule
- unless booths.blank?
- booths.each do |booth|
- content_for :modals do
= render 'modal_description', object: booth

View file

@ -1,40 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#callforpapers' } Call For Papers
.container
.row
.col-md-12.text-center
%h2
Call for Papers
%p.lead
We are ready to accept your proposals for sessions!
.row
.col-md-6.col-md-offset-3.col-sm-10.col-sm-offset-1
%p
- if @conference.program.event_types.any?
You can submit proposals for
= "#{event_types(@conference)}."
- if @conference.tracks.any?
Proposals should fit in one of the
= "#{pluralize(@conference.tracks.count, 'track')}:"
= "#{tracks(@conference)}."
The submission period has begun
%em
= @program.cfp.start_date.strftime('%A, %B %-d. %Y')
and closes
%em
= @program.cfp.end_date.strftime('%A, %B %-d. %Y.')
- if @conference.cfp_open?
That means you have only
%b= pluralize(@program.cfp.remaining_days, 'day')
left!
Remember
= @conference.short_title
will only be as good as the sessions you present. Submit early, submit often!
- else
The submission period is closed.
.row
.col-md-12.text-center
%p.cta-button
= link_to "Submit your paper now", conference_proposals_path(@conference.short_title), class: 'btn btn-success btn-lg text-center'

View file

@ -0,0 +1,33 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#registration' } Registration
- cache [conference, registration_period, tickets, '#splash#registration'] do
%section#registration
.container
.row
.col-md-12.text-center
%h1 Registration
- if conference.registration_limit_exceeded?
%p
Sorry, the conference registration limit has exceeded
- elsif tickets.empty?
%p.lead
Going to
= conference.short_title
is free of charge.
%p
We only ask you to register yourself before
= date_string(registration_period.end_date)
so we can plan for the right amount of people.
%p.cta-button
- else
%p
The registration period is open
= date_string(registration_period.start_date,
registration_period.end_date)
- if conference.registration_open?
%p.cta-button
= link_to('Register Now',
new_conference_conference_registration_path(conference_id),
class: 'btn btn-lg btn-success')

View file

@ -1,30 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#registration' } Registration
.container
.row
.col-md-12.text-center
%h1 Registration
- if @conference.registration_limit_exceeded?
%p
Sorry, the conference registration limit has exceeded
- else
- if @conference.tickets.empty?
%p.lead
Going to
= @conference.short_title
is free of charge.
%p
We only ask you to register yourself until
= @conference.registration_period.end_date.strftime('%A, %B %-d. %Y')
so we can plan for the right amount of people.
%p.cta-button
- else
%p
The registration period ends on
= @conference.registration_period.end_date.strftime('%A, %B %-d. %Y')
%p.cta-button
= link_to(new_conference_conference_registration_path(@conference.short_title), class: 'btn btn-lg btn-success') do
Register Now

View file

@ -1,57 +0,0 @@
.container
.row
.col-md-12
%h2.text-center
Program
%p.lead.text-center
%span.notranslate
= @conference.short_title
has the most awesome program ever!
- if @conference.splashpage and @conference.program.tracks.any? and @conference.splashpage.include_tracks
See rock-star speakers cover the topics of
- if @conference.splashpage and @conference.splashpage.include_tracks
- @conference.program.tracks.confirmed.each_slice(3) do |slice|
.row.row-centered
- slice.each do |track|
.col-md-4.col-sm-4.col-centered.col-top.track
%h4.text-center
= track.name
= markdown(track.description)
- if track.start_date
%br
From: #{track.start_date.strftime('%A, %B %-d. %Y')}
- if track.end_date
%br
To: #{track.end_date.strftime('%A, %B %-d. %Y')}
- if track.room
%br
In: #{track.room.name}
- if @conference.program and @conference.program.schedule_public
.row
.col-md-12
%p.cta-button.text-center
= link_to(conference_schedule_path(@conference.short_title), class: 'btn btn-default btn-lg') do
Full Schedule
%h3.text-center
Don't miss out!
%br
- if @conference.program.events.highlights.any?
.row
.col-md-12
- @conference.program.events.highlights.each_slice(2) do |slice|
.row.row-centered
- slice.each do |event|
.col-md-6.col-centered.col-top.highlights
%p.text-center
%b= event.title
%h5.text-center
= markdown truncate(event.abstract, length: 500, separator: ' ')
= link_to "Read More", conference_program_proposal_path(@conference.short_title, event)
= content_for :splash_nav do
%li
=link_to('#program', class: 'smoothscroll') do
Program

View file

@ -0,0 +1,20 @@
- cache [contact, '#splash#social'] do
%section#social-media
.container
.row
.col-md-12.text-center
- unless contact.facebook.blank?
= link_to "#{ contact.facebook }" do
%i.fa.fa-facebook-square.fa-4x
- unless contact.twitter.blank?
= link_to "#{ contact.twitter }" do
%i.fa.fa-twitter.fa-4x
- unless contact.instagram.blank?
= link_to "#{ contact.instagram }" do
%i.fa.fa-instagram.fa-4x
- unless contact.googleplus.blank?
= link_to "#{ contact.googleplus }" do
%i.fa.fa-google-plus-square.fa-4x
- unless contact.email.blank?
= mail_to "#{ contact.email }" do
%i.fa.fa-envelope-o.fa-4x

View file

@ -1,18 +0,0 @@
.container
.row
.col-md-12.text-center
- unless @conference.contact.facebook.blank?
= link_to "#{ @conference.contact.facebook }" do
%i.fa.fa-facebook-square.fa-4x
- unless @conference.contact.twitter.blank?
= link_to "#{ @conference.contact.twitter }" do
%i.fa.fa-twitter.fa-4x
- unless @conference.contact.instagram.blank?
= link_to "#{ @conference.contact.instagram }" do
%i.fa.fa-instagram.fa-4x
- unless @conference.contact.googleplus.blank?
= link_to "#{ @conference.contact.googleplus }" do
%i.fa.fa-google-plus-square.fa-4x
- unless @conference.contact.email.blank?
= mail_to "#{ @conference.contact.email }" do
%i.fa.fa-envelope-o.fa-4x

View file

@ -0,0 +1,36 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#sponsors' } Sponsors
- cache [conference, sponsorship_levels, '#splash#sponsors'] do
%section#sponsors
.container
- sponsorship_levels.each do |sponsorship_level|
- if sponsorship_level.sponsors.any?
.row.text-center
%h3
= sponsorship_level.title
= 'Sponsor'.pluralize(sponsorship_level.sponsors.length)
.row.row-centered
- sponsorship_level.sponsors.each do |sponsor|
.col-md-4.col-sm-4.col-centered.col-top
%a{ href: '#', data: { toggle: 'modal',
target: "#modal-sponsor-#{sponsor.id}" } }
- if sponsor.logo_file_name
= image_tag get_logo(sponsor),
class: ['img-responsive', 'img-sponsor',
"img-sponsor-#{sponsorship_level.position}"],
title: sponsor.name
- else
%h4.text-center= sponsor.name
.row
.col-md-12
%h3.text-center
Want to sponsor?
= link_to(sponsorship_mailto(conference)) do
Contact us!
- sponsorship_levels.collect(&:sponsors).flatten.each do |sponsor|
- content_for :modals do
= render 'modal_description', object: sponsor

View file

@ -1,41 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#sponsors' } Sponsors
.container
.row
.col-md-12.text-center
%h2 Sponsors
- @conference.sponsorship_levels.each do |sponsorship_level|
-if sponsorship_level.sponsors.any?
- sponsorship_level.sponsors.each_slice(3) do |slice|
.row.row-centered
- slice.each do |sponsor|
.col-md-4.col-sm-4.col-centered.col-top
%a{ href: '#', data: { toggle: 'modal', target: "#modal_#{sponsor.id}" } }
= image_tag get_logo(sponsor), class: "img-responsive img-sponsor img-sponsor-#{sponsorship_level.position}"
.modal.fade{ id: "modal_#{sponsor.id}" }
.modal-dialog
.modal-content
.modal-header
%button.close{ data: { dismiss: 'modal' } }
x
.modal-title
= sponsor.name
.modal-body.text-center
.logo
= link_to sponsor.website_url, target: '_blank' do
= image_tag get_logo(sponsor), class: "img-responsive img-sponsor img-sponsor-#{sponsorship_level.position}"
.description
= sponsor.description
.modal-footer
= link_to nil, "#{sponsor.website_url}", target: '_blank'
-if @conference.contact and !@conference.contact.sponsor_email.blank?
.row
.col-md-12
%p.text-muted.text-center
%small
Want to sponsor #{@conference.short_title}?
= link_to("mailto: #{@conference.contact.sponsor_email}?subject=#{@conference.short_title}%20Sponsorship") do
Please contact us!

View file

@ -0,0 +1,24 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#tickets' } Tickets
- cache [conference, tickets, '#splash#tickets'] do
%section#tickets
.container
.row
.col-md-12.text-center
%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
.caption
%h3.text-center
= ticket.title
= markdown(ticket.description)
%button.btn-block.btn.btn-lg.btn-success
%i.fa.fa-ticket.fa-fw
= humanized_money_with_symbol(ticket.price)

View file

@ -1,25 +0,0 @@
.container
.row
.col-md-12.text-center
%h2
Support
=@conference.short_title
%p.lead
To support our event you can get these tickets
- @conference.tickets.each_slice(4) do |slice|
.row.row-centered
- slice.each do |ticket|
.col-md-3.col-centered.col-top.col-sm-3
.thumbnail
%p.text-center
%i.fa.fa-ticket.fa-5x
.caption
%h3.text-center
= ticket.title
-if ticket.description.present?
= markdown(ticket.description)
%p.text-center
= link_to(conference_tickets_path(@conference.short_title), class: 'btn btn-success') do
Get Ticket
= humanized_money_with_symbol ticket.price

View file

@ -0,0 +1,16 @@
.row
.col-md-12
%h3.text-center Tracks
.row.row-centered
- tracks.each do |track|
.col-md-3.col-sm-3.col-centered.col-top.track
.thumbnail
.caption
%h3.text-center
= track.name
%p.text-center
- if track.start_date && track.end_date
= date_string(track.start_date, track.end_date)
- if track.room
In #{track.room.name}
= markdown truncate(track.description, length: 200, separator: ' ')

View file

@ -0,0 +1,43 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#venue' } Venue
%section#venue
- if venue.location?
= render '/conferences/venue_map', venue: venue
- else
- cache [venue, commercial, '#splash#venue'] do
.container
.row
.col-md-6
.thumbnail#venue-pic
- if commercial
.flexvideo{ id: "resource-content-#{commercial.id}" }
= render 'shared/media_item',
commercial: commercial
- elsif venue.picture?
= image_tag venue.picture.url,
title: venue.name, class: "img-responsive"
- else
%p.text-center
%span.fa.fa-university.fa-5x
.caption
%h3.text-center
= venue.name
- unless venue.description.blank?
= markdown(venue.description)
.col-md-6
%h2
= venue.city
\/
= venue.country_name
%address
= venue.street
%br
= venue.postalcode + ','
= venue.city
%br
= venue.country_name
- if venue.website
%br
= sanitize link_to(h(venue.website), h(venue.website))

View file

@ -1,35 +0,0 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#venue' } Venue
-if @conference.venue.location?
= render '/conferences/venue_map'
-else
.container
.row
.col-md-6
.thumbnail#venue-pic
- if @conference.venue.commercial.present? and @conference.venue.commercial.persisted?
.flexvideo{ id: "resource-content-#{@conference.venue.commercial.id}"}
= render partial: 'shared/media_item', locals: { commercial: @conference.venue.commercial }
- elsif @conference.venue.picture?
= image_tag @conference.venue.picture.url, alt: @conference.venue.name, class:"img-responsive"
- else
%p.text-center
%span.fa.fa-university.fa-5x
.caption
%h3.text-center
= @conference.venue.name
- unless @conference.venue.description.blank?
= markdown(@conference.venue.description)
.col-md-6
%h2
= "#{@conference.venue.city} / #{@conference.venue.country_name}"
%address
= @conference.venue.street
%br
= "#{@conference.venue.postalcode}, #{@conference.venue.city}"
%br
= @conference.venue.country_name
- if @conference.venue.website
%br
=link_to(h(@conference.venue.website), h(@conference.venue.website)).html_safe

View file

@ -1,16 +1,29 @@
#map{style: "height: 500px;" } #map{ style: "height: 500px;" }
- content_for(:script_body) do - content_for(:script_body) do
- marker = escape_javascript(render '/conferences/venue_map_marker',
venue: venue)
:javascript :javascript
// create a map in the "map" div, set the view to a given place and zoom // create a map in the "map" div, set the view to a given place and zoom
var map = L.map('map', { scrollWheelZoom: false }).setView([#{h(@conference.venue.latitude)}, #{h(@conference.venue.longitude)}], 11); var map = L.map('map', { scrollWheelZoom: false }).setView(
[
#{venue.latitude.to_f + 0.05},
#{h(venue.longitude)}
], 11);
// add an OpenStreetMap tile layer // add an OpenStreetMap tile layer
L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>', attribution: 'Map data &copy; \
<a href="http://openstreetmap.org">OpenStreetMap</a> contributors, \
<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, \
Imagery © <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18 maxZoom: 18
}).addTo(map); }).addTo(map);
// add a marker in the given location, attach some popup content to it and open the popup // add a marker in the given location, attach some popup content to it
L.marker([#{h @conference.venue.latitude}, #{h @conference.venue.longitude}]).addTo(map) // and open the popup
.bindPopup("#{escape_javascript(render '/conferences/venue_map_marker', venue: @conference.venue)}") L.marker([
#{h venue.latitude},
#{h venue.longitude}
]).addTo(map)
.bindPopup("#{marker}")
.openPopup(); .openPopup();
// Turn scrollwheel on when user clicks // Turn scrollwheel on when user clicks
map.on('focus', function(e) { map.on('focus', function(e) {

View file

@ -11,88 +11,64 @@
= @conference.title = @conference.title
#splash #splash
- if @conference.splashpage -# header/description
#banner = render 'header', conference: @conference, venue: @conference.venue
.container
.row
.col-md-8.col-md-offset-2#header
.row
.col-md-4
= image_tag(@conference.picture_url, class: 'img-responsive img-center', id: 'splash-logo') if @conference.picture?
.col-md-8
%h1
= @conference.title
%p.lead
- if @conference.venue
= "#{@conference.venue.city} / #{@conference.venue.country_name}"
- if @conference.start_date && @conference.end_date
%br
= date_string(@conference.start_date, @conference.end_date)
- unless @conference.description.blank? -# calls for content, or program
%section#about - if @conference.splashpage.include_cfp
.container = render 'call_for_content', conference: @conference,
.row call_for_events: @call_for_events, call_for_tracks: @call_for_tracks,
.col-md-8.col-md-offset-2 event_types: @event_types, tracks: @track_names
%h3.text-center
= markdown(@conference.description)
- if @conference.registration_open? and @conference.splashpage.include_registrations - if @conference.splashpage.include_program
%section#registration = render 'program', conference: @conference, tracks: @tracks,
= render 'registration' highlights: @highlights, booths: @booths
- if @conference.splashpage.include_program -# attendance/registration
%section#program - if @conference.splashpage.include_registrations
= render 'schedule_splashpage' - if @conference.registration_open?
= render 'registration', conference: @conference,
registration_period: @conference.registration_period,
tickets: @tickets, conference_id: @conference_id.short_title
- if @conference.splashpage.include_tickets && @conference.tickets.any?
= render 'tickets', conference: @conference, tickets: @tickets
- if @conference.program.cfp_open? and @conference.splashpage.include_cfp -# geo
%section#callforpapers - if @conference.splashpage.include_venue && @conference.venue
= render 'call_for_paper' = render 'venue', conference: @conference, venue: @conference.venue,
commercial: @conference.venue.commercial
- if @conference.splashpage.include_lodgings && @conference.lodgings.any?
= render 'lodging', venue: @conference.venue, lodgings: @lodgings
- if @conference.program.cfps.for_tracks.try(:open?) && @conference.splashpage.include_cfp -# sponsorship
%section#callfortracks - if @conference.splashpage.include_sponsors
= render 'call_for_tracks' = render 'sponsors', conference: @conference,
sponsorship_levels: @sponsorship_levels
- if @conference.venue and @conference.splashpage.include_venue -# footer
%section#venue - if @conference.splashpage.include_social_media
= render 'venue' - if @conference.contact.has_social_media?
= render 'social_media', contact: @conference.contact
= render 'footer'
- if @conference.lodgings.any? and @conference.splashpage.include_lodgings = yield :modals
%section#lodging
= render 'lodging'
- if @conference.tickets.any? and @conference.splashpage.include_tickets and @conference.pending? - cache [@conference.color, '#splash#inlinejs'] do
%section#tickets - content_for :script_head do
= render 'tickets' :javascript
var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic();
- if @conference.booths.confirmed.any? and @conference.splashpage.include_booths var triangle_colors = triangle_tcs.map(function(t) {
%section#booths return t.toHexString();
= render 'booths' });
$(function () {
- if @conference.sponsors.any? and @conference.splashpage.include_sponsors $(document).ready(function() {
%section#sponsors var triangle_width = document.body.clientWidth;
= render 'sponsors' var triangle_height = ($( "#banner" ).height() + 200 );
var pattern = Trianglify({ width: triangle_width,
- if @conference.contact.has_social_media? and @conference.splashpage.include_social_media height: triangle_height,
%section#social-media cell_size: 100,
= render 'social_media' x_colors: triangle_colors
});
// grmbl $('#banner').css('background-image', 'url("' + pattern.png() + '")');
= 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() + '")');
}); });
});

View file

@ -27,6 +27,11 @@
= link_to(admin_users_path) do = link_to(admin_users_path) do
%span.fa.fa-user %span.fa.fa-user
Users Users
- if can? :index, Organization
%li
= link_to(admin_organizations_path) do
%span.fa.fa-users
Organizations
- if can? :index, PaperTrail::Version - if can? :index, PaperTrail::Version
%li %li
= link_to(admin_revision_history_path) do = link_to(admin_revision_history_path) do

View file

@ -7,7 +7,7 @@
= link_to(edit_user_path(current_user.id)) do = link_to(edit_user_path(current_user.id)) do
%span.fa.fa-user %span.fa.fa-user
Edit Profile Edit Profile
-if @conference and @conference.program -if @conference && @conference.program
%li %li
= link_to(conference_program_proposals_path(@conference.short_title)) do = link_to(conference_program_proposals_path(@conference.short_title)) do
%span.fa.fa-comment %span.fa.fa-comment
@ -16,7 +16,7 @@
= link_to(conference_program_tracks_path(@conference.short_title)) do = link_to(conference_program_tracks_path(@conference.short_title)) do
%span.fa.fa-road %span.fa.fa-road
My Tracks My Tracks
-if @conference && @conference.program && (@conference.program.cfps.for_booths.try(:open?) || current_user.booths.where(conference_id: @conference.id).count > 0) -if @conference && (@conference.call_for_booths.try(:open?) || current_user.booths.where(conference_id: @conference.id).count > 0)
%li %li
= link_to (conference_booths_path(@conference.short_title)) do = link_to (conference_booths_path(@conference.short_title)) do
%span.fa.fa-shopping-bag %span.fa.fa-shopping-bag
@ -41,7 +41,7 @@
=link_to(new_admin_conference_path) do =link_to(new_admin_conference_path) do
%span.fa.fa-plus %span.fa.fa-plus
New Conference New Conference
-if @conference and @conference.id and can? :show, @conference -if @conference && @conference.id && can?(:show, @conference)
%li %li
= link_to(admin_conference_path(@conference.short_title)) do = link_to(admin_conference_path(@conference.short_title)) do
%span.fa.fa-cog %span.fa.fa-cog

View file

@ -43,5 +43,5 @@
You can run, copy, distribute, study, change and improve it. You can run, copy, distribute, study, change and improve it.
The source code and the developers are on The source code and the developers are on
=link_to "github.", "https://github.com/openSUSE/osem" =link_to "github.", "https://github.com/openSUSE/osem"
= content_for(:script_body) = yield :script_body
= piwik_tracking_tag = piwik_tracking_tag

View file

@ -31,12 +31,7 @@
= @user.email = @user.email
.col-md-5.col-md-offset-2.box.well .col-md-5.col-md-offset-2.box.well
- if @conference.picture? - if @conference.picture?
- width = @conference.picture.image[:width] = image_tag(@conference.picture.ticket.url, class: 'img-responsive')
- height = @conference.picture.image[:height]
- if 10 * width > 15 * height
= image_tag(@conference.picture_url, width: '150')
- else
= image_tag(@conference.picture_url, height: '100')
- else - else
= image_tag('/img/osem-logo.png', class: 'img-responsive') = image_tag('/img/osem-logo.png', class: 'img-responsive')
%p.text-left %p.text-left

View file

@ -1,7 +1,7 @@
%p.lead %p.lead
- if @program.event_types.any? - if @program.event_types.any?
You can submit proposals for You can submit proposals for
= "#{event_types(@conference)}." = "#{event_types_sentence(@conference)}."
- if @program.tracks.confirmed.cfp_active.any? - if @program.tracks.confirmed.cfp_active.any?
Proposals should fit in one of the Proposals should fit in one of the
= "#{pluralize(@program.tracks.confirmed.cfp_active.count, 'track')}:" = "#{pluralize(@program.tracks.confirmed.cfp_active.count, 'track')}:"

View file

@ -36,8 +36,10 @@
.col-md-8 .col-md-8
%h4 %h4
= link_to speaker.name, user_path(speaker.id) = link_to speaker.name, user_path(speaker.id)
%br
- if speaker.email_public? - if speaker.email_public?
= "(#{speaker.email})" = mail_to "#{ speaker.email }" do
%i.fa.fa-envelope-o.fa-2x
- if speaker.affiliation? - if speaker.affiliation?
.text-muted .text-muted
from from

View file

@ -9,10 +9,10 @@
%timeslot_duration= length_timestamp(@conference.program.schedule_interval) %timeslot_duration= length_timestamp(@conference.program.schedule_interval)
- if @events_xml.any? - if @events_xml.any?
- @events_xml.keys.each.with_index(1) do |day, index| - @events_xml.each_key.with_index(1) do |day, index|
%day{ date: day, index: index } %day{ date: day, index: index }
- events_in_rooms = @events_xml[day].group_by(&:room) - events_in_rooms = @events_xml[day].group_by(&:room)
- events_in_rooms.keys.each do |room| - events_in_rooms.each_key do |room|
%room{ name: room.name } %room{ name: room.name }
- events_in_rooms[room].each do |event| - events_in_rooms[room].each do |event|
%event{ guid: event.guid, id: event.id } %event{ guid: event.guid, id: event.id }

View file

@ -54,6 +54,7 @@ elif [[ "$ID" == "centos" || "$VERSION" == "7" ]]; then
tar jxvf /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /tmp/ phantomjs-2.1.1-linux-x86_64/bin/phantomjs tar jxvf /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /tmp/ phantomjs-2.1.1-linux-x86_64/bin/phantomjs
mv /tmp/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin mv /tmp/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin
pushd /vagrant
fi fi
echo -e "\ninstalling your bundle...\n" echo -e "\ninstalling your bundle...\n"
@ -64,7 +65,7 @@ if [ ! -f /vagrant/config/database.yml ] && [ -f /vagrant/config/database.yml.ex
echo -e "\nSetting up your database from config/database.yml...\n" echo -e "\nSetting up your database from config/database.yml...\n"
cp config/database.yml.example config/database.yml cp config/database.yml.example config/database.yml
if [ ! -f db/development.sqlite3 ] && [ ! -f db/test.sqlite3 ]; then if [ ! -f db/development.sqlite3 ] && [ ! -f db/test.sqlite3 ]; then
bundle exec rake db:setup su - vagrant -c "cd /vagrant/; bundle exec rake db:setup"
else else
echo -e "\n\nWARNING: You have already have a development/test database." echo -e "\n\nWARNING: You have already have a development/test database."
echo -e "WARNING: Please make sure this database works in this vagrant box!\n\n" echo -e "WARNING: Please make sure this database works in this vagrant box!\n\n"

View file

@ -9,6 +9,35 @@ development:
pool: 5 pool: 5
timeout: 5000 timeout: 5000
## PostgreSQL
## gem install pg
##
## Ensure the postgres gem is defined in your Gemfile
## gem 'pg'
## Update with your database name and login credentials
# development:
# adapter: postgresql
# encoding: unicode
# database: database_name
# pool: 5
# username: username
# password: password
## MySQL
## gem install mysql2
##
## Ensure the mysql gem is defined in your Gemfile
## gem 'mysql2'
## Update with your database name and login credentials
# development:
# adapter: mysql2
# encoding: utf8
# database: database_name
# pool: 5
# username: username
# password: password
# socket: /tmp/mysql.sock
# Warning: The database defined as "test" will be erased and # Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake". # re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production. # Do not set this db to the same as development or production.

View file

@ -12,6 +12,8 @@ Osem::Application.configure do
# since you don't have to restart the web server when you make code changes. # since you don't have to restart the web server when you make code changes.
config.cache_classes = false config.cache_classes = false
config.cache_store = :memory_store, { size: 64.megabytes }
# Show full error reports and disable caching # Show full error reports and disable caching
config.consider_all_requests_local = true config.consider_all_requests_local = true
config.action_controller.perform_caching = false config.action_controller.perform_caching = false

View file

@ -46,6 +46,14 @@ Osem::Application.configure do
# Use a different cache store in production # Use a different cache store in production
# config.cache_store = :mem_cache_store # config.cache_store = :mem_cache_store
if ENV["MEMCACHEDCLOUD_SERVERS"]
config.cache_store = :dalli_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(','), {
username: ENV["MEMCACHEDCLOUD_USERNAME"],
password: ENV["MEMCACHEDCLOUD_PASSWORD"]
}
else
config.cache_store = :memory_store, { size: 64.megabytes }
end
# Enable serving of images, stylesheets, and JavaScripts from an asset server # Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com" # config.action_controller.asset_host = "http://assets.example.com"

View file

@ -98,6 +98,7 @@ Osem::Application.routes.draw do
end end
resources :event_types resources :event_types
resources :difficulty_levels resources :difficulty_levels
post 'mass_upload_commercials' => 'commercials#mass_upload'
resources :events do resources :events do
member do member do
patch :toggle_attendance patch :toggle_attendance

View file

@ -77,7 +77,7 @@ class AddEventsPerWeekToConference < ActiveRecord::Migration
hash.each do |week, values| hash.each do |week, values|
if previous if previous
values.each do |state, _value| values.each_key do |state|
hash[week][state] += previous[state] hash[week][state] += previous[state]
end end
end end

View file

@ -0,0 +1,5 @@
class AddEnabledToEventSchedules < ActiveRecord::Migration
def change
add_column :event_schedules, :enabled, :boolean, default: true
end
end

View file

@ -0,0 +1,9 @@
class RebuildConferencePictures < ActiveRecord::Migration
def up
Conference.all.each do |conference|
conference.picture.recreate_versions!
end
end
def down; end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20171118113113) do ActiveRecord::Schema.define(version: 20171130172334) do
create_table "ahoy_events", force: :cascade do |t| create_table "ahoy_events", force: :cascade do |t|
t.integer "visit_id" t.integer "visit_id"
@ -217,6 +217,7 @@ ActiveRecord::Schema.define(version: 20171118113113) do
t.datetime "start_time" t.datetime "start_time"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.boolean "enabled", default: true
t.index ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true t.index ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true
t.index ["event_id"], name: "index_event_schedules_on_event_id" t.index ["event_id"], name: "index_event_schedules_on_event_id"
t.index ["room_id"], name: "index_event_schedules_on_room_id" t.index ["room_id"], name: "index_event_schedules_on_room_id"
@ -494,7 +495,7 @@ ActiveRecord::Schema.define(version: 20171118113113) do
t.integer "user_id" t.integer "user_id"
t.integer "payment_id" t.integer "payment_id"
t.integer "week" t.integer "week"
t.float "amount_paid", default: 0.0 t.float "amount_paid"
end end
create_table "ticket_scannings", force: :cascade do |t| create_table "ticket_scannings", force: :cascade do |t|

View file

@ -37,6 +37,9 @@ dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s true
if [ $(echo "show tables;" | mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then if [ $(echo "show tables;" | mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then
echo ">>> Initializing database..." echo ">>> Initializing database..."
bundle exec rake db:schema:load bundle exec rake db:schema:load
echo ">>> Seed database..."
bundle exec rake db:seed
fi fi
echo ">>> Upgrading database..." echo ">>> Upgrading database..."

View file

@ -0,0 +1,31 @@
require 'spec_helper'
describe Users::OmniauthCallbacksController do
context 'email is not there in auth hash' do
before do
stub_env_for_omniauth
get :google
end
it { expect(flash[:error]).to eq('Email field is missing in your google account') }
end
end
def stub_env_for_omniauth
request.env['devise.mapping'] = Devise.mappings[:user]
env = OmniAuth::AuthHash.new(
provider: 'google',
uid: 'google-test-uid-1',
info: {
name: 'google user',
email: nil,
username: 'user_google'
},
credentials: {
token: 'google_mock_token',
secret: 'google_mock_secret'
}
)
request.env['omniauth.auth'] = env
@controller.stub(:env).and_return(env)
end

View file

@ -2,7 +2,7 @@
FactoryGirl.define do FactoryGirl.define do
factory :commercial do factory :commercial do
url 'https://www.youtube.com/watch?v=BTTygyxuGj8' sequence(:url) { |n| "https://www.youtube.com/watch?v=4VrhlyIgo3M&factory=#{n}" }
factory :conference_commercial do factory :conference_commercial do
association :commercialable, factory: :conference association :commercialable, factory: :conference

View file

@ -5,7 +5,7 @@ FactoryGirl.define do
title { Faker::Book.title } title { Faker::Book.title }
short_title { SecureRandom.urlsafe_base64(4) } short_title { SecureRandom.urlsafe_base64(4) }
timezone { Faker::Address.time_zone } timezone { Faker::Address.time_zone }
start_date { Date.today } start_date { Date.current }
end_date { 6.days.from_now } end_date { 6.days.from_now }
start_hour 9 start_hour 9
end_hour 20 end_hour 20

View file

@ -4,7 +4,7 @@ FactoryGirl.define do
factory :event_user do factory :event_user do
user user
Hash[EventUser::ROLES].values.each do |role| Hash[EventUser::ROLES].each_value do |role|
factory role do factory role do
event_role role event_role role
end end

10
spec/factories/openid.rb Normal file
View file

@ -0,0 +1,10 @@
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :openid do
provider { Faker::Internet.domain_word }
email { Faker::Internet.email }
uid { SecureRandom.hex }
user
end
end

View file

@ -98,7 +98,8 @@ feature Commercial do
scenario 'does not update a commercial of an event with invalid data', feature: true, versioning: true, js: true do scenario 'does not update a commercial of an event with invalid data', feature: true, versioning: true, js: true do
commercial = create(:commercial, commercial = create(:commercial,
commercialable_id: event.id, commercialable_id: event.id,
commercialable_type: 'Event') commercialable_type: 'Event',
url: 'https://www.youtube.com/watch?v=BTTygyxuGj8')
visit edit_conference_program_proposal_path(conference.short_title, event.id) visit edit_conference_program_proposal_path(conference.short_title, event.id)
click_link 'Commercials' click_link 'Commercials'
fill_in "commercial_url_#{commercial.id}", with: 'invalid_commercial_url' fill_in "commercial_url_#{commercial.id}", with: 'invalid_commercial_url'

View file

@ -13,7 +13,7 @@ feature Splashpage do
visit admin_conference_splashpage_path(conference.short_title) visit admin_conference_splashpage_path(conference.short_title)
click_link 'Create Splashpage' click_link 'Create Splashpage'
click_button 'Save Splashpage' click_button 'Save Changes'
expect(flash).to eq('Splashpage successfully created.') expect(flash).to eq('Splashpage successfully created.')
expect(current_path).to eq(admin_conference_splashpage_path(conference.short_title)) expect(current_path).to eq(admin_conference_splashpage_path(conference.short_title))
@ -28,7 +28,7 @@ feature Splashpage do
click_link 'Edit' click_link 'Edit'
check('Make splash page public') check('Make splash page public')
click_button 'Save Splashpage' click_button 'Save Changes'
expect(flash).to eq('Splashpage successfully updated.') expect(flash).to eq('Splashpage successfully updated.')
expect(current_path).to eq(admin_conference_splashpage_path(conference.short_title)) expect(current_path).to eq(admin_conference_splashpage_path(conference.short_title))

View file

@ -233,18 +233,18 @@ feature 'Version' do
scenario 'display changes in splashpages', feature: true, versioning: true, js: true do scenario 'display changes in splashpages', feature: true, versioning: true, js: true do
visit admin_conference_splashpage_path(conference.short_title) visit admin_conference_splashpage_path(conference.short_title)
click_link 'Create Splashpage' click_link 'Create Splashpage'
click_button 'Save Splashpage' click_button 'Save Changes'
click_link 'Edit' click_link 'Edit'
uncheck('Display program') uncheck('Display the program')
uncheck('Display call for papers information on splashpage, while cfp is open') uncheck('Display call for papers and call for tracks, while open')
uncheck('Display venue') uncheck('Display the venue')
uncheck('Display tickets') uncheck('Display tickets')
uncheck('Display the lodgings') uncheck('Display the lodgings')
uncheck('Display sponsors') uncheck('Display sponsors')
uncheck('Display social media') uncheck('Display social media links')
check('Make splash page public?') check('Make splash page public?')
click_button 'Save Splashpage' click_button 'Save Changes'
splashpage_id = conference.splashpage.id splashpage_id = conference.splashpage.id
click_link 'Delete' click_link 'Delete'

View file

@ -1,8 +1,9 @@
require 'spec_helper' require 'spec_helper'
describe ApplicationHelper, type: :helper do describe ApplicationHelper, type: :helper do
let(:conference) { create(:conference) } let(:conference) { create(:full_conference) }
let(:event) { create(:event, program: conference.program) } let(:event) { create(:event, program: conference.program) }
let(:sponsor) { create(:sponsor) }
describe '#date_string' do describe '#date_string' do
it 'when conference lasts 1 day' do it 'when conference lasts 1 day' do
@ -75,4 +76,45 @@ describe ApplicationHelper, type: :helper do
end end
end end
end end
describe '#get_logo' do
context 'first sponsorship_level' do
before do
first_sponsorship_level = create(:sponsorship_level, position: 1)
sponsor.update_attributes(sponsorship_level: first_sponsorship_level)
end
it 'returns correct url' do
expect(get_logo(sponsor)).to match %r{.*(\bfirst/#{sponsor.logo_file_name}\b)}
end
end
context 'second sponsorship_level' do
before do
second_sponsorship_level = create(:sponsorship_level, position: 2)
sponsor.update_attributes(sponsorship_level: second_sponsorship_level)
end
it 'returns correct url' do
expect(get_logo(sponsor)).to match %r{.*(\bsecond/#{sponsor.logo_file_name}\b)}
end
end
context 'other sponsorship_level' do
before do
other_sponsorship_level = create(:sponsorship_level, position: 3)
sponsor.update_attributes(sponsorship_level: other_sponsorship_level)
end
it 'returns correct url' do
expect(get_logo(sponsor)).to match %r{.*(\bothers/#{sponsor.logo_file_name}\b)}
end
end
context 'non-sponsor' do
it 'returns correct url' do
expect(get_logo(conference)).to match %r{.*(\blarge/#{conference.logo_file_name}\b)}
end
end
end
end end

View file

@ -0,0 +1,68 @@
require 'spec_helper'
describe ConferenceHelper, type: :helper do
let!(:conference) { create(:conference) }
let!(:contact) { create(:contact, conference: conference) }
describe '#one_call_open' do
it 'is falsey if neither call is open' do
expect(one_call_open(*conference.program.cfps)).to be_falsey
end
it 'is truthy if call_for_papers is open' do
create(
:cfp,
program: conference.program,
cfp_type: 'events',
start_date: conference.start_date,
end_date: conference.end_date
)
expect(one_call_open(*conference.program.cfps)).to be_truthy
end
it 'is truthy if call_for_tracks is open' do
create(
:cfp,
program: conference.program,
cfp_type: 'tracks',
start_date: conference.start_date,
end_date: conference.end_date
)
expect(one_call_open(*conference.program.cfps)).to be_truthy
end
it 'is falsey if both calls are open' do
create(
:cfp,
program: conference.program,
cfp_type: 'events',
start_date: conference.start_date,
end_date: conference.end_date
)
create(
:cfp,
program: conference.program,
cfp_type: 'tracks',
start_date: conference.start_date,
end_date: conference.end_date
)
expect(one_call_open(*conference.program.cfps)).to be_falsey
end
end
describe '#sponsorship_mailto' do
it 'constructs a mailto URL' do
expect(sponsorship_mailto(conference)).to match 'mailto:'
end
it 'points to the conference sponsor address' do
expect(sponsorship_mailto(conference)).to match contact.sponsor_email
end
it 'includes a conference identifier' do
expect(sponsorship_mailto(conference)).to match conference.short_title
end
end
end

View file

@ -1,40 +0,0 @@
require 'spec_helper'
describe SponsorsHelper, type: :helper do
let(:sponsor) { create(:sponsor) }
describe '#get_logo' do
context 'first sponsorship_level' do
before do
first_sponsorship_level = create(:sponsorship_level, position: 1)
sponsor.update_attributes(sponsorship_level: first_sponsorship_level)
end
it 'returns correct url' do
expect(get_logo(sponsor)).to match %r{.*(\bfirst/#{sponsor.logo_file_name}\b)}
end
end
context 'second sponsorship_level' do
before do
second_sponsorship_level = create(:sponsorship_level, position: 2)
sponsor.update_attributes(sponsorship_level: second_sponsorship_level)
end
it 'returns correct url' do
expect(get_logo(sponsor)).to match %r{.*(\bsecond/#{sponsor.logo_file_name}\b)}
end
end
context 'other sponsorship_level' do
before do
other_sponsorship_level = create(:sponsorship_level, position: 3)
sponsor.update_attributes(sponsorship_level: other_sponsorship_level)
end
it 'returns correct url' do
expect(get_logo(sponsor)).to match %r{.*(\bothers/#{sponsor.logo_file_name}\b)}
end
end
end
end

View file

@ -1704,4 +1704,8 @@ describe Conference do
it { is_expected.to eq [past_conference1, past_conference2] } it { is_expected.to eq [past_conference1, past_conference2] }
end end
it 'should have a picture format for tickets' do
expect(create(:conference).picture.ticket.url)
end
end end

15
spec/models/openid.rb Normal file
View file

@ -0,0 +1,15 @@
require 'spec_helper'
describe Openid do
subject { create(:openid) }
describe 'validation' do
it { is_expected.to validate_presence_of(:provider) }
it { is_expected.to validate_presence_of(:uid) }
it { is_expected.to validate_presence_of(:email) }
end
describe 'association' do
it { is_expected.to belong_to(:user) }
end
end

View file

@ -2,7 +2,7 @@ require 'spec_helper'
describe Program do describe Program do
subject { create(:program) } subject { create(:program) }
let!(:conference) { create(:conference, end_date: Date.today + 3) } let!(:conference) { create(:conference, end_date: Date.current + 3) }
let!(:program) { conference.program } let!(:program) { conference.program }
describe 'association' do describe 'association' do
@ -241,6 +241,54 @@ describe Program do
end end
end end
describe '#any_event_for_this_date?' do
let(:event){ create(:event, program: program) }
context 'when no schedule is selected for the conference' do
let(:schedule) { create(:schedule, program: program) }
let!(:event_schedule) { create(:event_schedule, event: event, schedule: schedule, start_time: DateTime.parse("#{Date.current + 1} 10:00").utc) }
it 'returns false irrespective of any date' do
expect(program.any_event_for_this_date?(Date.current + 1)).to eq false
end
it 'returns false if date passed is empty' do
expect(program.any_event_for_this_date?('')).to eq false
end
it 'returns false if date passed is nil' do
expect(program.any_event_for_this_date?(nil)).to eq false
end
end
context 'when schedule is selected for the conference' do
let(:schedule) { create(:schedule, program: program) }
let!(:event_schedule) { create(:event_schedule, event: event, schedule: schedule, start_time: DateTime.parse("#{Date.current + 1} 10:00").utc) }
before :each do
program.selected_schedule = event_schedule.schedule
program.save!
end
it 'returns true if there is any event for this date' do
expect(program.any_event_for_this_date?(Date.current + 1)).to eq true
end
it 'returns false if there is no event for this date' do
expect(program.any_event_for_this_date?(Date.current + 2)).to eq false
end
it 'returns false if date passed is empty' do
expect(program.any_event_for_this_date?('')).to eq false
end
it 'returns false if date passed is nil' do
expect(program.any_event_for_this_date?(nil)).to eq false
end
end
end
describe '#cfp' do describe '#cfp' do
it 'returns the cfp for events' do it 'returns the cfp for events' do
create(:cfp, cfp_type: 'events', program: program, end_date: Date.current + 1) create(:cfp, cfp_type: 'events', program: program, end_date: Date.current + 1)

View file

@ -345,24 +345,34 @@ describe User do
end end
describe 'proposals methods' do describe 'proposals methods' do
let(:submitter) { create(:submitter, user: user) } let(:submitter) { create(:user) }
let(:speaker) { create(:user) }
let(:event1) { create(:event, program: conference.program) } let(:event1) { create(:event, program: conference.program) }
let(:event2) { create(:event, program: conference.program) } let(:event2) { create(:event, program: conference.program) }
before do before do
event1.event_users << create(:event_user, user: user, event_role: 'submitter') event1.event_users << create(:event_user, user: submitter, event_role: 'submitter')
event2.event_users << create(:event_user, user: user, event_role: 'submitter') event2.event_users << create(:event_user, user: submitter, event_role: 'submitter')
event1.event_users << create(:event_user, user: speaker, event_role: 'speaker')
end end
describe '#proposals' do describe '#proposals' do
it 'returns events submitted by user' do it 'returns events submitted by user' do
expect(user.proposals(conference)).to match [event1, event2] expect(submitter.proposals(conference)).to match [event1, event2]
end
it 'returns events in which user is a speaker' do
expect(speaker.proposals(conference)).to match [event1]
end end
end end
describe '#proposal_count' do describe '#proposal_count' do
it 'returns number of events submitted by user' do it 'returns number of events submitted by user' do
expect(user.proposal_count(conference)).to eq 2 expect(submitter.proposal_count(conference)).to eq 2
end
it 'returns number of events in which the user is a speaker' do
expect(speaker.proposal_count(conference)).to eq 1
end end
end end
end end