improve customer timetable

This commit is contained in:
Roland Schneider
2021-09-19 21:01:07 +02:00
parent fe2f0766e3
commit 678b005c1c
24 changed files with 314 additions and 246 deletions

View File

@@ -1,6 +1,6 @@
import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { Observable, throwError } from "rxjs";
import {EMPTY, Observable, throwError} from "rxjs";
import { catchError } from "rxjs/operators";
import { AuthenticationService} from "../services/authentication.service";
import {NavigationService} from "../services/navigation.service";
@@ -26,10 +26,11 @@ All other errors are RE-THROWN to be caught by the calling service so an alert c
this.authenticationService.logout();
this.navigationService.navigateToLogin();
// location.reload(true);
return EMPTY;
}
const error = err.error.message || err.statusText;
return throwError(error);
// const error = err.error.message || err.statusText;
// return throwError(error);
return throwError(err);
})
)

View File

@@ -83,7 +83,8 @@ export class FakeBackendInterceptor implements HttpInterceptor {
end: this.createEventDate(dayIndex, hourIndex + 1),
trainer: [trainer1, trainer2][id % 2],
eventType: eventTypes[id % eventTypes.length],
reservedAt: reservedAt,
// reservedAt: reservedAt,
registrations: [],
reservationCount: id % 11,
seat_count: 10
}

View File

@@ -9,3 +9,17 @@ export interface PasswordChangeRequest{
passwordOld: string;
password: string;
}
export const RegistrationErrors ={
CARD_NOT_FOUND : 1,
CUSTOMER_NOT_FOUND : 2,
TICKET_NOT_FOUND : 3,
NO_FREE_SEATS : 4,
EVENT_TYPE_NOT_FOUND : 5,
TICKET_INSUFFICIENT : 6,
UNKNOWN_ERROR : 7,
MAX_SEAT_COUNT_EXCEEDED : 8,
EVENT_UNAVAILABLE : 9,
ALREADY_REGISTERED : 10,
}

View File

@@ -1,9 +1,13 @@
<a
<span
(click)="selectEvent()"
class="event d-block p-1 pl-2 pr-2 mb-1 rounded text-truncate small bg-success text-white" title="Test Event 2">
class="event d-block p-1 pl-2 pr-2 mb-1 rounded text-truncate small text-white" title="Test Event 2"
[class.bg-dark]="maySelect()"
[class.bg-primary]="isRegistered()"
[class.bg-secondary]="isDisabled()"
>
{{formatTime()}}:{{event.eventType.name}}
<ng-container *ngIf="hasTrainer()">
<br>
{{formatTrainer()}}
</ng-container>
</a>
</span>

View File

@@ -1,25 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MonthCalendarEventComponent } from './month-calendar-event.component';
describe('MonthCalendarEventComponent', () => {
let component: MonthCalendarEventComponent;
let fixture: ComponentFixture<MonthCalendarEventComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ MonthCalendarEventComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MonthCalendarEventComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -40,4 +40,16 @@ export class MonthCalendarEventComponent implements OnInit {
event: this.event
})
}
maySelect() {
return this.event.registrations?.length == 0 && this.event.hasFreeSeats;
}
isRegistered() {
return this.event.registrations?.length > 0;
}
isDisabled() {
return false;
}
}

View File

@@ -2,8 +2,11 @@
<h1 class="text-center">Naptár</h1>
</header>
<div class="row text-white gx-2 d-none d-md-flex">
<div *ngFor="let dayOfWeek of daysOfWeek" class="col mb-2">
<div class="border bg-primary text-center py-1 px-2">
<div *ngFor="let dayOfWeek of daysOfWeek; let i = index" class="col mb-2">
<div class="border text-center py-1 px-2"
[class.bg-primary]="i % 7 < 6"
[class.bg-dark]="i % 7 == 6"
>
<span class="d-none d-lg-inline text-capitalize">{{dayOfWeek.name}}</span>
<span class="d-none d-md-inline d-lg-none text-capitalize" >{{dayOfWeek.shortName}}</span>
</div>

View File

