import { IEventBus } from '../types/CalendarTypes'; import { CoreEvents } from '../constants/CoreEvents'; import { CalendarConfig } from '../core/CalendarConfig'; import { DateCalculator } from '../utils/DateCalculator'; import { EventRenderingService } from './EventRendererManager'; /** * 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; private eventRenderer: EventRenderingService; constructor(eventBus: IEventBus, config: CalendarConfig, eventRenderer: EventRenderingService) { this.eventBus = eventBus; this.config = config; this.eventRenderer = eventRenderer; this.dateCalculator = new DateCalculator(config); this.setupEventListeners(); } /** * Setup event listeners for DOM updates */ private setupEventListeners(): void { this.eventBus.on(CoreEvents.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 { const weekEnd = this.dateCalculator.addDays(weekStart, 6); console.group(`🎨 RENDERING CONTAINER: ${weekStart.toDateString()} - ${weekEnd.toDateString()}`); console.log('1. Creating grid structure...'); // 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); console.log('2. Rendering headers and columns...'); this.renderWeekContentInContainer(newGrid, weekStart); console.log('3. Pre-rendering events synchronously...'); this.eventRenderer.renderEvents({ container: newGrid, startDate: weekStart, endDate: weekEnd }); console.log('✅ Container ready with pre-rendered events'); console.groupEnd(); 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); // 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'; } const dayName = this.dateCalculator.getDayName(date, 'short'); headerElement.innerHTML = ` ${dayName} ${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); }); } }