From b0e6700de5c412ee1a69f4a2319cc95d4d6afbc4 Mon Sep 17 00:00:00 2001
From: Ammaar Alam <ammaar@princeton.edu>
Date: Mon, 13 Jan 2025 13:06:26 -0500
Subject: [PATCH] making global variable live update instead

---
 public/index.html |  37 +++++++--------
 public/script.js  | 113 ++++++++++++++++++++++++++--------------------
 public/styles.css |  38 ++++++++++++----
 3 files changed, 113 insertions(+), 75 deletions(-)

diff --git a/public/index.html b/public/index.html
index 99948f0..c0d6ac5 100644
--- a/public/index.html
+++ b/public/index.html
@@ -37,13 +37,16 @@ <h2>Door Status</h2>
                     </label>
                     <span class="status-text" id="open">OPEN</span>
                 </div>
-                <button id="emergencyCloseButton">Emergency Close / Untangle</button>
+                <div class="manual-buttons-container">
+                    <button id="manualOpenButton" class="manual-btn open-btn">[MANUAL] Open Door</button>
+                    <button id="manualCloseButton" class="manual-btn close-btn">[MANUAL] Close Door</button>
+                </div>
                 <p
-                    style="font-size: 12px; font-family: sans-serif; text-align center; color: #848482"
+                    style="font-size: 12px; font-family: sans-serif; text-align: center; color: #848482; margin-top: 20px;"
                 >
-                    <i
-                        >PS: i know my friends, and to avoid getting kidnapped in the middle of the
-                        night, i enable password authentication when I sleep or when i'm gone for
+                    <i>
+                        PS: i know my friends, and to avoid getting kidnapped in the
+                        middle of the night, i enable password authentication when I sleep or when i'm gone for
                         days :P
                     </i>
                 </p>
@@ -52,23 +55,21 @@ <h2>Door Status</h2>
                 <h2>About This Project</h2>
                 <p>
                     This is a personal project I worked on over the summer. The switch at the top
-                    really does open or close my door hehe; it sends a command to my proxy server
-                    which routes that command to the Arduino IoT cloud server, relaying that command
-                    to the arduino. That arduino is connected to a motor driver which then spins a
-                    DC motor, reeling a fishing line knotted around my door handle, pulling it down.
+                    really does open or close my door; it sends a command to my proxy server
+                    which routes that command to the Arduino IoT cloud server, and then the Arduino
+                    is connected to a motor driver and DC motor that reels a fishing line around my
+                    door handle.
                 </p>
                 <p>
-                    For now, I don't really plan to add any more automation, this project was mainly
-                    inspired by my girlfriend, who joked about wanting to have her own prox for my
-                    room, and (just partly) by my very real problem of locking myself out somewhat
-                    frequently; although it was really fun to learn how to work with arduinos and
-                    circuitry,,, so maybe idk
+                    For now, I don't plan to add more automation. This project was partly
+                    inspired by my girlfriend wanting her own prox for my room, and partly by
+                    my real problem of locking myself out frequently. So, it was fun to learn about
+                    Arduinos and circuitry along the way.
                 </p>
                 <p class="disclaimer">
                     <i>
-                        All the parts I used, including those bought and printed, are all open
-                        source on the Github Repo, including the code, so feel free to make one
-                        yourself :)
+                        All the parts I used, including 3D-printed components and code, are open
+                        source on the Github Repo. Feel free to try making one yourself!
                     </i>
                 </p>
                 <hr />
@@ -101,4 +102,4 @@ <h2>Connect with Me</h2>
             <p>© 2024–25 Ammaar Alam. All rights reserved.</p>
         </footer>
     </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/public/script.js b/public/script.js
index e31d466..904eadb 100644
--- a/public/script.js
+++ b/public/script.js
@@ -1,6 +1,6 @@
 // redirect to HTTPS if accessed over HTTP
 // not necessary, but google crawler/url inspect is slow to update cache
-if (window.location.protocol !== "https:") {
+if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1' && window.location.protocol !== "https:") {
   window.location.href =
     "https://" + window.location.hostname + window.location.pathname + window.location.search;
 }
@@ -25,6 +25,8 @@ document.addEventListener("DOMContentLoaded", function () {
         localStorage.setItem("authToken", data.token);
         document.querySelector("#login-section").style.display = "none";
         document.querySelector(".control-panel").style.display = "block";
+        // After successful login, fetch the current door status to sync UI.
+        getDoorStatus();
       } else {
         document.getElementById("login-error").style.display = "block";
       }
@@ -45,27 +47,58 @@ document.addEventListener("DOMContentLoaded", function () {
         // if auth isn't required, hide login and show control panel
         document.querySelector("#login-section").style.display = "none";
         document.querySelector(".control-panel").style.display = "block";
+        getDoorStatus();
       }
     })
     .catch((error) => console.error("Error checking auth status:", error));
 
