diff --git a/myproject/orders/static/orders/css/date_filter.css b/myproject/orders/static/orders/css/date_filter.css index 6724c00..289ff1b 100644 --- a/myproject/orders/static/orders/css/date_filter.css +++ b/myproject/orders/static/orders/css/date_filter.css @@ -1,5 +1,5 @@ /** - * Стили для календарного фильтра с лентой из 19 дней + * Стили для календарного фильтра с динамическим количеством дней * Используется в компоненте date_range_filter.html */ @@ -118,6 +118,13 @@ text-transform: uppercase; } +.date-btn-month { + font-size: 0.65rem; + font-weight: 500; + color: #6c757d; + text-transform: lowercase; +} + /* Сегодняшний день (более светлый оттенок) */ .date-btn.today { background: #cfe2ff; @@ -127,7 +134,8 @@ .date-btn.today .date-btn-label, .date-btn.today .date-btn-day, -.date-btn.today .date-btn-weekday { +.date-btn.today .date-btn-weekday, +.date-btn.today .date-btn-month { color: #084298; } @@ -154,7 +162,8 @@ color: #dc3545; } -.date-btn.selected .date-btn-weekday { +.date-btn.selected .date-btn-weekday, +.date-btn.selected .date-btn-month { color: #6c757d; } @@ -189,6 +198,10 @@ .date-btn-weekday { font-size: 0.7rem; } + + .date-btn-month { + font-size: 0.6rem; + } } @media (max-width: 576px) { @@ -208,6 +221,10 @@ .date-btn-weekday { font-size: 0.65rem; } + + .date-btn-month { + font-size: 0.55rem; + } } /* Анимация при клике */ diff --git a/myproject/orders/static/orders/js/date_filter.js b/myproject/orders/static/orders/js/date_filter.js index 07f4f67..0ed917e 100644 --- a/myproject/orders/static/orders/js/date_filter.js +++ b/myproject/orders/static/orders/js/date_filter.js @@ -1,6 +1,6 @@ /** - * Календарная лента с 19 днями для фильтрации заказов - * Сегодня в центре, навигация стрелками + * Календарная лента с динамическим количеством дней для фильтрации заказов + * Сегодня всегда в центре при загрузке, количество дней зависит от ширины экрана */ document.addEventListener('DOMContentLoaded', function() { @@ -16,6 +16,13 @@ document.addEventListener('DOMContentLoaded', function() { // Инициализация с сегодняшней датой в центре const carousel = new DateCarousel(container, minInputId, maxInputId); carousel.init(); + + // Пересчёт количества дней при изменении размера окна + let resizeTimeout; + window.addEventListener('resize', () => { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => carousel.handleResize(), 250); + }); }); }); @@ -32,18 +39,76 @@ class DateCarousel { this.centerDate = new Date(); // Центральная дата (по умолчанию сегодня) this.today = new Date(); this.today.setHours(0, 0, 0, 0); + this.daysCount = 0; // Будет рассчитано динамически } /** * Инициализация календарной ленты */ init() { + this.calculateDaysCount(); + this.loadSelectedDate(); // Загрузить выбранную дату из фильтра this.render(); this.attachNavHandlers(); } /** - * Генерация и отображение 19 дней + * Загрузка выбранной даты из скрытых полей фильтра + */ + loadSelectedDate() { + // Если есть выбранная дата в фильтре, не центрируем на ней - пусть остается в том же положении + if (this.minInput.value && this.maxInput.value && + this.minInput.value === this.maxInput.value) { + const parts = this.minInput.value.split('-'); + if (parts.length === 3) { + const selectedDate = new Date( + parseInt(parts[0]), + parseInt(parts[1]) - 1, + parseInt(parts[2]) + ); + selectedDate.setHours(0, 0, 0, 0); + + // Не изменяем центральную дату, просто оставим как есть + console.log(`Selected date: ${this.formatDate(selectedDate)}, not centering`); + } + } else { + // Если фильтра нет, центрируем на сегодняшнем дне + console.log('No filter active - centering on today'); + } + } + + /** + * Расчёт количества дней на основе доступной ширины + */ + calculateDaysCount() { + const containerWidth = this.container.offsetWidth; + const dayButtonWidth = 78; // 70px min-width + 8px gap + const maxDays = Math.floor(containerWidth / dayButtonWidth); + + // Гарантируем нечётное количество дней для центрирования + this.daysCount = maxDays % 2 === 0 ? maxDays - 1 : maxDays; + + // Минимум 5 дней, максимум 31 день + this.daysCount = Math.max(5, Math.min(31, this.daysCount)); + + console.log(`Calculated days count: ${this.daysCount} (container width: ${containerWidth}px)`); + } + + /** + * Обработка изменения размера окна + */ + handleResize() { + const oldDaysCount = this.daysCount; + this.calculateDaysCount(); + + // Перерисовываем только если количество дней изменилось + if (oldDaysCount !== this.daysCount) { + this.render(); + } + } + + /** + * Генерация и отображение дней */ render() { this.container.innerHTML = ''; @@ -56,19 +121,20 @@ class DateCarousel { } /** - * Генерация массива из 19 дней (±9 от центральной даты) + * Генерация массива дней (динамическое количество от центральной даты) */ generateDays() { const days = []; + const halfDays = Math.floor(this.daysCount / 2); - for (let i = -9; i <= 9; i++) { + for (let i = -halfDays; i <= halfDays; i++) { const date = new Date(this.centerDate); date.setDate(date.getDate() + i); date.setHours(0, 0, 0, 0); days.push({ date: date, - label: this.getDateLabel(date, i), + label: this.getDateLabel(date), isToday: date.getTime() === this.today.getTime(), isCenter: i === 0 }); @@ -80,7 +146,7 @@ class DateCarousel { /** * Определение текстовой метки для даты */ - getDateLabel(date, offset) { + getDateLabel(date) { const yesterday = new Date(this.today); yesterday.setDate(yesterday.getDate() - 1); yesterday.setHours(0, 0, 0, 0); @@ -125,9 +191,14 @@ class DateCarousel { weekday.className = 'date-btn-weekday'; weekday.textContent = this.getWeekdayShort(dayData.date); + const month = document.createElement('div'); + month.className = 'date-btn-month'; + month.textContent = this.getMonthShort(dayData.date); + btn.appendChild(label); btn.appendChild(day); btn.appendChild(weekday); + btn.appendChild(month); // Обработчик клика btn.addEventListener('click', () => this.selectDate(dayData.date, btn)); @@ -139,8 +210,18 @@ class DateCarousel { * Получить короткое название дня недели (ПН, ВТ, СР, ЧТ, ПТ, СБ, ВС) */ getWeekdayShort(date) { - const weekdays = ['ВС', 'ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ']; - return weekdays[date.getDay()]; + const weekdays = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС']; + const dayIndex = date.getDay(); + // Сдвигаем индекс, чтобы понедельник был первым (0), а воскресенье - последним (6) + return weekdays[(dayIndex + 6) % 7]; + } + + /** + * Получить короткое название месяца (янв, фев, мар и т.д.) + */ + getMonthShort(date) { + const months = ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек']; + return months[date.getMonth()]; } /** diff --git a/myproject/orders/templates/orders/components/date_range_filter.html b/myproject/orders/templates/orders/components/date_range_filter.html index e00cecb..a7ef96a 100644 --- a/myproject/orders/templates/orders/components/date_range_filter.html +++ b/myproject/orders/templates/orders/components/date_range_filter.html @@ -25,7 +25,7 @@ {{ field_before }} - +