import { AfterViewInit, Component, effect, ElementRef, inject, OnInit, signal, ViewChild } from '@angular/core'; import { FullCalendarComponent, FullCalendarModule } from '@fullcalendar/angular'; import { CalendarOptions, EventInput } from '@fullcalendar/core'; import dayGridPlugin from '@fullcalendar/daygrid'; import timeGridPlugin from '@fullcalendar/timegrid'; import listPlugin from '@fullcalendar/list'; import interactionPlugin from '@fullcalendar/interaction'; import { Modal } from '@rschneider/ng-daisyui'; import { CreateEventForm } from '../create-event-form/create-event-form'; import { CalendarService } from '../../services/calendar.service'; import { addDays, subDays } from 'date-fns'; import { EventsInRangeDTO } from '../../models/events-in-range-dto.model'; import { map } from 'rxjs'; @Component({ selector: 'app-calendar-view', imports: [FullCalendarModule, Modal, CreateEventForm], templateUrl: './calendar-view.html', styleUrl: './calendar-view.css', }) export class CalendarView implements OnInit, AfterViewInit { @ViewChild('startHour') startHour!: ElementRef; @ViewChild('calendar') calendarComponent: FullCalendarComponent | undefined; calendarService = inject(CalendarService); workflow = signal(''); isOpen = signal(false); selectedDate = signal(undefined); selectedEventId = signal(undefined) events = signal([]); calendarOptions: CalendarOptions; constructor() { const start = new Date(); start.setHours(10, 0, 0); const end = new Date(); end.setHours(11, 0, 0); this.calendarOptions = { plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin], initialView: 'dayGridMonth', weekends: true, headerToolbar: { left: 'prev,next,today', center: 'title', // right: 'dayGridMonth,dayGridWeek,dayGridDay' // user can switch between the two right: 'dayGridMonth,dayGridWeek,dayGridDay,timeGridWeek,timeGridDay,listWeek', }, events: this.fetchEvents.bind(this), // Bind the context eventClick: function(info) { console.info('Event info: ', info); // change the border color just for fun info.el.style.borderColor = 'red'; }, dateClick: (info) => { console.info('setting day ',info); this.workflow.set('day'); this.selectedDate.set(info.date); this.selectedEventId.set(undefined); console.info("date click with", this.selectedDate()) this.isOpen.set(true); // console.info('Date click on: ' , info); // const calendarApi = info.view.calendar; // const start = new Date(info.date.getTime()) // start.setHours(2,0,0) // const end = new Date(info.date.getTime()) // end.setHours(3,0,0) // calendarApi.addEvent({ // title: 'New Event', // start, // end, // }); }, }; effect(() => { // this.calendarOptions.events = this.events }); } fetchEvents(fetchInfo: any, successCallback: (events: EventInput[]) => void, failureCallback: (error: any) => void): void { console.info('fetching events', fetchInfo); const start = fetchInfo.start; const end = fetchInfo.end; // if ( fetchInfo ){ // console.info("fetchinfo", fetchInfo); // successCallback([]); // return; // } this.calendarService.getEventsInRange({ startTime: start, endTime: end, }) .pipe( map(value => { console.info("vent got" , value ); const events: EventInput[] = value.map( (model) => { const calendarEvent: EventInput = { start: new Date(model.startTime), // end: model.end_time, title: model.title }; if ( model.eventType){ calendarEvent.borderColor = model.eventType.color; } // calendarEvent.backgroundColor = "#00ff00" return calendarEvent; }) return events; }), ) .subscribe({ next: (events) => { console.info("calendar events", events); successCallback(events); } , error: (error) => { console.error('Error fetching events', error); failureCallback(error); }, }, ); } ngAfterViewInit(): void { } ngOnInit(): void { } protected addEvent($event: PointerEvent) { let hourStr = this.startHour.nativeElement.value; const hour = parseInt(hourStr, 10); const date = new Date(); const start = new Date(date.getTime()); start.setHours(hour, 0, 0); const end = new Date(date.getTime()); // end.setHours(3,0,0) this.calendarComponent?.getApi().addEvent({ title: 'Event at ' + hour, start, }); } closeDialog() { this.isOpen.set(false); } }