import { Component, inject, OnInit, ViewChild, TemplateRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { OedbApi } from '../../services/oedb-api'; import { EditForm } from '../../forms/edit-form/edit-form'; import { CalendarModule, CalendarView, CalendarEvent } from 'angular-calendar'; import { CalendarEventAction, CalendarEventTimesChangedEvent } from 'angular-calendar'; import oedb from '../../../oedb-types'; interface OedbEvent { id: string; properties: { label?: string; name?: string; what?: string; start?: string; when?: string; stop?: string; description?: string; where?: string; }; geometry?: { type: string; coordinates: [number, number]; }; } interface DayEvents { date: Date; events: OedbEvent[]; } @Component({ selector: 'app-agenda', standalone: true, imports: [CommonModule, EditForm, CalendarModule], templateUrl: './agenda.html', styleUrl: './agenda.scss' }) export class Agenda implements OnInit { private oedbApi = inject(OedbApi); @ViewChild('eventTitleTemplate', { static: true }) eventTitleTemplate!: TemplateRef; events: OedbEvent[] = []; calendarEvents: CalendarEvent[] = []; selectedEvent: OedbEvent | null = null; showSidePanel = false; view: CalendarView = CalendarView.Month; viewDate: Date = new Date(); oedbPresets = oedb.presets.what; // Exposer CalendarView pour l'utiliser dans le template CalendarView = CalendarView; ngOnInit() { this.loadEvents(); } loadEvents() { const today = new Date(); const startDate = new Date(today); startDate.setDate(today.getDate() - 10); const endDate = new Date(today); endDate.setDate(today.getDate() + 10); const params = { start: `${startDate.toISOString().split('T')[0]}`, end: `${endDate.toISOString().split('T')[0]}`, limit: 1000 }; this.oedbApi.getEvents(params).subscribe((response: any) => { this.events = Array.isArray(response?.features) ? response.features : []; this.organizeEventsByDay(); }); } organizeEventsByDay() { this.calendarEvents = this.events.map(event => { const eventDate = this.getEventDate(event); const preset = this.getEventPreset(event); return { id: event.id, title: this.getEventTitle(event), start: eventDate || new Date(), color: this.getEventColor(preset), meta: { event: event, preset: preset } }; }); } getEventDate(event: OedbEvent): Date | null { const startDate = event.properties.start || event.properties.when; if (startDate) { return new Date(startDate); } return null; } getEventTitle(event: OedbEvent): string { return event.properties.label || event.properties.name || 'Événement sans titre'; } getEventTime(event: OedbEvent): string { const startDate = event.properties.start || event.properties.when; if (startDate) { const date = new Date(startDate); return date.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }); } return ''; } selectEvent(event: OedbEvent) { this.selectedEvent = event; this.showSidePanel = true; } onEventClicked({ event }: { event: CalendarEvent; sourceEvent: MouseEvent | KeyboardEvent }) { if (event.meta && event.meta.event) { this.selectEvent(event.meta.event); } } getEventPreset(event: OedbEvent): any { const what = event.properties.what; if (what && (this.oedbPresets as any)[what]) { return (this.oedbPresets as any)[what]; } return null; } getEventIcon(preset: any): string { if (preset) { return preset.emoji || '📅'; } return '📅'; } getEventColor(preset: any): any { if (preset) { // Couleurs basées sur la catégorie const categoryColors: { [key: string]: any } = { 'Communauté': { primary: '#007bff', secondary: '#cce7ff' }, 'Culture': { primary: '#28a745', secondary: '#d4edda' }, 'Musique': { primary: '#ffc107', secondary: '#fff3cd' }, 'Énergie': { primary: '#dc3545', secondary: '#f8d7da' }, 'Commerce': { primary: '#6f42c1', secondary: '#e2d9f3' }, 'Temps': { primary: '#17a2b8', secondary: '#d1ecf1' }, 'Tourisme': { primary: '#fd7e14', secondary: '#ffeaa7' }, 'Circulation': { primary: '#6c757d', secondary: '#e9ecef' }, 'Randonnée': { primary: '#20c997', secondary: '#d1f2eb' }, 'Vie sauvage': { primary: '#795548', secondary: '#efebe9' }, 'Météo': { primary: '#2196f3', secondary: '#e3f2fd' } }; const category = preset.category || 'Communauté'; return categoryColors[category] || { primary: '#6c757d', secondary: '#e9ecef' }; } return { primary: '#6c757d', secondary: '#e9ecef' }; } closeSidePanel() { this.showSidePanel = false; this.selectedEvent = null; } onEventSaved(event: any) { this.loadEvents(); // Recharger les événements après modification this.closeSidePanel(); } onEventCreated(event: any) { this.loadEvents(); // Recharger les événements après création this.closeSidePanel(); } onEventDeleted(event: any) { this.loadEvents(); // Recharger les événements après suppression this.closeSidePanel(); } setView(view: CalendarView) { this.view = view; } dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void { console.log('Day clicked:', date, events); } eventTimesChanged({ event, newStart, newEnd, }: CalendarEventTimesChangedEvent): void { console.log('Event times changed:', event, newStart, newEnd); } }