blob: 34e85901763e4d0316deb5fdb99c1a0bba82f3ff [file] [log] [blame]
delefmeeb0a4702020-10-04 18:15:55 +02001const idsFormulari = {
2 room: "1063142948",
3 day: "2115504093",
4 begins: "1749141911",
5 ends: "1827359679",
6 rows: {
7 A: "208184485",
8 B: "1077148310",
9 C: "642851281",
10 D: "1686039024",
11 E: "697835787",
12 F: "1511799646",
13 G: "809853432",
14 H: "182597499",
15 I: "1890539481",
16 J: "529159478",
17 K: "1615241874",
18 L: "1334263875"
19 },
20 notes: "1600275159"
21};
22
23const formBaseUrl = "https://docs.google.com/forms/d/e/1FAIpQLSfT9o287VqLyhwR8LPdloAQWhuqCgA3NfdhgP5vb9_sVQHL-g/viewform";
24
delefmeb5506032020-10-04 19:19:27 +020025const MIN_HOUR = 8;
26const MAX_HOUR = 23; // Pels altres graus de la Facultat
27
delefmeeb0a4702020-10-04 18:15:55 +020028var final_JSON = {
29 "class": null,
30 "number": "",
31 "letter": ""
32};
33
34var current_section = "section-1";
35
36var repeated_subjects;
delefmeb5506032020-10-04 19:19:27 +020037var current_time;
38
delefmeeb0a4702020-10-04 18:15:55 +020039
avm9996303e2c562020-10-14 17:29:22 +020040// From https://gist.github.com/treyhuffine/2ced8b8c503e5246e2fd258ddbd21b8c
41const debounce = (func, wait) => {
42 let timeout;
43
44 return function executedFunction(...args) {
45 const later = () => {
46 clearTimeout(timeout);
47 func(...args);
48 };
49
50 clearTimeout(timeout);
51 timeout = setTimeout(later, wait);
52 };
53};
54
delefmeeb0a4702020-10-04 18:15:55 +020055function fillInSummary() {
56 var begins = new Date(parseInt(final_JSON.class.begins)*1000);
57 var ends = new Date(parseInt(final_JSON.class.ends)*1000);
58
59 document.getElementById('subject-final').textContent = final_JSON.class.friendly_name || final_JSON.class.calendar_name;
60 document.getElementById('classroom-final').textContent = final_JSON.class.room;
delefmef6510222020-10-04 20:21:33 +020061 document.getElementById('date-final').textContent = formatDate(begins);
delefmeb5506032020-10-04 19:19:27 +020062 document.getElementById('time-final').textContent = formatTime(begins) + ' - ' + formatTime(ends);
delefmeeb0a4702020-10-04 18:15:55 +020063 document.getElementById('letter-final').textContent = final_JSON.letter;
64 document.getElementById('number-final').textContent = final_JSON.number;
65}
66
67function clickButton(element) {
68 var btn = element.currentTarget;
69 var parent = btn.parent;
70
71 if (parent == "subject-container") {
72 // Canvi de background del button
73 var selectedClass = JSON.parse(btn.getAttribute('data-class'));
avm99963a83f32a2020-10-09 00:39:17 +020074 $("#subject-container .complex-button, #subject-container .message-body").removeClass("is-selected")
75 btn.classList.add('is-selected');
76 btn.parentNode.parentNode.classList.add('is-selected');
delefmeeb0a4702020-10-04 18:15:55 +020077 // Canvi JSON
78 final_JSON["class"] = selectedClass;
delefmeeb0a4702020-10-04 18:15:55 +020079 // Anchor següent pregunta
80 switchSection("section-2");
81 } else if (parent == "number-container") {
82 // Canvi de background del button
83 $("#number-container .button").removeClass("is-link is-light is-active")
84 btn.classList.add("is-link", "is-light", "is-active");
85 // Canvi JSON
86 final_JSON["number"] = btn.getAttribute('data-number');
87 // Introducció de totes les dades al resum final
88 fillInSummary();
89 // Anchor següent pregunta
90 switchSection("section-send");
91 } else if (parent == "letter-container") {
92 // Canvi de background del button
93 $("#letter-container .button").removeClass("is-link is-light is-active")
94 btn.classList.add("is-link", "is-light", "is-active");
95 // Canvi JSON
96 final_JSON["letter"] = btn.getAttribute('data-letter');
97 // Anchor següent pregunta
98 switchSection("section-3");
99 }
100}
101
102function switchSection(s) {
103 setTimeout(function(){
delefmeb5506032020-10-04 19:19:27 +0200104 document.getElementById(current_section).classList.add('is-hidden');
105 document.getElementById(s).classList.remove('is-hidden');
delefmeeb0a4702020-10-04 18:15:55 +0200106 current_section = s;
107 }, 75);
108}
109
110function findRepeatedSubjects(classes) {
111 var rep = new Set();
112 for (var [i, classe] of classes.entries()) {
113 if (i > 0 && classes[i-1].calendar_name == classe.calendar_name) {
114 rep.add(classe.id);
115 rep.add(classes[i-1].id);
116 }
117 }
118 return rep;
119}
120
avm99963a83f32a2020-10-09 00:39:17 +0200121function transformClasses(rawClasses) {
122 var classes = [];
123 rawClasses.forEach(c => {
124 var found = false;
125 for (var i = 0; i < classes.length; ++i) {
126 if ((classes[i][0].friendly_name || classes[i][0].calendar_name) == (c.friendly_name || c.calendar_name)) {
127 classes[i].push(c);
128 found = true;
129 break;
130 }
131 }
132
133 if (!found) {
134 classes.push([c]);
135 }
delefme381067d2020-10-04 20:07:21 +0200136 });
avm99963a83f32a2020-10-09 00:39:17 +0200137
138 return classes;
139}
140
141function buildSubjectContainer(classes) {
142 // Flush existing classes
143 document.querySelectorAll('#subject-container .message').forEach(function(classe) {
144 classe.parentNode.removeChild(classe);
145 });
146
147 for (var uniqueClasses of classes) {
148 var firstClass = uniqueClasses[0];
149 var hora_inici = formatTime(new Date(parseInt(firstClass.begins)*1000));
150 var hora_final = formatTime(new Date(parseInt(firstClass.ends)*1000));
151
152 var classeDiv = document.createElement('div');
delefmeeb0a4702020-10-04 18:15:55 +0200153 classeDiv.classList.add('message', 'complex-button');
delefmeeb0a4702020-10-04 18:15:55 +0200154
155 var header = document.createElement('div');
156 header.classList.add('message-header');
avm99963a83f32a2020-10-09 00:39:17 +0200157 header.textContent = firstClass.friendly_name || firstClass.calendar_name;
delefmeeb0a4702020-10-04 18:15:55 +0200158
avm99963a83f32a2020-10-09 00:39:17 +0200159 var roomsDiv = document.createElement('div');
160 roomsDiv.classList.add('rooms-container');
delefmeeb0a4702020-10-04 18:15:55 +0200161
162 classeDiv.appendChild(header);
delefmeeb0a4702020-10-04 18:15:55 +0200163
avm99963a83f32a2020-10-09 00:39:17 +0200164 for (var classe of uniqueClasses) {
165 if (classe.user_selected) {
166 classeDiv.classList.add('is-primary');
167 }
168
169 var body = document.createElement('div');
170 body.classList.add('message-body');
171 body.setAttribute('data-class', JSON.stringify(classe));
172 body.addEventListener('click', clickButton);
173 body.parent = 'subject-container';
174
175 var div1 = document.createElement('div');
176
177 div1.classList.add('has-text-weight-bold');
178 div1.textContent = 'Aula ';
179
180 var span = document.createElement('span');
181 span.textContent = classe.room;
182 div1.appendChild(span);
183
184 var div2 = document.createElement('div');
185 div2.textContent = hora_inici + ' - ' + hora_final;
186
187 body.appendChild(div1);
188 body.appendChild(div2);
189 roomsDiv.appendChild(body);
190 }
191
192 classeDiv.appendChild(roomsDiv);
delefmeeb0a4702020-10-04 18:15:55 +0200193 document.getElementById("subject-container").appendChild(classeDiv);
delefmeeb0a4702020-10-04 18:15:55 +0200194 }
delefmeeb0a4702020-10-04 18:15:55 +0200195}
196
delefmeb5506032020-10-04 19:19:27 +0200197function getDefaultTime() {
198 var time = new Date();
199 time.setSeconds(0);
200 time.setMilliseconds(0);
201 if (time.getMinutes() < 30) time.setMinutes(0);
202 else time.setMinutes(30);
203 if (time.getHours() < MIN_HOUR) {
204 time.setHours(MIN_HOUR);
205 time.setMinutes(0);
206 }
207 if (time.getHours() >= MAX_HOUR) {
208 time.setHours(MAX_HOUR - 1);
209 time.setMinutes(30);
210 }
211 return time
212}
213
214function buildTimeSelector(date) {
215 document.getElementById("date-selector").value = formatDate(date);
216 var end_time = new Date(date.getTime() + 30*60000); // 1 min = 60000 ms
217 document.getElementById("time-selector").value = formatTime(date) + " - " + formatTime(end_time);
218}
219
avm99963ebb53842020-10-09 01:28:59 +0200220function isDateAfterTomorrow(potential_time) {
221 var now = new Date();
222 var tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
223
224 return (potential_time >= tomorrow);
225}
226
delefmeb5506032020-10-04 19:19:27 +0200227function addDateEventListeners(date) {
228 document.getElementById("date-prev").addEventListener('click', function (el) {
229 current_time = new Date(current_time.getTime() - 24*60*60000);
230 buildTimeSelector(current_time);
avm9996303e2c562020-10-14 17:29:22 +0200231 fetchClassesDebounced();
delefmeb5506032020-10-04 19:19:27 +0200232 });
233 document.getElementById("date-next").addEventListener('click', function (el) {
avm99963ebb53842020-10-09 01:28:59 +0200234 var potential_time = new Date(current_time.getTime() + 24*60*60000);
235
236 if (isDateAfterTomorrow(potential_time)) return;
237 current_time = potential_time;
238
delefmeb5506032020-10-04 19:19:27 +0200239 buildTimeSelector(current_time);
avm9996303e2c562020-10-14 17:29:22 +0200240 fetchClassesDebounced();
delefmeb5506032020-10-04 19:19:27 +0200241 });
242 document.getElementById("time-prev").addEventListener('click', function (el) {
243 current_time = new Date(current_time.getTime() - 30*60000);
244 if (current_time.getHours() < MIN_HOUR) {
245 current_time = new Date(current_time.getTime() - 24*60*60000);
246 current_time.setHours(MAX_HOUR - 1);
247 current_time.setMinutes(30);
248 }
249 buildTimeSelector(current_time);
avm9996303e2c562020-10-14 17:29:22 +0200250 fetchClassesDebounced();
delefmeb5506032020-10-04 19:19:27 +0200251 });
252 document.getElementById("time-next").addEventListener('click', function (el) {
avm99963ebb53842020-10-09 01:28:59 +0200253 var potential_time = new Date(current_time.getTime() + 30*60000);
254 if (potential_time.getHours() >= MAX_HOUR) {
255 potential_time = new Date(potential_time.getTime() + 24*60*60000);
256 potential_time.setHours(MIN_HOUR);
257 potential_time.setMinutes(0);
delefmeb5506032020-10-04 19:19:27 +0200258 }
avm99963ebb53842020-10-09 01:28:59 +0200259
260 if (isDateAfterTomorrow(potential_time)) return;
261 current_time = potential_time;
262
delefmeb5506032020-10-04 19:19:27 +0200263 buildTimeSelector(current_time);
avm9996303e2c562020-10-14 17:29:22 +0200264 fetchClassesDebounced();
delefmeb5506032020-10-04 19:19:27 +0200265 });
266}
267
268function formatTime(d) {
269 return d.toLocaleTimeString("ca", {timeStyle: 'short'});
270 /* var str = "";
delefmeeb0a4702020-10-04 18:15:55 +0200271 str += d.getHours();
272 str += ":";
273 if (d.getMinutes() < 10) str += "0";
delefmeb5506032020-10-04 19:19:27 +0200274 str += d.getMinutes();
275 return str; */
276}
277
278function formatDate(d) {
279 return d.toLocaleDateString("ca");
280}
281
282function fetchClasses() {
delefmeb5506032020-10-04 19:19:27 +0200283 fetch(api_url + "getClassesInTime/" + current_time.getTime()/1000, {
284 "mode": "cors",
285 "credentials": "include"
286 })
287 .then(response => response.json())
288 .then(data => {
289 if (data.payload.classes.length == 0) {
290 document.getElementById('no-subjects').classList.remove('is-hidden');
291 document.getElementById('subject-container').classList.add('is-hidden');
292 document.getElementById('fme-maps-container').classList.add('is-hidden');
293 } else {
avm99963a83f32a2020-10-09 00:39:17 +0200294 var transformedClasses = transformClasses(data.payload.classes);
295 buildSubjectContainer(transformedClasses);
delefmeb5506032020-10-04 19:19:27 +0200296 document.getElementById('no-subjects').classList.add('is-hidden');
297 document.getElementById('subject-container').classList.remove('is-hidden');
298 document.getElementById('fme-maps-container').classList.remove('is-hidden');
299 }
300
301 });
delefmeeb0a4702020-10-04 18:15:55 +0200302}
303
avm9996303e2c562020-10-14 17:29:22 +0200304const fetchClassesDebounced = debounce(fetchClasses, 400);
305
delefmeeb0a4702020-10-04 18:15:55 +0200306function onPageLoad() {
avm999630a9f0fe2020-10-09 00:50:44 +0200307 var searchParams = new URLSearchParams(location.search);
308 if (searchParams.has('apiUrl')) {
delefmeeb0a4702020-10-04 18:15:55 +0200309 var banner = document.getElementById('dev-mode');
delefmeb5506032020-10-04 19:19:27 +0200310 banner.classList.remove('is-hidden');
avm999630a9f0fe2020-10-09 00:50:44 +0200311 api_url = searchParams.get('apiUrl') || 'https://covid-tracability-backend-dev.sandbox.avm99963.com/api/v1/'
delefmeeb0a4702020-10-04 18:15:55 +0200312 } else {
313 api_url = "https://covid-tracability-backend-prod.sandbox.avm99963.com/api/v1/";
314 }
delefmeb5506032020-10-04 19:19:27 +0200315
316 current_time = getDefaultTime();
317 buildTimeSelector(current_time);
318
avm999630a9f0fe2020-10-09 00:50:44 +0200319 // Check if user is signed in
delefmeeb0a4702020-10-04 18:15:55 +0200320 fetch(api_url + "isSignedIn", {
321 "mode": "cors",
322 "credentials": "include"
323 })
324 .then(response => response.json())
325 .then(data => {
326 if (!data.payload.signedIn) {
327 console.log("Not signed in!");
328 fetch(api_url + "getAuthUrl", {
329 "mode": "cors",
330 "credentials": "include"
331 })
332 .then(response => response.json())
333 .then(data => {
334 // TODO: redirect here
335 // location.href = data.payload.url;
336 console.warn('Log in here: ', data.payload.url);
337 });
338 }
339 });
340
delefmeb5506032020-10-04 19:19:27 +0200341 fetchClasses();
delefmeeb0a4702020-10-04 18:15:55 +0200342}
343
344function sendForm() {
345 // Add subject to user
346 fetch(api_url + "addUserSubject", {
347 "method": "POST",
348 "body": JSON.stringify({
349 subject: final_JSON.class.subject_id
350 }),
351 "mode": "cors",
352 "credentials": "include"
353 })
354 .then(res => res.json())
355 .then(json => {
356 console.log("Subject added to user: ", json);
357
358 var begins = new Date(parseInt(final_JSON.class.begins)*1000);
359 var ends = new Date(parseInt(final_JSON.class.ends)*1000);
360
361 var params = new URLSearchParams();
362 params.append("entry." + idsFormulari.room, final_JSON.class.room); // class, number, letter
363 params.append("entry." + idsFormulari.day, begins.getFullYear().toString() + '-' + (begins.getMonth() + 1).toString().padStart(2, "0") + '-' + begins.getDate().toString().padStart(2, "0"));
delefmeb5506032020-10-04 19:19:27 +0200364 params.append("entry." + idsFormulari.begins, formatTime(begins));
365 params.append("entry." + idsFormulari.ends, formatTime(ends));
delefmeeb0a4702020-10-04 18:15:55 +0200366 params.append("entry." + idsFormulari.rows[final_JSON.letter], 'Columna ' + final_JSON.number);
367 // params.append("entry." + idsFormulari.notes, '[Autogenerat per delefme/covid-tracability -- Assignatura seleccionada: ' + (final_JSON.class.friendly_name || final_JSON.class.calendar_name) + ']');
368
369 var formulari_link = formBaseUrl + '?' + params.toString() + '#i1';
370 window.location.href = formulari_link;
371 });
372}
373
374
375function addEventListeners() {
376 window.addEventListener('load', onPageLoad);
377
378 var elements = document.getElementsByClassName("button");
379 Array.from(elements).forEach(function(element) {
380 element.addEventListener('click', clickButton);
381 element.parent = element.parentNode.id;
382 });
383
384 var elements = document.getElementsByClassName("complex-button");
385 Array.from(elements).forEach(function(element) {
386 element.addEventListener('click', clickButton);
387 element.parent = element.parentNode.id;
388 });
389
390 document.getElementById("send-button").addEventListener('click', function (el) {
391 document.getElementById("send-button").classList.add('is-loading');
392 sendForm();
393 });
delefmeb5506032020-10-04 19:19:27 +0200394
395 addDateEventListeners();
delefmeeb0a4702020-10-04 18:15:55 +0200396}
397
398addEventListeners();