Browse Source

Home page schedule, publish and unpublish schedule, extended user data in housing

development
Godwin 9 years ago
parent
commit
e9d9962d9a
  1. 52
      app/assets/javascripts/main.js
  2. 367
      app/assets/stylesheets/_application.scss
  3. 197
      app/controllers/application_controller.rb
  4. 710
      app/controllers/conferences_controller.rb
  5. 2
      app/models/organization.rb
  6. 4
      app/models/user.rb
  7. 14
      app/views/application/home.html.haml
  8. 2
      app/views/conferences/_questions.html.haml
  9. 23
      app/views/conferences/admin/_housing.html.haml
  10. 82
      app/views/conferences/admin/_schedule.html.haml
  11. 12
      app/views/conferences/admin/_stats.html.haml
  12. 6
      app/views/layouts/application.html.haml
  13. 2
      app/views/workshops/_workshop_previews.html.haml
  14. 2
      config/initializers/assets.rb
  15. 7
      config/locales/en.yml

52
app/assets/javascripts/main.js

@ -30,7 +30,38 @@
overlay.querySelector('.dlg.open').focus();
}
}, true);
window.openOverlay = function(dlg, primaryContent, body) {
primaryContent.setAttribute('aria-hidden', 'true');
body.classList.add('has-overlay');
var type = dlg.getAttribute('data-type');
if (type) {
body.classList.add('is-' + type + '-dlg');
}
dlg.removeAttribute('aria-hidden');
dlg.setAttribute('role', 'alertdialog');
dlg.setAttribute('tabindex', '0');
dlg.focus();
setTimeout(function() { dlg.classList.add('open'); }, 100);
}
window.closeOverlay = function(dlg, primaryContent, body) {
setTimeout(function() {
body.classList.remove('has-overlay');
body.removeAttribute('style');
}, 250);
var type = dlg.getAttribute('data-type');
if (type) {
body.classList.remove('is-' + type + '-dlg');
}
primaryContent.removeAttribute('aria-hidden');
dlg.setAttribute('aria-hidden', 'true');
dlg.removeAttribute('tabindex');
dlg.classList.remove('open');
dlg.removeAttribute('role');
}
function openDlg(dlg, link) {
document.getElementById('overlay').onclick =
dlg.querySelector('.close').onclick = function() { closeDlg(dlg); };
body.setAttribute('style', 'width: ' + body.clientWidth + 'px');
var msg = link.querySelector('.message');
if (msg) {
@ -61,27 +92,12 @@
}
});
}
primaryContent.setAttribute('aria-hidden', 'true');
document.getElementById('overlay').onclick =
dlg.querySelector('.close').onclick = function() { console.log('overlay'); closeDlg(dlg); };
body.classList.add('has-overlay');
dlg.removeAttribute('aria-hidden');
dlg.setAttribute('role', 'alertdialog');
dlg.setAttribute('tabindex', '0');
dlg.focus();
setTimeout(function() { dlg.classList.add('open'); }, 100);
window.openOverlay(dlg, primaryContent, body);
}
function closeDlg(dlg) {
setTimeout(function() {
body.classList.remove('has-overlay');
body.removeAttribute('style');
}, 250);
primaryContent.removeAttribute('aria-hidden');
dlg.setAttribute('aria-hidden', 'true');
dlg.removeAttribute('tabindex');
dlg.classList.remove('open');
dlg.removeAttribute('role');
window.closeOverlay(dlg, primaryContent, body);
}
var confirmationDlg = document.getElementById('confirmation-dlg');
forEachElement('[data-confirmation]', function(link) {
link.addEventListener('click', function(event) {

367
app/assets/stylesheets/_application.scss

@ -1543,6 +1543,7 @@ table.schedule {
margin: 0 0 1em;
td {
position: relative;
text-align: center;
&.empty {
@ -1571,6 +1572,25 @@ table.schedule {
@include font-family(secondary);
}
.event-detail-link {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: inherit;
@include after {
display: none;
}
&:hover {
outline: 0.33rem solid #02CA9E;
outline-offset: 0.25rem;
z-index: 1;
}
}
.status {
display: inline-block;
text-align: left;
@ -1621,6 +1641,7 @@ table.schedule {
}
}
#main .columns & form {
margin-top: 0;
@ -1632,10 +1653,45 @@ table.schedule {
}
}
.event-dlg {
@include _-(flex, 0);
position: relative;
z-index: 1000;
background-color: $white;
text-align: left;
padding: 2em 2em 0.5em;
min-width: 100%;
max-height: 100%;
overflow: auto;
margin: auto;
@include _(opacity, 0);
@include _(transition, opacity 150ms ease-in-out);
@include default-box-shadow(top, 2);
.actions {
margin: 2em 0 0;
}
&.open {
@include _(opacity, 1);
}
}
.event-details {
.title {
margin: 0 0 0.5em;
}
.address {
text-align: center;
}
}
#admin-schedule {
.workshop-list {
.workshops-to-schedule {
@include _-(display, flex);
@include _(flex-wrap, wrap);
list-style: none;
padding: 0;
li {
@ -1643,6 +1699,7 @@ table.schedule {
@include _(flex-basis, 48%);
margin: 1%;
@include _(transition, background-color 250ms ease-in-out);
background-color: #EEE;
.title {
@include _(transition, background-color 250ms ease-in-out);
@ -1690,6 +1747,26 @@ table.schedule {
margin: 0 5% 1em;
width: 90%;
}
.title {
margin: 0 0 0.5em;
padding: 0.5em;
background-color: $black;
color: $white;
}
.drop-downs {
padding: 0 1em 1em;
select {
width: 100%;
}
}
.actions {
margin: 0;
padding: 0 0.5em;
}
}
#main .columns & form {
@ -2126,6 +2203,15 @@ body {
display: block;
}
body.has-overlay.is-event-dlg & {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
@include _-(display, flex);
}
.dlg {
@include before {
content: '';
@ -2167,21 +2253,23 @@ body {
@include _(transform-origin, center 250%);
}
.title {
padding: 0.5em;
background-color: $colour-5;
color: $white;
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
}
.dlg-inner {
padding: 0 2em 2em;
.dlg {
.title {
padding: 0.5em;
background-color: $colour-5;
color: $white;
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
}
}
button, .button {
margin: 0 0.25em 0.5em;
}
.dlg-inner {
padding: 0 2em 2em;
}
.message {
margin-bottom: 2em;
}
@ -2808,23 +2896,6 @@ html[data-lingua-franca-example="html"] {
&:last-child {
border: 0;
}
// &:hover {
// @include default-box-shadow;
// }
&.interested {
.workshop-interest {
// background-color: rgba($colour-5, 0.5);
}
}
&.mine {
.workshop-interest {
// background-color: lighten($colour-1, 25%);
// background-color: rgba($colour-1, 0.5);
}
}
}
.actions {
@ -2845,28 +2916,22 @@ html[data-lingua-franca-example="html"] {
font-size: 1em;
}
.workshop-interest {
// padding: 0.5em 1em;
// font-weight: bold;
// background-color: #EEE;
}
.interest-button {
button {
margin: 0 0 0 1em;
font-size: 0.8em;
padding-top: 0.333em;
padding-bottom: 0.333em;
background-color: $colour-5;
}
}
h5, h6 {
margin: 1em 0 0;
}
}
#main .workshop-interest {
.interest-button {
button {
margin: 0 0 0 1em;
font-size: 0.8em;
padding-top: 0.333em;
padding-bottom: 0.333em;
background-color: $colour-5;
}
}
#main .workshop-interest, .workshop-interest {
text-align: right;
form {
@ -3073,116 +3138,116 @@ html[data-lingua-franca-example="html"] {
}
}
.programme {
// .programme {
.schedule {
width: auto;
margin: 0;
min-width: 100%;
@include _(box-shadow, none);
table-layout: fixed;
border-spacing: 0.25em;
border-collapse: separate;
// .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;
// td {
// position: relative;
// vertical-align: middle;
.title {
text-align: center;
@include font-family(secondary);
color: #666;
}
// .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 {
.title {
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;
}
}
// &.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 {
// .title {
// 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;
@ -3528,6 +3593,10 @@ html[data-ontop] {
padding: 0 2em;
}
.event-dlg {
min-width: 75%;
}
#main {
clear: right;

197
app/controllers/application_controller.rb

@ -67,14 +67,17 @@ class ApplicationController < LinguaFrancaApplicationController
@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}
@event_dlg = true
view_context.add_inline_script :schedule
get_scheule_data#(false)
# @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
@ -444,4 +447,182 @@ class ApplicationController < LinguaFrancaApplicationController
logger.info exception2.backtrace.join("\n")
end
end
def get_block_data
conference = @this_conference || @conference
@workshop_blocks = conference.workshop_blocks || []
@block_days = []
day = conference.start_date
while day <= conference.end_date
@block_days << day.wday
day += 1.day
end
end
def get_scheule_data(do_analyze = true)
conference = @this_conference || @conference
@meals = Hash[conference.meals.map{ |k, v| [k.to_i, v] }].sort.to_h
@events = Event.where(:conference_id => conference.id).order(start_time: :asc)
@workshops = Workshop.where(:conference_id => conference.id).order(start_time: :asc)
@locations = {}
get_block_data
@schedule = {}
day_1 = conference.start_date.wday
@workshop_blocks.each_with_index do | info, block |
info['days'].each do | block_day |
day_diff = block_day.to_i - day_1
day_diff += 7 if day_diff < 0
day = (conference.start_date + day_diff.days).to_date
time = info['time'].to_f
@schedule[day] ||= { times: {}, locations: {} }
@schedule[day][:times][time] ||= {}
@schedule[day][:times][time][:type] = :workshop
@schedule[day][:times][time][:length] = info['length'].to_f
@schedule[day][:times][time][:item] = { block: block, workshops: {} }
end
end
@workshops.each do | workshop |
if workshop.block.present?
block = @workshop_blocks[workshop.block['block'].to_i]
day_diff = workshop.block['day'].to_i - day_1
day_diff += 7 if day_diff < 0
day = (conference.start_date + day_diff.days).to_date
if @schedule[day].present? && @schedule[day][:times].present? && @schedule[day][:times][block['time'].to_f].present?
@schedule[day][:times][block['time'].to_f][:item][:workshops][workshop.event_location_id] = { workshop: workshop, status: { errors: [], warnings: [], conflict_score: nil } }
@schedule[day][:locations][workshop.event_location_id] ||= workshop.event_location
end
end
end
@meals.each do | time, meal |
day = meal['day'].to_date
time = meal['time'].to_f
@schedule[day] ||= {}
@schedule[day][:times] ||= {}
@schedule[day][:times][time] ||= {}
@schedule[day][:times][time][:type] = :meal
@schedule[day][:times][time][:length] = (meal['length'] || 1.0).to_f
@schedule[day][:times][time][:item] = meal
end
@events.each do | event |
day = event.start_time.midnight.to_date
time = event.start_time.hour.to_f + (event.start_time.min / 60.0)
@schedule[day] ||= {}
@schedule[day][:times] ||= {}
@schedule[day][:times][time] ||= {}
@schedule[day][:times][time][:type] = :event
@schedule[day][:times][time][:length] = (event.end_time - event.start_time) / 3600.0
@schedule[day][:times][time][:item] = event
end
@schedule = @schedule.sort.to_h
@schedule.each do | day, data |
@schedule[day][:times] = data[:times].sort.to_h
end
@schedule.each do | day, data |
last_event = nil
data[:times].each do | time, time_data |
if last_event.present?
@schedule[day][:times][last_event][:next_event] = time
end
last_event = time
end
end
@schedule.deep_dup.each do | day, data |
data[:times].each do | time, time_data |
if time_data[:next_event].present? || time_data[:length] > 0.5
span = 0.5
length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length]
while span < length
@schedule[day][:times][time + span] ||= {
type: (span >= time_data[:length] ? :empty : :nil),
length: 0.5
}
span += 0.5
end
end
end
end
@schedule = @schedule.sort.to_h
return unless do_analyze
@schedule.each do | day, data |
@schedule[day][:times] = data[:times].sort.to_h
data[:times].each do | time, time_data |
if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present?
ids = time_data[:item][:workshops].keys
(0..ids.length).each do | i |
if time_data[:item][:workshops][ids[i]].present?
workshop_i = time_data[:item][:workshops][ids[i]][:workshop]
conflicts = {}
(i+1..ids.length).each do | j |
workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil
if workshop_i.present? && workshop_j.present?
workshop_i.active_facilitators.each do | facilitator_i |
workshop_j.active_facilitators.each do | facilitator_j |
if facilitator_i.id == facilitator_j.id
@schedule[day][:times][time][:status] ||= {}
@schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << {
name: :common_facilitator,
facilitator: facilitator_i,
workshop: workshop_i,
i18nVars: {
facilitator_name: facilitator_i.name,
workshop_title: workshop_i.title
}
}
end
end
end
end
end
(0..ids.length).each do | j |
workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil
if workshop_i.present? && workshop_j.present? && workshop_i.id != workshop_j.id
workshop_i.interested.each do | interested_i |
workshop_j.interested.each do | interested_j |
conflicts[interested_i.id] ||= true
end
end
end
end
needs = JSON.parse(workshop_i.needs || '[]').map &:to_sym
amenities = JSON.parse(workshop_i.event_location.amenities || '[]').map &:to_sym
needs.each do | need |
@schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << {
name: :need_not_available,
need: need,
location: workshop_i.event_location,
workshop: workshop_i,
i18nVars: {
need: need.to_s,
location: workshop_i.event_location.title,
workshop_title: workshop_i.title
}
} unless amenities.include? need
end
@schedule[day][:times][time][:item][:workshops][ids[i]][:status][:conflict_score] = workshop_i.interested.present? ? (conflicts.length / workshop_i.interested.size) : 0
end
end
end
end
end
end
end

710
app/controllers/conferences_controller.rb

@ -743,6 +743,7 @@ class ConferencesController < ApplicationController
case @admin_step.to_sym
when :stats
@registrations = ConferenceRegistration.where(:conference_id => @this_conference.id)
if request.format.xlsx?
logger.info "Generating stats.xls"
@excel_data = {
@ -773,6 +774,23 @@ class ConferencesController < ApplicationController
# format.html
format.xlsx { render xlsx: :stats, filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" }
end
else
@registration_count = @registrations.size
@bikes = @registrations.count { |r| r.bike == 'yes' }
@donation_count =0
@donations = 0
@food = { meat: 0, vegan: 0, vegetarian: 0, all: 0 }
@registrations.each do | r |
if r.food.present?
@food[r.food.to_sym] += 1
@food[:all] += 1
end
if r.registration_fees_paid.present? && r.registration_fees_paid > 0
@donation_count += 1
@donations += r.registration_fees_paid
end
end
end
when :housing
# do a full analysis
@ -795,6 +813,8 @@ class ConferencesController < ApplicationController
'days' => []
}
when :schedule
@can_edit = true
@entire_page = true
get_scheule_data
end
when :done
@ -803,178 +823,6 @@ class ConferencesController < ApplicationController
end
def get_block_data
@workshop_blocks = @this_conference.workshop_blocks || []
@block_days = []
day = @this_conference.start_date
while day <= @this_conference.end_date
@block_days << day.wday
day += 1.day
end
end
def get_scheule_data
@meals = Hash[@this_conference.meals.map{ |k, v| [k.to_i, v] }].sort.to_h
@events = Event.where(:conference_id => @this_conference.id).order(start_time: :asc)
@workshops = Workshop.where(:conference_id => @this_conference.id).order(start_time: :asc)
@locations = {}
get_block_data
@schedule = {}
day_1 = @this_conference.start_date.wday
@workshop_blocks.each_with_index do | info, block |
info['days'].each do | block_day |
day_diff = block_day.to_i - day_1
day_diff += 7 if day_diff < 0
day = (@this_conference.start_date + day_diff.days).to_date
time = info['time'].to_f
@schedule[day] ||= { times: {}, locations: {} }
@schedule[day][:times][time] ||= {}
@schedule[day][:times][time][:type] = :workshop
@schedule[day][:times][time][:length] = info['length'].to_f
@schedule[day][:times][time][:item] = { block: block, workshops: {} }
end
end
@workshops.each do | workshop |
if workshop.block.present?
block = @workshop_blocks[workshop.block['block'].to_i]
day_diff = workshop.block['day'].to_i - day_1
day_diff += 7 if day_diff < 0
day = (@this_conference.start_date + day_diff.days).to_date
if @schedule[day].present? && @schedule[day][:times].present? && @schedule[day][:times][block['time'].to_f].present?
@schedule[day][:times][block['time'].to_f][:item][:workshops][workshop.event_location_id] = { workshop: workshop, status: { errors: [], warnings: [], conflict_score: nil } }
@schedule[day][:locations][workshop.event_location_id] ||= workshop.event_location
end
end
end
@meals.each do | time, meal |
day = meal['day'].to_date
time = meal['time'].to_f
@schedule[day] ||= {}
@schedule[day][:times] ||= {}
@schedule[day][:times][time] ||= {}
@schedule[day][:times][time][:type] = :meal
@schedule[day][:times][time][:length] = (meal['length'] || 1.0).to_f
@schedule[day][:times][time][:item] = meal
end
@events.each do | event |
day = event.start_time.midnight.to_date
time = event.start_time.hour.to_f + (event.start_time.min / 60.0)
@schedule[day] ||= {}
@schedule[day][:times] ||= {}
@schedule[day][:times][time] ||= {}
@schedule[day][:times][time][:type] = :event
@schedule[day][:times][time][:length] = (event.end_time - event.start_time) / 3600.0
@schedule[day][:times][time][:item] = event
end
@schedule = @schedule.sort.to_h
@schedule.each do | day, data |
@schedule[day][:times] = data[:times].sort.to_h
end
@schedule.each do | day, data |
last_event = nil
data[:times].each do | time, time_data |
if last_event.present?
@schedule[day][:times][last_event][:next_event] = time
end
last_event = time
end
end
@schedule.deep_dup.each do | day, data |
data[:times].each do | time, time_data |
if time_data[:next_event].present? || time_data[:length] > 0.5
span = 0.5
length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length]
while span < length
@schedule[day][:times][time + span] ||= {
type: (span >= time_data[:length] ? :empty : :nil),
length: 0.5
}
span += 0.5
end
end
end
end
@schedule = @schedule.sort.to_h
@schedule.each do | day, data |
@schedule[day][:times] = data[:times].sort.to_h
data[:times].each do | time, time_data |
if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present?
ids = time_data[:item][:workshops].keys
(0..ids.length).each do | i |
if time_data[:item][:workshops][ids[i]].present?
workshop_i = time_data[:item][:workshops][ids[i]][:workshop]
conflicts = {}
(i+1..ids.length).each do | j |
workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil
if workshop_i.present? && workshop_j.present?
workshop_i.active_facilitators.each do | facilitator_i |
workshop_j.active_facilitators.each do | facilitator_j |
if facilitator_i.id == facilitator_j.id
@schedule[day][:times][time][:status] ||= {}
@schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << {
name: :common_facilitator,
facilitator: facilitator_i,
workshop: workshop_i,
i18nVars: {
facilitator_name: facilitator_i.name,
workshop_title: workshop_i.title
}
}
end
end
end
end
end
(0..ids.length).each do | j |
workshop_j = time_data[:item][:workshops][ids[j]].present? ? time_data[:item][:workshops][ids[j]][:workshop] : nil
if workshop_i.present? && workshop_j.present? && workshop_i.id != workshop_j.id
workshop_i.interested.each do | interested_i |
workshop_j.interested.each do | interested_j |
conflicts[interested_i.id] ||= true
end
end
end
end
needs = JSON.parse(workshop_i.needs || '[]').map &:to_sym
amenities = JSON.parse(workshop_i.event_location.amenities || '[]').map &:to_sym
needs.each do | need |
@schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << {
name: :need_not_available,
need: need,
location: workshop_i.event_location,
workshop: workshop_i,
i18nVars: {
need: need.to_s,
location: workshop_i.event_location.title,
workshop_title: workshop_i.title
}
} unless amenities.include? need
end
@schedule[day][:times][time][:item][:workshops][ids[i]][:status][:conflict_score] = workshop_i.interested.present? ? (conflicts.length / workshop_i.interested.size) : 0
end
end
end
end
end
end
def get_housing_data
@hosts = {}
@guests = {}
@ -1290,10 +1138,16 @@ class ConferencesController < ApplicationController
workshop.block = nil
workshop.save!
success = true
when 'publish'
@this_conference.workshop_schedule_published = !@this_conference.workshop_schedule_published
@this_conference.save
return redirect_to administration_step_path(@this_conference.slug, :schedule)
end
if success
if request.xhr?
@can_edit = true
@entire_page = false
get_scheule_data
schedule = render_to_string partial: 'conferences/admin/schedule'
return render json: [ {
@ -1314,51 +1168,51 @@ class ConferencesController < ApplicationController
do_404
end
def registrations
registrations = ConferenceRegistration.where(:conference_id => @conference.id)
@registrations = registrations
end
# def registrations
# registrations = ConferenceRegistration.where(:conference_id => @conference.id)
# @registrations = registrations
# end
def register_confirm
set_conference
@conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token])
if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && !@conference_registration.complete
@conference_registration.is_confirmed = true
@conference_registration.save!
session[:registration] = YAML.load(@conference_registration.data)
session[:registration][:path] = Array.new
session[:registration][:registration_id] = @conference_registration.id
session[:registration_step] = 'confirm'
redirect_to action: 'register'
else
return do_404
end
end
# def register_confirm
# set_conference
# @conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token])
# if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && !@conference_registration.complete
# @conference_registration.is_confirmed = true
# @conference_registration.save!
# session[:registration] = YAML.load(@conference_registration.data)
# session[:registration][:path] = Array.new
# session[:registration][:registration_id] = @conference_registration.id
# session[:registration_step] = 'confirm'
# redirect_to action: 'register'
# else
# return do_404
# end
# end
def register_pay_registration
set_conference
@conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token])
host = "#{request.protocol}#{request.host_with_port}"
if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && @conference_registration.complete
amount = (params[:auto_payment_amount] || params[:payment_amount]).to_f
if amount > 0
response = PayPal!.setup(
PayPalRequest(amount),
host + (@conference.url + "/register/paypal-confirm/#{@conference_registration.payment_confirmation_token}/").gsub(/\/\/+/, '/'),
host + (@conference.url + "/register/paypal-cancel/#{@conference_registration.confirmation_token}/").gsub(/\/\/+/, '/')
)
redirect_to response.redirect_uri
else
session[:registration] = YAML.load(@conference_registration.data)
session[:registration][:registration_id] = @conference_registration.id
session[:registration][:path] = Array.new
session[:registration_step] = 'pay_now'
redirect_to action: 'register'
end
else
return do_404
end
end
# def register_pay_registration
# set_conference
# @conference_registration = ConferenceRegistration.find_by(confirmation_token: params[:confirmation_token])
# host = "#{request.protocol}#{request.host_with_port}"
# if !@conference_registration.nil? && @conference_registration.conference_id == @conference.id && @conference_registration.complete
# amount = (params[:auto_payment_amount] || params[:payment_amount]).to_f
# if amount > 0
# response = PayPal!.setup(
# PayPalRequest(amount),
# host + (@conference.url + "/register/paypal-confirm/#{@conference_registration.payment_confirmation_token}/").gsub(/\/\/+/, '/'),
# host + (@conference.url + "/register/paypal-cancel/#{@conference_registration.confirmation_token}/").gsub(/\/\/+/, '/')
# )
# redirect_to response.redirect_uri
# else
# session[:registration] = YAML.load(@conference_registration.data)
# session[:registration][:registration_id] = @conference_registration.id
# session[:registration][:path] = Array.new
# session[:registration_step] = 'pay_now'
# redirect_to action: 'register'
# end
# else
# return do_404
# end
# end
# def register_paypal_confirm
# set_conference
@ -1776,261 +1630,261 @@ class ConferencesController < ApplicationController
return redirect_to view_workshop_url(@this_conference.slug, workshop.id, anchor: "comment-#{new_comment.id}")
end
def schedule
set_conference
return do_404 unless @this_conference.workshop_schedule_published || @this_conference.host?(current_user)
# def schedule
# set_conference
# return do_404 unless @this_conference.workshop_schedule_published || @this_conference.host?(current_user)
@events = Event.where(:conference_id => @this_conference.id).order(start_time: :asc)
@locations = EventLocation.where(:conference_id => @this_conference.id)
# @events = Event.where(:conference_id => @this_conference.id).order(start_time: :asc)
# @locations = EventLocation.where(:conference_id => @this_conference.id)
render 'schedule/show'
end
# render 'schedule/show'
# end
def edit_schedule
set_conference
return do_404 unless @this_conference.host?(current_user)
# def edit_schedule
# set_conference
# return 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
# @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)
# @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
# (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
# @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?
# @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
# render 'schedule/edit'
# end
def save_schedule
set_conference
return do_404 unless @this_conference.host?(current_user)
# def save_schedule
# set_conference
# return 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)
# @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
# (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,
:event_location_id => @workshops[i].event_location_id
}
end
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,
# :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,
:event_location_id => @events[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,
# :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
# 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
# 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 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
# if save_conference
# @this_conference.save
# end
redirect_to edit_schedule_url(@this_conference.slug)
end
# redirect_to edit_schedule_url(@this_conference.slug)
# end
def add_event
set_conference
return do_404 unless @this_conference.host?(current_user)
# def add_event
# set_conference
# return do_404 unless @this_conference.host?(current_user)
render 'events/edit'
end
# render 'events/edit'
# end
def edit_event
set_conference
return do_404 unless @this_conference.host?(current_user)
# def edit_event
# set_conference
# return do_404 unless @this_conference.host?(current_user)
@event = Event.find(params[:id])
return do_403 unless @event.conference_id == @this_conference.id
# @event = Event.find(params[:id])
# return do_403 unless @event.conference_id == @this_conference.id
render 'events/edit'
end
# render 'events/edit'
# end
def save_event
set_conference
return do_404 unless @this_conference.host?(current_user)
# def save_event
# set_conference
# return do_404 unless @this_conference.host?(current_user)
if params[:event_id]
event = Event.find(params[:event_id])
return do_403 unless event.conference_id == @this_conference.id
else
event = Event.new(:conference_id => @this_conference.id)
end
# if params[:event_id]
# event = Event.find(params[:event_id])
# return 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.title = params[:title]
# event.info = params[:info]
# event.event_type = params[:event_type]
event.save
# event.save
return redirect_to schedule_url(@this_conference.slug)
end
# return redirect_to schedule_url(@this_conference.slug)
# end
def add_location
set_conference
return do_404 unless @this_conference.host?(current_user)
# def add_location
# set_conference
# return do_404 unless @this_conference.host?(current_user)
render 'event_locations/edit'
end
# render 'event_locations/edit'
# end
def edit_location
set_conference
return do_404 unless @this_conference.host?(current_user)
# def edit_location
# set_conference
# return do_404 unless @this_conference.host?(current_user)
@location = EventLocation.find(params[:id])
return do_403 unless @location.conference_id == @this_conference.id
# @location = EventLocation.find(params[:id])
# return do_403 unless @location.conference_id == @this_conference.id
@amenities = JSON.parse(@location.amenities || '[]').map &:to_sym
# @amenities = JSON.parse(@location.amenities || '[]').map &:to_sym
render 'event_locations/edit'
end
# render 'event_locations/edit'
# end
def save_location
set_conference
return do_404 unless @this_conference.host?(current_user)
# def save_location
# set_conference
# return do_404 unless @this_conference.host?(current_user)
if params[:location_id]
location = EventLocation.find(params[:location_id])
return do_403 unless location.conference_id == @this_conference.id
else
location = EventLocation.new(:conference_id => @this_conference.id)
end
# if params[:location_id]
# location = EventLocation.find(params[:location_id])
# return 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.title = params[:title]
# location.address = params[:address]
# location.amenities = (params[:needs] || {}).keys.to_json
location.save
# location.save
return redirect_to schedule_url(@this_conference.slug)
end
# return redirect_to schedule_url(@this_conference.slug)
# end
# DELETE /conferences/1
#def destroy

2
app/models/organization.rb

@ -31,6 +31,8 @@ class Organization < ActiveRecord::Base
def host?(user)
return false unless user.present?
return true if user.administrator?
users.each do |u|
return true if u.id == user.id
end

4
app/models/user.rb

@ -36,6 +36,10 @@ class User < ActiveRecord::Base
return "#{name} <#{email}>"
end
def administrator?
role == 'administrator'
end
def self.get(email)
user = where(email: email).first

14
app/views/application/home.html.haml

@ -6,11 +6,11 @@
= columns(medium: 10, push: {medium: 1}) do
%h2=_!@conference.title
= @conference.info.html_safe
- if @conference.workshops
- 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
- if @conference.registration_status == :open
%h3=_'articles.workshops.headings.Proposed_Workshops'
%p=_'articles.workshops.paragraphs.Proposed_Workshops'
= render 'workshops/workshop_previews', :workshops => @conference.workshops
- if @conference.workshop_schedule_published
%h3=_'articles.workshops.headings.Schedule'
= render 'conferences/admin/schedule'
- else
%h3=_'articles.workshops.headings.Proposed_Workshops'
%p=_'articles.workshops.paragraphs.Proposed_Workshops'
= render 'workshops/workshop_previews', :workshops => @conference.workshops

2
app/views/conferences/_questions.html.haml

@ -10,7 +10,7 @@
= selectfield :departure, @registration.departure || @this_conference.start_date, conference_days_options_list(:after)
= radiobuttons :bike, ConferenceRegistration.all_bike_options, @registration.bike, 'articles.conference_registration.questions.bike', heading: 'articles.conference_registration.headings.bike', inline: true, big: true
= radiobuttons :food, ConferenceRegistration.all_food_options, @registration.food, 'articles.conference_registration.questions.food', heading: 'articles.conference_registration.headings.food', inline: true, big: true
= emailfield :companion, (@registration.housing_data[:companions] || [nil]).first, heading: 'articles.conference_registration.headings.companion', help: 'articles.conference_registration.paragraphs.companion', big: true
= emailfield :companion, (@registration.housing_data['companions'] || [nil]).first, heading: 'articles.conference_registration.headings.companion', help: 'articles.conference_registration.paragraphs.companion', big: true
= textfield :allergies, @registration.allergies, heading: 'articles.conference_registration.headings.allergies'
= textarea :other, @registration.other, plain: true, heading: 'articles.conference_registration.headings.other'
= button_tag :register, :value => :questions

23
app/views/conferences/admin/_housing.html.haml

@ -20,7 +20,28 @@
%li.guest{id: "guest-#{id}", data: { id: id, 'affected-hosts': @hosts_affected_by_guests[id].join(',') }}
%h4= registration.user.name
.city=registration.city
.email.on-top-only=registration.user.email
.on-top-only.details
= data_set(:h4, 'articles.admin.housing.headings.email') do
= registration.user.email
= data_set(:h4, 'articles.admin.housing.headings.housing') do
= registration.housing
- if registration.arrival.present?
= data_set(:h4, 'articles.admin.housing.headings.arrival_departure') do
= date_span(registration.arrival.to_date, registration.departure.to_date)
- if (registration.housing_data || {})['companions'].present?
= data_set(:h4, 'articles.admin.housing.headings.companion') do
- companion = User.find_by_email(registration.housing_data['companions'].first)
- if companion
= "#{companion.firstname} (#{companion.email})"
- else
= registration.housing_data['companions'].first
= _'articles.admin.housing.headings.unregistered'
- if registration.allergies.present?
= data_set(:h4, 'articles.admin.housing.headings.allergies') do
= registration.allergies
- if registration.other.present?
= data_set(:h4, 'articles.admin.housing.headings.other') do
= registration.other
= button_tag :set_host, type: :button, class: [:small, 'set-host', 'not-on-top']

82
app/views/conferences/admin/_schedule.html.haml

@ -1,3 +1,13 @@
- conference = @this_conference || @conference
- if @entire_page
= form_tag administration_update_path(conference.slug, :schedule) do
- if conference.workshop_schedule_published
%p=_'articles.conference_registration.paragraphs.admin.schedule.published', :p
.actions= button_tag :un_publish, value: :publish, class: :delete
- else
%p=_'articles.conference_registration.paragraphs.admin.schedule.un_published', :p
.actions= button_tag :publish, value: :publish
#schedule-preview
- @schedule.each do | day, data |
%h4=date(day, :weekday)
@ -24,23 +34,33 @@
- workshop = status = nil
%td{class: [time_data[:type], workshop.present? ? :filled : nil], rowspan: rowspan}
- if workshop.present?
= form_tag administration_update_path(@this_conference.slug, :schedule), class: 'js-xhr' do
.title=workshop.title
.status
.conflict-score
%span.title Conflict Score:
%span.value="#{status[:conflict_score] * 100.0}%"
- if status[:errors].present?
.errors
- status[:errors].each do | error |
.error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars]
= hidden_field_tag :id, workshop.id
= button_tag :deschedule, value: :deschedule_workshop, class: [:delete, :small]
- else
= link_to off_screen(workshop.title), view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link'
%template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }}
%h1.title=workshop.title
%p.address
= workshop.event_location.title + _!(': ')
%a{ href: "http://www.google.com/maps/place/#{workshop.event_location.latitude},#{workshop.event_location.longitude}" }
= workshop.event_location.address
.workshop-description= richtext workshop.info, 1
.title=workshop.title
- if @can_edit
= form_tag administration_update_path(conference.slug, :schedule), class: 'js-xhr' do
.status
.conflict-score
%span.title Conflict Score:
%span.value="#{status[:conflict_score] * 100.0}%"
- if status[:errors].present?
.errors
- status[:errors].each do | error |
.error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars]
= hidden_field_tag :id, workshop.id
= button_tag :deschedule, value: :deschedule_workshop, class: [:delete, :small]
- elsif @can_edit
.title="Block #{time_data[:item][:block] + 1}"
- else
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1}
.title="Block #{time_data[:item][:block] + 1}"
- if @can_edit
.title="Block #{time_data[:item][:block] + 1}"
%td.status{rowspan: rowspan}
- if time_data[:status].present? && time_data[:status][:errors].present?
%ul.errors
@ -50,18 +70,34 @@
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1}
- case time_data[:type]
- when :meal
%a.event-detail-link=off_screen(time_data[:item]['title'])
- location = EventLocation.find(time_data[:item]['location'].to_i)
%template.event-details
%h1.title=time_data[:item]['title']
%p.address
= location.title + _!(': ')
%a{ href: "http://www.google.com/maps/place/#{location.latitude},#{location.longitude}" }
= location.address
.title= time_data[:item]['title']
.location= EventLocation.find(time_data[:item]['location'].to_i).title
.location= location.title
- when :event
%a.event-detail-link=off_screen(time_data[:item].title)
%template.event-details
%h1.title=time_data[:item].title
%p.address
= time_data[:item].event_location.title + _!(': ')
%a{ href: "http://www.google.com/maps/place/#{time_data[:item].event_location.latitude},#{time_data[:item].event_location.longitude}" }
= time_data[:item].event_location.address
= richtext time_data[:item].info, 1
.title= time_data[:item].title
.location= time_data[:item].event_location.title
%td.status{rowspan: rowspan}
- unless request.xhr?
%ul.workshop-list
- if @entire_page
%ul.workshops-to-schedule
- @workshops.each do | workshop |
%li{id: "workshop-#{workshop.id}", class: workshop.block.present? ? 'booked' : 'not-booked'}
%h4.title= workshop.title
= form_tag administration_update_path(@this_conference.slug, :schedule), class: 'js-xhr' do
= form_tag administration_update_path(conference.slug, :schedule), class: 'js-xhr' do
.already-booked
.field-error='This block is already booked'
.workshop-description
@ -89,10 +125,10 @@
= link_info_dlg truncate(workshop.notes), (richtext workshop.notes.html_safe), workshop.title
= hidden_field_tag :id, workshop.id
.flex-inputs
= location_select workshop.event_location_id, small: true, stretch: true
.drop-downs
= location_select workshop.event_location_id, small: true
= block_select workshop.block.present? ? "#{workshop.block['day']}:#{workshop.block['block']}" : nil, small: true
.actions.next-prev
= button_tag :deschedule, value: :deschedule_workshop, class: [:delete, 'booked-only']
= button_tag :reschedule, value: :schedule_workshop, class: [:secondary, 'booked-only']
= button_tag :schedule_workshop, value: :schedule_workshop, class: 'not-booked-only'
= button_tag :deschedule, value: :deschedule_workshop, class: [:delete, 'booked-only', :small]
= button_tag :reschedule, value: :schedule_workshop, class: [:secondary, 'booked-only', :small]
= button_tag :schedule_workshop, value: :schedule_workshop, class: ['not-booked-only', :small]

12
app/views/conferences/admin/_stats.html.haml

@ -1,5 +1,17 @@
.details
= data_set(:h4, 'articles.admin.stats.headings.registrations') do
= @registrations.size
= data_set(:h4, 'articles.admin.stats.headings.bikes') do
= "#{@bikes} (#{(@bikes / @registration_count) * 100.0}%)"
= data_set(:h4, 'articles.admin.stats.headings.food.meat') do
= "#{@food[:meat]} (#{(@food[:meat] / @food[:all]) * 100.0}%)"
= data_set(:h4, 'articles.admin.stats.headings.food.vegetarian') do
= "#{@food[:vegetarian]} (#{(@food[:vegetarian] / @food[:all]) * 100.0}%)"
= data_set(:h4, 'articles.admin.stats.headings.food.vegan') do
= "#{@food[:vegan]} (#{(@food[:vegan] / @food[:all]) * 100.0}%)"
= data_set(:h4, 'articles.admin.stats.headings.donation_count') do
= "#{@donation_count} (#{(@donation_count / @registration_count) * 100.0}%)"
= data_set(:h4, 'articles.admin.stats.headings.donation_total') do
= "$#{@donations}"
.actions
= link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :stats, :format => :xlsx), class: [:button, :download]

6
app/views/layouts/application.html.haml

@ -74,5 +74,11 @@
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: settings_path), class: [:button, :facebook]
%button.close.subdued=_'forms.actions.generic.cancel'
- if @event_dlg.present?
.event-dlg#event-dlg{ data: { type: :event } }
.event-details
.actions.right
%a.more-details.button{href: '#'}=_'articles.workshops.info.read_more'
%button.close-btn.subdued=_'forms.actions.generic.close'
= yield :footer_scripts if content_for?(:footer_scripts)
= inline_scripts

2
app/views/workshops/_workshop_previews.html.haml

@ -12,4 +12,4 @@
%span.interest-text=interest_text(w)
.workshop-description=richtext w.info, 4
.actions.right
= link_to (_'articles.workshops.info.read_more'), view_workshop_path(w.conference.slug, w.id), class: 'workshop-link', class: [:button, :small]
= link_to (_'articles.workshops.info.read_more'), view_workshop_path(w.conference.slug, w.id), class: ['workshop-link', :button, :small]

2
config/initializers/assets.rb

@ -8,4 +8,4 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js editor.js markdown.js html2canvas.js main.js housing.js favicon.ico )
Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js editor.js markdown.js html2canvas.js main.js housing.js schedule.js favicon.ico )

