Split down files and add question about covid-test
This commit is contained in:
293
web/index.html
293
web/index.html
@ -2,89 +2,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>FTracker</title>
|
||||
<meta charset="utf-8">
|
||||
<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;
|
||||
max-width: 512px;
|
||||
margin: auto;
|
||||
}
|
||||
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], input[type=button] {
|
||||
background: #c50e1f;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
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>
|
||||
<link href="style.css" rel="stylesheet" type="text/css">
|
||||
<script>
|
||||
// 1st script, prepares values needed for writing document
|
||||
var cbt = {
|
||||
@ -114,201 +35,41 @@
|
||||
else
|
||||
document.write('FTracker<br>V1')
|
||||
</script></h1>
|
||||
<form id="mainform">
|
||||
<div id="startpage">
|
||||
This is a web app to track which people
|
||||
were in the same rooms at which times in order to backtrace
|
||||
potential viral infections.<br><br>
|
||||
If you've reached this page that either means your're
|
||||
testing things or something has gone quite wrong with the\
|
||||
URL.<br>
|
||||
In the former case: Yay it works! In the latter you should
|
||||
probably contact an admin or a dev nearby :(<br><br>
|
||||
Here are a few links for testing:<br>
|
||||
<a href="/view">View Data</a>,
|
||||
<a href="/QRgen">Door Sign Generator</a>,
|
||||
<a href="/?arrival=42">Test Arrival</a>,
|
||||
<a href="/?departure=42">Test Departure</a><br><br>
|
||||
© 2020 made by <a target="_blank" href="mailto:o.winkels@fasttube.de">Oskar</a> \
|
||||
for <a target="_blank" href="//fasttube.de">FaSTTUBe</a>.<br>
|
||||
For source code & licensing see <a href="//git.fasttube.de/FaSTTUBe/ftracker">git repo</a>
|
||||
</div>
|
||||
<form id="mainform" style="display: none">
|
||||
<label>
|
||||
Full Name:<br>
|
||||
<input type="text" name="name" id="name" placeholder="John Doe" required>
|
||||
</label>
|
||||
<label id="agreelabel">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="agree" id="agree" required>
|
||||
<span><script>
|
||||
document.write(qp ? cbt[qp.action] : '')
|
||||
</script></span>
|
||||
</label>
|
||||
<script>
|
||||
if (qp && qp.action == 'arrival')
|
||||
document.write('<label class="checkbox"><input type="checkbox" name="tested" id="tested"><span>I have been tested negative for COVID in the last 24 hours</span></label>')
|
||||
</script>
|
||||
<input type="submit">
|
||||
</form>
|
||||
<script>
|
||||
var mform = document.getElementById('mainform')
|
||||
if (qp == null) {
|
||||
mform.innerHTML = 'This is a web app to track which people\
|
||||
were in the same rooms at which times in order to backtrace\
|
||||
potential viral infections.<br><br>\
|
||||
If you\'ve reached this page that either means your\'re\
|
||||
testing things or something has gone quite wrong with the\
|
||||
URL.<br>\
|
||||
In the former case: Yay it works! In the latter you should\
|
||||
probably contact an admin or a dev nearby :(<br><br>\
|
||||
Here are a few links for testing:<br>\
|
||||
<a href="/view">View Data</a>, \
|
||||
<a href="/QRgen">Door Sign Generator</a>, \
|
||||
<a href="/?arrival=42">Test Arrival</a>, \
|
||||
<a href="/?departure=42">Test Departure</a><br><br>\
|
||||
© 2020 made by <a target="_blank" href="mailto:o.winkels@fasttube.de">Oskar</a> \
|
||||
for <a target="_blank" href="//fasttube.de">FaSTTUBe</a>.<br> \
|
||||
For source code & licensing see <a href="//git.fasttube.de/FaSTTUBe/ftracker">git repo</a>'
|
||||
}
|
||||
|
||||
// Prefill the name field if it was successfully entered before
|
||||
var savedName = localStorage.getItem('name')
|
||||
if (savedName && qp)
|
||||
document.getElementById('name').value = savedName
|
||||
|
||||
// 2nd script, server API communication
|
||||
var name, agreed
|
||||
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 = ''
|
||||
var doubleT = ''
|
||||
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)}"`
|
||||
if (new Date() - d < 3 * 60 * 1000) {
|
||||
doubleT = '<b style="color:red">Your last sign in was less than 3 minutes ago. You might be accidentally trying to sign in twice. If you don\'t intend to log 2 arrivals within the last 3 minutes, please abort below.</b>'
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
${doubleT}
|
||||
<input type="submit">
|
||||
<input type="button" value="Abort" onclick="document.body.innerHTML='<h1>Aborted</h1><form>Nothing was logged.<br>You can close this tab/window now.</form>'">
|
||||
</form>
|
||||
</div>`
|
||||
|
||||
rform = document.getElementById('reqform')
|
||||
rform.onsubmit = async function(e) {
|
||||
await handleRequestSubmit(e, json)
|
||||
document.querySelector('.request').remove()
|
||||
setTimeout(sendMainData, 200)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user