feature: calendar
All checks were successful
Build and Push Docker Image / build-and-push (release) Successful in 9m41s

This commit is contained in:
2026-02-24 16:15:59 +03:00
parent bca07d4eb8
commit 90069d9aa7
3 changed files with 206 additions and 4 deletions

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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);