Enhance calendar layout and duty list rendering
- Introduced a sticky header for the calendar to improve navigation. - Updated the duty list display to highlight today's date with a distinct style. - Added new CSS styles for better visual presentation of duty days and improved layout consistency.
This commit is contained in:
@@ -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 += "<h2>" + date + "</h2>";
|
||||
const isToday = date === todayKey;
|
||||
const dayBlockClass = "duty-list-day" + (isToday ? " duty-list-day--today" : "");
|
||||
const titleText = isToday ? "Сегодня, " + dateKeyToDDMM(date) : dateKeyToDDMM(date);
|
||||
html += "<div class=\"" + dayBlockClass + "\"><h2 class=\"duty-list-day-title\">" + escapeHtml(titleText) + "</h2>";
|
||||
list.forEach(function (d) {
|
||||
const startDate = new Date(d.start_at);
|
||||
const endDate = new Date(d.end_at);
|
||||
@@ -396,6 +404,7 @@
|
||||
}
|
||||
html += "<div class=\"" + itemClass + "\"><span class=\"duty-item-type\">" + escapeHtml(typeLabel) + "</span> <span class=\"name\">" + escapeHtml(d.full_name) + "</span><div class=\"time\">" + timeOrRange + "</div></div>";
|
||||
});
|
||||
html += "</div>";
|
||||
});
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,15 +8,17 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<button type="button" class="nav" id="prevMonth" aria-label="Предыдущий месяц">‹</button>
|
||||
<h1 class="title" id="monthTitle"></h1>
|
||||
<button type="button" class="nav" id="nextMonth" aria-label="Следующий месяц">›</button>
|
||||
</header>
|
||||
<div class="weekdays">
|
||||
<span>Пн</span><span>Вт</span><span>Ср</span><span>Чт</span><span>Пт</span><span>Сб</span><span>Вс</span>
|
||||
<div class="calendar-sticky" id="calendarSticky">
|
||||
<header class="header">
|
||||
<button type="button" class="nav" id="prevMonth" aria-label="Предыдущий месяц">‹</button>
|
||||
<h1 class="title" id="monthTitle"></h1>
|
||||
<button type="button" class="nav" id="nextMonth" aria-label="Следующий месяц">›</button>
|
||||
</header>
|
||||
<div class="weekdays">
|
||||
<span>Пн</span><span>Вт</span><span>Ср</span><span>Чт</span><span>Пт</span><span>Сб</span><span>Вс</span>
|
||||
</div>
|
||||
<div class="calendar" id="calendar"></div>
|
||||
</div>
|
||||
<div class="calendar" id="calendar"></div>
|
||||
<div class="duty-list" id="dutyList"></div>
|
||||
<div class="loading" id="loading">Загрузка…</div>
|
||||
<div class="error" id="error" hidden></div>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user