From 90069d9aa782458437874b81cd6851e49c658e87 Mon Sep 17 00:00:00 2001 From: Beesquit Date: Tue, 24 Feb 2026 16:15:59 +0300 Subject: [PATCH] feature: calendar --- src/index.css | 107 ++++++++++++++++++++++++++++++++++++++++++++++++- src/index.html | 10 +++-- src/index.js | 93 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 4 deletions(-) diff --git a/src/index.css b/src/index.css index 8be49b9..6a01491 100644 --- a/src/index.css +++ b/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; + } } diff --git a/src/index.html b/src/index.html index 771158c..6b36a88 100644 --- a/src/index.html +++ b/src/index.html @@ -1,16 +1,13 @@ - - w-timerer -
@@ -36,6 +33,13 @@
+ +
+
+
+
+
+
diff --git a/src/index.js b/src/index.js index 2d80301..ce79324 100644 --- a/src/index.js +++ b/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);