diff --git a/Gemfile.lock b/Gemfile.lock
index f6fcb33..1ca0cf3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -162,11 +162,11 @@ GEM
daemons (1.2.3)
database_cleaner (1.5.0)
debug_inspector (0.0.2)
- delayed_job (4.0.6)
+ delayed_job (4.1.1)
activesupport (>= 3.0, < 5.0)
- delayed_job_active_record (4.0.3)
- activerecord (>= 3.0, < 5.0)
- delayed_job (>= 3.0, < 4.1)
+ delayed_job_active_record (4.1.0)
+ activerecord (>= 3.0, < 5)
+ delayed_job (>= 3.0, < 5)
diff-lcs (1.2.5)
diffy (3.0.7)
docile (1.1.5)
@@ -189,16 +189,16 @@ GEM
railties (>= 3.2, < 5.0)
forgery (0.6.0)
formatador (0.2.5)
- gdk_pixbuf2 (3.0.3)
- glib2 (= 3.0.3)
- gdk_pixbuf2 (3.0.3-x86-mingw32)
- glib2 (= 3.0.3)
+ gdk_pixbuf2 (3.0.5)
+ glib2 (= 3.0.5)
+ gdk_pixbuf2 (3.0.5-x86-mingw32)
+ glib2 (= 3.0.5)
geocoder (1.2.11)
gherkin3 (3.1.1)
git-version-bump (0.15.1)
- glib2 (3.0.3)
+ glib2 (3.0.5)
pkg-config
- glib2 (3.0.3-x86-mingw32)
+ glib2 (3.0.5-x86-mingw32)
cairo (>= 1.12.8)
pkg-config
globalid (0.3.6)
@@ -225,7 +225,7 @@ GEM
haml (>= 4.0.6, < 5.0)
html2haml (>= 1.0.1)
railties (>= 4.0.1)
- highline (1.7.5)
+ highline (1.7.7)
html2haml (2.0.0)
erubis (~> 2.7.0)
haml (~> 4.0.0)
@@ -266,7 +266,7 @@ GEM
mime-types (2.6.2)
mini_magick (4.3.3)
mini_portile (0.6.2)
- minitest (5.8.0)
+ minitest (5.8.1)
mocha (1.1.0)
metaclass (~> 0.0.1)
multi_json (1.11.2)
@@ -278,7 +278,7 @@ GEM
net-ssh (>= 2.6.5)
net-sftp (2.1.2)
net-ssh (>= 2.6.5)
- net-ssh (2.9.2)
+ net-ssh (3.0.1)
net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5)
netrc (0.10.3)
@@ -296,9 +296,9 @@ GEM
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
- pango (3.0.3-x86-mingw32)
+ pango (3.0.5-x86-mingw32)
cairo (>= 1.14.0)
- glib2 (= 3.0.3)
+ glib2 (= 3.0.5)
paper_trail (3.0.8)
activerecord (>= 3.0, < 5.0)
activesupport (>= 3.0, < 5.0)
@@ -314,11 +314,11 @@ GEM
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
- pry (0.10.1)
+ pry (0.10.2)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
- pry (0.10.1-x86-mingw32)
+ pry (0.10.2-x86-mingw32)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
@@ -397,13 +397,13 @@ GEM
rspec-mocks (~> 3.3.0)
rspec-support (~> 3.3.0)
rspec-support (3.3.0)
- rsvg2 (3.0.3)
+ rsvg2 (3.0.5)
cairo (>= 1.12.8)
- gdk_pixbuf2 (= 3.0.3)
- rsvg2 (3.0.3-x86-mingw32)
+ gdk_pixbuf2 (= 3.0.5)
+ rsvg2 (3.0.5-x86-mingw32)
cairo (>= 1.12.8)
- gdk_pixbuf2 (= 3.0.3)
- pango (>= 3.0.3)
+ gdk_pixbuf2 (= 3.0.5)
+ pango (>= 3.0.5)
ruby_parser (3.7.1)
sexp_processor (~> 4.1)
rubyzip (1.1.7)
@@ -411,7 +411,7 @@ GEM
capistrano (~> 2.15.4)
safe_yaml (1.0.4)
sass (3.4.18)
- sass-json-vars (0.3.2)
+ sass-json-vars (0.3.3)
sass (>= 3.1)
sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0)
@@ -438,8 +438,8 @@ GEM
bcrypt (~> 3.1)
oauth (~> 0.4, >= 0.4.4)
oauth2 (>= 0.8.0)
- sprockets (3.3.4)
- rack (~> 1.0)
+ sprockets (3.3.5)
+ rack (> 1, < 3)
sprockets-rails (2.3.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss
index 4b31f79..d38194d 100644
--- a/app/assets/stylesheets/_application.scss
+++ b/app/assets/stylesheets/_application.scss
@@ -88,7 +88,6 @@ button,
&.register {
background-color: $colour-4;
- //@include _(text-shadow, 0 0 0.15em rgba(0, 0, 0, 0.5));
}
form.logout & {
@@ -102,6 +101,10 @@ button,
#main &.delete {
background-color: $colour-4;
}
+
+ #main &.secondary {
+ background-color: $colour-1;
+ }
}
a.button {
@@ -505,12 +508,16 @@ input {
padding: 0 0.25em;
font-weight: normal;
@include font-family(secondary);
- @include _(text-stroke, 0.5px #000)
+ @include _(text-stroke, 0.5px #000);
}
.date-labels {
float: left;
}
+
+ .date-field {
+ overflow: auto;
+ }
}
form {
@@ -530,6 +537,10 @@ form {
vertical-align: middle;
}
+ &.left {
+ text-align: left;
+ }
+
&.right {
text-align: right;
@@ -1940,3 +1951,234 @@ html[data-lingua-franca-example="html"] {
float: left;
}
}
+
+.conferences-edit_schedule {
+ #main {
+ .location {
+ padding-top: 0.25em;
+ }
+ .errors {
+ padding: 0.25em;
+ background-color: $colour-2;
+ color: $white;
+ @include _(text-stroke, 0.5px #000);
+ }
+ .conflict-score {
+ padding: 0.25em;
+ background-color: $colour-3;
+ color: #333;
+ }
+ .all-workshops, .all-events {
+ list-style: none;
+ padding: 0;
+
+ li {
+ margin: 0.5em;
+ padding: 0.5em;
+ border: 1px solid #CCC;
+ background-color: lighten($colour-1, 35);
+ @include default-box-shadow(top, 2);
+
+ &.error {
+ outline: 0.2em solid $colour-2;
+ outline-offset: -0.2em;
+ }
+ }
+
+ h3 {
+ margin: 0;
+ }
+
+ .workshop-interest {
+ color: #888;
+ text-align: left;
+ margin: 0.25em 0;
+ }
+
+ .error-description {
+ background-color: $colour-2;
+ color: $white;
+ padding: 0.5em;
+ margin-top: 0.5em;
+ }
+
+ .warnings {
+ background-color: $colour-3;
+ color: #333;
+ padding: 0.5em;
+ margin-top: 0.5em;
+ list-style: none;
+
+ li {
+ padding: 0;
+ margin: 0;
+ background-color: transparent;
+ @include _(box-shadow, none);
+ }
+ }
+ }
+ .day_parts {
+ list-style: none;
+
+ h4 {
+ display: inline-block;
+ min-width: 12.5em;
+ margin: 0.25em 0;
+ }
+
+ select, .select {
+ float: right;
+ min-width: 5em;
+ }
+
+ .select {
+ padding-left: 0.25em;
+ }
+ }
+ .actions {
+ margin: 2em;
+ }
+ .unsaved {
+ @include font-family(secondary);
+ background-color: lighten($colour-3, 25);
+ margin: 0 5em 2em;
+ padding: 0.5em;
+ }
+ .all-events {
+ li {
+ background-color: lighten($colour-5, 35);
+
+ &.meal {
+ background-color: lighten($colour-3, 25);
+ }
+ }
+
+ h3 {
+ margin-bottom: 0.5em;
+ }
+ }
+ }
+}
+
+.programme {
+
+ .schedule {
+ width: auto;
+ margin: 0;
+ min-width: 100%;
+ @include _(box-shadow, none);
+ table-layout: fixed;
+ border-spacing: 0.25em;
+ border-collapse: separate;
+
+ td {
+ position: relative;
+ vertical-align: middle;
+
+ .title {
+ text-align: center;
+ @include font-family(secondary);
+ color: #666;
+ }
+
+
+ &.previewable {
+ cursor: pointer;
+
+ &:hover {
+ @include default-box-shadow(top, 2);
+ }
+ }
+
+ &.workshop {
+ background-color: lighten($colour-1, 35);
+ border: 0.25em solid $colour-1;
+
+ .preview {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+
+ @include after {
+ display: none;
+ }
+ }
+ }
+
+ &.event {
+ background-color: lighten($colour-5, 35);
+ border: 0.25em solid $colour-5;
+ }
+
+ &.meal {
+ background-color: lighten($colour-3, 25);
+ border: 0.25em solid $colour-3;
+ }
+
+ &.not-interested {
+ opacity: 0.5;
+ }
+
+ .info {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1000;
+ background-color: $white;
+ text-align: left;
+ overflow-y: auto;
+ @include _(transition, transform 250ms ease-in-out);
+ @include _(transform-origin, center bottom);
+ @include _(transform, rotate(180deg) translate3d(0, 0, 0));
+
+ .close {
+ float: right;
+ font-size: 2em;
+
+ @include before {
+ content: '×';
+ padding: 0 0.5em;
+ }
+
+ @include after {
+ display: none;
+ }
+ }
+
+ h2 {
+ margin-bottom: 0.5em;
+ }
+ }
+
+ &:target .info {
+ @include _(transform, rotate(0) translate3d(0, 0, 0));
+ }
+ }
+ }
+
+ .programme-day {
+ margin-top: 2em;
+ }
+
+ .programme-day-part {
+ overflow-x: auto;
+ }
+}
+
+.select-field {
+ line-height: 1.75em;
+
+ select {
+ display: block;
+ width: 100%;
+ height: 2.1em;
+ font-family: inherit;
+ font-size: 1.5em;
+ padding: 0.25em;
+ @include default-box-shadow(top, 1.5, false);
+ }
+}
diff --git a/app/assets/stylesheets/_settings.scss b/app/assets/stylesheets/_settings.scss
index 980120f..6d5e9d3 100644
--- a/app/assets/stylesheets/_settings.scss
+++ b/app/assets/stylesheets/_settings.scss
@@ -7,7 +7,7 @@ $sidebar-width: rems(19);
// $colour-5: #8EA604;
$colour-1: #00ADEF; // blue
-$colour-2: #DD57EF; // pink
+$colour-2: #EF57B4; // #DD57EF; // pink
$colour-3: #E6C74B; // yellow
$colour-4: #D89E59; // orange
$colour-5: #02CA9E; // green
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 94bd7a2..f0c201a 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -4,6 +4,8 @@ module ActiveRecord
end
class ApplicationController < LinguaFrancaApplicationController
+ include ScheduleHelper
+
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception, :except => [:do_confirm]
@@ -35,6 +37,21 @@ class ApplicationController < LinguaFrancaApplicationController
super
end
+ def home
+ @workshops = Workshop.where(:conference_id => @conference.id)
+
+ if @conference.workshop_schedule_published
+ @events = Event.where(:conference_id => @conference.id)
+ schedule = get_schedule_data
+ @schedule = schedule[:schedule]
+ @locations = Hash.new
+ EventLocation.where(:conference_id => @conference.id).each do |l|
+ @locations[l.id.to_s] = l
+ end
+ @day_parts = @conference.day_parts ? JSON.parse(@conference.day_parts) : {:morning => 0, :afternoon => 13, :evening => 18}
+ end
+ end
+
def policy
@is_policy_page = true
end
diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb
index 450f87a..fe2a31e 100644
--- a/app/controllers/conferences_controller.rb
+++ b/app/controllers/conferences_controller.rb
@@ -2,6 +2,8 @@ require 'geocoder/calculations'
require 'rest_client'
class ConferencesController < ApplicationController
+ include ScheduleHelper
+
before_action :set_conference, only: [:show, :edit, :update, :destroy, :registrations]
before_filter :authenticate, only: [:registrations]
@@ -890,8 +892,8 @@ class ConferencesController < ApplicationController
can_edit = workshop.can_edit?(current_user)
do_403 unless can_edit || workshop.can_translate?(current_user, I18n.locale)
- workshop.title = params[:title]
- workshop.info = params[:info]
+ workshop.title = params[:title]
+ workshop.info = params[:info]
if can_edit
# dont allow translators to edit these fields
@@ -1033,6 +1035,269 @@ class ConferencesController < ApplicationController
return redirect_to view_workshop_url(@this_conference.slug, params[:workshop_id])
end
+ def schedule
+ set_conference
+ do_404 unless @this_conference.workshop_schedule_published || @this_conference.host?(current_user)
+
+ @events = Event.where(:conference_id => @this_conference.id)
+ @locations = EventLocation.where(:conference_id => @this_conference.id)
+
+ render 'schedule/show'
+ end
+
+ def edit_schedule
+ set_conference
+ set_conference_registration
+ do_404 unless @this_conference.host?(current_user)
+
+ @workshops = Workshop.where(:conference_id => @this_conference.id)
+ @events = Event.where(:conference_id => @this_conference.id)
+ if session[:workshops]
+ (0...@workshops.count).each do |i|
+ id = @workshops[i].id
+ w = session[:workshops][id.to_s]
+ if w
+ @workshops[i].start_time = w[:start_time]
+ @workshops[i].end_time = w[:end_time]
+ @workshops[i].event_location_id = w[:event_location_id]
+ end
+ end
+ end
+ if session[:events]
+ (0...@events.count).each do |i|
+ id = @events[i].id
+ w = session[:events][id.to_s]
+ if w
+ @events[i].start_time = w[:start_time]
+ @events[i].end_time = w[:end_time]
+ @events[i].event_location_id = w[:event_location_id]
+ end
+ end
+ end
+ @locations = EventLocation.where(:conference_id => @this_conference.id)
+ @location_hash = Hash.new
+ @locations.each do |l|
+ @location_hash[l.id.to_s] = l
+ end
+
+ @days = Array.new
+ start_day = @this_conference.start_date.strftime('%u').to_i
+ end_day = start_day + ((@this_conference.end_date - @this_conference.start_date) / 86400)
+
+ (start_day..end_day).each do |i|
+ @days << [(@this_conference.start_date + (i - start_day).days).strftime('%a'), ((i + 1) - start_day)]
+ end
+
+ @hours = Array.new
+ (0..48).each do |i|
+ hour = (Date.today + (i / 2.0).hours).strftime('%R')
+ @hours << hour
+ end
+
+ @event_durations = [['30 mins', 30], ['1 hour', 60], ['1.5 hours', 90], ['2 hours', 120], ['2.5 hours', 150]]
+ @workshop_durations = [['1 hour', 60], ['1.5 hours', 90], ['2 hours', 120]]
+
+ schedule_data = get_schedule_data
+ @schedule = schedule_data[:schedule]
+ @errors = schedule_data[:errors]
+ @warnings = schedule_data[:warnings]
+ @conflict_score = schedule_data[:conflict_score]
+ @error_count = schedule_data[:error_count]
+ if session[:day_parts]
+ @day_parts = JSON.parse(session[:day_parts])
+ elsif @this_conference.day_parts
+ @day_parts = JSON.parse(@this_conference.day_parts)
+ else
+ @day_parts = {:morning => 0, :afternoon => 13, :evening => 18}
+ end
+ @saved = session[:workshops].nil?
+
+ render 'schedule/edit'
+ end
+
+ def save_schedule
+ set_conference
+ do_404 unless @this_conference.host?(current_user)
+
+ @days = Array.new
+ start_day = @this_conference.start_date.strftime('%u').to_i
+ end_day = start_day + ((@this_conference.end_date - @this_conference.start_date) / 86400)
+
+ (start_day..end_day).each do |i|
+ @days << [(@this_conference.start_date + (i - start_day).days).strftime('%a'), i]
+ end
+
+ @workshops = Workshop.where(:conference_id => @this_conference.id)
+ @events = Event.where(:conference_id => @this_conference.id)
+ @locations = EventLocation.where(:conference_id => @this_conference.id)
+
+ do_save = (params[:button] == 'save' || params[:button] == 'publish')
+ session[:workshops] = do_save ? nil : Hash.new
+ session[:events] = do_save ? nil : Hash.new
+ session[:day_parts] = do_save ? nil : Hash.new
+
+ (0...@workshops.count).each do |i|
+ id = @workshops[i].id.to_s
+ if params[:workshop_day][id].present? && params[:workshop_hour][id].present? && params[:workshop_duration][id].present?
+ date = @this_conference.start_date + (params[:workshop_day][id].to_i - 1).days
+ h = params[:workshop_hour][id].split(':')
+ date = date.change({hour: h.first, minute: h.last})
+ @workshops[i].start_time = date
+ @workshops[i].end_time = date + (params[:workshop_duration][id].to_i).minutes
+ else
+ @workshops[i].start_time = nil
+ @workshops[i].end_time = nil
+ end
+ @workshops[i].event_location_id = params[:workshop_location][id]
+ if do_save
+ @workshops[i].save
+ else
+ session[:workshops][id] = {
+ :start_time => @workshops[i].start_time,
+ :end_time => @workshops[i].end_time,
+ :end_time => @workshops[i].end_time,
+ :event_location_id => @workshops[i].event_location_id
+ }
+ end
+ end
+
+ (0...@events.count).each do |i|
+ id = @events[i].id.to_s
+ if params[:event_day][id].present? && params[:event_hour][id].present? && params[:event_duration][id].present?
+ date = @this_conference.start_date + (params[:event_day][id].to_i - 1).days
+ h = params[:event_hour][id].split(':')
+ date = date.change({hour: h.first, minute: h.last})
+ @events[i].start_time = date
+ @events[i].end_time = date + (params[:event_duration][id].to_i).minutes
+ else
+ @events[i].start_time = nil
+ @events[i].end_time = nil
+ end
+ @events[i].event_location_id = params[:event_location][id]
+ if do_save
+ @events[i].save
+ else
+ session[:events][id] = {
+ :start_time => @events[i].start_time,
+ :end_time => @events[i].end_time,
+ :end_time => @events[i].end_time,
+ :event_location_id => @events[i].event_location_id
+ }
+ end
+ end
+
+ if params[:day_parts]
+ day_parts = {:morning => 0}
+ params[:day_parts].each do |part, h|
+ h = h.split(':')
+ day_parts[part.to_sym] = h[0].to_f + (h[1].to_i > 0 ? 0.5 : 0)
+ end
+ if do_save
+ @this_conference.day_parts = day_parts.to_json
+ else
+ session[:day_parts] = day_parts.to_json
+ end
+ end
+
+ save_conference = do_save
+
+ if params[:button] == 'publish'
+ @this_conference.workshop_schedule_published = true
+ save_conference = true
+ elsif params[:button] == 'unpublish'
+ @this_conference.workshop_schedule_published = false
+ save_conference = true
+ end
+
+ if save_conference
+ @this_conference.save
+ end
+
+ redirect_to edit_schedule_url(@this_conference.slug)
+ end
+
+ def add_event
+ set_conference
+ set_conference_registration
+ do_404 unless @this_conference.host?(current_user)
+
+ render 'events/edit'
+ end
+
+ def edit_event
+ set_conference
+ set_conference_registration
+ do_404 unless @this_conference.host?(current_user)
+
+ @event = Event.find(params[:id])
+ do_403 unless @event.conference_id == @this_conference.id
+
+ render 'events/edit'
+ end
+
+ def save_event
+ set_conference
+ do_404 unless @this_conference.host?(current_user)
+
+
+ if params[:event_id]
+ event = Event.find(params[:event_id])
+ do_403 unless event.conference_id == @this_conference.id
+ else
+ event = Event.new(:conference_id => @this_conference.id)
+ end
+
+ event.title = params[:title]
+ event.info = params[:info]
+ event.event_type = params[:event_type]
+
+ event.save
+
+ return redirect_to schedule_url(@this_conference.slug)
+ end
+
+ def add_location
+ set_conference
+ set_conference_registration
+ do_404 unless @this_conference.host?(current_user)
+
+ render 'event_locations/edit'
+ end
+
+ def edit_location
+ set_conference
+ set_conference_registration
+ do_404 unless @this_conference.host?(current_user)
+
+ @location = EventLocation.find(params[:id])
+ do_403 unless @location.conference_id == @this_conference.id
+
+ @amenities = JSON.parse(@location.amenities || '[]').map &:to_sym
+
+ render 'event_locations/edit'
+ end
+
+ def save_location
+ set_conference
+ do_404 unless @this_conference.host?(current_user)
+
+
+ if params[:location_id]
+ location = EventLocation.find(params[:location_id])
+ do_403 unless location.conference_id == @this_conference.id
+ else
+ location = EventLocation.new(:conference_id => @this_conference.id)
+ end
+
+ location.title = params[:title]
+ location.address = params[:address]
+ location.amenities = (params[:needs] || {}).keys.to_json
+
+ location.save
+
+ return redirect_to schedule_url(@this_conference.slug)
+ end
+
# DELETE /conferences/1
#def destroy
# @conference.destroy
@@ -1053,6 +1318,7 @@ class ConferencesController < ApplicationController
register_path(@this_conference.slug) => 'registration.Registration',
workshops_path(@this_conference.slug) => 'registration.Workshops'
}
+ @submenu[schedule_path(@this_conference.slug)] = 'registration.Schedule' if @this_conference.workshop_schedule_published || @is_host
if @is_host
@submenu[edit_conference_path(@this_conference.slug)] = 'registration.Edit'
@submenu[stats_path(@this_conference.slug)] = 'registration.Stats'
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index fffecd9..c72001b 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,6 +1,8 @@
require 'redcarpet'
module ApplicationHelper
+ include ScheduleHelper
+
@@keyQueue = nil
@@translationsOnThisPage = nil
@@lastTranslation = nil
diff --git a/app/helpers/schedule_helper.rb b/app/helpers/schedule_helper.rb
new file mode 100644
index 0000000..e3a7d20
--- /dev/null
+++ b/app/helpers/schedule_helper.rb
@@ -0,0 +1,146 @@
+
+module ScheduleHelper
+ def get_schedule_data
+ schedule = Hash.new
+ workshop_errors = Hash.new
+ workshop_warnings = Hash.new
+
+ all_events = (@workshops + @events)
+ conflicts = 0
+ errors = 0
+
+ (0...all_events.count).each do |i|
+ w = all_events[i]
+
+ if w.start_time.present? && w.end_time.present? && w.event_location_id.present?
+ type = w.is_a?(Workshop) ? :workshop : :event
+
+ hour = w.start_time.strftime('%H').to_i
+ hour += 0.5 if w.start_time.strftime('%M').to_i > 15
+
+ end_hour = w.end_time.strftime('%H').to_i
+ end_hour += 0.5 if w.end_time.strftime('%M').to_i > 15
+
+ day = w.conference_day
+
+ schedule[day] ||= Hash.new
+ schedule[day][:locations] ||= Hash.new
+ schedule[day][:locations][w.event_location_id] ||= Hash.new
+
+ conflict = nil
+ (hour...end_hour).step(0.5).each do |h|
+ h = h.to_i if h == h.to_i
+ if !conflict && schedule[day][:locations][w.event_location_id][h].present?
+ conflict = schedule[day][:locations][w.event_location_id][h]
+ end
+ end
+
+ if conflict.present?
+ w_conflict = get_workshop(conflict, @workshops, @events)
+ workshop_errors[(w_conflict.is_a?(Workshop) ? 'w' : 'e') + w_conflict.id.to_s] = "Time conflict with “#{w_conflict.title}”".html_safe
+ workshop_errors[(w.is_a?(Workshop) ? 'w' : 'e') + w.id.to_s] = "Time conflict with “#{w.title}”".html_safe
+ errors += 1 if workshop_errors[(w_conflict.is_a?(Workshop) ? 'w' : 'e') + w_conflict.id.to_s].nil?
+ else
+ schedule[day][:start_time] = hour if schedule[day][:start_time].nil? || hour < schedule[day][:start_time]
+ schedule[day][:end_time] = end_hour if schedule[day][:end_time].nil? || end_hour > schedule[day][:end_time]
+
+ schedule[day][:locations][w.event_location_id][hour] = {
+ :span => w.duration / 60.0,
+ :type => w.is_a?(Event) ? w.event_type : :workshop
+ }
+ schedule[day][:locations][w.event_location_id][hour][:workshop] = i if type == :workshop
+ schedule[day][:locations][w.event_location_id][hour][:event] = (i - @workshops.count) if type == :event
+ end
+ else
+ workshop_warnings["w#{w.id}"] ||= Array.new
+ workshop_warnings["w#{w.id}"] << (w.is_a?(Workshop) ? "This workshop is not scheduled" : "This event is not scheduled")
+ end
+ end
+
+ schedule.each do |day, day_data|
+ day_data[:locations].each do |location1, location_data1|
+ location_data1.each do |time1, data1|
+ day_data[:locations].each do |location2, location_data2|
+ location_data2.each do |time2, data2|
+ if data1[:workshop].present?
+ if data2[:workshop].present?
+ unless location1 == location2 && time1 == time2
+ if workshop_errors[data1[:workshop]].nil?
+ w1 = @workshops[data1[:workshop]]
+ w2 = @workshops[data2[:workshop]]
+ if time1 == time2
+ w1.workshop_facilitators.each do |f|
+ u = User.find(f.user_id)
+ if w2.active_facilitator?(u)
+ errors += 1 if workshop_errors[(w2.is_a?(Workshop) ? 'w' : 'e') + w2.id.to_s].nil?
+ workshop_errors["w#{w1.id}"] = "This workshop shares facilitators with “#{w2.title}”".html_safe
+ end
+ end
+ connection ||= ActiveRecord::Base.connection
+ common_interest_count = connection.select_value("SELECT COUNT(w1.user_id) FROM workshop_interests AS w1 JOIN workshop_interests AS w2 ON w2.user_id=w1.user_id WHERE w1.workshop_id=#{w1.id} AND w2.workshop_id=#{w2.id}")
+ common_interest_count = common_interest_count ? common_interest_count.to_i : 0
+ if common_interest_count > 0
+ conflicts += common_interest_count
+ workshop_warnings["w#{w1.id}"] ||= Array.new
+ workshop_warnings["w#{w1.id}"] << "#{common_interest_count} people are also interested in “#{w2.title}”".html_safe
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ {
+ :schedule => schedule.sort,
+ :errors => workshop_errors,
+ :warnings => workshop_warnings,
+ :conflict_score => conflicts,
+ :error_count => errors
+ }
+ end
+
+ def get_workshop(workshop, workshops, events)
+ workshop[:workshop] ? workshops[workshop[:workshop]] : (events[workshop[:event]] || :event)
+ end
+
+ def workshop_classes(workshop, show_interest)
+ classes = [workshop.is_a?(Workshop) ? :workshop : workshop.event_type]
+ if show_interest && workshop.is_a?(Workshop) && current_user && WorkshopInterest.where(:user_id => current_user.id)
+ if workshop.interested?(current_user) || workshop.facilitator?(current_user)
+ classes << 'interested'
+ else
+ classes << 'not-interested'
+ end
+ end
+
+ return classes
+ end
+
+ def schedule_start_and_end_times(day_part, day_parts, day_schedule)
+ start_time = [day_parts[day_parts.keys[day_part]], day_schedule[:start_time]].max
+ end_time = [day_parts[day_parts.keys[day_part + 1]] || 24, day_schedule[:end_time]].min
+
+ min_time = nil
+ max_time = nil
+
+ day_schedule[:locations].each do |location, location_schedule|
+ location_schedule.each do |hour, workshop|
+ t_start = hour
+ t_end = hour + workshop[:span]
+ if t_start >= start_time && t_end <= end_time
+ min_time = [min_time || 24, t_start].min
+ max_time = [max_time || 0, t_end].max
+ end
+ end
+ end
+
+ return nil unless min_time.present? && max_time.present?
+
+ [min_time || 0, max_time || 24]
+ end
+end
diff --git a/app/models/event.rb b/app/models/event.rb
index 3a829fd..98f8c29 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -1,2 +1,17 @@
-class Event < ActiveRecord::Base
-end
+class Event < ActiveRecord::Base
+ belongs_to :conference
+
+ def conference_day
+ return nil unless start_time.present? && end_time.present?
+
+ start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
+ w_start_day = start_time.change(hour: 0, minute: 0, second: 0)
+ return (((w_start_day - start_day) / 86400) + 1).to_i
+ end
+
+ def duration
+ return nil unless start_time.present? && end_time.present?
+ ((end_time - start_time) / 60).to_i
+ end
+
+end
diff --git a/app/models/event_location.rb b/app/models/event_location.rb
new file mode 100644
index 0000000..4f4866a
--- /dev/null
+++ b/app/models/event_location.rb
@@ -0,0 +1,2 @@
+class EventLocation < ActiveRecord::Base
+end
diff --git a/app/models/workshop.rb b/app/models/workshop.rb
index 290c920..e3171cc 100644
--- a/app/models/workshop.rb
+++ b/app/models/workshop.rb
@@ -87,6 +87,19 @@ class Workshop < ActiveRecord::Base
(user.can_translate? && lang.to_sym != locale.to_sym) || can_edit?(user)
end
+ def conference_day
+ return nil unless start_time.present? && end_time.present?
+
+ start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
+ w_start_day = start_time.change(hour: 0, minute: 0, second: 0)
+ return (((w_start_day - start_day) / 86400) + 1).to_i
+ end
+
+ def duration
+ return nil unless start_time.present? && end_time.present?
+ ((end_time - start_time) / 60).to_i
+ end
+
private
def make_slug
if !self.slug
diff --git a/app/views/application/home.html.haml b/app/views/application/home.html.haml
index a3fa192..8a85596 100644
--- a/app/views/application/home.html.haml
+++ b/app/views/application/home.html.haml
@@ -4,16 +4,20 @@
%article
%h2=_!@conference.title
=@conference.info.html_safe
- %h3=_'articles.workshops.headings.Proposed_Workshops'
- %p=_'articles.workshops.paragraphs.Proposed_Workshops', "Would you like to facilitate your own workshop? Simply register and visit the workshops page. If you have already registered you can access the page by restarting the registration process."
- if @conference.workshops
- %ul.workshop-list
- - @conference.workshops.sort_by{|w| w.title}.each do |w|
- %li
- %h4=w.title
- .workshop-interest
- - if w.interested?(current_user)
- =_'articles.workshops.info.you_are_interested_count', "You and #{w.interested_count - 1} others are interested in this workshop", :vars => {:count => (w.interested_count - 1)}
- - elsif w.interested_count > 0
- =_'articles.workshops.info.interested_count', "#{w.interested_count} people are interested in this workshop", :vars => {:count => w.interested_count}
- .workshop-description=markdown w.info
+ - if @schedule
+ %h3=_'articles.workshops.headings.Schedule'
+ = render 'schedule/programme', :schedule => @schedule, :conference => @conference, :workshops => @workshops, :events => @events, :locations => @locations, :show_interest => true, :day_parts => @day_parts, :show_previews => true
+ - else
+ %h3=_'articles.workshops.headings.Proposed_Workshops'
+ %p=_'articles.workshops.paragraphs.Proposed_Workshops', "Would you like to facilitate your own workshop? Simply register and visit the workshops page. If you have already registered you can access the page by restarting the registration process."
+ %ul.workshop-list
+ - @conference.workshops.sort_by{|w| w.title}.each do |w|
+ %li
+ %h4=w.title
+ .workshop-interest
+ - if w.interested?(current_user)
+ =_'articles.workshops.info.you_are_interested_count', "You and #{w.interested_count - 1} others are interested in this workshop", :vars => {:count => (w.interested_count - 1)}
+ - elsif w.interested_count > 0
+ =_'articles.workshops.info.interested_count', "#{w.interested_count} people are interested in this workshop", :vars => {:count => w.interested_count}
+ .workshop-description=markdown w.info
diff --git a/app/views/event_locations/edit.html.haml b/app/views/event_locations/edit.html.haml
new file mode 100644
index 0000000..6813aec
--- /dev/null
+++ b/app/views/event_locations/edit.html.haml
@@ -0,0 +1,23 @@
+= render 'conferences/page_header', :page_key => (@location ? 'Edit_Location' : 'New_Location')
+%article
+ = form_tag save_location_path(@this_conference.slug), class: 'composition' do
+ = row do
+ = columns(medium: 12) do
+ = (hidden_field_tag :location_id, @location.id) if @location
+ .text-field.input-field.big
+ = label_tag :title
+ = text_field_tag :title, @location ? @location.title : nil, :required => true
+ = row do
+ = columns(medium: 6) do
+ .text-area-field.input-field
+ = label_tag :address
+ = text_area_tag :address, @location ? @location.address : nil, :required => true
+ = columns(medium: 6) do
+ %h3=_'articles.locations.headings.amenities'
+ - [:sound, :projector, :tools].each do |need|
+ .single-check-box-field.input-field
+ = label_tag "needs_#{need}" do
+ = check_box_tag "needs[#{need}]", 1, @location && @amenities.include?(need)
+ = _"workshop.options.needs.#{need}"
+ .actions
+ = button_tag :save, :value => :save
diff --git a/app/views/events/edit.html.haml b/app/views/events/edit.html.haml
index 5828e7a..d9afcb7 100644
--- a/app/views/events/edit.html.haml
+++ b/app/views/events/edit.html.haml
@@ -1,7 +1,22 @@
-%h1 Editing event
-
-= render 'form'
-
-= link_to 'Show', @event
-\|
-= link_to 'Back', events_path
+= render 'conferences/page_header', :page_key => (@event ? 'Edit_Event' : 'New_Event')
+%article
+ = form_tag save_event_path(@this_conference.slug), class: 'composition' do
+ = row do
+ = columns(medium: 9) do
+ = (hidden_field_tag :event_id, @event.id) if @event
+ .text-field.input-field.big
+ = label_tag :title
+ = text_field_tag :title, @event ? @event.title : nil, :required => true
+ = columns(medium: 3) do
+ .select-field.input-field
+ = label_tag :event_type do
+ = select_tag :event_type, options_for_select([:event, :meal], @event ? @event.event_type : nil), :include_blank => true
+ =_'forms.labels.generic.event_type'
+ = row do
+ = columns(medium: 12) do
+ .text-area-field.input-field
+ = label_tag :info
+ = text_area_tag :info, @event ? @event.info : nil, :required => true
+ = columns(medium: 12) do
+ .actions.right
+ = button_tag :save, :value => :save
diff --git a/app/views/schedule/_programme.html.haml b/app/views/schedule/_programme.html.haml
new file mode 100644
index 0000000..75101b0
--- /dev/null
+++ b/app/views/schedule/_programme.html.haml
@@ -0,0 +1,36 @@
+.programme
+ - schedule.each do |day, day_schedule|
+ .programme-day
+ %h2=I18n.l(conference.start_date + (day - 1).days, :format => "%A")
+ - (0...day_parts.length).each do |day_part|
+ .programme-day-part
+ - times = schedule_start_and_end_times(day_part, day_parts, day_schedule)
+ - if times.present?
+ %h3=_"articles.headings.schedule.day_parts.#{day_parts.keys[day_part].to_s}" if day_parts.length > 1
+ %table.schedule
+ %tr
+ %th
+ - (times.first...times.last).step(0.5).each do |t|
+ - t = t.to_i if t == t.to_i
+ %th=I18n.l(Date.today + t.hours, :format => :short)
+ - day_schedule[:locations].each do |location, location_schedule|
+ %tr
+ %th=locations[location.to_s].title
+ - skip = 0
+ - (times.first...times.last).step(0.5).each do |t|
+ - t = t.to_i if t == t.to_i
+ - if location_schedule[t].present?
+ - workshop = location_schedule[t]
+ - w = get_workshop(workshop, workshops, events)
+ %td{:class => workshop_classes(w, show_interest) + [show_previews && workshop[:type] == :workshop ? 'previewable' : nil], :colspan => (workshop[:span] * 2), :id => "workshop-#{w.id}"}
+ .title= w.title
+ - if show_previews && workshop[:type] == :workshop
+ .info
+ %a.close{href: "#!"}
+ = render 'workshops/show', :workshop => w, :preview => true
+ %a{class: 'preview', href: "#workshop-#{w.id}"}
+ - skip = workshop[:span] - 0.5
+ - elsif skip > 0
+ - skip -= 0.5
+ - else
+ %td.empty
diff --git a/app/views/schedule/edit.html.haml b/app/views/schedule/edit.html.haml
new file mode 100644
index 0000000..bcc06a0
--- /dev/null
+++ b/app/views/schedule/edit.html.haml
@@ -0,0 +1,77 @@
+= render 'conferences/page_header', :page_key => 'Edit_Schedule'
+%article
+ = form_tag save_schedule_path(@this_conference.slug), class: 'composition' do
+ = row do
+ = columns(medium: 12) do
+ = render 'schedule/programme', :schedule => @schedule, :conference => @this_conference, :workshops => @workshops, :events => @events, :locations => @location_hash, :show_interest => false, :day_parts => @day_parts, :show_previews => false
+ = row do
+ = columns(medium: 12) do
+ - if @error_count && @error_count > 0
+ %h3.errors
+ =_'errors.schedule.errors',"Errors:"
+ = @error_count
+ - if @conflict_score && @conflict_score > 0
+ %h3.conflict-score
+ =_'errors.schedule.conflict_score',"Interest Conflicts:"
+ = @conflict_score
+ = row do
+ = columns(medium: 12) do
+ = (hidden_field_tag :location_id, @location.id) if @location
+ .actions
+ - if @this_conference.workshop_schedule_published
+ = button_tag :Unpublish, :value => :unpublish, :class => 'delete'
+ - elsif @error_count < 1
+ = button_tag :Publish, :value => :publish
+ = button_tag :Preview, :value => :preview, :class => 'secondary'
+ - unless @this_conference.workshop_schedule_published && @error_count > 0
+ = button_tag :save, :value => :save
+ - unless @saved
+ .unsaved=_'errors.schedule.unsaved','Your changes will not be saved until you press Save or Publish'
+ = row do
+ = columns(medium: 6) do
+ %h2=_"articles.headings.schedule.day_parts.Workshops"
+ %ul.all-workshops
+ - @workshops.each do |i|
+ - error = @errors["w#{i.id}"]
+ - warnings = @warnings["w#{i.id}"]
+ %li{class: error.present? ? :error : nil}
+ %h3=i.title
+ .workshop-interest=_'articles.workshops.info.interested_count', "#{i.interested_count} people are interested in this workshop", :vars => {:count => i.interested_count}
+ .time
+ = select_tag "workshop_day[#{i.id}]", options_for_select(@days, i.conference_day), :include_blank => true
+ = select_tag "workshop_hour[#{i.id}]", options_for_select(@hours, i.start_time ? i.start_time.strftime('%R') : nil), :include_blank => true
+ = select_tag "workshop_duration[#{i.id}]", options_for_select(@workshop_durations, i.duration || 60)
+ .location
+ = select_tag "workshop_location[#{i.id}]", options_from_collection_for_select(@locations, :id, :title, i.event_location_id), :include_blank => true
+ - if warnings
+ %ul.warnings
+ - warnings.each do |warning|
+ %li=warning
+ - if error
+ .error-description=error
+ = columns(medium: 6) do
+ %h2=_"articles.headings.schedule.day_parts.Events"
+ %ul.all-events
+ - @events.each do |i|
+ - error = @errors["e#{i.id}"]
+ %li{:class => [i.event_type, error.present? ? :error : nil]}
+ %h3=i.title
+ .time
+ = select_tag "event_day[#{i.id}]", options_for_select(@days, i.conference_day)
+ = select_tag "event_hour[#{i.id}]", options_for_select(@hours, i.start_time ? i.start_time.strftime('%R') : '12:00')
+ = select_tag "event_duration[#{i.id}]", options_for_select(@event_durations, i.duration || 60)
+ .location
+ = select_tag "event_location[#{i.id}]", options_from_collection_for_select(@locations, :id, :title, i.event_location_id), :include_blank => true
+ - if error
+ .error-description=error
+ %h2=_"articles.headings.schedule.day_parts.Day_Parts"
+ %ul.day_parts
+ - [:morning, :afternoon, :evening].each do |day_part|
+ %li
+ %h4
+ =_"articles.headings.schedule.day_parts.#{day_part.to_s}"
+ - h = (Date.today + @day_parts[day_part.to_s].to_f.hours).strftime('%R')
+ - if day_part == :morning
+ .select=h
+ - else
+ = select_tag "day_parts[#{day_part.to_s}]", options_for_select(@hours, h)
diff --git a/app/views/schedule/show.html.haml b/app/views/schedule/show.html.haml
new file mode 100644
index 0000000..a3c0839
--- /dev/null
+++ b/app/views/schedule/show.html.haml
@@ -0,0 +1,28 @@
+= render 'conferences/page_header', :page_key => 'Schedule'
+%article
+ - if @this_conference.host?(current_user)
+ = row do
+ = columns(medium: 12) do
+ .actions.left
+ = link_to (_'actions.schedule.edit','Edit Schedule'), edit_schedule_path(@this_conference.slug), class: [:button]
+ = row do
+ = columns(medium: 6) do
+ %h2=_'articles.schedule.headings.Events'
+ - if @events
+ %ul
+ - @events.each do |event|
+ %li
+ %h3=_!event.title
+ = link_to (_'actions.events.edit','Edit'), edit_event_path(@this_conference.slug, event.id), class: [:button, :modify]
+ .actions.left
+ = link_to (_'actions.events.create','Add Event'), add_event_path(@this_conference.slug), class: [:button, :modify]
+ = columns(medium: 6) do
+ %h2=_'articles.schedule.headings.Locations'
+ - if @locations
+ %ul
+ - @locations.each do |location|
+ %li
+ %h3=_!location.title
+ = link_to (_'actions.locations.edit','Edit'), edit_location_path(@this_conference.slug, location.id), class: [:button, :modify]
+ .actions.left
+ = link_to (_'actions.schedule.edit','Add Location'), add_location_path(@this_conference.slug), class: [:button, :modify]
diff --git a/app/views/workshops/_show.html.haml b/app/views/workshops/_show.html.haml
new file mode 100644
index 0000000..54bb221
--- /dev/null
+++ b/app/views/workshops/_show.html.haml
@@ -0,0 +1,58 @@
+= row do
+ = columns(medium: 12) do
+ %h2=_!workshop.title
+ .workshop-interest
+ - if workshop.interested?(current_user)
+ =_'articles.workshops.info.you_are_interested_count', "You and #{workshop.interested_count - 1} others are interested in this workshop", :vars => {:count => (workshop.interested_count - 1)}
+ - else
+ =_'articles.workshops.info.interested_count', "#{workshop.interested_count} people are interested in this workshop", :vars => {:count => workshop.interested_count}
+ - if !preview && workshop.can_show_interest?(current_user)
+ = form_tag toggle_workshop_interest_path(workshop.conference.slug, workshop.id) do
+ = button_tag (workshop.interested?(current_user) ? :remove_interest : :show_interest), :value => :toggle_interest, :class => (workshop.interested?(current_user) ? 'delete' : 'add')
+ =markdown _!(workshop.info) || ''
+ - if !preview && logged_in? && current_user.can_translate?
+ .actions
+ - I18n.backend.enabled_locales.each do |locale|
+ = (link_to (_'actions.workshops.Translate', "Translate into #{language_name(locale)}", :vars => {:language => language_name(locale)}), edit_workshop_url(workshop.conference.slug, workshop.id, url_params(locale)), :class => 'button translate') if workshop.can_translate?(current_user, locale)
+ = columns(medium: 6) do
+ %h3=_'articles.workshops.headings.facilitators'
+ .facilitators
+ - workshop.workshop_facilitators.each do |f|
+ - u = User.find(f.user_id)
+ - if logged_in? && (workshop.public_facilitator?(u) || f.user_id == current_user.id || workshop.active_facilitator?(current_user))
+ .facilitator
+ .name=_!(u.firstname || u.username || u.email)
+ .role
+ =_"roles.workshops.facilitator.#{workshop.role(u).to_s}"
+ - if !preview && f.role.to_sym == :requested && workshop.active_facilitator?(current_user)
+ =(link_to (_'actions.workshops.Approve'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'approve'), :class => 'button modify')
+ =(link_to (_'actions.workshops.Deny'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'deny'), :class => 'button delete')
+ - elsif !preview && (f.user_id == current_user.id && f.role.to_sym != :creator) || (!workshop.conference.registered?(u) && workshop.active_facilitator?(current_user))
+ =(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'remove'), :class => 'button delete')
+ - if !preview
+ .actions
+ =(link_to (_'actions.workshops.Facilitate'), facilitate_workshop_path(workshop.conference.slug, workshop.id), :class => 'button modify') if !workshop.facilitator?(current_user)
+ - if workshop.active_facilitator?(current_user)
+ = form_tag workshop_add_facilitator_path(workshop.conference.slug, workshop.id), :class => 'add-facilitator' do
+ %h4='Add a facilitator'
+ .email-field.input-field
+ = email_field_tag :email, nil, required: true
+ = label_tag :email
+ = button_tag :add
+ - if workshop.languages
+ = columns(medium: 6) do
+ %h3=_'articles.workshops.headings.languages','Workshop Language'
+ %p= _!((JSON.parse(workshop.languages || '[]').map { |x| _"languages.#{x}" }).join(', ').to_s.html_safe)
+ - if workshop.theme
+ = columns(medium: 6) do
+ %h3=_'articles.workshops.headings.theme','Theme'
+ %p= [:race_gender, :mechanics, :funding, :organization, :community].include?((workshop.theme || '').to_sym) ? (_"workshop.options.theme.#{workshop.theme}") : workshop.theme
+ - if workshop.active_facilitator?(current_user) || workshop.conference.host?(current_user)
+ - if workshop.needs
+ = columns(medium: 6) do
+ %h3=_'articles.workshops.headings.needs','What do you need?'
+ %p= _!((JSON.parse(workshop.needs || '[]').map { |x| _"workshop.options.needs.#{x}" }).join(', ').to_s.html_safe)
+ - if workshop.notes
+ = columns(medium: 12) do
+ %h3=_'articles.workshops.headings.notes','Notes'
+ =markdown _!(workshop.notes)
diff --git a/app/views/workshops/show.html.haml b/app/views/workshops/show.html.haml
index caec851..3a7cd4d 100644
--- a/app/views/workshops/show.html.haml
+++ b/app/views/workshops/show.html.haml
@@ -1,62 +1,7 @@
= render 'conferences/page_header', :page_key => 'View_Workshop'
%article
+ = render 'workshops/show', :workshop => @workshop, :preview => false
= row do
- = columns(medium: 12) do
- %h2=_!@workshop.title
- .workshop-interest
- - if @workshop.interested?(current_user)
- =_'articles.workshops.info.you_are_interested_count', "You and #{@workshop.interested_count - 1} others are interested in this workshop", :vars => {:count => (@workshop.interested_count - 1)}
- - else
- =_'articles.workshops.info.interested_count', "#{@workshop.interested_count} people are interested in this workshop", :vars => {:count => @workshop.interested_count}
- - if @workshop.can_show_interest?(current_user)
- = form_tag toggle_workshop_interest_path(@this_conference.slug, @workshop.id) do
- = button_tag (@workshop.interested?(current_user) ? :remove_interest : :show_interest), :value => :toggle_interest, :class => (@workshop.interested?(current_user) ? 'delete' : 'add')
- =markdown _!(@workshop.info) || ''
- - if current_user.can_translate?
- .actions
- - I18n.backend.enabled_locales.each do |locale|
- = (link_to (_'actions.workshops.Translate', "Translate into #{language_name(locale)}", :vars => {:language => language_name(locale)}), edit_workshop_url(@this_conference.slug, @workshop.id, url_params(locale)), :class => 'button translate') if @workshop.can_translate?(current_user, locale)
- = columns(medium: 6) do
- %h3=_'articles.workshops.headings.facilitators'
- .facilitators
- - @workshop.workshop_facilitators.each do |f|
- - u = User.find(f.user_id)
- - if @workshop.public_facilitator?(u) || f.user_id == current_user.id || @workshop.active_facilitator?(current_user)
- .facilitator
- .name=_!(u.firstname || u.username || u.email)
- .role
- =_"roles.workshops.facilitator.#{@workshop.role(u).to_s}"
- - if f.role.to_sym == :requested && @workshop.active_facilitator?(current_user)
- =(link_to (_'actions.workshops.Approve'), approve_facilitate_workshop_request_path(@this_conference.slug, @workshop.id, f.user_id, 'approve'), :class => 'button modify')
- =(link_to (_'actions.workshops.Deny'), approve_facilitate_workshop_request_path(@this_conference.slug, @workshop.id, f.user_id, 'deny'), :class => 'button delete')
- - elsif (f.user_id == current_user.id && f.role.to_sym != :creator) || (!@this_conference.registered?(u) && @workshop.active_facilitator?(current_user))
- =(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(@this_conference.slug, @workshop.id, f.user_id, 'remove'), :class => 'button delete')
- .actions
- =(link_to (_'actions.workshops.Facilitate'), facilitate_workshop_path(@this_conference.slug, @workshop.id), :class => 'button modify') if !@workshop.facilitator?(current_user)
- - if @workshop.active_facilitator?(current_user)
- = form_tag workshop_add_facilitator_path(@this_conference.slug, @workshop.id), :class => 'add-facilitator' do
- %h4='Add a facilitator'
- .email-field.input-field
- = email_field_tag :email, nil, required: true
- = label_tag :email
- = button_tag :add
- - if @workshop.languages
- = columns(medium: 6) do
- %h3=_'articles.workshops.headings.languages','Workshop Language'
- %p= _!((JSON.parse(@workshop.languages || '[]').map { |x| _"languages.#{x}" }).join(', ').to_s.html_safe)
- - if @workshop.theme
- = columns(medium: 6) do
- %h3=_'articles.workshops.headings.theme','Theme'
- %p= [:race_gender, :mechanics, :funding, :organization, :community].include?((@workshop.theme || '').to_sym) ? (_"workshop.options.theme.#{@workshop.theme}") : @workshop.theme
- - if @workshop.active_facilitator?(current_user) || @this_conference.host?(current_user)
- - if @workshop.needs
- = columns(medium: 6) do
- %h3=_'articles.workshops.headings.needs','What do you need?'
- %p= _!((JSON.parse(@workshop.needs || '[]').map { |x| _"workshop.options.needs.#{x}" }).join(', ').to_s.html_safe)
- - if @workshop.notes
- = columns(medium: 12) do
- %h3=_'articles.workshops.headings.notes','Notes'
- =markdown _!(@workshop.notes)
= columns(medium: 12) do
.actions.right
= (link_to (_'actions.workshops.Edit'), edit_workshop_path(@this_conference.slug, @workshop.id), :class => 'button modify') if @workshop.can_edit?(current_user)
diff --git a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--.html b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--.html
index 97a8d9b..052f244 100644
--- a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--.html
+++ b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--.html
@@ -46,7 +46,7 @@
Guadalajara, Jalisco, Mexico
-August 22 – 26, 2015
+August 27 – 31, 2015
diff --git a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-1.html b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-1.html
index 75d25d4..e0e18be 100644
--- a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-1.html
+++ b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-1.html
@@ -51,7 +51,7 @@
-Mauris Enim Leo, Rhoncus Sed, Vestibulum Sit Amet, Cursus Id, Turpis
+
Sed Accumsan Felis
You are interested in this workshop
-
Maecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris viverra diam vitae quam. Suspendisse potenti.
+
Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.
-
+
diff --git a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-2.html b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-2.html
index 0e8807a..5c2caea 100644
--- a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-2.html
+++ b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1-2.html
@@ -51,7 +51,7 @@
-Mauris Enim Leo, Rhoncus Sed, Vestibulum Sit Amet, Cursus Id, Turpis
+
Sed Accumsan Felis
No one is interested in this workshop yet
-
Maecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris viverra diam vitae quam. Suspendisse potenti.
+
Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.
-
+
diff --git a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1.html b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1.html
index 0e8807a..5c2caea 100644
--- a/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1.html
+++ b/config/locales/data/html_records/Be-the-first-to-like-a-workshop--conferences.MyBikeBike.workshops.1.html
@@ -51,7 +51,7 @@
-Mauris Enim Leo, Rhoncus Sed, Vestibulum Sit Amet, Cursus Id, Turpis
+
Sed Accumsan Felis
No one is interested in this workshop yet
-
Maecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris viverra diam vitae quam. Suspendisse potenti.
+
Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.
-
+
diff --git a/config/locales/data/html_records/Broadcast-message--.html b/config/locales/data/html_records/Broadcast-message--.html
index c4e65bc..e4ad3d8 100644
--- a/config/locales/data/html_records/Broadcast-message--.html
+++ b/config/locales/data/html_records/Broadcast-message--.html
@@ -46,7 +46,7 @@
San Marcos, Texas
-August 22 – 26, 2015
+August 27 – 31, 2015
diff --git a/config/locales/data/html_records/Broadcast-message--conferences.MyBikeBike.broadcast-1.html b/config/locales/data/html_records/Broadcast-message--conferences.MyBikeBike.broadcast-1.html
index e31ec46..42e7393 100644
--- a/config/locales/data/html_records/Broadcast-message--conferences.MyBikeBike.broadcast-1.html
+++ b/config/locales/data/html_records/Broadcast-message--conferences.MyBikeBike.broadcast-1.html
@@ -47,6 +47,7 @@