diff --git a/webapp/app.js b/webapp/app.js index 36ede1e..24ad526 100644 --- a/webapp/app.js +++ b/webapp/app.js @@ -368,6 +368,7 @@ grouped[date].push(d); }); const dates = Object.keys(grouped).sort(); + const todayKey = localDateString(new Date()); let html = ""; /** Format UTC date from ISO string as DD.MM for display. */ function formatDateKey(isoDateStr) { @@ -376,9 +377,16 @@ const month = String(d.getUTCMonth() + 1).padStart(2, "0"); return day + "." + month; } + /** Format YYYY-MM-DD as DD.MM for list header. */ + function dateKeyToDDMM(key) { + return key.slice(8, 10) + "." + key.slice(5, 7); + } dates.forEach(function (date) { const list = grouped[date]; - html += "

" + date + "

"; + const isToday = date === todayKey; + const dayBlockClass = "duty-list-day" + (isToday ? " duty-list-day--today" : ""); + const titleText = isToday ? "Сегодня, " + dateKeyToDDMM(date) : dateKeyToDDMM(date); + html += "

" + escapeHtml(titleText) + "

"; list.forEach(function (d) { const startDate = new Date(d.start_at); const endDate = new Date(d.end_at); @@ -396,6 +404,7 @@ } html += "
" + escapeHtml(typeLabel) + " " + escapeHtml(d.full_name) + "
" + timeOrRange + "
"; }); + html += "
"; }); dutyListEl.innerHTML = html; } @@ -527,8 +536,20 @@ loadMonth(); }); + function bindStickyScrollShadow() { + var stickyEl = document.getElementById("calendarSticky"); + if (!stickyEl || document._stickyScrollBound) return; + document._stickyScrollBound = true; + function updateScrolled() { + stickyEl.classList.toggle("is-scrolled", window.scrollY > 0); + } + window.addEventListener("scroll", updateScrolled, { passive: true }); + updateScrolled(); + } + runWhenReady(function () { requireTelegramOrLocalhost(function () { + bindStickyScrollShadow(); loadMonth(); }); }); diff --git a/webapp/index.html b/webapp/index.html index 801e7ee..e64ec3f 100644 --- a/webapp/index.html +++ b/webapp/index.html @@ -8,15 +8,17 @@
-
- -

- -
-
- ПнВтСрЧтПтСбВс +
+
+ +

+ +
+
+ ПнВтСрЧтПтСбВс +
+
-
Загрузка…
diff --git a/webapp/style.css b/webapp/style.css index b15c56e..c1027a6 100644 --- a/webapp/style.css +++ b/webapp/style.css @@ -73,6 +73,19 @@ body { text-align: center; } +.calendar-sticky { + position: sticky; + top: 0; + z-index: 10; + background: var(--bg); + padding-bottom: 12px; + margin-bottom: 4px; +} + +.calendar-sticky.is-scrolled { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); +} + .calendar { display: grid; grid-template-columns: repeat(7, 1fr); @@ -215,6 +228,26 @@ body { margin: 0 0 8px 0; } +.duty-list-day { + margin-bottom: 16px; +} + +.duty-list-day--today .duty-list-day-title { + color: var(--today); + font-weight: 700; +} + +.duty-list-day--today .duty-list-day-title::before { + content: ""; + display: inline-block; + width: 4px; + height: 1em; + background: var(--today); + border-radius: 2px; + margin-right: 8px; + vertical-align: middle; +} + .duty-item { display: grid; grid-template-columns: 5.5em 1fr;