@@ -1,4 +1,4 @@
<div class="container" *ngIf="event">
<div class="container" *ngIf="event && eventForm">
<h1>Jelentkezés</h1>
<form [formGroup]="eventForm">
<div class="row">
@@ -25,51 +25,15 @@
<div class="col-lg-3 col-sm-12"><span class="title">Terem</span></div>
<div class="col-lg-9 col-sm-12"><span>{{event?.room?.name }}</span></div>
</div>
<h2 *ngIf="event.equipmentTypeAssignments.length > 0">
Szükséges eszközök
</h2>
<ng-container *ngFor="let equipment of event.equipmentTypeAssignments; let i = index; ">
<h3>{{equipment?.equipmentType?.name }}</h3>
<div class="row">
<div class="col-lg-12 col-sm-12">
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="{{'equipment'+equipment.id}}"
formControlName="{{'equipment'+equipment.id}}"
autocomplete="off"
id="equipment_{{equipment.id}}_1"
value="1"
>
<label class="form-check-label" for="equipment_{{equipment.id}}_1">
Szeretném a terem saját eszközét használni
</label>
</div>
<div class="form-check">
<input class="form-check-input"
type="radio"
name="{{'equipment'+equipment.id}}"
formControlName="{{'equipment'+equipment.id}}"
autocomplete="off"
id="equipment_{{equipment.id}}_0"
value="0"
>
<label class="form-check-label" for="equipment_{{equipment.id}}_0">
A saját eszközömet használom
</label>
</div>
</div>
</div>
</ng-container>
<div class="row">
<div class="col-lg-9 col-sm-12 pt-2">
<a *ngIf="mayRegister(event)" class="btn btn-primary " (click)="register(event)">Foglalás</a>
<a *ngIf="mayCancel(event)" class="btn btn-primary" (click)="cancel(event)">Lemondás</a>
<span *ngIf="!mayCancel(event) && noFreeSeat(event)">Már nincs szabad hely</span>
<a *ngIf="mayRegister(event)" class="btn btn-primary me-3" (click)="register(event)">Foglalás</a>
<a *ngIf="mayCancel(event)" class="btn btn-primary me-3" (click)="cancel(event)">Lemondás</a>
<span class="warning me-3" *ngIf="!event.hasFreeSeats && event.registrations.length == 0">Már nincs szabad hely</span>
<a class="btn btn-primary me-3" (click)="goBack(event)">Vissza</a>
</div>
<div class="col-lg-3 text-lg-right col-sm-12 pt-2">
<a class="btn btn-primary " (click)="goBack(event)">Vissza</a>
</div>
</div>
</form>

View File

