Skip to content
This repository was archived by the owner on Jul 24, 2020. It is now read-only.

Commit d80d6fb

Browse files
committed
Merge pull request #12 from YaleSTC/12_calendar_view
Calendar View of item availablity
2 parents ce4ed96 + d648934 commit d80d6fb

File tree

9 files changed

+288
-85
lines changed

9 files changed

+288
-85
lines changed

app/assets/javascripts/application.js

+1-17
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
//= require variables.js
2525
//= require select2
2626
//= require_self
27+
//= require calendar.js
2728

2829
function truncate() {
2930
if ($(".caption_cat").length) {
@@ -219,23 +220,6 @@ if ($(window).width() > 767) {
219220
$(".not-qualified-icon").tooltip();
220221
$(".not-qualified-icon-em").tooltip();
221222

222-
// Equipment Model - show - progress bar
223-
224-
$('.progress .bar').each(function() {
225-
var me = $(this);
226-
var perc = me.attr("data-percentage");
227-
var current_perc = 0;
228-
229-
var progress = setInterval(function() {
230-
if (current_perc>=perc) {
231-
clearInterval(progress);
232-
} else {
233-
current_perc = perc;
234-
me.css('width', (current_perc)+'%');
235-
}
236-
}, 100);
237-
});
238-
239223
$('.associated_em_box img').popover({ placement: 'bottom' });
240224
$("#my_reservations .dropdown-menu a").popover({ placement: 'bottom' });
241225
$("#my_equipment .dropdown-menu a").popover({ placement: 'bottom' });

app/assets/javascripts/calendar.js

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
function decCellValue(cell) {
2+
var obj = cell.children('.num').children()[0];
3+
obj.innerHTML = parseInt(obj.innerHTML) - 1;
4+
};
5+
6+
function parseDate(dateString){
7+
//why the fck cant we have normal datestrings
8+
var d = new Date(dateString);
9+
var string = d.toISOString();
10+
return string.substring(5,7) + "/" + string.substring(8,10) + '/' + string.substring(0,4);
11+
}
12+
function dateToRubyString(date) {
13+
return date.toISOString().substring(0,10);
14+
};
15+
16+
function dateToHeading(date) {
17+
var days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat','Sun'];
18+
return ' ' + days[date.getUTCDay()];
19+
};
20+
21+
function renderCalendar(reservations, week_start, max, blackouts) {
22+
//set initial values and date ids
23+
var date = new Date(week_start.getTime());
24+
$('.calendar_cell').each(function() {
25+
$(this).children('.head').children()[0].innerHTML = date.getUTCDate().toString();
26+
$(this).children('.head').children()[1].innerHTML = dateToHeading(date);
27+
$(this).children('.num').children()[0].innerHTML = max.toString();
28+
$(this).attr('id',dateToRubyString(date));
29+
date.setDate(date.getDate()+1);
30+
});
31+
var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
32+
33+
$('.month').children()[0].innerHTML = months[week_start.getMonth()] + " " + date.getFullYear().toString();
34+
35+
//set cell values based on reservations
36+
for(var d = 0; d < reservations.length; d++) {
37+
var end = new Date (reservations[d].end);
38+
var start = new Date (reservations[d].start);
39+
var week_end = new Date();
40+
week_end.setDate(week_start.getDate() + 7);
41+
if ((start < week_end) && (end >= week_start)) {
42+
//for each reservation, decrement availability per day
43+
var begin_date = ((week_start > start) ? week_start : start);
44+
var end_date = ((week_end < end) ? week_end : end);
45+
for (var date = new Date(begin_date.getTime());
46+
date <= end_date;
47+
date.setDate(date.getDate()+1)) {
48+
decCellValue($('#'+dateToRubyString(date)));
49+
}
50+
}
51+
}
52+
53+
//color cells appropriately
54+
$('.calendar_cell').each(function() {
55+
var blacked = false;
56+
for(var b = 0; b < blackouts.length; b++) {
57+
date = new Date($(this).attr('id'));
58+
if ((new Date(blackouts[b].start) <= date) && (new Date(blackouts[b].end) >= date)) {
59+
blacked = true;
60+
break;
61+
}
62+
}
63+
if (blacked) {
64+
var color = '#999999';
65+
} else {
66+
var val = parseInt($(this).children('.num').children()[0].innerHTML);
67+
var red = Math.min(Math.floor(510 - val*510/max),255).toString();
68+
var green = Math.min(Math.floor(val*510/max),255).toString();
69+
var color = 'rgba(' + red + ',' + green + ',0,0.5)';
70+
}
71+
$(this).css("background-color",color);
72+
73+
});
74+
75+
};
76+
77+
function shiftCalendar(offset) {
78+
var reservations = $('#res-data').data('url');
79+
var blackouts = $('#res-data').data('blackouts');
80+
var week_start = new Date($('.calendar_cell').first().attr('id'));
81+
var today = new Date($('#res-data').data('today'));
82+
var date_max = new Date($('#res-data').data('dateMax'));
83+
var max = $('#res-data').data('max');
84+
week_start.setDate(week_start.getDate() + offset);
85+
if (week_start < today) {
86+
week_start.setTime(today.getTime());
87+
}
88+
if (week_start > date_max) {
89+
week_start.setTime(date_max.getTime());
90+
}
91+
renderCalendar(reservations,week_start,max,blackouts);
92+
};
93+
94+
95+
$('#reservation-calendar').ready(function() {
96+
97+
//quit if no reservation calendar present
98+
//there's probably a better way to do this?
99+
100+
if ($('#reservation-calendar').size() == 0) {
101+
return false;
102+
}
103+
104+
shiftCalendar(0);
105+
106+
$('.calendar_cell').click(function() {
107+
//set cart dates to day clicked
108+
$('#cart_start_date_cart').attr('value', parseDate($(this).attr('id'))).trigger('change');
109+
});
110+
111+
$('.control').click(function() {
112+
shiftCalendar(parseInt($(this).attr('change')));
113+
});
114+
115+
});

app/assets/stylesheets/equipment_models/_show.css.scss

+71-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,74 @@
1-
.progress {
2-
margin-bottom: 0;
1+
2+
$border-att: 1px solid darken($bodyBackground, 20%);
3+
4+
.num,.head {
5+
text-align:center;
6+
}
7+
8+
.reservation_calendar {
9+
overflow: hidden;
10+
}
11+
12+
#calendar-ul {
13+
margin-left: 0px;
14+
margin-bottom: 3px;
15+
margin-top: 3px;
16+
}
17+
18+
.calendar_cell {
19+
border: $border-att;
20+
border-radius: 3px;
21+
width: 13%;
22+
display: inline-block;
23+
vertical-align:top;
24+
background-color: rgba(0,255,0,0.5);
25+
opacity: 0.9;
26+
padding-top: 3px;
27+
padding-bottom: 5px;
28+
}
29+
30+
.month {
31+
margin-top:3px;
32+
}
33+
34+
.calendar_cell:hover{
35+
opacity: 1.0;
36+
cursor: pointer;
37+
}
38+
39+
.c-left {
40+
float: left;
341
}
42+
43+
.c-right {
44+
float: right;
45+
}
46+
47+
.control {
48+
font-size:20px;
49+
margin:3px;
50+
opacity: 0.8;
51+
-webkit-touch-callout: none;
52+
-webkit-user-select: none;
53+
-khtml-user-select: none;
54+
-moz-user-select: none;
55+
-ms-user-select: none;
56+
user-select: none;
57+
}
58+
59+
.control:hover{
60+
cursor:pointer;
61+
opacity: 1.0;
62+
}
63+
64+
.control:active{
65+
color: black;
66+
}
67+
68+
.lite {
69+
opacity: 0.7;
70+
}
71+
472
.btn-large {
573
float: right;
674
}
@@ -69,4 +137,4 @@ a.not-qualified-icon-em {
69137
text-decoration: none;
70138
color: $btnWarningBackground;
71139
}
72-
}
140+
}

app/controllers/equipment_models_controller.rb

+17
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,25 @@ def index
2626

2727
def show
2828
@associated_equipment_models = @equipment_model.associated_equipment_models.sample(6)
29+
@model_reservations = Reservation.active.for_eq_model @equipment_model
30+
@reservation_data = []
31+
@model_reservations.each do |r|
32+
@reservation_data << {
33+
start: r.start_date, end: r.due_date}
34+
end
35+
@blackouts = []
36+
Blackout.active.each do |b|
37+
@blackouts << {
38+
start: b.start_date, end: b.end_date}
39+
end
40+
@date = Time.current.to_date
41+
@date_max = @date + 1.month - 1.week
42+
@max = @equipment_model.equipment_objects.count
43+
44+
@restricted = @equipment_model.model_restricted?(cart.reserver_id)
2945
end
3046

47+
3148
def new
3249
@equipment_model = EquipmentModel.new(category: @category)
3350
end

app/models/blackout.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ class Blackout < ActiveRecord::Base
1414
validate :validate_end_date_before_start_date
1515
# this only matters if a user tries to inject into params because the datepicker
1616
# doesn't allow form submission of invalid dates
17-
17+
18+
scope :active, where("end_date >= ?", Date.today)
1819
def self.blackouts_on_date(date) # Returns the blackout object that blacks out the day if the day is blacked out. Otherwise, returns nil.
1920
blackouts = []
2021
Blackout.all.each do |blackout|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<% if @restricted %>
2+
<%= link_to "#qualifications_modal",
3+
class: 'not-qualified-icon-em',
4+
rel: "tooltip",
5+
title: 'Not Qualified (click for more info)',
6+
:"data-toggle" => 'modal' do %>
7+
<i class="icon-warning-sign"></i>
8+
<% end %>
9+
<%= button_tag "Add to Cart", remote: true, class: 'btn btn-primary btn-large disabled' %>
10+
<div id="qualifications_modal" class="modal hide fade">
11+
<div class="modal-header">
12+
<button type="button" class="close" data-dismiss="modal">×</button>
13+
<h3><%= "Qualification Required" %></h3>
14+
</div>
15+
<div class="modal-body">
16+
<p>
17+
<%= Requirement.list_requirement_admins(current_user, @equipment_model)%>
18+
</p>
19+
</div>
20+
</div>
21+
<% else %>
22+
23+
<%= link_to "Add to Cart", {:url => add_to_cart_path(@equipment_model)},
24+
:href => add_to_cart_path(@equipment_model),
25+
:method => :put, :remote => true, :class => 'btn btn-primary btn-large' %>
26+
<% end %>
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<h3>Availability</h3>
2+
<div id="reservation-calendar">
3+
<%= 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 %>
4+
<% end %>
5+
<div class = "month"><h4></h4></div>
6+
7+
<ul id = "calendar-ul">
8+
<li class = "calendar_cell" id ="<%= cart.start_date %>">
9+
<% for d in 0...6 %>
10+
<div class = "head"><strong></strong><i></i></div>
11+
<div class = "num"><h2></h2></div>
12+
</li>
13+
<li class = "calendar_cell">
14+
<% end %>
15+
<div class = "head"><strong></strong><i></i></div>
16+
<div class = "num"><h2></h2></div>
17+
</li>
18+
</ul>
19+
20+
<div class = "controls c-left">
21+
<i class="control icon-backward" change="-7" title="Move back a week"></i>
22+
<i class="control lite icon-chevron-left" change="-1" title="Move back a day"></i>
23+
</div>
24+
<div class = "controls c-right">
25+
<i class="control lite icon-chevron-right" change="1" title="Move forward a day"></i>
26+
<i class="control icon-forward" change="7" title="Move forward a week"></i>
27+
</div>
28+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<div class="calendar">
2+
3+
<% for d in @beginning...(@beginning+7.day) %>
4+
<div class = "day">
5+
<%= d.day %>
6+
<% @model_reservations.each do |r| %>
7+
<% if r.start_date.to_date == d %>
8+
<div class = "reservation" >
9+
<% if r.equipment_object %>
10+
<% label = r.equipment_object.name %>
11+
<% else %>
12+
<% label = 'Reserved' %>
13+
<% end %>
14+
<%= label %>
15+
</div>
16+
<% end %>
17+
<% end %>
18+
</div>
19+
<% end %>
20+
</div>

0 commit comments

Comments
 (0)