diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 359bef9d4..ab64a24a3 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -24,6 +24,7 @@ //= require variables.js //= require select2 //= require_self +//= require calendar.js function truncate() { if ($(".caption_cat").length) { @@ -219,23 +220,6 @@ if ($(window).width() > 767) { $(".not-qualified-icon").tooltip(); $(".not-qualified-icon-em").tooltip(); - // Equipment Model - show - progress bar - - $('.progress .bar').each(function() { - var me = $(this); - var perc = me.attr("data-percentage"); - var current_perc = 0; - - var progress = setInterval(function() { - if (current_perc>=perc) { - clearInterval(progress); - } else { - current_perc = perc; - me.css('width', (current_perc)+'%'); - } - }, 100); - }); - $('.associated_em_box img').popover({ placement: 'bottom' }); $("#my_reservations .dropdown-menu a").popover({ placement: 'bottom' }); $("#my_equipment .dropdown-menu a").popover({ placement: 'bottom' }); diff --git a/app/assets/javascripts/calendar.js b/app/assets/javascripts/calendar.js new file mode 100644 index 000000000..864e0d44c --- /dev/null +++ b/app/assets/javascripts/calendar.js @@ -0,0 +1,115 @@ +function decCellValue(cell) { + var obj = cell.children('.num').children()[0]; + obj.innerHTML = parseInt(obj.innerHTML) - 1; +}; + +function parseDate(dateString){ +//why the fck cant we have normal datestrings + var d = new Date(dateString); + var string = d.toISOString(); + return string.substring(5,7) + "/" + string.substring(8,10) + '/' + string.substring(0,4); +} +function dateToRubyString(date) { + return date.toISOString().substring(0,10); +}; + +function dateToHeading(date) { + var days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat','Sun']; + return ' ' + days[date.getUTCDay()]; +}; + +function renderCalendar(reservations, week_start, max, blackouts) { + //set initial values and date ids + var date = new Date(week_start.getTime()); + $('.calendar_cell').each(function() { + $(this).children('.head').children()[0].innerHTML = date.getUTCDate().toString(); + $(this).children('.head').children()[1].innerHTML = dateToHeading(date); + $(this).children('.num').children()[0].innerHTML = max.toString(); + $(this).attr('id',dateToRubyString(date)); + date.setDate(date.getDate()+1); + }); + var months = ['January','February','March','April','May','June','July','August','September','October','November','December']; + + $('.month').children()[0].innerHTML = months[week_start.getMonth()] + " " + date.getFullYear().toString(); + + //set cell values based on reservations + for(var d = 0; d < reservations.length; d++) { + var end = new Date (reservations[d].end); + var start = new Date (reservations[d].start); + var week_end = new Date(); + week_end.setDate(week_start.getDate() + 7); + if ((start < week_end) && (end >= week_start)) { + //for each reservation, decrement availability per day + var begin_date = ((week_start > start) ? week_start : start); + var end_date = ((week_end < end) ? week_end : end); + for (var date = new Date(begin_date.getTime()); + date <= end_date; + date.setDate(date.getDate()+1)) { + decCellValue($('#'+dateToRubyString(date))); + } + } + } + + //color cells appropriately + $('.calendar_cell').each(function() { + var blacked = false; + for(var b = 0; b < blackouts.length; b++) { + date = new Date($(this).attr('id')); + if ((new Date(blackouts[b].start) <= date) && (new Date(blackouts[b].end) >= date)) { + blacked = true; + break; + } + } + if (blacked) { + var color = '#999999'; + } else { + var val = parseInt($(this).children('.num').children()[0].innerHTML); + var red = Math.min(Math.floor(510 - val*510/max),255).toString(); + var green = Math.min(Math.floor(val*510/max),255).toString(); + var color = 'rgba(' + red + ',' + green + ',0,0.5)'; + } + $(this).css("background-color",color); + + }); + +}; + +function shiftCalendar(offset) { + var reservations = $('#res-data').data('url'); + var blackouts = $('#res-data').data('blackouts'); + var week_start = new Date($('.calendar_cell').first().attr('id')); + var today = new Date($('#res-data').data('today')); + var date_max = new Date($('#res-data').data('dateMax')); + var max = $('#res-data').data('max'); + week_start.setDate(week_start.getDate() + offset); + if (week_start < today) { + week_start.setTime(today.getTime()); + } + if (week_start > date_max) { + week_start.setTime(date_max.getTime()); + } + renderCalendar(reservations,week_start,max,blackouts); +}; + + +$('#reservation-calendar').ready(function() { + + //quit if no reservation calendar present + //there's probably a better way to do this? + + if ($('#reservation-calendar').size() == 0) { + return false; + } + + shiftCalendar(0); + + $('.calendar_cell').click(function() { + //set cart dates to day clicked + $('#cart_start_date_cart').attr('value', parseDate($(this).attr('id'))).trigger('change'); + }); + + $('.control').click(function() { + shiftCalendar(parseInt($(this).attr('change'))); + }); + +}); diff --git a/app/assets/stylesheets/equipment_models/_show.css.scss b/app/assets/stylesheets/equipment_models/_show.css.scss index f518f9957..c1a2d3917 100644 --- a/app/assets/stylesheets/equipment_models/_show.css.scss +++ b/app/assets/stylesheets/equipment_models/_show.css.scss @@ -1,6 +1,74 @@ -.progress { - margin-bottom: 0; + +$border-att: 1px solid darken($bodyBackground, 20%); + +.num,.head { + text-align:center; +} + +.reservation_calendar { + overflow: hidden; +} + +#calendar-ul { + margin-left: 0px; + margin-bottom: 3px; + margin-top: 3px; +} + +.calendar_cell { + border: $border-att; + border-radius: 3px; + width: 13%; + display: inline-block; + vertical-align:top; + background-color: rgba(0,255,0,0.5); + opacity: 0.9; + padding-top: 3px; + padding-bottom: 5px; + } + +.month { + margin-top:3px; +} + +.calendar_cell:hover{ + opacity: 1.0; + cursor: pointer; +} + +.c-left { + float: left; } + +.c-right { + float: right; +} + +.control { + font-size:20px; + margin:3px; + opacity: 0.8; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.control:hover{ + cursor:pointer; + opacity: 1.0; +} + +.control:active{ + color: black; +} + +.lite { + opacity: 0.7; +} + .btn-large { float: right; } @@ -69,4 +137,4 @@ a.not-qualified-icon-em { text-decoration: none; color: $btnWarningBackground; } -} \ No newline at end of file +} diff --git a/app/controllers/equipment_models_controller.rb b/app/controllers/equipment_models_controller.rb index e5036f667..0d8295eb9 100644 --- a/app/controllers/equipment_models_controller.rb +++ b/app/controllers/equipment_models_controller.rb @@ -26,8 +26,25 @@ def index def show @associated_equipment_models = @equipment_model.associated_equipment_models.sample(6) + @model_reservations = Reservation.active.for_eq_model @equipment_model + @reservation_data = [] + @model_reservations.each do |r| + @reservation_data << { + start: r.start_date, end: r.due_date} + end + @blackouts = [] + Blackout.active.each do |b| + @blackouts << { + start: b.start_date, end: b.end_date} + end + @date = Time.current.to_date + @date_max = @date + 1.month - 1.week + @max = @equipment_model.equipment_objects.count + + @restricted = @equipment_model.model_restricted?(cart.reserver_id) end + def new @equipment_model = EquipmentModel.new(category: @category) end diff --git a/app/models/blackout.rb b/app/models/blackout.rb index bbae3ac56..10e73687f 100644 --- a/app/models/blackout.rb +++ b/app/models/blackout.rb @@ -14,7 +14,8 @@ class Blackout < ActiveRecord::Base validate :validate_end_date_before_start_date # this only matters if a user tries to inject into params because the datepicker # doesn't allow form submission of invalid dates - + + scope :active, where("end_date >= ?", Date.today) def self.blackouts_on_date(date) # Returns the blackout object that blacks out the day if the day is blacked out. Otherwise, returns nil. blackouts = [] Blackout.all.each do |blackout| diff --git a/app/views/equipment_models/_add_to_cart.html.erb b/app/views/equipment_models/_add_to_cart.html.erb new file mode 100644 index 000000000..8f487e578 --- /dev/null +++ b/app/views/equipment_models/_add_to_cart.html.erb @@ -0,0 +1,27 @@ + <% if @restricted %> + <%= link_to "#qualifications_modal", + class: 'not-qualified-icon-em', + rel: "tooltip", + title: 'Not Qualified (click for more info)', + :"data-toggle" => 'modal' do %> + + <% end %> + <%= button_tag "Add to Cart", remote: true, class: 'btn btn-primary btn-large disabled' %> + + <% else %> + + <%= link_to "Add to Cart", {:url => add_to_cart_path(@equipment_model)}, + :href => add_to_cart_path(@equipment_model), + :method => :put, :remote => true, :class => 'btn btn-primary btn-large' %> + <% end %> + diff --git a/app/views/equipment_models/_calendar.html.erb b/app/views/equipment_models/_calendar.html.erb new file mode 100644 index 000000000..1adbdfbbf --- /dev/null +++ b/app/views/equipment_models/_calendar.html.erb @@ -0,0 +1,28 @@ +