@@ -1,8 +1,10 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {Event, EventService, RegisterEventRequest} from "../../services/event.service";
import {ActivatedRoute} from "@angular/router";
import {NavigationService} from "../../services/navigation.service";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {ToastrService} from "ngx-toastr";
import {RegistrationErrors} from "../../app.types";
@Component({
selector: 'app-event-details',
@@ -20,39 +22,32 @@ export class EventDetailsComponent implements OnInit {
private fb: FormBuilder,
private eventService: EventService,
private route: ActivatedRoute,
private navigationService: NavigationService
) { }
private navigationService: NavigationService,
private toastr: ToastrService
) {
this.formControls = {
idEvent: ["", [Validators.required]],
}
this.eventForm = this.fb.group(this.formControls);
}
ngOnInit() {
console.info("event details")
this.formControls = {
idEvent: ["", [Validators.required ]],
}
let idEvent = +this.route.snapshot.paramMap.get('idEvent');
this.eventService.findEvent(idEvent).subscribe(
value => {
this.event = value;
this.event.equipmentTypeAssignments.forEach((assignment,index) =>{
this.formControls['equipment'+assignment.id] = ["", [Validators.required ]]
})
this.eventForm = this.fb.group(this.formControls);
this.eventForm.patchValue({"idEvent": this.event.id})
}
);
}
mayRegister(event: Event) {
// return event.reservedAt == null && event.reservationCount < event.seat_count;
return true
return event.hasFreeSeats && event.registrations.length == 0;
}
mayCancel(event: Event) {
return event.reservedAt;
}
noFreeSeat(event: Event) {
return event.reservedAt == null && event.reservationCount >= event.seat_count;
return event.registrations.length > 0;
}
goBack(event: Event) {
@@ -60,33 +55,53 @@ export class EventDetailsComponent implements OnInit {
}
register(event: Event) {
console.info("register", event);
console.info(this.eventForm.value);
let request :RegisterEventRequest= {
let request: RegisterEventRequest = {
idEvent: this.eventForm.value.idEvent,
equipment: []
};
this.event.equipmentTypeAssignments.forEach((value, index) => {
if ( this.eventForm.value.hasOwnProperty('equipment'+value.id) ){
if ( this.eventForm.value['equipment'+value.id] === "1"){
request.equipment.push(value.id);
}
}
});
console.info(request);
this.eventService.register(request)
.subscribe(
value => {},
value => {},
value => {
this.toastr.success('Sikeresen Foglalás', 'Foglalás');
this.navigationService.navigateToHome()
},
error => {
let status = error.status;
let code = error?.error?.code;
let message = "Hiba történt";
if (status == 400) {
switch (code) {
case RegistrationErrors.ALREADY_REGISTERED:
message = "Már regisztárlt erre az edzésre!";
break;
case RegistrationErrors.MAX_SEAT_COUNT_EXCEEDED:
case RegistrationErrors.TICKET_INSUFFICIENT:
message = "Nem rendelkezik megfelelő bérlettel!"
break;
case RegistrationErrors.NO_FREE_SEATS:
message = "Nincs több szabad hely!"
break;
}
}
this.toastr.error(message, "Foglalás")
},
);
}
cancel(event: Event) {
this.eventService.cancelRegistration(event.registrations[0].id)
.subscribe(
() => {
this.navigationService.navigateToHome();
},
() => {
this.toastr.error("Hiba történt", "Lemondás")
});
}
}

View File

@@ -27,8 +27,8 @@
<div class="row">
<div class="col-lg-9 col-sm-12 pt-2">
<a *ngIf="mayRegister(event)" class="btn btn-primary " (click)="register(event)" >Foglalás</a>
<a *ngIf="mayCancel(event)" class="btn btn-primary" (click)="cancel(event)" >Lemondás</a>
<a *ngIf="!mayCancel(event) && noFreeSeat(event)" class="btn btn-info btn-di" disabled >Már nincsen szabad hely</a>
<!-- <a *ngIf="mayCancel(event)" class="btn btn-primary" (click)="cancel(event)" >Lemondás</a>-->
<!-- <a *ngIf="!mayCancel(event) && noFreeSeat(event)" class="btn btn-info btn-di" disabled >Már nincsen szabad hely</a>-->
</div>
<div class="col-lg-3 text-lg-right col-sm-12 pt-2">
<a class="btn btn-primary" (click)="closeEvent(event)" >Vissza</a>

View File

@@ -69,15 +69,15 @@ export class EventsComponent implements OnInit {
}
mayRegister(event: Event) {
return event.reservedAt == null && event.reservationCount < event.seat_count;
return event.hasFreeSeats && event.registrations.length == 0;
}
mayCancel(event: Event) {
return event.reservedAt;
}
// mayCancel(event: Event) {
// return event.reservedAt;
// }
noFreeSeat(event: Event) {
return event.reservedAt == null && event.reservationCount >= event.seat_count;
return !event.hasFreeSeats;
}
prepareEventDates(events: Event[]) {

View File

@@ -1,25 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RegistrationsComponent } from './registrations.component';
describe('RegistrationsComponent', () => {
let component: RegistrationsComponent;
let fixture: ComponentFixture<RegistrationsComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ RegistrationsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RegistrationsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,9 +1,7 @@
import {Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {Endpoints} from "./endpoints";
import {forkJoin, Observable} from "rxjs";
import {map} from "rxjs/operators";
import {CalendarEvent} from "../app.types";
import { Observable} from "rxjs";
@Injectable({
providedIn: 'root'
@@ -64,9 +62,9 @@ export interface Event {
seat_count: number;
reservationCount: number;
eventType: EventType;
reservedAt: number;
room: Room;
equipmentTypeAssignments?: EquipmentTypeAssignment[];
registrations: Registration[];
hasFreeSeats?: boolean;
}
export interface EquipmentTypeAssignment {
@@ -106,7 +104,7 @@ export interface EventsAvailableResponse {
export interface Registration {
id: number;
created_at: number;
event: Event
event?: Event
}
export interface RegisterEventRequest{

View File

@@ -29,5 +29,9 @@ export class NavigationService {
this.navigate(['/registration/'+idRegistration ])
}
public navigateRegistrations(){
this.navigate(['/registrations' ]);
}
}