diff options
| author | altaf-creator <dev@altafcreator.com> | 2026-01-23 09:50:33 +0800 |
|---|---|---|
| committer | altaf-creator <dev@altafcreator.com> | 2026-01-23 09:50:33 +0800 |
| commit | e5d96d19292224ea9513e145b02e35338eff0857 (patch) | |
| tree | 1ef0e0f362b1bbcddd661f19e22493282fd49316 | |
| parent | aab0cbcfcd8699c9715196b2d2b948011be58642 (diff) | |
machine override status
| -rw-r--r-- | backend/main.py | 23 | ||||
| -rw-r--r-- | frontend/admin/admin-style.css | 39 | ||||
| -rw-r--r-- | frontend/admin/admin.js | 57 | ||||
| -rw-r--r-- | frontend/admin/index.html | 3 | ||||
| -rw-r--r-- | frontend/admin/panel.html | 78 | ||||
| -rw-r--r-- | frontend/index.js | 2 |
6 files changed, 184 insertions, 18 deletions
diff --git a/backend/main.py b/backend/main.py index cbd7b10..e2c7163 100644 --- a/backend/main.py +++ b/backend/main.py @@ -135,7 +135,7 @@ class FinishRequestData(BaseModel): class OverrideMachineData(BaseModel): block: int machine_id: int - status: int # according to class Status + disabled: bool class Status(Enum): @@ -542,6 +542,27 @@ def override_status(data: OverrideMachineData, response: fastapi.Response, admin response.status_code = fastapi.status.HTTP_401_UNAUTHORIZED return "Unauthorised." + cursor.execute("SELECT * FROM admin_cookies WHERE cookie = ?", (admin_auth,)) + rows = cursor.fetchall() + + if len(rows) > 0: + if (data.disabled): + machine_status[data.block - 1][data.machine_id - 1] = Status.OUTOFSERVICE + else: + cursor.execute("SELECT * FROM timers WHERE ((block = ?) AND (machine = ?))", (data.block, data.machine_id)) + rows = cursor.fetchall() + + if len(rows) > 0: + machine_status[data.block - 1][data.machine_id - 1] = Status.RUNNING + else: + machine_status[data.block - 1][data.machine_id - 1] = Status.EMPTY + + response.status_code = fastapi.status.HTTP_200_OK + return "Set!" + else: + response.status_code = fastapi.status.HTTP_403_FORBIDDEN + return "Forbidden." + # --- change admin password @app.post("/admin_change_password", response_class=PlainTextResponse) diff --git a/frontend/admin/admin-style.css b/frontend/admin/admin-style.css index 86be9f5..e04a047 100644 --- a/frontend/admin/admin-style.css +++ b/frontend/admin/admin-style.css @@ -7,5 +7,42 @@ } .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 > 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 index bc31007..8a4a331 100644 --- a/frontend/admin/admin.js +++ b/frontend/admin/admin.js @@ -11,6 +11,9 @@ async function login() { }, body: `{"password": "${field.value}"}`, }); + + if (response.status == 202) window.location.href = "./panel.html"; + else document.getElementById("passwordFeedback").style.display = "inherit"; } async function checkLoginStatus() { @@ -18,5 +21,57 @@ async function checkLoginStatus() { method: "POST", credentials: "include" }); - console.log(response); + + 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"; + } else { + msg.style.display = "inherit"; + authDiv.style.display = "none"; + } +} + +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}/admin_login`, { + 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 index 8ce5812..76df357 100644 --- a/frontend/admin/index.html +++ b/frontend/admin/index.html @@ -8,9 +8,10 @@ <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> - checkLoginStatus(); + autoLogin(); </script> </body> </html> diff --git a/frontend/admin/panel.html b/frontend/admin/panel.html index b912553..1169c30 100644 --- a/frontend/admin/panel.html +++ b/frontend/admin/panel.html @@ -10,22 +10,74 @@ <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="admin-machine-container"> - <div> - <img src="" alt=""> - <select id="h1w1" name=""> - <option value="normal">Normal</option> - <option value="down">Out of Service</option> - </select> + <div class="blocks-container"> + <div class="admin-machine-container" style="background-color: lightyellow;"> + <h2>Block H2</h2> + <div> + <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> + <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> + <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> + <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> - <img src="" alt=""> - <select id="h1d1" name=""> - <option value="normal">Normal</option> - <option value="down">Out of Service</option> - </select> + <div class="admin-machine-container" style="background-color: skyblue;"> + <h2>Block H1</h2> + <div> + <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> + <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> + <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> + <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> + panelLoginCheck(); + </script> </body> </html> diff --git a/frontend/index.js b/frontend/index.js index f4f89b3..12f1e97 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -5,7 +5,7 @@ } else { const urlCookie = await cookieStore.get("last_used_url"); - if (urlCookie) { + if (urlCookie && urlCookie != null && urlCookie != "null") { window.location.href = `./start/?machine=${urlCookie.value}`; } else { window.location.href = './status/' |
