Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac2696d387 | |||
| 90069d9aa7 | |||
| bca07d4eb8 |
@@ -10,12 +10,10 @@ Just copy this compose.yml file:
|
|||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
work-timerer:
|
work-timerer:
|
||||||
image: git.frik.su/Beesquit/work-timerer:latest
|
image: git.frik.su/beesquit/work-timerer:latest
|
||||||
container_name: work-timerer
|
container_name: work-timerer
|
||||||
ports:
|
ports:
|
||||||
- 4000:80
|
- 4000:80
|
||||||
volumes:
|
|
||||||
- ./src:/usr/share/nginx/html
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -23,6 +21,7 @@ The application should be available at the `localhost:4000`
|
|||||||
|
|
||||||
### Todo:
|
### Todo:
|
||||||
- [ ] Make travel time customizable with env
|
- [ ] Make travel time customizable with env
|
||||||
|
- [ ] Add mobile website adaptation
|
||||||
|
|
||||||
### Limitations:
|
### Limitations:
|
||||||
- The app is linked to the system time
|
- The app is linked to the system time
|
||||||
|
|||||||
@@ -4,6 +4,4 @@ services:
|
|||||||
container_name: work-timerer
|
container_name: work-timerer
|
||||||
ports:
|
ports:
|
||||||
- 4000:80
|
- 4000:80
|
||||||
volumes:
|
|
||||||
- ./src:/usr/share/nginx/html
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
+106
-1
@@ -76,8 +76,8 @@ H1 {
|
|||||||
|
|
||||||
.time-row {
|
.time-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#currentTime {
|
#currentTime {
|
||||||
@@ -86,6 +86,91 @@ H1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.calendar-container {
|
||||||
|
margin-top: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-container .hblock {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#currentDate {
|
||||||
|
font-size: 2em;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #ffffff;
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table thead tr {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table tbody {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table tbody tr {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th,
|
||||||
|
.calendar-table td {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 65px;
|
||||||
|
height: 45px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 1em;
|
||||||
|
border: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th {
|
||||||
|
background-color: #3a3a3a;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table td {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th.weekend-text {
|
||||||
|
color: #6b9ac0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table td.weekend-text {
|
||||||
|
color: #6b9ac0;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table td.today-text {
|
||||||
|
color: #d4a017;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
font-weight: 700;
|
||||||
|
border: 2px solid #d4a017;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table td.other-month {
|
||||||
|
opacity: 0.4;
|
||||||
|
background-color: #232323;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.time-blocks {
|
.time-blocks {
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@@ -95,4 +180,24 @@ H1 {
|
|||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
min-width: 50px;
|
min-width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.calendar-container {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th,
|
||||||
|
.calendar-table td {
|
||||||
|
width: 50px;
|
||||||
|
height: 38px;
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table {
|
||||||
|
border-spacing: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table thead tr,
|
||||||
|
.calendar-table tbody tr {
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -1,16 +1,11 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>w-timerer</title>
|
<title>w-timerer</title>
|
||||||
<link rel="stylesheet" type="text/css" href="index.css">
|
<link rel="stylesheet" type="text/css" href="index.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="parent">
|
<div class="parent">
|
||||||
<div class="vblock">
|
<div class="vblock">
|
||||||
@@ -36,6 +31,13 @@
|
|||||||
<div class="time-blocks jetbrains-mono" id="timeDifferences"></div>
|
<div class="time-blocks jetbrains-mono" id="timeDifferences"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="vblock calendar-container">
|
||||||
|
<div class="hblock">
|
||||||
|
<div class="jetbrains-mono" id="currentDate"></div>
|
||||||
|
<table class="jetbrains-mono calendar-table" id="calendar"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
|
|||||||
+228
-76
@@ -1,80 +1,50 @@
|
|||||||
function updateTimes() {
|
const TRAVEL_TIME_HOURS = 1;
|
||||||
const travelTime = 1; // in hours
|
const FIRST_HOUR = 13;
|
||||||
|
const LAST_HOUR = 22;
|
||||||
|
|
||||||
const now = new Date();
|
let clockEl, dateEl;
|
||||||
const currentHours = now.getHours();
|
let diffNodes = [];
|
||||||
const currentMinutes = now.getMinutes();
|
let resizeTimer = null;
|
||||||
const currentSeconds = now.getSeconds();
|
let lastDayKey = "";
|
||||||
|
|
||||||
const currentTimeElement = document.getElementById('currentTime');
|
function pad2(n) {
|
||||||
currentTimeElement.textContent = `${currentHours.toString().padStart(2, '0')}:${currentMinutes.toString().padStart(2, '0')}:${currentSeconds.toString().padStart(2, '0')}`;
|
return n < 10 ? "0" + n : "" + n;
|
||||||
|
}
|
||||||
|
|
||||||
const targetTimesElement = document.getElementById('targetTimes');
|
function formatClock(d) {
|
||||||
const leaveTimesElement = document.getElementById('leaveTimes');
|
return pad2(d.getHours()) + ":" + pad2(d.getMinutes()) + ":" + pad2(d.getSeconds());
|
||||||
const timeDifferencesElement = document.getElementById('timeDifferences');
|
}
|
||||||
|
|
||||||
targetTimesElement.innerHTML = '';
|
function formatDate(d) {
|
||||||
leaveTimesElement.innerHTML = '';
|
return pad2(d.getDate()) + "." + pad2(d.getMonth() + 1) + "." + d.getFullYear();
|
||||||
timeDifferencesElement.innerHTML = '';
|
}
|
||||||
|
|
||||||
const ttBlock = document.createElement('span');
|
function diffText(targetMs, nowMs) {
|
||||||
ttBlock.className = 'time-block label-block';
|
const diffMs = targetMs - nowMs;
|
||||||
ttBlock.textContent = 'TT';
|
|
||||||
targetTimesElement.appendChild(ttBlock);
|
|
||||||
|
|
||||||
const ltBlock = document.createElement('span');
|
|
||||||
ltBlock.className = 'time-block label-block';
|
|
||||||
ltBlock.textContent = 'LT';
|
|
||||||
leaveTimesElement.appendChild(ltBlock);
|
|
||||||
|
|
||||||
const tdBlock = document.createElement('span');
|
|
||||||
tdBlock.className = 'time-block label-block';
|
|
||||||
tdBlock.textContent = 'TD';
|
|
||||||
timeDifferencesElement.appendChild(tdBlock);
|
|
||||||
|
|
||||||
const targetTimeBlocks = [];
|
|
||||||
const leaveTimeBlocks = [];
|
|
||||||
const diffTimeBlocks = [];
|
|
||||||
|
|
||||||
for (let hour = 13; hour <= 22; hour++) {
|
|
||||||
let leaveHour = hour - travelTime;
|
|
||||||
|
|
||||||
const timeBlock = document.createElement('span');
|
|
||||||
timeBlock.className = 'time-block';
|
|
||||||
timeBlock.textContent = `${hour.toString().padStart(2, '0')}:00`;
|
|
||||||
targetTimeBlocks.push(timeBlock);
|
|
||||||
|
|
||||||
const leaveTimeBlock = document.createElement('span');
|
|
||||||
leaveTimeBlock.className = 'time-block';
|
|
||||||
leaveTimeBlock.textContent = `${(leaveHour).toString().padStart(2, '0')}:00`;
|
|
||||||
leaveTimeBlocks.push(leaveTimeBlock);
|
|
||||||
|
|
||||||
const targetTime = new Date();
|
|
||||||
targetTime.setHours(leaveHour, 0, 0, 0);
|
|
||||||
|
|
||||||
const diffBlock = document.createElement('span');
|
|
||||||
diffBlock.className = 'time-block';
|
|
||||||
|
|
||||||
const diffMs = targetTime - now;
|
|
||||||
if (diffMs < 0) {
|
if (diffMs < 0) {
|
||||||
const diffHours = -1 * Math.ceil(diffMs / (1000 * 60 * 60));
|
const diffHours = -1 * Math.ceil(diffMs / 3600000);
|
||||||
const diffMinutes = -1 * Math.ceil((diffMs % (1000 * 60 * 60)) / (1000 * 60));
|
const diffMinutes = -1 * Math.ceil((diffMs % 3600000) / 60000);
|
||||||
diffBlock.textContent = `-${diffHours.toString().padStart(2, '0')}:${diffMinutes.toString().padStart(2, '0')}`;
|
return "-" + pad2(diffHours) + ":" + pad2(diffMinutes);
|
||||||
} else {
|
}
|
||||||
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
const diffHours = Math.floor(diffMs / 3600000);
|
||||||
const diffMinutes = Math.ceil((diffMs % (1000 * 60 * 60)) / (1000 * 60));
|
const diffMinutes = Math.ceil((diffMs % 3600000) / 60000);
|
||||||
diffBlock.textContent = `${diffHours.toString().padStart(2, '0')}:${diffMinutes.toString().padStart(2, '0')}`;
|
return pad2(diffHours) + ":" + pad2(diffMinutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
diffTimeBlocks.push(diffBlock);
|
function buildLabel(text) {
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.className = "time-block label-block";
|
||||||
|
span.textContent = text;
|
||||||
|
return span;
|
||||||
}
|
}
|
||||||
|
|
||||||
distributeBlocks(targetTimesElement, targetTimeBlocks);
|
function buildTimeBlock(text) {
|
||||||
distributeBlocks(leaveTimesElement, leaveTimeBlocks);
|
const span = document.createElement("span");
|
||||||
distributeBlocks(timeDifferencesElement, diffTimeBlocks);
|
span.className = "time-block";
|
||||||
|
span.textContent = text;
|
||||||
|
return span;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function distributeBlocks(container, blocks) {
|
function distributeBlocks(container, blocks) {
|
||||||
const screenWidth = window.innerWidth;
|
const screenWidth = window.innerWidth;
|
||||||
const blockWidth = 120;
|
const blockWidth = 120;
|
||||||
@@ -83,36 +53,218 @@ function distributeBlocks(container, blocks) {
|
|||||||
const availableWidth = screenWidth - labelWidth;
|
const availableWidth = screenWidth - labelWidth;
|
||||||
const blocksPerRow = Math.floor(availableWidth / blockWidth);
|
const blocksPerRow = Math.floor(availableWidth / blockWidth);
|
||||||
|
|
||||||
|
while (container.childNodes.length > 1) {
|
||||||
|
container.removeChild(container.lastChild);
|
||||||
|
}
|
||||||
|
|
||||||
if (blocksPerRow > blocks.length) {
|
if (blocksPerRow > blocks.length) {
|
||||||
blocks.forEach(block => container.appendChild(block));
|
blocks.forEach(function (b) { container.appendChild(b); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalBlocks = blocks.length;
|
const totalBlocks = blocks.length;
|
||||||
const halfBlocks = Math.ceil(totalBlocks / 2);
|
const halfBlocks = Math.ceil(totalBlocks / 2);
|
||||||
|
|
||||||
const rowsContainer = document.createElement('div');
|
const rowsContainer = document.createElement("div");
|
||||||
rowsContainer.className = 'multi-rows-container';
|
rowsContainer.className = "multi-rows-container";
|
||||||
|
|
||||||
const topRow = document.createElement('div');
|
const topRow = document.createElement("div");
|
||||||
topRow.className = 'time-row';
|
topRow.className = "time-row";
|
||||||
for (let i = 0; i < halfBlocks; i++) {
|
for (let i = 0; i < halfBlocks; i++) {
|
||||||
topRow.appendChild(blocks[i]);
|
topRow.appendChild(blocks[i]);
|
||||||
}
|
}
|
||||||
rowsContainer.appendChild(topRow);
|
rowsContainer.appendChild(topRow);
|
||||||
|
|
||||||
const bottomRow = document.createElement('div');
|
const bottomRow = document.createElement("div");
|
||||||
bottomRow.className = 'time-row';
|
bottomRow.className = "time-row";
|
||||||
for (let i = halfBlocks; i < totalBlocks; i++) {
|
for (let i = halfBlocks; i < totalBlocks; i++) {
|
||||||
bottomRow.appendChild(blocks[i]);
|
bottomRow.appendChild(blocks[i]);
|
||||||
}
|
}
|
||||||
rowsContainer.appendChild(bottomRow);
|
rowsContainer.appendChild(bottomRow);
|
||||||
|
|
||||||
const label = container.firstChild;
|
|
||||||
container.appendChild(rowsContainer);
|
container.appendChild(rowsContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildTargetBlocks() {
|
||||||
|
const targetTimesElement = document.getElementById("targetTimes");
|
||||||
|
const leaveTimesElement = document.getElementById("leaveTimes");
|
||||||
|
const timeDifferencesElement = document.getElementById("timeDifferences");
|
||||||
|
|
||||||
updateTimes();
|
targetTimesElement.appendChild(buildLabel("TT"));
|
||||||
setInterval(updateTimes, 200);
|
leaveTimesElement.appendChild(buildLabel("LT"));
|
||||||
window.addEventListener('resize', updateTimes);
|
timeDifferencesElement.appendChild(buildLabel("TD"));
|
||||||
|
|
||||||
|
const targetBlocks = [];
|
||||||
|
const leaveBlocks = [];
|
||||||
|
const diffBlocks = [];
|
||||||
|
|
||||||
|
for (let hour = FIRST_HOUR; hour <= LAST_HOUR; hour++) {
|
||||||
|
const leaveHour = hour - TRAVEL_TIME_HOURS;
|
||||||
|
|
||||||
|
targetBlocks.push(buildTimeBlock(pad2(hour) + ":00"));
|
||||||
|
leaveBlocks.push(buildTimeBlock(pad2(leaveHour) + ":00"));
|
||||||
|
diffBlocks.push(buildTimeBlock(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
distributeBlocks(targetTimesElement, targetBlocks);
|
||||||
|
distributeBlocks(leaveTimesElement, leaveBlocks);
|
||||||
|
distributeBlocks(timeDifferencesElement, diffBlocks);
|
||||||
|
|
||||||
|
diffNodes = diffBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCalendar() {
|
||||||
|
const calendar = document.getElementById("calendar");
|
||||||
|
calendar.innerHTML = "";
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const daysOfWeek = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
||||||
|
|
||||||
|
const thead = document.createElement("thead");
|
||||||
|
const headerRow = document.createElement("tr");
|
||||||
|
daysOfWeek.forEach(function (day, index) {
|
||||||
|
const th = document.createElement("th");
|
||||||
|
th.textContent = day;
|
||||||
|
if (index === 5 || index === 6) {
|
||||||
|
th.classList.add("weekend-text");
|
||||||
|
}
|
||||||
|
headerRow.appendChild(th);
|
||||||
|
});
|
||||||
|
thead.appendChild(headerRow);
|
||||||
|
calendar.appendChild(thead);
|
||||||
|
|
||||||
|
const tbody = document.createElement("tbody");
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = now.getMonth();
|
||||||
|
const firstDayOfMonth = new Date(year, month, 1);
|
||||||
|
let firstDayWeek = firstDayOfMonth.getDay();
|
||||||
|
firstDayWeek = firstDayWeek === 0 ? 7 : firstDayWeek;
|
||||||
|
|
||||||
|
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||||
|
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
||||||
|
|
||||||
|
let dayCounter = 1;
|
||||||
|
let nextMonthDayCounter = 1;
|
||||||
|
let startDay = daysInPrevMonth - firstDayWeek + 2;
|
||||||
|
|
||||||
|
const totalRows = Math.ceil((firstDayWeek - 1 + daysInMonth) / 7);
|
||||||
|
for (let row = 0; row < totalRows; row++) {
|
||||||
|
const tr = document.createElement("tr");
|
||||||
|
for (let col = 0; col < 7; col++) {
|
||||||
|
const td = document.createElement("td");
|
||||||
|
|
||||||
|
let cellDay;
|
||||||
|
let isCurrentMonth = true;
|
||||||
|
|
||||||
|
if (row === 0 && col < firstDayWeek - 1) {
|
||||||
|
cellDay = startDay + col;
|
||||||
|
isCurrentMonth = false;
|
||||||
|
} else if (dayCounter <= daysInMonth) {
|
||||||
|
cellDay = dayCounter;
|
||||||
|
dayCounter++;
|
||||||
|
} else {
|
||||||
|
cellDay = nextMonthDayCounter;
|
||||||
|
nextMonthDayCounter++;
|
||||||
|
isCurrentMonth = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.textContent = cellDay;
|
||||||
|
|
||||||
|
if (isCurrentMonth && cellDay === now.getDate()) {
|
||||||
|
td.classList.add("today-text");
|
||||||
|
}
|
||||||
|
if (col === 5 || col === 6) {
|
||||||
|
td.classList.add("weekend-text");
|
||||||
|
}
|
||||||
|
if (!isCurrentMonth) {
|
||||||
|
td.classList.add("other-month");
|
||||||
|
}
|
||||||
|
tr.appendChild(td);
|
||||||
|
}
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
}
|
||||||
|
calendar.appendChild(tbody);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateClock() {
|
||||||
|
const now = new Date();
|
||||||
|
clockEl.textContent = formatClock(now);
|
||||||
|
scheduleNextClockTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleNextClockTick() {
|
||||||
|
const delay = 1000 - new Date().getMilliseconds();
|
||||||
|
setTimeout(updateClock, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDiffs() {
|
||||||
|
const now = new Date();
|
||||||
|
for (let hour = FIRST_HOUR; hour <= LAST_HOUR; hour++) {
|
||||||
|
const target = new Date();
|
||||||
|
target.setHours(hour - TRAVEL_TIME_HOURS, 0, 0, 0);
|
||||||
|
diffNodes[hour - FIRST_HOUR].textContent = diffText(target.getTime(), now.getTime());
|
||||||
|
}
|
||||||
|
scheduleNextDiffTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleNextDiffTick() {
|
||||||
|
const now = new Date();
|
||||||
|
const msUntilNextMinute =
|
||||||
|
(60 - now.getSeconds()) * 1000 - now.getMilliseconds();
|
||||||
|
setTimeout(updateDiffs, msUntilNextMinute);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkDayChange() {
|
||||||
|
const now = new Date();
|
||||||
|
const key =
|
||||||
|
now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
|
||||||
|
if (key !== lastDayKey) {
|
||||||
|
lastDayKey = key;
|
||||||
|
dateEl.textContent = formatDate(now);
|
||||||
|
buildCalendar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
clockEl = document.getElementById("currentTime");
|
||||||
|
dateEl = document.getElementById("currentDate");
|
||||||
|
|
||||||
|
buildTargetBlocks();
|
||||||
|
buildCalendar();
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
lastDayKey = now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
|
||||||
|
dateEl.textContent = formatDate(now);
|
||||||
|
|
||||||
|
updateClock();
|
||||||
|
updateDiffs();
|
||||||
|
|
||||||
|
setInterval(checkDayChange, 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize() {
|
||||||
|
if (resizeTimer !== null) clearTimeout(resizeTimer);
|
||||||
|
resizeTimer = setTimeout(function () {
|
||||||
|
resizeTimer = null;
|
||||||
|
const targetTimesElement = document.getElementById("targetTimes");
|
||||||
|
const leaveTimesElement = document.getElementById("leaveTimes");
|
||||||
|
const timeDifferencesElement = document.getElementById("timeDifferences");
|
||||||
|
|
||||||
|
const allBlocks = [].slice.call(
|
||||||
|
timeDifferencesElement.querySelectorAll(".time-block:not(.label-block)")
|
||||||
|
);
|
||||||
|
const targetBlocks = [].slice.call(
|
||||||
|
targetTimesElement.querySelectorAll(".time-block:not(.label-block)")
|
||||||
|
);
|
||||||
|
const leaveBlocks = [].slice.call(
|
||||||
|
leaveTimesElement.querySelectorAll(".time-block:not(.label-block)")
|
||||||
|
);
|
||||||
|
|
||||||
|
distributeBlocks(targetTimesElement, targetBlocks);
|
||||||
|
distributeBlocks(leaveTimesElement, leaveBlocks);
|
||||||
|
distributeBlocks(timeDifferencesElement, allBlocks);
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
window.addEventListener("resize", onResize);
|
||||||
|
|||||||
Reference in New Issue
Block a user