feature: calendar
All checks were successful
Build and Push Docker Image / build-and-push (release) Successful in 9m41s
All checks were successful
Build and Push Docker Image / build-and-push (release) Successful in 9m41s
This commit is contained in:
107
src/index.css
107
src/index.css
@@ -76,8 +76,8 @@ H1 {
|
||||
|
||||
.time-row {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
#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) {
|
||||
.time-blocks {
|
||||
gap: 10px;
|
||||
@@ -95,4 +180,24 @@ H1 {
|
||||
padding: 8px 12px;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<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 name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>w-timerer</title>
|
||||
<link rel="stylesheet" type="text/css" href="index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="parent">
|
||||
<div class="vblock">
|
||||
@@ -36,6 +33,13 @@
|
||||
<div class="time-blocks jetbrains-mono" id="timeDifferences"></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>
|
||||
|
||||
<script src="index.js"></script>
|
||||
|
||||
93
src/index.js
93
src/index.js
@@ -72,6 +72,8 @@ function updateTimes() {
|
||||
distributeBlocks(targetTimesElement, targetTimeBlocks);
|
||||
distributeBlocks(leaveTimesElement, leaveTimeBlocks);
|
||||
distributeBlocks(timeDifferencesElement, diffTimeBlocks);
|
||||
|
||||
updateCalendar();
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +114,98 @@ function distributeBlocks(container, blocks) {
|
||||
container.appendChild(rowsContainer);
|
||||
}
|
||||
|
||||
function updateCalendar() {
|
||||
const now = new Date();
|
||||
const currentDateElement = document.getElementById('currentDate');
|
||||
|
||||
const day = now.getDate().toString().padStart(2, '0');
|
||||
const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
||||
const year = now.getFullYear();
|
||||
currentDateElement.textContent = `${day}.${month}.${year}`;
|
||||
|
||||
const calendarElement = document.getElementById('calendar');
|
||||
calendarElement.innerHTML = '';
|
||||
|
||||
const daysOfWeek = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];
|
||||
|
||||
const firstDayOfMonth = new Date(year, now.getMonth(), 1);
|
||||
let firstDayWeek = firstDayOfMonth.getDay();
|
||||
firstDayWeek = firstDayWeek === 0 ? 7 : firstDayWeek;
|
||||
|
||||
const lastDayOfMonth = new Date(year, now.getMonth() + 1, 0);
|
||||
const daysInMonth = lastDayOfMonth.getDate();
|
||||
|
||||
const lastDayOfPrevMonth = new Date(year, now.getMonth(), 0);
|
||||
const daysInPrevMonth = lastDayOfPrevMonth.getDate();
|
||||
|
||||
const thead = document.createElement('thead');
|
||||
const headerRow = document.createElement('tr');
|
||||
daysOfWeek.forEach((day, index) => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = day;
|
||||
th.className = 'calendar-weekday';
|
||||
if (index === 5 || index === 6) {
|
||||
th.classList.add('weekend-text');
|
||||
}
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
thead.appendChild(headerRow);
|
||||
calendarElement.appendChild(thead);
|
||||
|
||||
const tbody = document.createElement('tbody');
|
||||
|
||||
let dayCounter = 1;
|
||||
let nextMonthDayCounter = 1;
|
||||
|
||||
let startDay = daysInPrevMonth - firstDayWeek + 2;
|
||||
|
||||
for (let row = 0; row < 5; row++) {
|
||||
const tr = document.createElement('tr');
|
||||
|
||||
for (let col = 0; col < 7; col++) {
|
||||
const td = document.createElement('td');
|
||||
td.className = 'calendar-cell';
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
calendarElement.appendChild(tbody);
|
||||
}
|
||||
|
||||
|
||||
// Init
|
||||
updateTimes();
|
||||
setInterval(updateTimes, 200);
|
||||
window.addEventListener('resize', updateTimes);
|
||||
|
||||
Reference in New Issue
Block a user