Availability

+
+ <%= content_tag "div", id: "res-data", data:{url:@reservation_data, blackouts:@blackouts, today:@date.to_s, max:@max, date_max: @date_max.to_s} do %> + <% end %> +

+ + + +
+ + +
+
+ + +
+
diff --git a/app/views/equipment_models/calendar.html.erb b/app/views/equipment_models/calendar.html.erb new file mode 100644 index 000000000..ed9030d2d --- /dev/null +++ b/app/views/equipment_models/calendar.html.erb @@ -0,0 +1,20 @@ +
+ +<% for d in @beginning...(@beginning+7.day) %> +
+ <%= d.day %> + <% @model_reservations.each do |r| %> + <% if r.start_date.to_date == d %> +
+ <% if r.equipment_object %> + <% label = r.equipment_object.name %> + <% else %> + <% label = 'Reserved' %> + <% end %> + <%= label %> +
+ <% end %> + <% end %> +
+<% end %> +
diff --git a/app/views/equipment_models/show.html.erb b/app/views/equipment_models/show.html.erb index 8cb2df8bd..2bb6cbe90 100644 --- a/app/views/equipment_models/show.html.erb +++ b/app/views/equipment_models/show.html.erb @@ -25,77 +25,18 @@ <%= image_tag "no-image-260.gif" %> <% end %> + +
-

