import { EventBus } from '../core/EventBus'; import { IEventBus, CalendarEvent } from '../types/CalendarTypes'; import { EventTypes } from '../constants/EventTypes'; /** * EventManager - Administrerer event lifecycle og CRUD operationer * Håndterer mock data og event synchronization */ export class EventManager { private eventBus: IEventBus; private events: CalendarEvent[] = []; constructor(eventBus: IEventBus) { this.eventBus = eventBus; this.setupEventListeners(); this.loadMockData(); } private setupEventListeners(): void { this.eventBus.on(EventTypes.CALENDAR_INITIALIZED, () => { this.syncEvents(); }); this.eventBus.on(EventTypes.DATE_CHANGED, () => { this.syncEvents(); }); this.eventBus.on(EventTypes.VIEW_RENDERED, () => { this.syncEvents(); }); } private loadMockData(): void { // Mock events for current week (July 27 - August 2, 2025) this.events = [ // Sunday August 3, 2025 { id: '1', title: 'Weekend Planning', start: '2025-08-03T10:00:00', end: '2025-08-03T11:00:00', type: 'work', allDay: false, syncStatus: 'synced', metadata: { duration: 60, color: '#9c27b0' } // Purple }, // Monday August 4, 2025 { id: '2', title: 'Team Standup', start: '2025-08-04T09:00:00', end: '2025-08-04T09:30:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 30, color: '#ff5722' } // Deep Orange }, { id: '3', title: 'Project Kickoff', start: '2025-08-04T14:00:00', end: '2025-08-04T15:30:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 90, color: '#e91e63' } // Pink }, // Tuesday August 5, 2025 { id: '4', title: 'Deep Work Session', start: '2025-08-05T10:00:00', end: '2025-08-05T12:00:00', type: 'work', allDay: false, syncStatus: 'synced', metadata: { duration: 120, color: '#3f51b5' } // Indigo }, { id: '5', title: 'Lunch Meeting', start: '2025-08-05T12:30:00', end: '2025-08-05T13:30:00', type: 'meal', allDay: false, syncStatus: 'synced', metadata: { duration: 60, color: '#ff9800' } // Orange }, // Wednesday August 6, 2025 { id: '6', title: 'Client Review', start: '2025-08-06T15:00:00', end: '2025-08-06T16:00:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 60, color: '#795548' } // Brown }, // Thursday August 7, 2025 { id: '7', title: 'Sprint Planning', start: '2025-08-07T09:00:00', end: '2025-08-07T10:30:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 90, color: '#607d8b' } // Blue Grey }, { id: '8', title: 'Code Review', start: '2025-08-07T14:00:00', end: '2025-08-07T15:00:00', type: 'work', allDay: false, syncStatus: 'synced', metadata: { duration: 60, color: '#009688' } // Teal }, // Friday August 8, 2025 { id: '9', title: 'Team Standup', start: '2025-08-08T09:00:00', end: '2025-08-08T09:30:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 30, color: '#8bc34a' } // Light Green }, { id: '10', title: 'Client Meeting', start: '2025-08-08T14:00:00', end: '2025-08-08T15:30:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 90, color: '#cddc39' } // Lime }, // Saturday August 9, 2025 { id: '11', title: 'Weekend Project', start: '2025-08-09T10:00:00', end: '2025-08-09T12:00:00', type: 'work', allDay: false, syncStatus: 'synced', metadata: { duration: 120, color: '#f44336' } // Red }, // Test events for early/late hours { id: '12', title: 'Early Morning Workout', start: '2025-08-05T06:00:00', end: '2025-08-05T07:00:00', type: 'work', allDay: false, syncStatus: 'synced', metadata: { duration: 60, color: '#00bcd4' } // Cyan }, { id: '13', title: 'Late Evening Call', start: '2025-08-06T21:00:00', end: '2025-08-06T22:00:00', type: 'meeting', allDay: false, syncStatus: 'synced', metadata: { duration: 60, color: '#673ab7' } // Deep Purple }, { id: '14', title: 'Midnight Deployment', start: '2025-08-07T23:00:00', end: '2025-08-08T01:00:00', type: 'work', allDay: false, syncStatus: 'synced', metadata: { duration: 120, color: '#ffc107' } // Amber }, // All-day events for demo { id: '15', title: 'Company Holiday', start: '2025-08-04T00:00:00', end: '2025-08-05T23:59:59', type: 'milestone', allDay: true, syncStatus: 'synced', metadata: { duration: 1440, // Full day in minutes color: '#4caf50' // Green color } }, { id: '16', title: 'Team Building Event', start: '2025-08-06T00:00:00', end: '2025-08-06T23:59:59', type: 'meeting', allDay: true, syncStatus: 'synced', metadata: { duration: 1440, // Full day in minutes color: '#2196f3' // Blue color } } ]; console.log(`EventManager: Loaded ${this.events.length} mock events`); console.log('EventManager: First event:', this.events[0]); console.log('EventManager: Last event:', this.events[this.events.length - 1]); } private syncEvents(): void { // Emit events for rendering this.eventBus.emit(EventTypes.EVENTS_LOADED, { events: this.events }); console.log(`EventManager: Synced ${this.events.length} events`); } public getEvents(): CalendarEvent[] { return [...this.events]; } public getEventById(id: string): CalendarEvent | undefined { return this.events.find(event => event.id === id); } public addEvent(event: Omit): CalendarEvent { const newEvent: CalendarEvent = { ...event, id: Date.now().toString() }; this.events.push(newEvent); this.syncEvents(); this.eventBus.emit(EventTypes.EVENT_CREATED, { event: newEvent }); return newEvent; } public updateEvent(id: string, updates: Partial): CalendarEvent | null { const eventIndex = this.events.findIndex(event => event.id === id); if (eventIndex === -1) return null; const updatedEvent = { ...this.events[eventIndex], ...updates }; this.events[eventIndex] = updatedEvent; this.syncEvents(); this.eventBus.emit(EventTypes.EVENT_UPDATED, { event: updatedEvent }); return updatedEvent; } public deleteEvent(id: string): boolean { const eventIndex = this.events.findIndex(event => event.id === id); if (eventIndex === -1) return false; const deletedEvent = this.events[eventIndex]; this.events.splice(eventIndex, 1); this.syncEvents(); this.eventBus.emit(EventTypes.EVENT_DELETED, { event: deletedEvent }); return true; } public refresh(): void { this.syncEvents(); } public destroy(): void { this.events = []; } }