import { IEventBus } from '../types/CalendarTypes'; import { EventTypes } from '../constants/EventTypes'; import { DateUtils } from '../utils/DateUtils'; import { CalendarConfig } from '../core/CalendarConfig'; /** * NavigationRenderer - Handles DOM rendering for navigation containers * Separated from NavigationManager to follow Single Responsibility Principle */ export class NavigationRenderer { private eventBus: IEventBus; private config: CalendarConfig; constructor(eventBus: IEventBus, config: CalendarConfig) { this.eventBus = eventBus; this.config = 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 = ''; // Render headers for target week const workWeekSettings = this.config.getWorkWeekSettings(); workWeekSettings.workDays.forEach((dayOfWeek, i) => { const date = new Date(weekStart); // Set to the start of the week (Sunday = 0) date.setDate(weekStart.getDate() - weekStart.getDay()); // Add the specific day of week date.setDate(date.getDate() + dayOfWeek); const headerElement = document.createElement('swp-day-header'); if (this.isToday(date)) { headerElement.dataset.today = 'true'; } headerElement.innerHTML = ` ${workWeekSettings.dayNames[i]} ${date.getDate()} `; headerElement.dataset.date = this.formatDate(date); header.appendChild(headerElement); }); // Render day columns for target week workWeekSettings.workDays.forEach(dayOfWeek => { const column = document.createElement('swp-day-column'); const date = new Date(weekStart); // Set to the start of the week (Sunday = 0) date.setDate(weekStart.getDate() - weekStart.getDay()); // Add the specific day of week date.setDate(date.getDate() + dayOfWeek); column.dataset.date = this.formatDate(date); const eventsLayer = document.createElement('swp-events-layer'); column.appendChild(eventsLayer); dayColumns.appendChild(column); }); } /** * Utility method to format date */ private formatDate(date: Date): string { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } /** * Check if date is today */ private isToday(date: Date): boolean { const today = new Date(); return date.toDateString() === today.toDateString(); } }