Add UI
Signed-off-by: Joey <bevilacquajoey@gmail.com>
This commit is contained in:
parent
78b4feb51d
commit
5ac9d3a28e
3 changed files with 219 additions and 43 deletions
63
index.css
Normal file
63
index.css
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
* {
|
||||||
|
font-family: 'IBM Plex Sans', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-left: 10vw;
|
||||||
|
padding-right: 10vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-map {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room {
|
||||||
|
margin: 0.5rem;
|
||||||
|
background: #e0e0e0;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room h3 {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room p {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-big {
|
||||||
|
flex: 1 1 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-small {
|
||||||
|
flex: 1 1 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule {
|
||||||
|
border-color: #f1f2f3;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px;
|
||||||
|
padding: 0.2rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
81
index.html
81
index.html
|
@ -3,30 +3,75 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<title>USI INF room checker</title>
|
<title>USI • Rooms availability</title>
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=IBM+Plex+Mono|IBM+Plex+Sans&display=swap">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>USI INF room checker</h1>
|
<h1>USI INF room availability</h1>
|
||||||
<h4>By maggicl</h4>
|
|
||||||
<section class="times">
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<template id="room">
|
<div class="room-map">
|
||||||
<h2 class="room-title"></h2>
|
<div class="room room-big" id="SI-003">
|
||||||
<ul class="list"></ul>
|
<h3>SI-003</h3>
|
||||||
</template>
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
<!-- Row -->
|
||||||
|
<div class="room room-small" id="SI-004">
|
||||||
|
<h3>SI-004</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
<div class="room room-small" id="SI-015">
|
||||||
|
<h3>SI-015</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
<!-- Row -->
|
||||||
|
<div class="room room-big" id="SI-006">
|
||||||
|
<h3>SI-006</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
<!-- Row -->
|
||||||
|
<div class="room room-small" id="SI-007">
|
||||||
|
<h3>SI-007</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
<div class="room room-small" id="SI-013">
|
||||||
|
<h3>SI-013</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
<!-- Row -->
|
||||||
|
<div class="room room-big room" id="SI-008">
|
||||||
|
<h3>SI-008</h3>
|
||||||
|
<p>Free</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<template id="time-free">
|
<h2 id="timepreviewer">Time: 18:00</h2>
|
||||||
<li><strong>Free all day</strong></li>
|
<input type="range" id="timemachine" />
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="time-slot">
|
<div class="schedule">
|
||||||
<li>
|
<h1>Schedule for today</h1>
|
||||||
<span class="title"></span>
|
<section class="times">
|
||||||
(<span class="start"></span>-<span class="end"></span>)
|
</section>
|
||||||
</li>
|
|
||||||
</template>
|
<template id="room">
|
||||||
|
<h2 class="room-title"></h2>
|
||||||
|
<ul class="list"></ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="time-free">
|
||||||
|
<li><strong>Free all day</strong></li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="time-slot">
|
||||||
|
<li>
|
||||||
|
<span class="title"></span>
|
||||||
|
(<span class="start"></span>-<span class="end"></span>)
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
<script src='index.js'></script>
|
<script src='index.js'></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
118
index.js
118
index.js
|
@ -1,6 +1,9 @@
|
||||||
// vim: set ts=2 sw=2 et tw=80:
|
// vim: set ts=2 sw=2 et tw=80:
|
||||||
|
|
||||||
const URL = 'http://atelier.inf.usi.ch/~maggicl/proxy.php?url=https://aule.usi.ch/aule/View.aspx?name=';
|
const URL = 'http://atelier.inf.usi.ch/~maggicl/proxy.php?url=https://aule.usi.ch/aule/View.aspx?name=';
|
||||||
|
const NOW = new Date();
|
||||||
|
|
||||||
|
const timeTable = {};
|
||||||
|
|
||||||
function roomStatus(room, callback) {
|
function roomStatus(room, callback) {
|
||||||
return new Promise((resolve, _) => {
|
return new Promise((resolve, _) => {
|
||||||
|
@ -39,13 +42,13 @@ function roomStatus(room, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ROOMS = [
|
const ROOMS = [
|
||||||
|
'SI-003',
|
||||||
'SI-004',
|
'SI-004',
|
||||||
'SI-005',
|
'SI-015',
|
||||||
'SI-006',
|
'SI-006',
|
||||||
'SI-007',
|
'SI-007',
|
||||||
'SI-008',
|
|
||||||
'SI-013',
|
'SI-013',
|
||||||
'SI-015'
|
'SI-008',
|
||||||
];
|
];
|
||||||
|
|
||||||
const ROOM_LIST = document.querySelector(".times");
|
const ROOM_LIST = document.querySelector(".times");
|
||||||
|
@ -53,39 +56,104 @@ const ROOM_TEMPLATE = document.getElementById("room");
|
||||||
const SLOT_TEMPLATE = document.getElementById("time-slot");
|
const SLOT_TEMPLATE = document.getElementById("time-slot");
|
||||||
const FREE_SLOT_TEMPLATE = document.getElementById("time-free");
|
const FREE_SLOT_TEMPLATE = document.getElementById("time-free");
|
||||||
|
|
||||||
|
function getRoomNode() {
|
||||||
|
return document.importNode(ROOM_TEMPLATE.content, true);
|
||||||
|
}
|
||||||
|
|
||||||
function formatTime(date) {
|
function formatTime(date) {
|
||||||
return (date.getHours() < 10 ? '0' : '') + date.getHours() + ':' +
|
const twoDigits = (n) => {
|
||||||
(date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
|
return n < 10 ? "0" + n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return twoDigits(date.getHours()) + ':' +
|
||||||
|
twoDigits(date.getMinutes());
|
||||||
|
}
|
||||||
|
|
||||||
|
function colorRoom(roomTitle, node, time = NOW /* QuantumLeap */) {
|
||||||
|
const data = timeTable[roomTitle];
|
||||||
|
if (data == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(roomTitle, time);
|
||||||
|
|
||||||
|
const currentLecture = data.filter(d => d.start < time && d.end > time)[0];
|
||||||
|
const isFree = currentLecture === void(0);
|
||||||
|
const block = document.getElementById(roomTitle);
|
||||||
|
|
||||||
|
block.style.background = isFree ? "#d4edda" : "#f8d7da";
|
||||||
|
block.style.color = isFree ? "#155724" : "#721c24";
|
||||||
|
|
||||||
|
block.querySelector('p').innerHTML = isFree ? 'Free' :
|
||||||
|
currentLecture.title + "<br> (" + formatTime(currentLecture.start) + " - " +
|
||||||
|
formatTime(currentLecture.end) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildRoomMarkup(roomTitle) {
|
async function buildRoomMarkup(roomTitle) {
|
||||||
const data = await roomStatus(roomTitle);
|
const data = await roomStatus(roomTitle);
|
||||||
const room = document.importNode(ROOM_TEMPLATE.content, true);
|
const room = getRoomNode();
|
||||||
const title = room.querySelector('.room-title');
|
const title = room.querySelector('.room-title');
|
||||||
title.innerHTML = roomTitle;
|
title.innerHTML = roomTitle;
|
||||||
const list = room.querySelector('.list');
|
const list = room.querySelector('.list');
|
||||||
|
|
||||||
for (const d of data) {
|
for (const d of data) {
|
||||||
const slot = document.importNode(SLOT_TEMPLATE.content, true);
|
const slot = document.importNode(SLOT_TEMPLATE.content, true);
|
||||||
const title = slot.querySelector('.title');
|
const title = slot.querySelector('.title');
|
||||||
document.getElementById("room");title.innerHTML = d.title;
|
document.getElementById("room");title.innerHTML = d.title;
|
||||||
const start = slot.querySelector('.start');
|
const start = slot.querySelector('.start');
|
||||||
start.innerHTML = formatTime(d.start);
|
start.innerHTML = formatTime(d.start);
|
||||||
const end = slot.querySelector('.end');
|
const end = slot.querySelector('.end');
|
||||||
end.innerHTML = formatTime(d.end);
|
end.innerHTML = formatTime(d.end);
|
||||||
list.appendChild(slot);
|
list.appendChild(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.length == 0) {
|
timeTable[roomTitle] = data;
|
||||||
list.appendChild(document.importNode(FREE_SLOT_TEMPLATE.content, true));
|
colorRoom(roomTitle, room);
|
||||||
}
|
|
||||||
|
|
||||||
ROOM_LIST.appendChild(room);
|
if (data.length == 0) {
|
||||||
|
list.appendChild(document.importNode(FREE_SLOT_TEMPLATE.content, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
ROOM_LIST.appendChild(room);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTimePreview(date = NOW) {
|
||||||
|
const timePreview = document.getElementById('timepreviewer');
|
||||||
|
timePreview.innerText = formatTime(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupTimeMachine() {
|
||||||
|
const slider = document.getElementById('timemachine');
|
||||||
|
slider.min = 0;
|
||||||
|
slider.max = 92 - (NOW.getHours() * 4); // 24 * 4 - now[h]
|
||||||
|
// 00 15 30 45 60 15 30 45 00 15 30 45
|
||||||
|
// 00 00 00 00 01 01 01
|
||||||
|
//
|
||||||
|
|
||||||
|
slider.value = slider.min;
|
||||||
|
|
||||||
|
slider.addEventListener("input", (e) => {
|
||||||
|
const hours = Math.round(slider.value / 4);
|
||||||
|
const mins = Math.round(slider.value % 60);
|
||||||
|
console.log(hours, mins);
|
||||||
|
let newDate = new Date();
|
||||||
|
newDate.setHours(newDate.getHours() + hours);
|
||||||
|
newDate.setMinutes(newDate.getMinutes() + mins);
|
||||||
|
const node = getRoomNode();
|
||||||
|
|
||||||
|
setTimePreview(newDate)
|
||||||
|
|
||||||
|
ROOMS.forEach((roomTitle) => {
|
||||||
|
colorRoom(roomTitle, node, newDate);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
(async function() {
|
(async function() {
|
||||||
for (const room of ROOMS) {
|
for (const room of ROOMS) {
|
||||||
await buildRoomMarkup(room);
|
await buildRoomMarkup(room);
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
|
setupTimeMachine();
|
||||||
|
setTimePreview();
|
||||||
|
|
Loading…
Reference in a new issue