<!DOCTYPE html> <html> <head> <title>FTracker</title> <meta name="theme-color" content="#c50e1f"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <style> html, body { margin: 0; padding: 0; height: 100%; background: #ddd; font-family: sans-serif; } h1 { margin: 0; padding: 16px; text-transform: uppercase; color: #eee; background: #c50e1f; text-align: center; } form { padding: 16px; } label { display: block; font-size: 16px; margin-bottom: 16px; color: #444; } label#agreelabel { height: 32px; line-height: 32px; } label span { width: calc(100% - 50px); display: inline-block; vertical-align: middle; line-height: normal; } input { border: none; padding: 16px; margin: 4px 0; font-size: 16px; } input[type=text] { color: #000; width: calc(100% - 32px); } input[type=submit] { background: #c50e1f; text-transform: uppercase; font-weight: bold; color: #fff; width: 100%; } input[type=checkbox] { transform: translateY(-3px); float: left; height: 32px; width: 32px; margin-right: 8px; } .request { display: block; position: fixed; background: #ddd; top: 16px; left: 16px; width: calc(100% - 32px); box-shadow: 0 1px 4px 0; } input[type=datetime-local] { width: calc(100% - 24px); padding: 12px; font-size: 12px; background: #fff; } </style> <script> // 1st script, prepares values needed for writing document var cbt = { 'arrival': 'I have read and will adhere to the <a href="/guidelines" target="_blank">protection guidelines</a>', 'departure': 'I have cleaned my workspace' } function getParams() { var h = document.location.href var qparam = h.split('?')[1] || null if (qparam == null) { alert("Query parameter(s) missing") return null } var vals = qparam.split('=') if (vals.length < 2 || !cbt.hasOwnProperty(vals[0])) { alert("Invalid query parameter") return null } return { action: vals[0], room: vals[1] } } var qp = getParams() </script> </head> <body> <h1><script> document.write(qp.action + "<br>Room " + qp.room) </script></h1> <form id="mainform"> <label> Full Name:<br> <input type="text" name="name" id="name" placeholder="John Doe" required> </label> <label id="agreelabel"> <input type="checkbox" name="agree" id="agree" required> <span><script>document.write(cbt[qp.action])</script></span> </label> <input type="submit"> </form> <script> // Prefill the name field if it was successfully entered before var savedName = localStorage.getItem('name') if (savedName) document.getElementById('name').value = savedName // 2nd script, server API communication var name, agreed var mform = document.getElementById('mainform') mform.onsubmit = function(e) { e.preventDefault() name = e.srcElement[0].value agreed = e.srcElement[1].checked sendMainData() } function sendMainData() { // POST JSON. See docs/API.md var payload = (qp.action == 'arrival') ? { 'room': qp.room, 'name': name, 'agreetoguidelines': agreed } : { 'name': name, 'cleanedworkspace': agreed } post("/" + qp.action, payload) } function post(url, payload) { console.log("Sending payload:", payload) return fetch(url, { method: "POST", body: JSON.stringify(payload) }).then(res => { handleResponse(res) }) } function handleResponse(res) { console.log("Request complete! response:", res) if (Math.floor(res.status / 100) == 2) { // Success mform = document.getElementById('mainform') mform.innerHTML = "<h2>Done. Thanks!</h2>" localStorage.setItem('name', name) } else if (res.status == 409) { // Conflict, more data requested handleRequest(res) } else { // Any other generic error res.text().then(function (text) { alert(text) }) } } function handleRequestSubmit(e, json) { e.preventDefault() var input = e.srcElement[0].value var iso = new Date(input).toISOString() // POST JSON. See docs/API.md var payload = (json.request == 'arrival') ? { 'room': qp.room, 'name': name, 'arrival': iso, 'agreetoguidelines': agreed } : { 'name': name, 'departure': iso, 'cleanedworkspace': agreed } return post("/" + json.request, payload) } function localISOTimeMinutes(date) { var tzoffset = date.getTimezoneOffset() * 60000; //offset in milliseconds var localISOTime = (new Date(date - tzoffset)).toISOString().slice(0, -1); return localISOTime.split(':').slice(0,2).join(':') } function handleRequest(res) { var reqt = { 'arrival': 'You probably forgot to sign in when you arrived. Please enter your arrival time now:', 'departure': 'You probably forgot to sign out when you left. Please enter your departure time now:' } mform.innerHTML = "<h2>Processing Request...</h2>" res.json().then(function (json) { var aInfo = '' var minD = '' if (json.request == 'departure') { var d = new Date(json.arrival.time) var dInfo = d.toString('en-GB').split(' ').slice(0,5).join(' ') aInfo = `Your last arrival was on <b>${dInfo}</b> in room <b>${json.arrival.room}</b>.` minD = `min="${localISOTimeMinutes(d)}"` } var now = localISOTimeMinutes(new Date()) document.body.innerHTML += `<div class="request"> <h1>${json.request} missing!</h1> <form id="reqform"> <label> ${reqt[json.request]} <input type="datetime-local" id="datetime" ${minD} max="${now}" required> ${aInfo} </label> <input type="submit"> </form> </div>` rform = document.getElementById('reqform') rform.onsubmit = async function(e) { await handleRequestSubmit(e, json) document.querySelector('.request').remove() setTimeout(sendMainData, 200) } }) } </script> </body> </html>