250 lines
6.2 KiB
JavaScript

var PX_PER_MINUTE = 5
var data = null;
var names = document.querySelector('main #names')
var times = document.querySelector('main #times')
function exportCSV() {
if (data == null) {
alert('No data found.')
return
}
var startInput = document.querySelector('input#start')
var endInput = document.querySelector('input#end')
var gameInput = document.querySelector('input#game')
var startDate = new Date(startInput.value)
var endDate = new Date(endInput.value)
var gameRE = new RegExp(gameInput.value || '.*')
csv = 'timestamp,name,game,checkpoint\n'
for (var [name, list] of Object.entries(data)) {
for (entry of list) {
if (entry.game.match(gameRE) == null)
continue
var arrD = new Date(entry.arrival)
if (arrD < startDate || arrD > endDate)
continue
var arrTS = localISOTimeSeconds(arrD)
csv += `${arrTS},${name},${entry.game},${entry.checkpoint}\n`
}
}
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(csv));
element.setAttribute('download', 'schnitzeljagd-export.csv');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function renderData() {
if (data == null) {
alert('No data found.')
return
}
names = document.querySelector('main #names')
times = document.querySelector('main #times')
names.innerHTML = ''
times.innerHTML = ''
var startInput = document.querySelector('input#start')
var endInput = document.querySelector('input#end')
var gameInput = document.querySelector('input#game')
var startDate = new Date(startInput.value)
var endDate = new Date(endInput.value)
var gameRE = new RegExp(gameInput.value || '.*')
// Clear everything below hours because that would lead to
// misalignments with the day grid
startDate.setMinutes(0,0,0)
var tc = new Date(startDate.getTime())
var content = ''
while (tc < endDate) {
var h = tc.getHours()
var m = tc.getMinutes()
var t = (h == 0) ?
'<b>'+tc.getDate()+'.'+(tc.getMonth()+1)+'.</b>' :
h+':'+m.toString().padStart(2, "0")
var left = ((tc - startDate) / (1000 * 60))
content += '<span style="left:'+(PX_PER_MINUTE*left)+'px;">'+t+'</span>'
tc.setTime(tc.getTime() + (15*60*1000));
}
var timeheader = document.getElementById('timelabels')
timeheader.innerHTML = content
var viewwidth = ((endDate - startDate) / (1000 * 60))
timeheader.style.width = (PX_PER_MINUTE * viewwidth) + 'px'
times.style.width = (PX_PER_MINUTE * viewwidth) + 'px'
var rowCount = 0
for (var [name, list] of Object.entries(data)) {
var row = document.createElement('div')
row.classList.add('row')
var rowHasBlock = false
for (entry of list) {
if (entry.game.match(game) == null)
continue
var arrD = new Date(entry.arrival)
var depD = new Date(arrD) + 1000 * 60 * 5
if (depD < startDate || arrD > endDate)
continue
rowHasBlock = true
// Minutes since start date / beginning
var arr = (arrD - startDate) / (1000 * 60)
var dep = (depD - startDate) / (1000 * 60)
var dur = dep - arr
var block = document.createElement('span')
block.innerHTML = entry.checkpoint
block.style.left = (PX_PER_MINUTE * arr) + 'px' // 1px/min
block.style.width = (PX_PER_MINUTE * Math.max(0,(dur-14))) + 'px' // 1px/min
if (entry.game == "zeitfahren")
block.classList.add('blue')
row.appendChild(block)
}
if (rowHasBlock) {
var vname = name.replace(/-/g, ' ')
names.innerHTML += '<div class="row"><span>'+vname+'</span></div>'
times.appendChild(row)
rowCount += 12
}
}
//var viewheight = rowCount * 32;
//times.style.height = viewheight + 'px'
var tw = document.querySelector('main .scroll')
tw.scrollLeft = tw.scrollWidth
}
function saveData(rdata) {
data = rdata.reduce((acc, entry) => {
var name = entry.name
delete entry.name
acc[name] = [...acc[name] || [], entry];
return acc;
}, {});
console.log(data)
renderData()
}
function submitCredentials() {
var cp = document.querySelector('#credprompt')
var user = cp.querySelector('#user').value
var pass = cp.querySelector('#pass').value
cp.remove()
var auth = btoa(user + ":" + pass)
localStorage.setItem('dataauth', auth)
loadData()
}
function loadData() {
var auth = localStorage.getItem('dataauth')
if (auth == null) {
var prompt = document.createElement('div')
prompt.id = 'credprompt'
prompt.innerHTML = '<h1>Credentials Required</h1>\
<input type="text" id="user" placeholder="username" onkeydown="if (event.keyCode == 13) {submitCredentials()}">\
<input type="password" id="pass" placeholder="password" onkeydown="if (event.keyCode == 13) {submitCredentials()}">\
<input type="submit" onclick="submitCredentials()">'
document.body.appendChild(prompt)
document.querySelector('#credprompt #user').focus()
return // Abort load, wait for submit
}
var headers = new Headers()
headers.append('Authorization', 'Basic ' + auth)
var fetchopts = {
method: 'GET',
headers: headers
}
fetch('/game/data', fetchopts)
.then(res => {
if (Math.floor(res.status / 100) == 2)
return res.json()
else
localStorage.removeItem('dataauth')
res.text().then(function (text) {
alert(text)
location.reload()
})
})
.then(rdata => saveData(rdata))
}
function localISOTimeSeconds(date) {
var tzoffset = date.getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(date - tzoffset)).toISOString().slice(0, -1);
return localISOTime
}
function localISOTimeMinutes(date) {
return localISOTimeSeconds(date).split(':').slice(0,2).join(':')
}
var now = new Date()
now.setHours(now.getHours()+1,0,0,0)
now.setMinutes(0,0,0)
var startDate = new Date()
startDate.setDate(now.getDate())
startDate.setHours(8,0,0,0)
document.querySelector('input#start').value = localISOTimeMinutes(startDate)
document.querySelector('input#end').value = localISOTimeMinutes(now)
var scrollbox = document.querySelector('.scroll')
var timehead = document.querySelector('#timeheader')
var namebox = document.querySelector('section.names')
scrollbox.onscroll = function() {
timehead.scrollLeft = scrollbox.scrollLeft
namebox.scrollTop = scrollbox.scrollTop
}
loadData()