diff --git a/admin/src/app/components/detail-view/detail-view.css b/admin/src/app/components/detail-view/detail-view.css
new file mode 100644
index 0000000..e69de29
diff --git a/admin/src/app/components/detail-view/detail-view.html b/admin/src/app/components/detail-view/detail-view.html
new file mode 100644
index 0000000..586fe53
--- /dev/null
+++ b/admin/src/app/components/detail-view/detail-view.html
@@ -0,0 +1,28 @@
+{{config().data}}
+@if (config().data){
+
+
+
+ @for (row of config().rows; track row.attribute) {
+
+ |
+ @if (row.titleComponent) {
+
+ } @else {
+ {{ getTitle(row, config().data) }}
+ }
+ |
+
+ @if (row.component) {
+
+ } @else {
+ {{ getFormattedValue(row, config().data) }}
+ }
+ |
+
+ }
+
+
+
+
+}
diff --git a/admin/src/app/components/detail-view/detail-view.spec.ts b/admin/src/app/components/detail-view/detail-view.spec.ts
new file mode 100644
index 0000000..bd5e1bc
--- /dev/null
+++ b/admin/src/app/components/detail-view/detail-view.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DetailView } from './detail-view';
+
+describe('DetailView', () => {
+ let component: DetailView;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [DetailView]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(DetailView);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/admin/src/app/components/detail-view/detail-view.ts b/admin/src/app/components/detail-view/detail-view.ts
new file mode 100644
index 0000000..7c45859
--- /dev/null
+++ b/admin/src/app/components/detail-view/detail-view.ts
@@ -0,0 +1,70 @@
+import { Component, input, Type } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+export interface CellComponent {
+ component?: Type;
+ componentInputs?: (obj: T) => { [key: string]: any };
+}
+
+export interface DetailViewRow extends CellComponent {
+ attribute: keyof T;
+ getValue?: (obj: T) => any;
+ format?: 'date' | 'datetime' | 'number' | 'raw' | ((value: any) => string);
+ getTitle?: string | ((obj: T) => string);
+ getDetailClass?: (obj: T) => string;
+ getTitleStyleClass?: (obj: T) => string;
+ getValueStyleClass?: (obj: T) => string;
+ titleComponent?: Type;
+ titleComponentInputs?: (obj: T) => { [key: string]: any };
+}
+
+export interface DetailViewConfig {
+ data: T;
+ rows: DetailViewRow[];
+ styleClass?: string;
+}
+
+@Component({
+ selector: 'app-detail-view',
+ imports: [CommonModule],
+ templateUrl: './detail-view.html',
+ styleUrl: './detail-view.css',
+})
+export class DetailView {
+ config = input.required>();
+
+ getFormattedValue(row: DetailViewRow, data: T): string {
+ const value = row.getValue ? row.getValue(data) : data[row.attribute];
+
+ if (row.component) {
+ return '';
+ }
+
+ if (typeof row.format === 'function') {
+ return row.format(value);
+ }
+
+ switch (row.format) {
+ case 'date':
+ return new Date(value).toLocaleDateString();
+ case 'datetime':
+ return new Date(value).toLocaleString();
+ case 'number':
+ return Number(value).toString();
+ case 'raw':
+ default:
+ return value;
+ }
+ }
+
+ getTitle(row: DetailViewRow, data: T): string {
+ if (row.titleComponent) {
+ return '';
+ }
+
+ if (typeof row.getTitle === 'function') {
+ return row.getTitle(data);
+ }
+ return row.getTitle || String(row.attribute);
+ }
+}
diff --git a/admin/src/app/features/calendar/components/calendar-view/calendar-view.html b/admin/src/app/features/calendar/components/calendar-view/calendar-view.html
index 81b9330..3daf11d 100644
--- a/admin/src/app/features/calendar/components/calendar-view/calendar-view.html
+++ b/admin/src/app/features/calendar/components/calendar-view/calendar-view.html
@@ -6,11 +6,18 @@
-
-
- @if (isOpen()){
-
+{{"workflow:"+workflow()}}
+
+ @if (workflow() == 'create') {
+
}
-
+
+
+@if (workflow() == 'event-dashboard' && selectedEvent()) {
+
+
+
+}
diff --git a/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts b/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts
index 8f5fc24..907590f 100644
--- a/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts
+++ b/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts
@@ -9,13 +9,13 @@ 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 { CalendarEventDto, EventsInRangeDTO } from '../../models/events-in-range-dto.model';
import { map } from 'rxjs';
+import { SingleEventDashboard } from './single-event-dashboard/single-event-dashboard';
@Component({
selector: 'app-calendar-view',
- imports: [FullCalendarModule, Modal, CreateEventForm],
+ imports: [FullCalendarModule, Modal, CreateEventForm, SingleEventDashboard],
templateUrl: './calendar-view.html',
styleUrl: './calendar-view.css',
})
@@ -27,67 +27,40 @@ export class CalendarView implements OnInit, AfterViewInit {
calendarService = inject(CalendarService);
workflow = signal('');
- isOpen = signal(false);
selectedDate = signal(undefined);
- selectedEventId = signal(undefined)
-
- events = signal([]);
+ selectedEvent = signal(undefined)
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,
+ firstDay: 1,
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';
+ eventClick: (info) => {
+ this.selectedEvent.set(info.event.extendedProps['event']);
+ this.workflow.set('event-dashboard');
},
dateClick: (info) => {
- console.info('setting day ',info);
- this.workflow.set('day');
+ console.info('create new evet for day ',info);
+ this.workflow.set('create');
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,
- // });
+ this.selectedEvent.set(undefined);
},
};
- effect(() => {
- // this.calendarOptions.events = this.events
-
- });
}
fetchEvents(fetchInfo: any, successCallback: (events: EventInput[]) => void, failureCallback: (error: any) => void): void {
@@ -111,7 +84,10 @@ export class CalendarView implements OnInit, AfterViewInit {
const calendarEvent: EventInput = {
start: new Date(model.startTime),
// end: model.end_time,
- title: model.title
+ title: model.title,
+ extendedProps: {
+ event: value
+ }
};
if ( model.eventType){
calendarEvent.borderColor = model.eventType.color;
@@ -160,6 +136,6 @@ export class CalendarView implements OnInit, AfterViewInit {
}
closeDialog() {
- this.isOpen.set(false);
+ this.workflow.set('');
}
}
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.css b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.css
new file mode 100644
index 0000000..e69de29
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html
new file mode 100644
index 0000000..fce4be3
--- /dev/null
+++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html
@@ -0,0 +1,3 @@
+
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts
new file mode 100644
index 0000000..5f3b128
--- /dev/null
+++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts
@@ -0,0 +1,28 @@
+import { Component, input, signal } from '@angular/core';
+import { CalendarEventDto, EventsInRangeDTO } from '../../../models/events-in-range-dto.model';
+import { DetailView, DetailViewConfig } from '../../../../../components/detail-view/detail-view';
+
+@Component({
+ selector: 'app-single-event-dashboard',
+ imports: [
+ DetailView,
+ ],
+ templateUrl: './single-event-dashboard.html',
+ styleUrl: './single-event-dashboard.css',
+})
+export class SingleEventDashboard {
+
+ event = input();
+
+ config: DetailViewConfig;
+ constructor() {
+ this.config = {
+ data: this.event()!,
+
+ rows: [{
+ attribute: 'title',
+ getTitle: 'title',
+ }]
+ }
+ }
+}