diff options
Diffstat (limited to 'frontend/admin')
| -rw-r--r-- | frontend/admin/admin-style.css | 53 | ||||
| -rw-r--r-- | frontend/admin/admin.js | 110 | ||||
| -rw-r--r-- | frontend/admin/index.html | 17 | ||||
| -rw-r--r-- | frontend/admin/panel.html | 95 |
4 files changed, 275 insertions, 0 deletions
diff --git a/frontend/admin/admin-style.css b/frontend/admin/admin-style.css new file mode 100644 index 0000000..9c866ff --- /dev/null +++ b/frontend/admin/admin-style.css @@ -0,0 +1,53 @@ +#unauthorised { + +} + +#authorised { + +} + +.admin-machine-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + background-color: lightgrey; + gap: 16px; + padding: 16px; + width: fit-content; + max-width: 100%; + box-sizing: border-box; +} + +.admin-machine-container > div { + display: flex; + flex-direction: column; + gap: 16px; +} + +.admin-machine-container > div > img { + width: 128px; +} + +.admin-machine-container > div > span { + text-align: center; + font-weight: 600; +} + +.admin-machine-container > h2 { + writing-mode: vertical-lr; + transform: rotate(180deg); + margin: 0; + height: fit-content; +} + +#passwordFeedback { + display: none; + color: red; +} + +.blocks-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 16px; +} diff --git a/frontend/admin/admin.js b/frontend/admin/admin.js new file mode 100644 index 0000000..ff1c463 --- /dev/null +++ b/frontend/admin/admin.js @@ -0,0 +1,110 @@ +const API_URL = "https://backend.laundryweb.altafcreator.com" + +async function login() { + const field = document.getElementById("pwfield"); + + const response = await fetch(`${API_URL}/admin_login`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json" + }, + body: `{"password": "${field.value}"}`, + }); + + if (response.status == 202) window.location.href = "./panel.html"; + else document.getElementById("passwordFeedback").style.display = "inherit"; +} + +async function checkLoginStatus() { + const response = await fetch(`${API_URL}/admin_check`, { + method: "POST", + credentials: "include" + }); + + return response.status == 202; +} + +async function autoLogin() { + if (await checkLoginStatus()) { + window.location.href = "./panel.html"; + } +} + +async function panelLoginCheck() { + const msg = document.getElementById("unauthorised"); + const authDiv = document.getElementById("authorised"); + + if (await checkLoginStatus()) { + msg.style.display = "none"; + authDiv.style.display = "inherit"; + return true; + } else { + msg.style.display = "inherit"; + authDiv.style.display = "none"; + return false; + } +} + +async function syncMachineStatus() { + const response = await fetch(`${API_URL}/admin_machine_status`, { + method: "POST", + credentials: "include", + }); + const data = await response.json(); + + for (let b = 0; b < data.length; b++) { + for (let m = 0; m < data[b].length; m++) { + const img = document.getElementById("h"+(b+1).toString()+"m"+(m+1).toString()+"img"); + const dropdown = document.getElementById("h"+(b+1).toString()+"m"+(m+1).toString()); + + if (data[b][m] != "OUTOFSERVICE") { + if (m % 2 == 0) { + img.src = "/assets/img/dryer_off.png"; + } else { + img.src = "/assets/img/washer_off.png"; + } + dropdown.selectedIndex = 0; + } else { + if (m % 2 == 0) { + img.src = "/assets/img/dryer_down.png"; + } else { + img.src = "/assets/img/washer_down.png"; + } + dropdown.selectedIndex = 1; + } + } + } +} + +async function overrideMachineStatus(block, machine) { + const img = document.getElementById("h"+block.toString()+"m"+machine.toString()+"img"); + const dropdown = document.getElementById("h"+block.toString()+"m"+machine.toString()); + + const response = await fetch(`${API_URL}/override_status`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json" + }, + body: `{"block": ${block}, "machine_id": ${machine}, "disabled": ${dropdown.selectedIndex == 1}}`, + }); + + if (response.status != 200) { + return; + } + + if (dropdown.selectedIndex == 1) { + if (machine % 2 == 0) { + img.src = "/assets/img/washer_down.png"; + } else { + img.src = "/assets/img/dryer_down.png"; + } + } else { + if (machine % 2 == 0) { + img.src = "/assets/img/washer_off.png"; + } else { + img.src = "/assets/img/dryer_off.png"; + } + } +} diff --git a/frontend/admin/index.html b/frontend/admin/index.html new file mode 100644 index 0000000..76df357 --- /dev/null +++ b/frontend/admin/index.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>Victoria Hall LaundryWeb Admin Panel</title> + <link rel="stylesheet" href="./admin-style.css"> +</head> +<body> + <h1>LaundryWeb Admin Panel Log In</h1> + <input type="password" id="pwfield"> <button onclick="login()">Log In</button> + <p id="passwordFeedback">Invalid password.</p> + <script src="./admin.js"></script> + <script> + autoLogin(); + </script> +</body> +</html> diff --git a/frontend/admin/panel.html b/frontend/admin/panel.html new file mode 100644 index 0000000..4813c06 --- /dev/null +++ b/frontend/admin/panel.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>Victoria Hall LaundryWeb Admin Panel</title> + <link rel="stylesheet" href="./admin-style.css"> +</head> +<body> + <h1>LaundryWeb Admin Panel</h1> + <p id="unauthorised">You are unauthorised.</p> + <!-- even if you make this div visible, you won't be able to do anything if you are unauthorised --> + <div id="authorised"> + <div class="blocks-container"> + <div class="admin-machine-container" style="background-color: lightyellow;"> + <h2>Block H2</h2> + <div> + <span>Dryer 1</span> + <img id="h2m1img" src="/assets/img/dryer_off.png" alt=""> + <select id="h2m1" name="" onchange="overrideMachineStatus(2, 1);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + <div> + <span>Washer 1</span> + <img id="h2m2img" src="/assets/img/washer_off.png" alt=""> + <select id="h2m2" name="" onchange="overrideMachineStatus(2, 2);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + <div> + <span>Dryer 2</span> + <img id="h2m3img" src="/assets/img/dryer_off.png" alt=""> + <select id="h2m3" name="" onchange="overrideMachineStatus(2, 3);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + <div> + <span>Washer 2</span> + <img id="h2m4img" src="/assets/img/washer_off.png" alt=""> + <select id="h2m4" name="" onchange="overrideMachineStatus(2, 4);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + </div> + <div class="admin-machine-container" style="background-color: skyblue;"> + <h2>Block H1</h2> + <div> + <span>Dryer 1</span> + <img id="h1m1img" src="/assets/img/dryer_off.png" alt=""> + <select id="h1m1" name="" onchange="overrideMachineStatus(1, 1);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + <div> + <span>Washer 1</span> + <img id="h1m2img" src="/assets/img/washer_off.png" alt=""> + <select id="h1m2" name="" onchange="overrideMachineStatus(1, 2);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + <div> + <span>Dryer 2</span> + <img id="h1m3img" src="/assets/img/dryer_off.png" alt=""> + <select id="h1m3" name="" onchange="overrideMachineStatus(1, 3);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + <div> + <span>Washer 2</span> + <img id="h1m4img" src="/assets/img/washer_off.png" alt=""> + <select id="h1m4" name="" onchange="overrideMachineStatus(1, 4);"> + <option value="normal">Normal</option> + <option value="down">Out of Service</option> + </select> + </div> + </div> + </div> + </div> + <script src="admin.js"></script> + <script> + (async () => { + if (await panelLoginCheck()) { + syncMachineStatus(); + } + })(); + </script> +</body> +</html> |