+  // fetch door status from server
+  async function getDoorStatus() {
+    try {
+      const headers = { "Content-Type": "application/json" };
+      if (authRequired) {
+        const token = localStorage.getItem("authToken");
+        if (token) {
+          headers["Authorization"] = token;
+        }
+      }
+      const response = await fetch("/status", {
+        method: "GET",
+        headers,
+      });
+      if (!response.ok) {
+        console.error("Failed to get door status:", await response.text());
+        return;
+      }
+      const data = await response.json();
+      setToggle(data.doorOpen);
+    } catch (error) {
+      console.error("Error fetching door status:", error);
+    }
+  }
+
+  // set toggle state based on doorOpen boolean
+  function setToggle(isOpen) {
+    const doorSwitch = document.getElementById("doorSwitch");
+    doorSwitch.checked = !!isOpen;
+    updateStatus();
+  }
+
   async function sendCommand(command) {
     try {
+      const headers = { "Content-Type": "application/json" };
       if (authRequired) {
-        // if auth is required, check for token
         const token = localStorage.getItem("authToken");
         if (!token) {
-          console.error("No auth token found. please log in again.");
+          console.error("No auth token found. Please log in again.");
           return;
         }
+        headers["Authorization"] = token;
       }
 
       const response = await fetch("/command", {
         method: "POST",
-        headers: {
-          "Content-Type": "application/json",
-          Authorization: authRequired ? localStorage.getItem("authToken") : "", // only add token if auth is required
-        },
+        headers,
         body: JSON.stringify({ command }),
       });
 
@@ -74,8 +107,9 @@ document.addEventListener("DOMContentLoaded", function () {
         console.error("Failed to send command:", errorDetail);
         return;
       }
-
       console.log(await response.text());
+      // Refresh door status after sending command so UI stays in sync
+      getDoorStatus();
     } catch (error) {
       console.error("Error during the request:", error);
     }
@@ -86,15 +120,17 @@ document.addEventListener("DOMContentLoaded", function () {
     const openStatus = document.getElementById("open");
     const closedStatus = document.getElementById("closed");
 
-    if (!doorSwitch.checked) {
-      closedStatus.style.color = "rgba(76, 175, 80, 1)"; // solid green
-      openStatus.style.color = "#888"; // default gray
-    } else {
+    // If switch is checked, door is considered open; otherwise closed
+    if (doorSwitch.checked) {
       openStatus.style.color = "rgba(255, 94, 85, 1)"; // solid red
       closedStatus.style.color = "#888"; // default gray
+    } else {
+      closedStatus.style.color = "rgba(76, 175, 80, 1)"; // solid green
+      openStatus.style.color = "#888"; // default gray
     }
   }
 
+  // handle user toggling the switch
   function toggleSwitch() {
     const doorSwitch = document.getElementById("doorSwitch");
     const command = doorSwitch.checked ? "open" : "close";
@@ -102,49 +138,30 @@ document.addEventListener("DOMContentLoaded", function () {
     updateStatus();
   }
 
-  async function emergencyClose() {
-    try {
-      if (authRequired) {
-        // if auth is required, check for token
-        const token = localStorage.getItem("authToken");
-        if (!token) {
-          console.error("No auth token found. please log in again.");
-          return;
-        }
-      }
-
-      const response = await fetch("/emergency-close", {
-        method: "POST",
-        headers: {
-          "Content-Type": "application/json",
-          Authorization: authRequired ? localStorage.getItem("authToken") : "", // only add token if auth is required
-        },
-      });
-
-      if (!response.ok) {
-        const errorDetail = await response.text();
-        console.error("Failed to send emergency close command:", errorDetail);
-        return;
-      }
+  // manual open door
+  function manualOpen() {
+    sendCommand("open");
+  }
 
-      console.log(await response.text());
-    } catch (error) {
-      console.error("Error during emergency close request:", error);
-    }
+  // manual close door
+  function manualClose() {
+    sendCommand("close");
   }
 
   const doorSwitch = document.getElementById("doorSwitch");
   if (doorSwitch) {
-    doorSwitch.onclick = toggleSwitch;
-    updateStatus(); // initialize the status on page load
+    doorSwitch.addEventListener("change", toggleSwitch);
   } else {
     console.error("doorSwitch element not found");
   }
 
-  const emergencyCloseButton = document.getElementById("emergencyCloseButton");
-  if (emergencyCloseButton) {
-    emergencyCloseButton.onclick = emergencyClose;
-  } else {
-    console.error("emergencyCloseButton element not found");
+  // new manual open/close buttons
+  const openButton = document.getElementById("manualOpenButton");
+  const closeButton = document.getElementById("manualCloseButton");
+  if (openButton) {
+    openButton.onclick = manualOpen;
+  }
+  if (closeButton) {
+    closeButton.onclick = manualClose;
   }
-});
+});
\ No newline at end of file
diff --git a/public/styles.css b/public/styles.css
index 74c9d45..1969594 100644
--- a/public/styles.css
+++ b/public/styles.css
@@ -259,24 +259,44 @@ footer p {
         align-items: stretch;
         padding: 10px;
     }
-    
+
     .social-links a {
         justify-content: center;
     }
 }
+
 #emergencyCloseButton {
-    background-color: #ff0d00; /* red */
-    color: #f8f7f9; /* seasalt */
+    display: none; /* Removed the old emergency close button. */
+}
+
+.manual-buttons-container {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-top: 20px;
+    gap: 20px;
+}
+
+.manual-btn {
     border: none;
     border-radius: 5px;
-    padding: 10px 20px;
-    font-size: 16px;
+    padding: 12px 20px;
+    font-size: 12px;
     cursor: pointer;
     transition: background-color 0.3s ease;
-    margin-top: 20px;
-    margin-bottom: 10px;
+    color: #f8f7f9; /* seasalt */
+    background-color: #444; /* fallback */
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
+}
+
+.manual-btn:hover {
+    opacity: 0.9;
 }
 
-#emergencyCloseButton:hover {
-    background-color: #b80900; /* this colour is called "engineering orange" lol seems fitting */
+.open-btn {
+    background-color: #4caf50; /* green */
 }
+
+.close-btn {
+    background-color: #ff5e55; /* red */
+}
\ No newline at end of file