style marqueurs events, page nouvelles catégories
This commit is contained in:
parent
20a8445a5f
commit
9fb9986a2c
15 changed files with 987 additions and 203 deletions
|
@ -1,9 +1,12 @@
|
|||
import { Component, inject, OnInit } from '@angular/core';
|
||||
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 Event {
|
||||
interface OedbEvent {
|
||||
id: string;
|
||||
properties: {
|
||||
label?: string;
|
||||
|
@ -23,23 +26,31 @@ interface Event {
|
|||
|
||||
interface DayEvents {
|
||||
date: Date;
|
||||
events: Event[];
|
||||
events: OedbEvent[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-agenda',
|
||||
standalone: true,
|
||||
imports: [CommonModule, EditForm],
|
||||
imports: [CommonModule, EditForm, CalendarModule],
|
||||
templateUrl: './agenda.html',
|
||||
styleUrl: './agenda.scss'
|
||||
})
|
||||
export class Agenda implements OnInit {
|
||||
private oedbApi = inject(OedbApi);
|
||||
|
||||
events: Event[] = [];
|
||||
daysWithEvents: DayEvents[] = [];
|
||||
selectedEvent: Event | null = null;
|
||||
@ViewChild('eventTitleTemplate', { static: true }) eventTitleTemplate!: TemplateRef<any>;
|
||||
|
||||
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();
|
||||
|
@ -66,37 +77,24 @@ export class Agenda implements OnInit {
|
|||
}
|
||||
|
||||
organizeEventsByDay() {
|
||||
const daysMap = new Map<string, DayEvents>();
|
||||
|
||||
// Initialiser les 20 jours
|
||||
for (let i = -10; i <= 10; i++) {
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() + i);
|
||||
const dateKey = date.toISOString().split('T')[0];
|
||||
daysMap.set(dateKey, {
|
||||
date: new Date(date),
|
||||
events: []
|
||||
});
|
||||
}
|
||||
|
||||
// Organiser les événements par jour
|
||||
this.events.forEach(event => {
|
||||
this.calendarEvents = this.events.map(event => {
|
||||
const eventDate = this.getEventDate(event);
|
||||
if (eventDate) {
|
||||
const dateKey = eventDate.toISOString().split('T')[0];
|
||||
const dayEvents = daysMap.get(dateKey);
|
||||
if (dayEvents) {
|
||||
dayEvents.events.push(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
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
this.daysWithEvents = Array.from(daysMap.values()).sort((a, b) =>
|
||||
a.date.getTime() - b.date.getTime()
|
||||
);
|
||||
}
|
||||
|
||||
getEventDate(event: Event): Date | null {
|
||||
getEventDate(event: OedbEvent): Date | null {
|
||||
const startDate = event.properties.start || event.properties.when;
|
||||
if (startDate) {
|
||||
return new Date(startDate);
|
||||
|
@ -104,11 +102,11 @@ export class Agenda implements OnInit {
|
|||
return null;
|
||||
}
|
||||
|
||||
getEventTitle(event: Event): string {
|
||||
getEventTitle(event: OedbEvent): string {
|
||||
return event.properties.label || event.properties.name || 'Événement sans titre';
|
||||
}
|
||||
|
||||
getEventTime(event: Event): string {
|
||||
getEventTime(event: OedbEvent): string {
|
||||
const startDate = event.properties.start || event.properties.when;
|
||||
if (startDate) {
|
||||
const date = new Date(startDate);
|
||||
|
@ -120,11 +118,55 @@ export class Agenda implements OnInit {
|
|||
return '';
|
||||
}
|
||||
|
||||
selectEvent(event: Event) {
|
||||
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;
|
||||
|
@ -145,22 +187,19 @@ export class Agenda implements OnInit {
|
|||
this.closeSidePanel();
|
||||
}
|
||||
|
||||
isToday(date: Date): boolean {
|
||||
const today = new Date();
|
||||
return date.toDateString() === today.toDateString();
|
||||
setView(view: CalendarView) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
isPast(date: Date): boolean {
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return date < today;
|
||||
dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void {
|
||||
console.log('Day clicked:', date, events);
|
||||
}
|
||||
|
||||
formatDate(date: Date): string {
|
||||
return date.toLocaleDateString('fr-FR', {
|
||||
weekday: 'long',
|
||||
day: 'numeric',
|
||||
month: 'long'
|
||||
});
|
||||
eventTimesChanged({
|
||||
event,
|
||||
newStart,
|
||||
newEnd,
|
||||
}: CalendarEventTimesChangedEvent): void {
|
||||
console.log('Event times changed:', event, newStart, newEnd);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue