import { IEventBus } from '../types/CalendarTypes'; import { EventTypes } from '../constants/EventTypes'; import { DateUtils } from '../utils/DateUtils'; import { CalendarConfig } from '../core/CalendarConfig'; import { DateCalculator } from '../utils/DateCalculator'; /** * NavigationRenderer - Handles DOM rendering for navigation containers * Separated from NavigationManager to follow Single Responsibility Principle */ export class NavigationRenderer { private eventBus: IEventBus; private config: CalendarConfig; private dateCalculator: DateCalculator; constructor(eventBus: IEventBus, config: CalendarConfig) { this.eventBus = eventBus; this.config = config; this.dateCalculator = new DateCalculator(config); this.setupEventListeners(); } /** * Setup event listeners for DOM updates */ private setupEventListeners(): void { this.eventBus.on(EventTypes.WEEK_INFO_UPDATED, (event: Event) => { const customEvent = event as CustomEvent; const { weekNumber, dateRange } = customEvent.detail; this.updateWeekInfoInDOM(weekNumber, dateRange); }); } /** * Update week info in DOM elements */ private updateWeekInfoInDOM(weekNumber: number, dateRange: string): void { const weekNumberElement = document.querySelector('swp-week-number'); const dateRangeElement = document.querySelector('swp-date-range'); if (weekNumberElement) { weekNumberElement.textContent = `Week ${weekNumber}`; } if (dateRangeElement) { dateRangeElement.textContent = dateRange; } } /** * Render a complete container with content and events */ public renderContainer(parentContainer: HTMLElement, weekStart: Date): HTMLElement { console.log('NavigationRenderer: Rendering new container for week:', weekStart.toDateString()); // Create new grid container const newGrid = document.createElement('swp-grid-container'); newGrid.innerHTML = ` `; // Position new grid - NO transform here, let Animation API handle it newGrid.style.position = 'absolute'; newGrid.style.top = '0'; newGrid.style.left = '0'; newGrid.style.width = '100%'; newGrid.style.height = '100%'; // Add to parent container parentContainer.appendChild(newGrid); // Render week content (headers and columns) this.renderWeekContentInContainer(newGrid, weekStart); // Emit event to trigger event rendering const weekEnd = DateUtils.addDays(weekStart, 6); this.eventBus.emit(EventTypes.CONTAINER_READY_FOR_EVENTS, { container: newGrid, startDate: weekStart, endDate: weekEnd }); return newGrid; } /** * Render week content in specific container */ private renderWeekContentInContainer(gridContainer: HTMLElement, weekStart: Date): void { const header = gridContainer.querySelector('swp-calendar-header'); const dayColumns = gridContainer.querySelector('swp-day-columns'); if (!header || !dayColumns) return; // Clear existing content header.innerHTML = ''; dayColumns.innerHTML = ''; // Get dates using DateCalculator const dates = this.dateCalculator.getWorkWeekDates(weekStart); const workWeekSettings = this.config.getWorkWeekSettings(); // Render headers for target week dates.forEach((date, i) => { const headerElement = document.createElement('swp-day-header'); if (this.dateCalculator.isToday(date)) { headerElement.dataset.today = 'true'; } headerElement.innerHTML = ` ${workWeekSettings.dayNames[i]} ${date.getDate()} `; headerElement.dataset.date = this.dateCalculator.formatISODate(date); header.appendChild(headerElement); }); // Render day columns for target week dates.forEach(date => { const column = document.createElement('swp-day-column'); column.dataset.date = this.dateCalculator.formatISODate(date); const eventsLayer = document.createElement('swp-events-layer'); column.appendChild(eventsLayer); dayColumns.appendChild(column); }); } }