From e9d9962d9af1a28f72d778b7a817d39c1b4cdaf9 Mon Sep 17 00:00:00 2001 From: Godwin Date: Sun, 17 Jul 2016 20:04:15 -0700 Subject: [PATCH] Home page schedule, publish and unpublish schedule, extended user data in housing --- app/assets/javascripts/main.js | 52 +- app/assets/stylesheets/_application.scss | 367 +++++---- app/controllers/application_controller.rb | 197 ++++- app/controllers/conferences_controller.rb | 710 +++++++----------- app/models/organization.rb | 2 + app/models/user.rb | 4 + app/views/application/home.html.haml | 14 +- app/views/conferences/_questions.html.haml | 2 +- .../conferences/admin/_housing.html.haml | 23 +- .../conferences/admin/_schedule.html.haml | 82 +- app/views/conferences/admin/_stats.html.haml | 12 + app/views/layouts/application.html.haml | 6 + .../workshops/_workshop_previews.html.haml | 2 +- config/initializers/assets.rb | 2 +- config/locales/en.yml | 7 +- 15 files changed, 844 insertions(+), 638 deletions(-) diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 982285e..ee10e21 100644 --- a/app/assets/javascripts/main.js +++ b/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) { diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss index d996a75..84aa1b6 100644 --- a/app/assets/stylesheets/_application.scss +++ b/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; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7356f14..32fa240 100644 --- a/app/controllers/application_controller.rb +++ b/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 diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 7e889a2..8df843a 100644 --- a/app/controllers/conferences_controller.rb +++ b/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 diff --git a/app/models/organization.rb b/app/models/organization.rb index b207523..5117fd1 100644 --- a/app/models/organization.rb +++ b/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 diff --git a/app/models/user.rb b/app/models/user.rb index bbe7cab..117f06c 100644 --- a/app/models/user.rb +++ b/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 diff --git a/app/views/application/home.html.haml b/app/views/application/home.html.haml index d822f0e..870caf0 100644 --- a/app/views/application/home.html.haml +++ b/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 diff --git a/app/views/conferences/_questions.html.haml b/app/views/conferences/_questions.html.haml index 8820617..48366d5 100644 --- a/app/views/conferences/_questions.html.haml +++ b/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 diff --git a/app/views/conferences/admin/_housing.html.haml b/app/views/conferences/admin/_housing.html.haml index 85ad805..e2a455d 100644 --- a/app/views/conferences/admin/_housing.html.haml +++ b/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'] diff --git a/app/views/conferences/admin/_schedule.html.haml b/app/views/conferences/admin/_schedule.html.haml index ca62c31..9cbed17 100644 --- a/app/views/conferences/admin/_schedule.html.haml +++ b/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] diff --git a/app/views/conferences/admin/_stats.html.haml b/app/views/conferences/admin/_stats.html.haml index eb97fc8..1537de3 100644 --- a/app/views/conferences/admin/_stats.html.haml +++ b/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] diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index bc807d7..a09c671 100644 --- a/app/views/layouts/application.html.haml +++ b/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 diff --git a/app/views/workshops/_workshop_previews.html.haml b/app/views/workshops/_workshop_previews.html.haml index 7b7a29b..14219d8 100644 --- a/app/views/workshops/_workshop_previews.html.haml +++ b/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] diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 79fd481..9472591 100644 --- a/config/initializers/assets.rb +++ b/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 ) diff --git a/config/locales/en.yml b/config/locales/en.yml index 39f790c..7472434 100644 --- a/config/locales/en.yml +++ b/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