import { EventBus } from '../core/EventBus'; import { CalendarView, IEventBus } from '../types/CalendarTypes'; import { calendarConfig } from '../core/CalendarConfig'; import { EventTypes } from '../constants/EventTypes'; /** * ViewManager - Håndterer skift mellem dag/uge/måned visninger * Arbejder med custom tags fra POC design */ export class ViewManager { private eventBus: IEventBus; private currentView: CalendarView = 'week'; constructor(eventBus: IEventBus) { this.eventBus = eventBus; this.setupEventListeners(); } private setupEventListeners(): void { this.eventBus.on(EventTypes.CALENDAR_INITIALIZED, () => { this.initializeView(); }); this.eventBus.on(EventTypes.VIEW_CHANGE_REQUESTED, (event: Event) => { const customEvent = event as CustomEvent; const { currentView } = customEvent.detail; this.changeView(currentView); }); this.eventBus.on(EventTypes.DATE_CHANGED, () => { this.refreshCurrentView(); }); // Setup view button handlers this.setupViewButtonHandlers(); } private setupViewButtonHandlers(): void { const viewButtons = document.querySelectorAll('swp-view-button[data-view]'); viewButtons.forEach(button => { button.addEventListener('click', (event) => { event.preventDefault(); const view = button.getAttribute('data-view') as CalendarView; if (view && this.isValidView(view)) { this.changeView(view); } }); }); } private initializeView(): void { this.renderTimeAxis(); this.renderWeekHeaders(); this.renderDayColumns(); this.updateViewButtons(); this.eventBus.emit(EventTypes.VIEW_RENDERED, { view: this.currentView }); } private changeView(newView: CalendarView): void { if (newView === this.currentView) return; const previousView = this.currentView; this.currentView = newView; console.log(`ViewManager: Changing view from ${previousView} to ${newView}`); this.updateViewButtons(); this.eventBus.emit(EventTypes.VIEW_CHANGED, { previousView, currentView: newView }); } private renderTimeAxis(): void { const timeAxis = document.querySelector('swp-time-axis'); if (!timeAxis) return; const startHour = calendarConfig.get('dayStartHour'); const endHour = calendarConfig.get('dayEndHour'); timeAxis.innerHTML = ''; for (let hour = startHour; hour <= endHour; hour++) { const marker = document.createElement('swp-hour-marker'); const period = hour >= 12 ? 'PM' : 'AM'; const displayHour = hour > 12 ? hour - 12 : (hour === 0 ? 12 : hour); marker.textContent = `${displayHour} ${period}`; timeAxis.appendChild(marker); } } private renderWeekHeaders(): void { const weekHeader = document.querySelector('swp-week-header'); if (!weekHeader) return; const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; weekHeader.innerHTML = ''; for (let i = 0; i < 7; i++) { const header = document.createElement('swp-day-header'); header.innerHTML = ` ${days[i]} ${i + 1} `; header.dataset.dayIndex = i.toString(); // Check if today (this will be updated by NavigationManager later) if (i === 1) { // Mock today as Monday for now header.setAttribute('data-today', 'true'); } weekHeader.appendChild(header); } } private renderDayColumns(): void { const dayColumns = document.querySelector('swp-day-columns'); if (!dayColumns) return; dayColumns.innerHTML = ''; for (let i = 0; i < 7; i++) { const column = document.createElement('swp-day-column'); column.dataset.dayIndex = i.toString(); const eventsLayer = document.createElement('swp-events-layer'); column.appendChild(eventsLayer); dayColumns.appendChild(column); } } private updateViewButtons(): void { const viewButtons = document.querySelectorAll('swp-view-button[data-view]'); viewButtons.forEach(button => { const buttonView = button.getAttribute('data-view') as CalendarView; if (buttonView === this.currentView) { button.setAttribute('data-active', 'true'); } else { button.removeAttribute('data-active'); } }); } private refreshCurrentView(): void { this.renderWeekHeaders(); this.renderDayColumns(); this.eventBus.emit(EventTypes.VIEW_RENDERED, { view: this.currentView }); } private isValidView(view: string): view is CalendarView { return ['day', 'week', 'month'].includes(view); } public getCurrentView(): CalendarView { return this.currentView; } public refresh(): void { this.refreshCurrentView(); } public destroy(): void { // Event listeners bliver automatisk fjernet af EventBus } }