Line 0
Link Here
|
0 |
- |
1 |
[% USE raw %] |
|
|
2 |
[% USE Asset %] |
3 |
[% SET footerjs = 1 %] |
4 |
[% USE TablesSettings %] |
5 |
[% INCLUDE 'doc-head-open.inc' %] |
6 |
<title> |
7 |
Curbside pickup › Administration › Koha |
8 |
</title> |
9 |
[% INCLUDE 'doc-head-close.inc' %] |
10 |
<style> |
11 |
.pickup-slot { |
12 |
border: solid; |
13 |
padding: 1em; |
14 |
} |
15 |
</style> |
16 |
</head> |
17 |
|
18 |
<body id="admin_curbside_pickup" class="admin"> |
19 |
[% INCLUDE 'header.inc' %] |
20 |
[% INCLUDE 'cities-admin-search.inc' %] |
21 |
|
22 |
[% USE format_minutes = format('%02d') %] |
23 |
[% MACRO minutes_format BLOCK %][% IF m != "" %][% format_minutes(m) | html %][% END %][% END %] |
24 |
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb"> |
25 |
<ol> |
26 |
<li> |
27 |
<a href="/cgi-bin/koha/mainpage.pl">Home</a> |
28 |
</li> |
29 |
<li> |
30 |
<a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> |
31 |
</li> |
32 |
|
33 |
<li> |
34 |
<a href="#" aria-current="page"> |
35 |
Curbside pickup |
36 |
</a> |
37 |
</li> |
38 |
</ol> |
39 |
</nav> |
40 |
|
41 |
<div class="main container-fluid"> |
42 |
<div class="row"> |
43 |
<div class="col-sm-10 col-sm-push-2"> |
44 |
<main> |
45 |
|
46 |
[% FOR m IN messages %] |
47 |
<div class="dialog [% m.type | html %]"> |
48 |
[% SWITCH m.code %] |
49 |
[% CASE %] |
50 |
<span>[% m.code | html %]</span> |
51 |
[% END %] |
52 |
</div> |
53 |
[% END %] |
54 |
|
55 |
[% IF op == 'list' %] |
56 |
|
57 |
<h1>Curbside pickup configuration</h1> |
58 |
|
59 |
<form method="post" class="form"> |
60 |
<div id="curbside_pickup_tabs" class="toptabs"> |
61 |
<ul class="nav nav-tabs" role="tablist"> |
62 |
[% FOREACH l IN libraries %] |
63 |
[% IF loop.first %] |
64 |
<li role="presentation" class="active"> |
65 |
[% ELSE %] |
66 |
<li role="presentation"> |
67 |
[% END %] |
68 |
<a href="#conf-[% l.branchcode | uri %]" aria-controls="conf-[% l.branchcode | html %]" role="tab" data-toggle="tab">[% l.branchname | html %]</a> |
69 |
</li> |
70 |
[% END %] |
71 |
</ul> |
72 |
|
73 |
<div class="tab-content"> |
74 |
[% FOREACH l IN libraries %] |
75 |
[% SET branchcode = l.branchcode %] |
76 |
[% IF loop.first %] |
77 |
<div id="conf-[% l.branchcode | html %]" role="tabpanel" class="tab-pane active"> |
78 |
[% ELSE %] |
79 |
<div id="conf-[% l.branchcode | html %]" role="tabpanel" class="tab-pane"> |
80 |
[% END %] |
81 |
<fieldset class="rows" style="float: none;"> |
82 |
<ol> |
83 |
<li> |
84 |
<label for="enable-[% l.branchcode | html %]">Enable: </label> |
85 |
[% IF policies.$branchcode.enabled %] |
86 |
<input name="enable-[% l.branchcode | html %]" id="enable-[% l.branchcode | html %]" value="1" type="checkbox" checked> |
87 |
[% ELSE %] |
88 |
<input name="enable-[% l.branchcode | html %]" id="enable-[% l.branchcode | html %]" value="1" type="checkbox"> |
89 |
[% END %] |
90 |
<span class="hint">Enable curbside pickup.<span> |
91 |
</li> |
92 |
|
93 |
<li> |
94 |
<label for="interval-[% l.branchcode | html %]">Pickup interval: </label> |
95 |
<input name="interval-[% l.branchcode | html %]" id="interval-[% l.branchcode | html %]" value="[% policies.$branchcode.pickup_interval | html %]" type="text"> |
96 |
<span class="hint">Number of minutes each curbside pickup interaction will take.</span> |
97 |
</li> |
98 |
|
99 |
<li> |
100 |
<label for="max-per-interval-[% l.branchcode | html %]">Maximum patrons per interval: </label> |
101 |
<input name="max-per-interval-[% l.branchcode | html %]" id="max-per-interval-[% l.branchcode | html %]" value="[% policies.$branchcode.patrons_per_interval | html %]" type="text"> |
102 |
<span class="hint">Maximum number of simultaneus pickups per interval.</span> |
103 |
</li> |
104 |
|
105 |
<li> |
106 |
<label for="patron-scheduled-[% l.branchcode | html %]">Patron-scheduled pickup: </label> |
107 |
[% IF policies.$branchcode.patron_scheduled_pickup %] |
108 |
<input name="patron-scheduled-[% l.branchcode | html %]" id="patron-scheduled-[% l.branchcode | html %]" value="1" type="checkbox" checked> |
109 |
[% ELSE %] |
110 |
<input name="patron-scheduled-[% l.branchcode | html %]" id="patron-scheduled-[% l.branchcode | html %]" value="1" type="checkbox"> |
111 |
[% END %] |
112 |
<span class="hint">Enable patrons to schedule their own curbside pickups.</span> |
113 |
</li> |
114 |
</ol> |
115 |
</fieldset> |
116 |
|
117 |
<fieldset class="rows" style="float: none;"> |
118 |
<legend>Curbside pickup hours</legend> |
119 |
|
120 |
<em>Times should be in 24-hour format ( 00:00 to 23:59 ).</em> |
121 |
|
122 |
<ol class="pickup_hours"> |
123 |
[% BLOCK pickup_hours_day %] |
124 |
[% SET day_start_hour = d _ '_start_hour' %] |
125 |
[% SET day_start_minute = d _ '_start_minute' %] |
126 |
[% SET day_end_hour = d _ '_end_hour' %] |
127 |
[% SET day_end_minute = d _ '_end_minute' %] |
128 |
[% SET p = policies.$branchcode %] |
129 |
[% IF p.$day_start_hour && p.$day_start_minute && p.$day_end_hour && p.$day_end_minute %] |
130 |
<li> |
131 |
<span class="slot"> |
132 |
<input type="hidden" class="pickup-slot" name="pickup-slot-[% l.branchcode | html %]" value="[% d | html %]-[% p.$day_start_hour %]:[% p.$day_start_minute %]-[% p.$day_end_hour %]:[% p.$day_end_minute %]" /> |
133 |
</span> |
134 |
</li> |
135 |
[% END %] |
136 |
[% END %] |
137 |
[% PROCESS pickup_hours_day d => 'sunday' %] |
138 |
[% PROCESS pickup_hours_day d => 'monday' %] |
139 |
[% PROCESS pickup_hours_day d => 'tuesday' %] |
140 |
[% PROCESS pickup_hours_day d => 'wednesday' %] |
141 |
[% PROCESS pickup_hours_day d => 'thursday' %] |
142 |
[% PROCESS pickup_hours_day d => 'friday' %] |
143 |
[% PROCESS pickup_hours_day d => 'saturday' %] |
144 |
</ol> |
145 |
|
146 |
<ol> |
147 |
<li> |
148 |
<label>New slot:</label> |
149 |
<div> |
150 |
<select id="day-[% l.branchcode | html %]"> |
151 |
<option value="0">Sunday</option> |
152 |
<option value="1">Monday</option> |
153 |
<option value="2">Tuesday</option> |
154 |
<option value="3">Wednesday</option> |
155 |
<option value="4">Thursday</option> |
156 |
<option value="5">Friday</option> |
157 |
<option value="6">Saturday</option> |
158 |
<span> |
159 |
From <input type="text" size="5" class="noEnterSubmit" id="new-start-[% l.branchcode | html %]" placeholder="00:00" /> |
160 |
to <input type="text" size="5" class="noEnterSubmit" id="new-end-[% l.branchcode | html %]" placeholder="23:55" /> |
161 |
</span> |
162 |
</select> |
163 |
<input type="button" class="add-new-slot" data-branchcode="[% l.branchcode | html %]" value="Add" /> |
164 |
</div> |
165 |
</li> |
166 |
|
167 |
</ol> |
168 |
</fieldset> |
169 |
</div> |
170 |
[% END %] |
171 |
</div> |
172 |
</div> |
173 |
|
174 |
<input type="hidden" name="op" value="save" /> |
175 |
|
176 |
<fieldset class="action"> |
177 |
<input type="submit" value="Save configuration" /> |
178 |
</fieldset> |
179 |
</form> |
180 |
[% END %] |
181 |
|
182 |
</main> |
183 |
</div> <!-- /.col-sm-10.col-sm-push-2 --> |
184 |
|
185 |
<div class="col-sm-2 col-sm-pull-10"> |
186 |
<aside> |
187 |
[% INCLUDE 'admin-menu.inc' %] |
188 |
</aside> |
189 |
</div> <!-- /.col-sm-2.col-sm-pull-10 --> |
190 |
</div> <!-- /.row --> |
191 |
|
192 |
[% MACRO jsinclude BLOCK %] |
193 |
[% Asset.js("js/admin-menu.js") | $raw %] |
194 |
<script> |
195 |
|
196 |
let opening_slots = {}; |
197 |
let slots; |
198 |
[% FOR l IN libraries %] |
199 |
[% SET branchcode = l.branchcode %] |
200 |
slots = []; |
201 |
[% FOR p IN policies.$branchcode.opening_slots %] |
202 |
slots.push('%s-%s-%s'.format("[% p.day | html %]", format_hhmm("[% p.start_hour | html %]:[% p.start_minute | html %]"), format_hhmm("[% p.end_hour | html %]:[% p.end_minute | html %]"))); |
203 |
[% END %] |
204 |
opening_slots["[% l.branchcode | html %]"] = slots; |
205 |
[% END %] |
206 |
|
207 |
function format_hhmm(hhmm){ |
208 |
let hh, mm; |
209 |
[ hh, mm ] = hhmm.split(':'); |
210 |
return String(hh).padStart(2, '0') + ':' + String(mm).padStart(2, '0'); |
211 |
} |
212 |
function format_slot(slot){ |
213 |
let start = slot[0]; |
214 |
let end = slot[1]; |
215 |
return format_hhmm(start) + _(" to ") + format_hhmm(end); |
216 |
} |
217 |
function refresh_pickup_hours(branchcode) { |
218 |
let slots = {}; |
219 |
$("#conf-"+branchcode).find("input.pickup-slot").each(function(){ |
220 |
let splitted = $(this).val().split("-"); |
221 |
let day = splitted[0]; |
222 |
let start = splitted[1]; |
223 |
let end = splitted[2]; |
224 |
|
225 |
if(!slots[day]) slots[day] = []; |
226 |
|
227 |
slots[day].push([start, end]); |
228 |
}); |
229 |
|
230 |
let new_slot_node = $("<span class='slot'><input type='hidden' class='pickup-slot' name='pickup-slot-"+branchcode+"' value='"+day+"-"+start+"-"+end+"'/></span>"); |
231 |
$("#conf-"+branchcode).find(".pickup_hours").append(new_slot_node); |
232 |
|
233 |
$("#conf-"+branchcode).find(".pickup_hours li").remove(); |
234 |
|
235 |
Object.keys(slots).forEach(function(day){ |
236 |
let li_node = $('<li><label>'+get_day_lib(day)+'<label></li>'); |
237 |
slots[day].forEach(function(slot) { |
238 |
li_node.append('<span>'+format_slot(slot)+'</span>'); |
239 |
}); |
240 |
li_node.appendTo($("#conf-"+branchcode).find(".pickup_hours")); |
241 |
}); |
242 |
} |
243 |
function get_day_lib(day){ |
244 |
let lib; |
245 |
switch(day){ |
246 |
case 'sunday': |
247 |
lib = _("Sunday"); |
248 |
break; |
249 |
case 'monday': |
250 |
lib = _("Monday"); |
251 |
break; |
252 |
case 'tuesday': |
253 |
lib = _("Tuesday"); |
254 |
break; |
255 |
case 'wednesday': |
256 |
lib = _("Wednesday"); |
257 |
break; |
258 |
case 'thursday': |
259 |
lib = _("Thursday"); |
260 |
break; |
261 |
case 'friday': |
262 |
lib = _("Friday"); |
263 |
break; |
264 |
case 'saturday': |
265 |
lib = _("Saturday"); |
266 |
break; |
267 |
} |
268 |
return lib; |
269 |
} |
270 |
|
271 |
let opening_slots = {}; |
272 |
[% FOR l IN libraries %] |
273 |
opening_slots["[% l.branchcode | html %]"] = []; |
274 |
[% END %] |
275 |
$(document).ready(function(){ |
276 |
[% FOR l IN libraries %] |
277 |
refresh_pickup_hours("[% l.branchcode | html %]"); |
278 |
[% END %] |
279 |
|
280 |
$(".add-new-slot").on("click", function(){ |
281 |
let branchcode = $(this).data('branchcode'); |
282 |
let day = $("#day-" + branchcode).val(); |
283 |
let start = $("#new-start-" + branchcode).val(); |
284 |
let end = $("#new-end-" + branchcode).val(); |
285 |
// FIXME confirm selection |
286 |
|
287 |
let start_hour, start_minute, end_hour, end_minute; |
288 |
[ start_hour, start_minute ] = start.split(":"); |
289 |
[ end_hour, end_minute ] = end.split(":"); |
290 |
if ( start_hour === undefined |
291 |
|| start_minute === undefined |
292 |
|| end_hour === undefined |
293 |
|| end_minute === undefined |
294 |
|| isNaN(parseInt(start_hour)) |
295 |
|| isNaN(parseInt(end_hour)) |
296 |
|| isNaN(parseInt(start_minute)) |
297 |
|| isNaN(parseInt(end_minute)) |
298 |
|| start_hour > 23 || start_minute > 59 |
299 |
|| end_hour > 23 || end_minute > 59 |
300 |
) { |
301 |
$("#invalid_slot_warning").show(); |
302 |
return; |
303 |
} else { |
304 |
$("#invalid_slot_warning").hide(); |
305 |
} |
306 |
|
307 |
let new_slot = day + '-' + start + '-' + end; |
308 |
if ( opening_slots[branchcode].indexOf(new_slot) < 0 ) |
309 |
opening_slots[branchcode].push(new_slot); |
310 |
|
311 |
refresh_pickup_hours(branchcode); |
312 |
}) |
313 |
}); |
314 |
</script> |
315 |
[% END %] |
316 |
[% INCLUDE 'intranet-bottom.inc' %] |