فهرست منبع

Event registrations client integration

Lukas Angerer 2 سال پیش
والد
کامیت
fec8f973df

+ 6 - 4
src/RunnersMeet.Client/src/app/app.module.ts

@@ -33,9 +33,10 @@ import { TrackPickerComponent } from './tracks/track-picker/track-picker.compone
 import { TrackPickerDialogComponent } from './tracks/track-picker-dialog/track-picker-dialog.component';
 import { TrackPickerDialogComponent } from './tracks/track-picker-dialog/track-picker-dialog.component';
 import { EventViewComponent } from './events/event-view/event-view.component';
 import { EventViewComponent } from './events/event-view/event-view.component';
 import { ViewEventPageComponent } from './pages/view-event-page/view-event-page.component';
 import { ViewEventPageComponent } from './pages/view-event-page/view-event-page.component';
-import { UiLibraryModule } from './ui-library.module';
-import { DistancePipe } from './tracks/distance.pipe';
+import { UiLibraryModule } from './ui-library.module';
+import { DistancePipe } from './tracks/distance.pipe';
 import { ElevationPipe } from './tracks/elevation.pipe';
 import { ElevationPipe } from './tracks/elevation.pipe';
+import { RegistrationStatePipe } from './events/registration-state.pipe';
 
 
 @NgModule({
 @NgModule({
 	declarations: [
 	declarations: [
@@ -57,8 +58,9 @@ import { ElevationPipe } from './tracks/elevation.pipe';
 		TrackPickerDialogComponent,
 		TrackPickerDialogComponent,
 		EventViewComponent,
 		EventViewComponent,
 		ViewEventPageComponent,
 		ViewEventPageComponent,
-  DistancePipe,
-  ElevationPipe,
+		DistancePipe,
+		ElevationPipe,
+		RegistrationStatePipe,
 	],
 	],
 	imports: [
 	imports: [
 		BrowserModule,
 		BrowserModule,

+ 12 - 0
src/RunnersMeet.Client/src/app/events-api.service.ts

@@ -5,6 +5,8 @@ import { ConfigService } from './config.service';
 import { EventSearchParams } from './events/event-search-params';
 import { EventSearchParams } from './events/event-search-params';
 import { GroupEvent } from './events/group-event';
 import { GroupEvent } from './events/group-event';
 import { ResultPage } from './result-page';
 import { ResultPage } from './result-page';
+import { Registration } from './events/registration';
+import { RegistrationState } from './events/registration-state';
 
 
 @Injectable({
 @Injectable({
 	providedIn: 'root'
 	providedIn: 'root'
@@ -39,4 +41,14 @@ export class EventsApiService {
 	public deleteEvent(event: GroupEvent): Promise<void> {
 	public deleteEvent(event: GroupEvent): Promise<void> {
 		return lastValueFrom(this.http.delete(this.config.apiUri(`/api/events/${event.eventId}`))).then();
 		return lastValueFrom(this.http.delete(this.config.apiUri(`/api/events/${event.eventId}`))).then();
 	}
 	}
+
+	public register(event: GroupEvent, state: RegistrationState): Promise<Registration> {
+		return lastValueFrom(this.http.put<Registration>(this.config.apiUri(`/api/events/${event.eventId}/register`), state))
+			.then(registration => Registration.deserialize(registration));
+	}
+
+	public getRegistrations(eventId: string): Promise<Array<Registration>> {
+		return lastValueFrom(this.http.get<Array<Registration>>(this.config.apiUri(`/api/events/${eventId}/registrations`)))
+			.then(registrations => registrations.map(r => Registration.deserialize(r)));
+	}
 }
 }

+ 8 - 0
src/RunnersMeet.Client/src/app/events/event-view/event-view.component.html

@@ -7,3 +7,11 @@
 	<dt>Description</dt>
 	<dt>Description</dt>
 	<dd>{{ event?.description }}</dd>
 	<dd>{{ event?.description }}</dd>
 </dl>
 </dl>
+
+<h1>Registrations</h1>
+<h3>Your registration</h3>
+<p-selectButton [options]="registrationStates" [(ngModel)]="currentState" (onChange)="updateRegistration($event)" optionLabel="label" optionValue="value"></p-selectButton>
+<h3>Other registrations</h3>
+<ul>
+	<li *ngFor="let registration of registrations">{{ registration.owner?.displayName }}: {{ registration.status | stateDisplay }}</li>
+</ul>

+ 25 - 0
src/RunnersMeet.Client/src/app/events/event-view/event-view.component.ts

@@ -1,6 +1,10 @@
 import { Component, Input } from '@angular/core';
 import { Component, Input } from '@angular/core';
 import { EventsApiService } from 'src/app/events-api.service';
 import { EventsApiService } from 'src/app/events-api.service';
 import { GroupEvent } from '../group-event';
 import { GroupEvent } from '../group-event';
+import { RegistrationState, RegistrationStateItems } from '../registration-state';
+import { Registration } from '../registration';
+import { AuthService } from '@auth0/auth0-angular';
+import { combineLatest, take } from 'rxjs';
 
 
 @Component({
 @Component({
 	selector: 'app-event-view',
 	selector: 'app-event-view',
@@ -12,8 +16,14 @@ export class EventViewComponent {
 	public eventId: string = '';
 	public eventId: string = '';
 
 
 	public event: GroupEvent | null = null;
 	public event: GroupEvent | null = null;
+	public registrations: Array<Registration> = [];
+
+	public registrationStates = RegistrationStateItems;
+
+	public currentState = RegistrationState.Unknown;
 
 
 	public constructor(
 	public constructor(
+		private readonly authService: AuthService,
 		private readonly eventsApi: EventsApiService
 		private readonly eventsApi: EventsApiService
 	) { }
 	) { }
 
 
@@ -21,5 +31,20 @@ export class EventViewComponent {
 		this.eventsApi.getEvent(this.eventId).then(event => {
 		this.eventsApi.getEvent(this.eventId).then(event => {
 			this.event = event;
 			this.event = event;
 		});
 		});
+		combineLatest([this.authService.user$, this.eventsApi.getRegistrations(this.eventId)])
+			.pipe(take(1))
+			.subscribe(([user, registrations]) => {
+				const currentRegistrationIndex = registrations.findIndex(r => r.owner?.userId === user?.sub);
+
+				this.currentState = (currentRegistrationIndex >= 0 ? registrations.splice(currentRegistrationIndex, 1)[0] : null)?.status ?? RegistrationState.Unknown;
+				this.registrations = registrations;
+			});
+	}
+
+	public updateRegistration(evt: any): void {
+		if (this.event) {
+			console.log(evt, this.currentState);
+			this.eventsApi.register(this.event, this.currentState);
+		}
 	}
 	}
 }
 }

+ 11 - 0
src/RunnersMeet.Client/src/app/events/registration-state.pipe.ts

@@ -0,0 +1,11 @@
+import { Pipe, PipeTransform } from '@angular/core';
+import { RegistrationState, RegistrationStateItems } from './registration-state';
+
+@Pipe({
+  name: 'stateDisplay'
+})
+export class RegistrationStatePipe implements PipeTransform {
+  transform(value: RegistrationState | undefined): string {
+    return RegistrationStateItems.find(item => item.value === value)?.label ?? '';
+  }
+}

+ 26 - 0
src/RunnersMeet.Client/src/app/events/registration-state.ts

@@ -0,0 +1,26 @@
+
+export enum RegistrationState {
+	Unknown = 0,
+	Yes = 1,
+	No = 2,
+	Maybe = 3,
+};
+
+export const RegistrationStateItems = [
+	{
+		label: 'Unknown',
+		value: RegistrationState.Unknown
+	},
+	{
+		label: 'Yes',
+		value: RegistrationState.Yes
+	},
+	{
+		label: 'No',
+		value: RegistrationState.No
+	},
+	{
+		label: 'Maybe',
+		value: RegistrationState.Maybe
+	},
+];

+ 15 - 0
src/RunnersMeet.Client/src/app/events/registration.ts

@@ -0,0 +1,15 @@
+import { UserProfile } from "../users/user-profile";
+import { GroupEvent } from "./group-event";
+import { RegistrationState } from "./registration-state";
+
+export class Registration {
+	public owner?: UserProfile;
+	public event?: GroupEvent;
+	public status = RegistrationState.Unknown;
+
+	public static deserialize(data: Readonly<Registration>): Registration {
+		const obj = new Registration();
+		Object.assign(obj, data);
+		return obj;
+	}
+}

+ 2 - 0
src/RunnersMeet.Client/src/app/ui-library.module.ts

@@ -7,6 +7,7 @@ import { CalendarModule } from 'primeng/calendar';
 import { DynamicDialogModule } from 'primeng/dynamicdialog';
 import { DynamicDialogModule } from 'primeng/dynamicdialog';
 import { TableModule } from 'primeng/table';
 import { TableModule } from 'primeng/table';
 import { PanelModule } from 'primeng/panel';
 import { PanelModule } from 'primeng/panel';
+import { SelectButtonModule } from 'primeng/selectbutton';
 import { NgModule, Type } from '@angular/core';
 import { NgModule, Type } from '@angular/core';
 
 
 const primeNgModules: Array<Type<any>> = [
 const primeNgModules: Array<Type<any>> = [
@@ -19,6 +20,7 @@ const primeNgModules: Array<Type<any>> = [
 	DynamicDialogModule,
 	DynamicDialogModule,
 	TableModule,
 	TableModule,
 	PanelModule,
 	PanelModule,
+	SelectButtonModule,
 ];
 ];
 
 
 @NgModule({
 @NgModule({