Merge pull request #14 from delefme/topic-time-selection-improvements

Incorporar millores de l'agrupament d'assignaures i selector de temps
diff --git a/css/bulma-adjustments.css b/css/bulma-adjustments.css
index 739591c..ff91e36 100644
--- a/css/bulma-adjustments.css
+++ b/css/bulma-adjustments.css
@@ -1,5 +1,6 @@
 html {
     min-width: auto;
+    touch-action: manipulation;
 }
 
 .buttons.grid {
@@ -21,6 +22,36 @@
 .buttons.grid .complex-button {
     flex: 1 0 34%;
     margin: 15px 10px;
+    min-width: min(100%, 300px);
+}
+
+.buttons.grid .complex-button.is-selected .message-header {
+    background-color: #3273dc;
+    color: #fff;
+}
+
+.buttons.grid .complex-button.is-selected .message-body.is-selected {
+    background-color: #eef3fc;
+    color: #2160c4;
+}
+
+.rooms-container {
+    display: flex;
+    flex-direction: row;
+}
+
+.rooms-container .message-body {
+    border-width: 0;
+    border-top-left-radius: 0;
+    border-top-right-radius: 0;
+    flex-grow: 1;
+
+    cursor: pointer;
+}
+
+.rooms-container .message-body:not(:last-child) {
+    border-bottom-right-radius: 0;
+    border-right: solid 1px #4a4a4a;
 }
 
 .section {
diff --git a/css/duplicate-subjects.css b/css/duplicate-subjects.css
deleted file mode 100644
index f27d1bb..0000000
--- a/css/duplicate-subjects.css
+++ /dev/null
@@ -1,26 +0,0 @@
-.buttons.grid .complex-button {
-    flex: 1 0 34%;
-    margin: 15px 10px;
-
-}
-
-.buttons.grid .complex-button-full {
-    flex: 1 0 68%;
-    margin: 15px 10px;
-}
-
-.buttons.grid .complex-button2Right {
-    flex: 1 0 34%;
-    margin: 15px 10px;
-    border-bottom-left-radius: 0px;
-    margin-left: -10px;
-    border-left: 3.5px solid #4A4A4A;
-}
-
-.buttons.grid .complex-button2Left {
-    flex: 1 0 34%;
-    margin: 15px 10px;
-    margin-right: -10px;
-    border-bottom-right-radius: 0px;
-    border-right: 3.5px solid #4A4A4A;
-}
diff --git a/index.html b/index.html
index fbec2d0..7d822a7 100644
--- a/index.html
+++ b/index.html
@@ -3,21 +3,19 @@
 <html lang="ca">
     <head>
         <meta charset="UTF-8">
-		<title>Seients DAFME</title>
+        <title>Seients DAFME</title>
 
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<link rel="manifest" href="manifest.json">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <link rel="manifest" href="manifest.json">
 
-		<!-- Apple web app -->
-		<link rel="apple-touch-icon" href="./images/icon-64.png">
-		<meta name="apple-mobile-web-app-title" content="Seients DAFME">
-		<meta name="apple-mobile-web-app-capable" content="yes">
-		<meta name="apple-mobile-web-app-status-bar-style" content="white">
-        
+        <!-- Apple web app -->
+        <link rel="apple-touch-icon" href="./images/icon-64.png">
+        <meta name="apple-mobile-web-app-title" content="Seients DAFME">
+        <meta name="apple-mobile-web-app-capable" content="yes">
+        <meta name="apple-mobile-web-app-status-bar-style" content="white">
         <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
         <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css">
         <link rel="stylesheet" href="./css/bulma-adjustments.css">
-	<link rel="stylesheet" href="./css/duplicate-subjects.css">
     </head>
     <body>
         <script></script>
diff --git a/js/build_page.js b/js/build_page.js
index 2c80793..aedfbdb 100644
--- a/js/build_page.js
+++ b/js/build_page.js
@@ -56,17 +56,11 @@
     if (parent == "subject-container") {

         // Canvi de background del button

         var selectedClass = JSON.parse(btn.getAttribute('data-class'));

-        $("#subject-container .complex-button").removeClass("is-link")

-        btn.classList.add("is-link");

+        $("#subject-container .complex-button, #subject-container .message-body").removeClass("is-selected")

+        btn.classList.add('is-selected');

+        btn.parentNode.parentNode.classList.add('is-selected');

         // Canvi JSON

         final_JSON["class"] = selectedClass;

-        // Missatge advertència classe repetida

-        if (repeated_subjects.has(selectedClass.id)) {

-            document.getElementById('repeated-subject-warning').classList.remove('is-hidden');

-            document.getElementById('repeated-subject-warning-class').textContent = selectedClass.room;

-        } else {

-            document.getElementById('repeated-subject-warning').classList.add('is-hidden');

-        }

         // Anchor següent pregunta

         switchSection("section-2");

     } else if (parent == "number-container") {

@@ -109,102 +103,80 @@
     return rep;

 }

 

-function buildSubjectContainer(classes, repeated) {

-    var duplicateSubjectBoolNext, duplicateSubjectBoolPrev;

-    var duplicateSubjectCounter = 0;

-    

-    // Flush existing classes

-    document.querySelectorAll('.message').forEach(function(classe) {

-        classe.classList.add('is-hidden');

+function transformClasses(rawClasses) {

+    var classes = [];

+    rawClasses.forEach(c => {

+        var found = false;

+        for (var i = 0; i < classes.length; ++i) {

+            if ((classes[i][0].friendly_name || classes[i][0].calendar_name) == (c.friendly_name || c.calendar_name)) {

+                classes[i].push(c);

+                found = true;

+                break;

+            }

+        }

+

+        if (!found) {

+            classes.push([c]);

+        }

     });

-    

-    for (var [i, classe] of classes.entries()) {       

-        console.log(classe);

-        var hora_inici = formatTime(new Date(parseInt(classe.begins)*1000));

-        var hora_final = formatTime(new Date(parseInt(classe.ends)*1000));

-        var classeDiv;

-        

-        // Check if the subject is repeated

-        if (i < classes.length - 1) {

-            duplicateSubjectBoolNext = classes[i+1].friendly_name == classe.friendly_name;

-        }

-        else { 

-            duplicateSubjectBoolNext = false;

-        }

-        if (i > 0) {

-            duplicateSubjectBoolPrev = classes[i-1].friendly_name == classe.friendly_name;

-        }

-        else {

-            duplicateSubjectBoolPrev = false;

-        }

-        

-        // Change the previous classeDiv

-        if(duplicateSubjectBoolNext && duplicateSubjectCounter%2 == 1) {

-            classeDiv.classList.add('message', 'complex-button-full');

-            duplicateSubjectCounter++;

-        }

-        

-        classeDiv = document.createElement('div');

-        

-        if (duplicateSubjectBoolPrev) {

-            classeDiv.classList.add('message', 'complex-button2Right');

-        } else if(duplicateSubjectBoolNext) {

-            classeDiv.classList.add('message', 'complex-button2Left');

-            console.log("hola");

-        } else {

-            classeDiv.classList.add('message', 'complex-button');

-        }

-        

+

+    return classes;

+}

+

+function buildSubjectContainer(classes) {

+    // Flush existing classes

+    document.querySelectorAll('#subject-container .message').forEach(function(classe) {

+        classe.parentNode.removeChild(classe);

+    });

+

+    for (var uniqueClasses of classes) {

+        var firstClass = uniqueClasses[0];

+        var hora_inici = formatTime(new Date(parseInt(firstClass.begins)*1000));

+        var hora_final = formatTime(new Date(parseInt(firstClass.ends)*1000));

+

+        var classeDiv = document.createElement('div');

         classeDiv.classList.add('message', 'complex-button');

-        classeDiv.id = 'subject-' + classe.subject_id + '-' + classe.room;

-        classeDiv.setAttribute('data-class', JSON.stringify(classe));

 

         var header = document.createElement('div');

         header.classList.add('message-header');

+        header.textContent = firstClass.friendly_name || firstClass.calendar_name;

 

-        if (!(duplicateSubjectBoolPrev)) {

-            header.textContent = classe.friendly_name || classe.calendar_name;

-            header.style.color = "#FFFFFF";

-        } else {

-            header.textContent = classe.friendly_name || classe.calendar_name;;

-            header.style.color = "#4A4A4A";

-        }

-        

-        var body = document.createElement('div');

-        body.classList.add('message-body');

-

-        var div1 = document.createElement('div');

-        var span = document.createElement('span');

-        span.textContent = classe.room;

-

-        div1.classList.add('has-text-weight-bold');

-

-        div1.textContent = 'Aula ';

-        div1.appendChild(span);

-

-        var div2 = document.createElement('div');

-        div2.textContent = hora_inici + ' - ' + hora_final;

-

-        body.appendChild(div1);

-        body.appendChild(div2);

+        var roomsDiv = document.createElement('div');

+        roomsDiv.classList.add('rooms-container');

 

         classeDiv.appendChild(header);

-        classeDiv.appendChild(body);

 

+        for (var classe of uniqueClasses) {

+            if (classe.user_selected) {

+                classeDiv.classList.add('is-primary');

+            }

+

+            var body = document.createElement('div');

+            body.classList.add('message-body');

+            body.setAttribute('data-class', JSON.stringify(classe));

+            body.addEventListener('click', clickButton);

+            body.parent = 'subject-container';

+

+            var div1 = document.createElement('div');

+

+            div1.classList.add('has-text-weight-bold');

+            div1.textContent = 'Aula ';

+

+            var span = document.createElement('span');

+            span.textContent = classe.room;

+            div1.appendChild(span);

+

+            var div2 = document.createElement('div');

+            div2.textContent = hora_inici + ' - ' + hora_final;

+

+            body.appendChild(div1);

+            body.appendChild(div2);

+            roomsDiv.appendChild(body);

+        }

+

+        classeDiv.appendChild(roomsDiv);

         document.getElementById("subject-container").appendChild(classeDiv);

-        ++duplicateSubjectCounter;

     }

-  

-    var elements = document.getElementsByClassName("button");

-    Array.from(elements).forEach(function(element) {

-        element.addEventListener('click', clickButton);

-        element.parent = element.parentNode.id;

-    });

-    var elements = document.getElementsByClassName("complex-button");

-    Array.from(elements).forEach(function(element) {

-        element.addEventListener('click', clickButton);

-        element.parent = element.parentNode.id;

-    });

 }

 

 function getDefaultTime() {

@@ -230,6 +202,13 @@
     document.getElementById("time-selector").value = formatTime(date) + " - " + formatTime(end_time);

 }

 

+function isDateAfterTomorrow(potential_time) {

+  var now = new Date();

+  var tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);

+

+  return (potential_time >= tomorrow);

+}

+

 function addDateEventListeners(date) {

     document.getElementById("date-prev").addEventListener('click', function (el) {

         current_time = new Date(current_time.getTime() - 24*60*60000);

@@ -237,7 +216,11 @@
         fetchClasses();

     });

     document.getElementById("date-next").addEventListener('click', function (el) {

-        current_time = new Date(current_time.getTime() + 24*60*60000);

+        var potential_time = new Date(current_time.getTime() + 24*60*60000);

+

+        if (isDateAfterTomorrow(potential_time)) return;

+        current_time = potential_time;

+

         buildTimeSelector(current_time);

         fetchClasses();

     });

@@ -252,12 +235,16 @@
         fetchClasses();

     });

     document.getElementById("time-next").addEventListener('click', function (el) {

-        current_time = new Date(current_time.getTime() + 30*60000);

-        if (current_time.getHours() >= MAX_HOUR) {

-            current_time = new Date(current_time.getTime() + 24*60*60000);

-            current_time.setHours(MIN_HOUR);

-            current_time.setMinutes(0);

+        var potential_time = new Date(current_time.getTime() + 30*60000);

+        if (potential_time.getHours() >= MAX_HOUR) {

+            potential_time = new Date(potential_time.getTime() + 24*60*60000);

+            potential_time.setHours(MIN_HOUR);

+            potential_time.setMinutes(0);

         }

+

+        if (isDateAfterTomorrow(potential_time)) return;

+        current_time = potential_time;

+

         buildTimeSelector(current_time);

         fetchClasses();

     });

@@ -278,7 +265,6 @@
 }

 

 function fetchClasses() {

-    console.log(api_url + "getClassesInTime/" + current_time.getTime()/1000);

     fetch(api_url + "getClassesInTime/" + current_time.getTime()/1000, {

         "mode": "cors",

         "credentials": "include"

@@ -290,8 +276,8 @@
                 document.getElementById('subject-container').classList.add('is-hidden');

                 document.getElementById('fme-maps-container').classList.add('is-hidden');

             } else {

-                repeated_subjects = findRepeatedSubjects(data.payload.classes);

-                buildSubjectContainer(data.payload.classes, repeated_subjects);

+                var transformedClasses = transformClasses(data.payload.classes);

+                buildSubjectContainer(transformedClasses);

                 document.getElementById('no-subjects').classList.add('is-hidden');

                 document.getElementById('subject-container').classList.remove('is-hidden');

                 document.getElementById('fme-maps-container').classList.remove('is-hidden');

@@ -301,16 +287,11 @@
 }

 

 function onPageLoad() {

-

-    // Check if user is signed in

-    if (localStorage.getItem('devMode') == 'true') {

+    var searchParams = new URLSearchParams(location.search);

+    if (searchParams.has('apiUrl')) {

         var banner = document.getElementById('dev-mode');

-        banner.addEventListener('click', _ => {

-            localStorage.devMode = 'false';

-            location.reload();

-        });

         banner.classList.remove('is-hidden');

-        api_url = localStorage.getItem('apiUrl') || 'https://covid-tracability-backend-dev.sandbox.avm99963.com/api/v1/'

+        api_url = searchParams.get('apiUrl') || 'https://covid-tracability-backend-dev.sandbox.avm99963.com/api/v1/'

     } else {

         api_url = "https://covid-tracability-backend-prod.sandbox.avm99963.com/api/v1/";

     }

@@ -318,6 +299,7 @@
     current_time = getDefaultTime();

     buildTimeSelector(current_time);

 

+    // Check if user is signed in

     fetch(api_url + "isSignedIn", {

         "mode": "cors",

         "credentials": "include"