- <%= @equipment_model.num_available(cart.start_date, cart.due_date) || "0"%> available of <%= @equipment_model.equipment_objects.size %> -

-

- <%= content_tag :div, class: "progress #{progress_color}" do %> - <%= content_tag :div, nil, class: 'bar', style: "width: 0%;", :"data-percentage" => bar_progress.chop %> - <% end %> -

-

from <%= cart.start_date.strftime("%b %d, %Y") %> – <%= cart.due_date.strftime("%b %d, %Y") %>

+ <%= render :partial => 'calendar' %>
- -
<%# TODO: Not super DRY right now, will refactor in the future %> - <% if @equipment_model.model_restricted?(cart.reserver_id) %> - <%= link_to "#qualifications_modal", class: 'not-qualified-icon-em', rel: "tooltip", title: "Not Qualified (click for more info)", :"data-toggle" => 'modal' do %> - - <% end %> - - <%= button_tag "Add to Cart", remote: true, class: 'btn btn-primary btn-large disabled' %> - - - <% elsif Blackout.hard_blackout_exists_on_date(cart.start_date) %> - <%= link_to "#qualifications_modal", class: 'not-qualified-icon-em', rel: "tooltip", title: "Not Available (click for more info)", :"data-toggle" => 'modal' do %> - - <% end %> - - <%= button_tag "Add to Cart", remote: true, class: 'btn btn-primary btn-large disabled' %> - - <% elsif Blackout.hard_blackout_exists_on_date(cart.due_date) %> - - <% else %> - - <%= link_to "Add to Cart", {:url => add_to_cart_path(@equipment_model)}, - :href => add_to_cart_path(@equipment_model), - :method => :put, :remote => true, :class => 'btn btn-primary btn-large' %> - <% end %> +
+ <%= render :partial => 'add_to_cart' %>
-
@@ -118,6 +59,8 @@
+ +