7
config/locales/en.yml

@ -5405,7 +5405,7 @@ en:
notes: Notes
admin:
edit:
info: 'Conference Info'
info: Info
companion: Companion
paragraphs:
Policy_Agreement: Ensuring that all attendees feel welcome, safe, and respected at all times is especially important to us all. Please ensure that you have fully read and understand our safer spaces policy below, if you have any questions or concerns you can reach out to the organizers at any time.
@ -5464,6 +5464,9 @@ en:
admin:
edit:
info: This is the copy that is displayed on the front page of the site.
schedule:
published: Your scheulde is currently published and viewable on the front-page. Un-publishing the schedule will remove it from the front-page and show a list of proposed workshops instead.
un_published: Your schedule is not yet published. Publishing the schedule will replace the list of proposed workshops on the front-page with the schedule as it is shown below.
companion: Is there someone who you would like us to ensure that you are housed with?
arrival_and_departure: If you don't need housing, just tell us how long you plan to hang out with Bike!Bike!
host:
@ -5705,6 +5708,8 @@ en:
add_comment: Add Comment
reply: Reply
add_member: Add
publish: Publish Schedule
un_publish: Un-Publish Schedule
aria:
remove_interest: Click if you are no longer interested in this workshop
show_interest: Click if you are interested in this workshop

Loading…
Cancel
Save