diff --git a/.rubocop.yml b/.rubocop.yml
index 98897ae2..7da4d8d5 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -95,7 +95,7 @@ Metrics/BlockNesting:
Max: 4
Metrics/ClassLength:
- Max: 570
+ Max: 575
# avoid redundunt curly braces when it is obvious that hash is used
Style/BracesAroundHashParameters:
diff --git a/app/assets/stylesheets/osem-schedule.css.scss b/app/assets/stylesheets/osem-schedule.css.scss
index cc48da5d..bdcb6544 100644
--- a/app/assets/stylesheets/osem-schedule.css.scss
+++ b/app/assets/stylesheets/osem-schedule.css.scss
@@ -69,28 +69,14 @@ a.unstyled-link {
outline: 0;
}
-#schedule td.event {
- background-image: linear-gradient(to top, #f7faf2 24%, #c2e8be 97%,
-#c2e8be 100%);
-}
-
-#schedule td.event:hover {
- background-image: linear-gradient(to top, #f7faf2 24%, #53ab4a 97%,
-#53ab4a 100%);
-}
-
-.schedule-dropdown{
+.program-dropdown, .schedule-dropdown{
margin-left: 20%;
margin-right: 20%;
- margin-top: 20px;
+ margin-top: 40px;
margin-bottom: 20px;
}
-.schedule-dropdown > button{
- width: 100%;
-}
-
-.schedule-dropdown > .dropdown-menu{
+.schedule-dropdown > button, .program-dropdown > button, .program-dropdown > .dropdown-menu, .schedule-dropdown > .dropdown-menu{
width: 100%;
}
@@ -149,6 +135,64 @@ td.no-padding{
padding:0px !important;
}
+.all-events-title{
+ margin-top: 40px;
+ border-bottom: 1px solid #848484;
+}
+
+.date-title{
+ font-size: 23px;
+ font-weight: bold;
+ padding-bottom: 2px;
+ display:inline-block;
+}
+
+.start-time{
+ font-size: 16px;
+ padding-left: 30px;
+ margin-top: 32px;
+}
+
+.new-time-event{
+ margin-top: 20px;
+}
+
+.date-content{
+ border-bottom: 1px solid #6E6E6E;
+ margin-top: 30px;
+}
+
+.unscheduled-event{
+ margin-top: 8px;
+}
+
+.all-speaker-pic{
+ padding: 20px 10px 20px 10px;
+}
+
+.track{
+ padding: 0px 5px 0px 5px;
+ display: inline-block;
+ }
+
+.program-dropdown{
+ margin-left: 20%;
+ margin-right: 20%;
+ margin-top: 40px;
+}
+
+.program-dropdown > button{
+ width: 100%;
+}
+
+.program-dropdown > .dropdown-menu{
+ width: 100%;
+}
+
+.no-events-day{
+ color: #D8D8D8 !important;
+}
+
/* Small devices (tablets, 768px and up) */
@media (min-width: 768px) {
.room, .event-title{
diff --git a/app/controllers/conference_controller.rb b/app/controllers/conference_controller.rb
index da98b944..1dc1ded8 100644
--- a/app/controllers/conference_controller.rb
+++ b/app/controllers/conference_controller.rb
@@ -13,6 +13,10 @@ class ConferenceController < ApplicationController
def schedule
@rooms = @conference.venue.rooms if @conference.venue
+ unless @conference.program.events.scheduled.any?
+ redirect_to events_conference_path(@conference.short_title)
+ end
+
@events = @conference.program.events
@events_xml = @events.scheduled.order(start_time: :asc).group_by{ |event| event.start_time.to_date }
@dates = @conference.start_date..@conference.end_date
@@ -21,11 +25,22 @@ class ConferenceController < ApplicationController
conf_end = 20
@conf_period = conf_end - @conf_start
- if @dates == Date.current
- @today = Date.current.strftime('%Y-%m-%d')
- else
- @today = @conference.start_date.strftime('%Y-%m-%d')
- end
+ # the schedule takes you to today if it is a date of the schedule
+ @current_day = @conference.current_conference_day
+ @day = @current_day.present? ? @current_day : @dates.first
+ return unless @current_day
+ # the schedule takes you to the current time if it is beetween the start and the end time.
+ @hour_column = @conference.hours_from_start_time(@conf_start, conf_end)
+ end
+
+ def events
+ @dates = @conference.start_date..@conference.end_date
+
+ @scheduled_events = @conference.program.events.scheduled
+ @unscheduled_events = @conference.program.events.unscheduled
+
+ day = @conference.current_conference_day
+ @tag = day.strftime('%Y-%m-%d') if day
end
private
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 5004347c..ddc072af 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -335,4 +335,14 @@ module ApplicationHelper
# speaker picture padding: 4px 2px; and we want the picture to be a circle
speaker_height(rooms) - 4
end
+
+ def carousel_item_class(number, carousel_number, num_cols, col)
+ item_class = 'item'
+ item_class += ' first' if number == 0
+ item_class += ' last' if number == (carousel_number - 1)
+ if (col && ((col / num_cols) == number)) || (!col && number == 0)
+ item_class += ' active'
+ end
+ item_class
+ end
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index fb48808a..76e1fc4c 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -34,7 +34,7 @@ class Ability
conference.splashpage && conference.splashpage.public == true
end
# Can view the schedule
- can [:schedule], Conference do |conference|
+ can [:schedule, :events], Conference do |conference|
conference.program.cfp && conference.program.schedule_public
end
diff --git a/app/models/conference.rb b/app/models/conference.rb
index 149504d5..6d35946b 100644
--- a/app/models/conference.rb
+++ b/app/models/conference.rb
@@ -609,6 +609,21 @@ class Conference < ActiveRecord::Base
next_color(start_index[collection])
end
+ # Returns the current day if it is a day of the schedule or nil otherwise
+ def current_conference_day
+ day = Time.find_zone(timezone).today
+ day if (start_date..end_date).cover? day
+ end
+
+ # Returns the number of hours since the conference start hour (9) to the
+ # current hour, in case that the current hour is beetween the start and the
+ # end hour (20). Otherwise, returns 0
+ def hours_from_start_time(start_hour, end_hour)
+ current_time = Time.find_zone(timezone).now
+ current_hour = current_time.strftime('%H').to_i
+ (start_hour..(end_hour-1)).cover?(current_hour) ? current_hour - start_hour : 0
+ end
+
private
# Returns a different html colour for every i and consecutive colors are
diff --git a/app/models/event.rb b/app/models/event.rb
index a079cd13..3813c030 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -73,7 +73,7 @@ class Event < ActiveRecord::Base
# ====Returns
# * +true+ or +false+
def scheduled?
- room && start_time ? true : false
+ room.present? && start_time.present?
end
def registration_possible?
diff --git a/app/models/program.rb b/app/models/program.rb
index eba1d4b0..ffbb5ef0 100644
--- a/app/models/program.rb
+++ b/app/models/program.rb
@@ -27,7 +27,11 @@ class Program < ActiveRecord::Base
end
def scheduled
- where.not(start_time: nil).where.not(room: nil)
+ where.not(start_time: nil).where.not(room: nil).order(start_time: :asc)
+ end
+
+ def unscheduled
+ confirmed.where('start_time IS NULL OR room_id IS NULL')
end
def highlights
@@ -87,6 +91,17 @@ class Program < ActiveRecord::Base
self.languages.split(',').map {|l| ISO_639.find(l).english_name} if self.languages.present?
end
+ ##
+ # Checks if there is any event in the program that starts in the given date
+ #
+ # ====Returns
+ # * +True+ -> If there is any event for the given date
+ # * +False+ -> If there is not any event for the given date
+ def any_event_for_this_date?(date)
+ parsed_date = DateTime.parse("#{date} 00:00").utc
+ events.where(start_time: parsed_date..(parsed_date + 1)).any?
+ end
+
private
##
diff --git a/app/views/conference/_all_events.html.erb b/app/views/conference/_all_events.html.erb
deleted file mode 100644
index f7fd7fc0..00000000
--- a/app/views/conference/_all_events.html.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-
Program for <%= @conference.title %>
-<% @conference.program.events.confirmed.each do |event| %>
-
-
- <%= link_to event.title, conference_program_proposal_path(@conference.short_title, event.id) %>
-
-
- <%= event.subtitle %>
-
-
-
- presented by <%= event.speaker_names %>
-
-
- <%= truncate(event.abstract, :length => 400) -%>
- <%= link_to 'more', conference_program_proposal_path(@conference.short_title, @conference.program.id, event.id) if event.abstract.length > 400 %>
-
-
-<% end %>
diff --git a/app/views/conference/_carousel.html.erb b/app/views/conference/_carousel.html.erb
deleted file mode 100644
index fbdc8fa1..00000000
--- a/app/views/conference/_carousel.html.erb
+++ /dev/null
@@ -1,63 +0,0 @@
-<% intervals = number_columns * 60 / EventType::LENGTH_STEP + 1 %>
-<% width = 85 / intervals %>
-<% carousel_number = (@conf_period / number_columns.to_f).ceil %>
-
-
-
- <% start_time = DateTime.parse("#{date} #{@conf_start}:00") %>
- <% (0..carousel_number-1).each do |number| %>
-
-
-
- |
- <% td_start_time = start_time %>
- <% (1..intervals).each do |i| %>
- <%= (td_start_time).strftime("%H:%M") %> |
- <% td_start_time += @step_minutes %>
- <% end %>
-
-
- <% start_room_time = start_time %>
- <% @rooms.each do |room| %>
- <% start_room_time = start_time %>
- <% span = 1 %>
-
- |
-
- <%= room.name %>
-
- |
- <% events = room.events{ |e| e.start_time >= start_time and e.start_time < (start_time + number_columns.hour)} %>
- <% (1..intervals).each do |i| %>
- <% if span > 1 %>
- <% span -= 1 %>
- <% else %>
- <% event = events.find{|e| e.start_time <= start_room_time and e.end_time > start_room_time} %>
- <% if event %>
-
- <% event_span = (event.end_time.to_i - start_room_time.to_i) / 60 / EventType::LENGTH_STEP %>
- <% span = ((event_span + i - 1 ) > intervals ? intervals + 1 - i : event_span) %>
- <%= render partial: 'schedule_item', locals: {event: event, span: span, width: width} %>
- <% else %>
-
- |
- <% end %>
- <% end %>
- <% start_room_time += @step_minutes %>
- <% end %>
-
- <% end %>
- <% start_time = start_room_time - @step_minutes %>
-
-
- <% end %>
-
-
-
-
-
-
-
-
-
-
diff --git a/app/views/conference/_carousel.html.haml b/app/views/conference/_carousel.html.haml
new file mode 100644
index 00000000..bc8b3157
--- /dev/null
+++ b/app/views/conference/_carousel.html.haml
@@ -0,0 +1,55 @@
+- intervals = number_columns * 60 / EventType::LENGTH_STEP + 1
+- width = 85 / intervals
+- carousel_number = (@conf_period / number_columns.to_f).ceil
+.carousel.slide{ id: "carousel-#{ date }-#{ number_columns }", |
+ "data-ride" => "carousel", |
+ "data-wrap" => "false", |
+ "data-interval" => "false" }
+ / Wrapper for slides
+ .carousel-inner
+ - start_time = DateTime.parse("#{date} #{@conf_start}:00")
+ - (0..carousel_number-1).each do |number|
+ %div{ class: "#{ carousel_item_class(number, carousel_number, number_columns, @hour_column)}" }
+ %table.table.table-bordered.schedule-table#schedule
+ %tr
+ %th
+ - td_start_time = start_time
+ - (1..intervals).each do |i|
+ %th.date
+ = (td_start_time).strftime("%H:%M")
+ - td_start_time += @step_minutes
+
+ - start_room_time = start_time
+ - @rooms.each do |room|
+ - start_room_time = start_time
+ - span = 1
+ %tr
+ %td.room{ style: "height: #{ td_height(@rooms) }px;" }
+ .room.elipsis.break-words{ style: "-webkit-line-clamp: #{ room_lines(@rooms) }; height: #{ room_height(@rooms) }px;" }
+ = room.name
+ - events = room.events{ |e| e.start_time >= start_time and e.start_time < (start_time + number_columns.hour)}
+ - (1..intervals).each do |i|
+ - if span > 1
+ - span -= 1
+ - else
+ - event = events.find{|e| e.start_time <= start_room_time and e.end_time > start_room_time}
+ - if event
+ / There is an event, calculate the span and show it
+ - event_span = (event.end_time.to_i - start_room_time.to_i) / 60 / EventType::LENGTH_STEP
+ - span = ((event_span + i - 1 ) > intervals ? intervals + 1 - i : event_span)
+ = render partial: 'schedule_item', locals: {event: event, span: span, width: width}
+ - else
+ / if span equals 1 show an empty td
+ %td.no-padding{ width: "#{ width }%"}
+ - start_room_time += @step_minutes
+ - start_time = start_room_time - @step_minutes
+
+ / Controls
+ %a.left.carousel-control{ href: "#carousel-#{ date }-#{ number_columns }", |
+ role: "button", |
+ "data-slide" => "prev" }
+ %span.glyphicon.glyphicon-chevron-left
+ %a.right.carousel-control{ href: "#carousel-#{ date }-#{ number_columns }", |
+ role: "button", |
+ "data-slide" => "next" }
+ %span.glyphicon.glyphicon-chevron-right
diff --git a/app/views/conference/_event.html.haml b/app/views/conference/_event.html.haml
new file mode 100644
index 00000000..98c835d3
--- /dev/null
+++ b/app/views/conference/_event.html.haml
@@ -0,0 +1,33 @@
+%a.unstyled-link{href: url_for(conference_program_proposal_path(@conference.short_title, event.id))}
+ .panel.panel-default
+ .panel-body
+ - if speaker = event.speakers.first
+ = image_tag speaker.gravatar_url, :class => "img-circle pull-right all-speaker-pic", |
+ :alt => speaker.name, |
+ :title => speaker.name |
+ %span.h3
+ = event.title
+ %br
+ %small
+ = event.subtitle
+ %h4
+ presented by #{event.speaker_names}
+ %p
+ = truncate(event.abstract, :length => 400)
+ = link_to 'more', conference_program_proposal_path(@conference.short_title, event.id) if event.abstract.length > 400
+ - if event.scheduled?
+ %span.track
+ %span.fa.fa-clock-o
+ %span.label{ style: "background-color: grey" }
+ = event.start_time.strftime('%H:%M')
+ \-
+ = event.end_time.strftime('%H:%M')
+ %span.track
+ %span.fa.fa-map-marker
+ %span.label{ style: "background-color: grey" }
+ = event.room.name
+ - if event.track
+ %span.track
+ %span.fa.fa-road
+ %span.label{ style: "background-color: #{event.track.color}; color: #{ contrast_color(event.track.color) }" }
+ = event.track.name
diff --git a/app/views/conference/_schedule.html.erb b/app/views/conference/_schedule.html.erb
deleted file mode 100644
index 991529cc..00000000
--- a/app/views/conference/_schedule.html.erb
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
Schedule for <%= @conference.title %>
-
-
-
-
-
-
- <% @dates.each do |date| %>
-
-
-
- <% number_columns = 1 %>
- <%= render 'carousel', date: date, number_columns: number_columns %>
-
-
-
- <% number_columns = 2 %>
- <%= render 'carousel', date: date, number_columns: number_columns %>
-
-
-
- <% number_columns = 3 %>
- <%= render 'carousel', date: date, number_columns: number_columns %>
-
-
-
- <% end %>
-
-
-<%= javascript_tag do %>
-// change of active tab and the button title when a date clicked
-$(function() {
- $('.date-tab').on('click', function(e) {
- $('.li-dropdown-schedule').removeClass('active');
- $('.schedule-dropdown').find('button').text($(this).text());
- });
-});
-
-// use the date tag in the url to select a tab and the title of the button
-$(function() {
- var hash = window.location.hash;
- if(hash && !(hash === '#schedule')){
- hash && $('ul a[href="' + hash + '"]').tab('show');
- $('button.dropdown-toggle').text(hash.substr(1));
- }
-});
-
-// hide the right and left controls when neccesary after moving the carousel
-$('.carousel').on('slid.bs.carousel', '',
-function(){
- $(this).children('.left.carousel-control').show();
- $(this).children('.right.carousel-control').show();
- if($(this).find('.first').hasClass('active')) {
- $(this).children('.left.carousel-control').hide();
- } else if($(this).find('.last').hasClass('active')) {
- $(this).children('.right.carousel-control').hide();
- }
-});
-
-$(document).ready(function(){
- // hide the left control when the page is ready
- $('.carousel').children('.left.carousel-control').hide();
-
- // carousel swipe
- $(".carousel-inner").swiperight(function() {
- $(this).parent().carousel('prev');
- });
- $(".carousel-inner").swipeleft(function() {
- $(this).parent().carousel('next');
- });
-});
-<% end %>
diff --git a/app/views/conference/_schedule.html.haml b/app/views/conference/_schedule.html.haml
new file mode 100644
index 00000000..d0d1e3de
--- /dev/null
+++ b/app/views/conference/_schedule.html.haml
@@ -0,0 +1,68 @@
+#schedule-content
+ %h1.text-center
+ Schedule for
+ = @conference.title
+ .dropdown.schedule-dropdown
+ %button{ type: "button", class: "btn btn-default dropdown-toggle", 'data-toggle' => "dropdown" }
+ = @dates.first
+ %span.caret
+ %ul.dropdown-menu
+ - @dates.each do |date|
+ %li.li-dropdown-schedule
+ = link_to date, "#" + "#{date}", "data-toggle" => "tab", "class" => "date-tab"
+
+ .tab-content
+ - @dates.each do |date|
+ %div{ class: "tab-pane #{ 'active' if @dates.first == date }", id: "#{ date }" }
+
+ .visible-xs-inline
+ = render partial: 'carousel', locals: { date: date, number_columns: 1 }
+
+ .visible-sm-inline
+ = render partial: 'carousel', locals: { date: date, number_columns: 2 }
+
+ .visible-md-inline.visible-lg-inline
+ = render partial: 'carousel', locals: { date: date, number_columns: 3 }
+
+:javascript
+ // change of active tab and the button title when a date clicked
+ $(function() {
+ $('.date-tab').on('click', function(e) {
+ $('.li-dropdown-schedule').removeClass('active');
+ $('.schedule-dropdown').find('button').text($(this).text());
+ });
+ });
+
+ // use the date tag in the url to select a tab and the title of the button
+ $(function() {
+ var hash = window.location.hash;
+ if(hash && !(hash === '#schedule')){
+ hash && $('ul a[href="' + hash + '"]').tab('show');
+ $('button.dropdown-toggle').text(hash.substr(1));
+ }
+ });
+
+ // hide the right and left controls when neccesary after moving the carousel
+ $('.carousel').on('slid.bs.carousel', '',
+ function(){
+ $(this).children('.left.carousel-control').show();
+ $(this).children('.right.carousel-control').show();
+ if($(this).find('.first').hasClass('active')) {
+ $(this).children('.left.carousel-control').hide();
+ } else if($(this).find('.last').hasClass('active')) {
+ $(this).children('.right.carousel-control').hide();
+ }
+ });
+
+ $(document).ready(function(){
+ // hide the left control when the page is ready
+ $('.carousel').children('.left.carousel-control').hide();
+
+ // carousel swipe
+ $(".carousel-inner").swiperight(function() {
+ $(this).parent().carousel('prev');
+ });
+ $(".carousel-inner").swipeleft(function() {
+ $(this).parent().carousel('next');
+ });
+ });
diff --git a/app/views/conference/_schedule_item.html.haml b/app/views/conference/_schedule_item.html.haml
index d4d34ac7..c611e2ad 100644
--- a/app/views/conference/_schedule_item.html.haml
+++ b/app/views/conference/_schedule_item.html.haml
@@ -1,6 +1,6 @@
%td.event{ width: "#{ width * span }%" , |
colspan: span, |
- role: "button" } |
+ role: "button" }
%a.unstyled-link{href: url_for(conference_program_proposal_path(@conference.short_title, event.id))}
%div{ class: "elipsis break-words event-title", |
style: "-webkit-line-clamp: #{ event_lines(@rooms) }; height: #{ event_height(@rooms) }px;"} |
diff --git a/app/views/conference/_schedule_tabs.html.haml b/app/views/conference/_schedule_tabs.html.haml
new file mode 100644
index 00000000..6ca529b3
--- /dev/null
+++ b/app/views/conference/_schedule_tabs.html.haml
@@ -0,0 +1,7 @@
+%div{ role: "tabpanel" }
+ / Nav tabs
+ %ul.nav.nav-tabs{ role: "tablist" }
+ %li{ class: "schedule #{ 'active' if active == 'schedule' }", role: "presentation" }
+ = link_to('Schedule', schedule_conference_path(@conference.short_title))
+ %li{ class: "program #{ 'active' if active == 'program' }", role: "presentation" }
+ = link_to('All events', events_conference_path(@conference.short_title))
diff --git a/app/views/conference/events.html.haml b/app/views/conference/events.html.haml
new file mode 100644
index 00000000..d011390d
--- /dev/null
+++ b/app/views/conference/events.html.haml
@@ -0,0 +1,65 @@
+.container#program
+ -if @scheduled_events.any?
+ = render partial: 'schedule_tabs', locals: { active: 'program' }
+
+ %h1.text-center
+ Program for
+ = @conference.title
+ .dropdown.program-dropdown
+ %button{ type: "button", class: "btn btn-default dropdown-toggle", 'data-toggle' => "dropdown" }
+ Dates
+ %span.caret
+ %ul.dropdown-menu
+ - @dates.each do |date|
+ %li.li-dropdown-program
+ = link_to date, "##{date}", class: "program-selector#{ ' no-events-day' unless @conference.program.any_event_for_this_date?(date) }"
+ - if @unscheduled_events.any?
+ %li.li-dropdown-program
+ = link_to('Unscheduled', "#unscheduled", class: 'program-selector')
+
+ .row
+
+ / scheduled events
+ - date = nil
+ - time = nil
+ - @scheduled_events.each do |event|
+ - unless event.start_time.strftime('%Y-%m-%d').eql?(date)
+ .col-xs-12.col-md-12
+ .date-content
+ %span{ class: 'date-title', id: "#{ event.start_time.strftime('%Y-%m-%d') }" }
+ = date = event.start_time.strftime('%Y-%m-%d')
+ %a{ title: "Go up", class: "pull-right", href: "#program" }
+ %i{ class: "fa fa-angle-double-up fa-lg", 'aria-hidden' => true }
+ - unless event.start_time.strftime('%H:%M').eql?(time)
+ .col-xs-12.col-md-1
+ .start-time
+ = time = event.start_time.strftime('%H:%M')
+ .col-xs-12.col-md-11
+ .new-time-event
+ = render partial: 'event', locals: {event: event}
+ - else
+ .col-xs-12.col-md-11.col-md-offset-1
+ = render partial: 'event', locals: {event: event}
+
+ / confirmed events that are not scheduled
+ - if @unscheduled_events.any?
+ .col-xs-12.col-md-12
+ .date-content
+ %span.date-title#unscheduled
+ Unscheduled events
+ %a{ title: "Go up", class: "pull-right", href: "#program" }
+ %i{ class: "fa fa-angle-double-up fa-lg", 'aria-hidden' => true }
+ - @unscheduled_events.each do |event|
+ .col-xs-12.col-md-12
+ .unscheduled-event
+ = render partial: 'event', locals: {event: event}
+
+:javascript
+ $('.program-selector').on('click', function(e) {
+ $('.li-dropdown-program').removeClass('active');
+ });
+
+ // Go to current date and time
+ $(document).ready(function(){
+ document.getElementById("#{ @tag }").scrollIntoView();
+ });
diff --git a/app/views/conference/schedule.html.erb b/app/views/conference/schedule.html.erb
deleted file mode 100644
index f39b0cc2..00000000
--- a/app/views/conference/schedule.html.erb
+++ /dev/null
@@ -1,27 +0,0 @@
-
- <% if @rooms.length > 1 and @conference.program.events.scheduled.any? %>
-
-
-
-
-
-
-
- <%= render 'schedule' %>
-
-
- <%= render 'all_events' %>
-
-
-
- <% else %>
- <%= render 'all_events' %>
- <% end %>
-
diff --git a/app/views/conference/schedule.html.haml b/app/views/conference/schedule.html.haml
new file mode 100644
index 00000000..ea9971c1
--- /dev/null
+++ b/app/views/conference/schedule.html.haml
@@ -0,0 +1,81 @@
+.container
+ = render partial: 'schedule_tabs', locals: { active: 'schedule' }
+
+ #schedule-content
+ %h1.text-center
+ Schedule for
+ = @conference.title
+ .dropdown.schedule-dropdown
+ %button{ type: "button", class: "btn btn-default dropdown-toggle", 'data-toggle' => "dropdown" }
+ = @day
+ %span.caret
+ %ul.dropdown-menu
+ - @dates.each do |date|
+ %li.li-dropdown-schedule{ class: "#{ 'active' if @day == date }" }
+ = link_to date, "#" + "#{date}", "data-toggle" => "tab", "class" => "date-tab"
+
+ .tab-content
+ - @dates.each do |date|
+ %div{ class: "tab-pane #{ 'active' if @day == date }", id: "#{ date }" }
+
+ .visible-xs-inline
+ = render partial: 'carousel', locals: { date: date, number_columns: 1 }
+
+ .visible-sm-inline
+ = render partial: 'carousel', locals: { date: date, number_columns: 2 }
+
+ .visible-md-inline.visible-lg-inline
+ = render partial: 'carousel', locals: { date: date, number_columns: 3 }
+
+:javascript
+ // change of active tab and the button title when a date is clicked
+ $(function() {
+ $('.date-tab').on('click', function(e) {
+ $('.li-dropdown-schedule').removeClass('active');
+ $('.schedule-dropdown').find('button').text($(this).text());
+ });
+ });
+
+ // hide the right and left controls when neccesary after moving the carousel
+ $('.carousel').on('slid.bs.carousel', '',
+ function(){
+ $(this).children('.left.carousel-control').show();
+ $(this).children('.right.carousel-control').show();
+ if($(this).find('.first').hasClass('active')) {
+ $(this).children('.left.carousel-control').hide();
+ }
+ if($(this).find('.last').hasClass('active')) {
+ $(this).children('.right.carousel-control').hide();
+ }
+ });
+
+ $(document).ready(function(){
+ // hide the left control when the page is ready
+ $('.carousel').each(function() {
+ if($(this).find('.first').hasClass('active')) {
+ $(this).children('.left.carousel-control').hide();
+ }
+ if($(this).find('.last').hasClass('active')) {
+ $(this).children('.right.carousel-control').hide();
+ }
+ });
+
+ // carousel swipe
+ $(".carousel-inner").swiperight(function() {
+ $(this).parent().carousel('prev');
+ });
+ $(".carousel-inner").swipeleft(function() {
+ $(this).parent().carousel('next');
+ });
+
+ var day = "#{@current_day}";
+ // we only go to the date tag in the url if the conference is not taking place now
+ if(day === ""){
+ // use the date tag in the url to select a tab and the title of the button
+ var hash = window.location.hash;
+ if(hash && !(hash === '#schedule')){
+ hash && $('ul a[href="' + hash + '"]').tab('show');
+ $('button.dropdown-toggle').text(hash.substr(1));
+ }
+ }
+ });
diff --git a/config/routes.rb b/config/routes.rb
index 3e83fd1b..a2bd18a6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -115,6 +115,7 @@ Osem::Application.routes.draw do
member do
get :schedule
+ get :events
end
end