@ichgamer999/wmctest 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/app-ostbahn/app.component.css +0 -0
- package/src/app-ostbahn/app.component.html +1 -0
- package/src/app-ostbahn/app.component.ts +14 -0
- package/src/app-ostbahn/app.config.ts +12 -0
- package/src/app-ostbahn/app.routes.ts +12 -0
- package/src/app-ostbahn/auth.guard.ts +29 -0
- package/src/app-ostbahn/auth.interceptor.ts +14 -0
- package/src/app-ostbahn/auth.service.ts +41 -0
- package/src/app-ostbahn/domains/child.ts +11 -0
- package/src/app-ostbahn/domains/connection.ts +22 -0
- package/src/app-ostbahn/domains/customer.ts +17 -0
- package/src/app-ostbahn/domains/reservationRequest.ts +14 -0
- package/src/app-ostbahn/domains/reservationResponse.ts +16 -0
- package/src/app-ostbahn/domains/station.ts +10 -0
- package/src/app-ostbahn/http.service.ts +34 -0
- package/src/app-ostbahn/login/login.component.css +0 -0
- package/src/app-ostbahn/login/login.component.html +14 -0
- package/src/app-ostbahn/login/login.component.ts +32 -0
- package/src/app-ostbahn/overview/overview.component.css +0 -0
- package/src/app-ostbahn/overview/overview.component.html +14 -0
- package/src/app-ostbahn/overview/overview.component.ts +41 -0
- package/src/app-ostbahn/reservation/reservation.component.css +0 -0
- package/src/app-ostbahn/reservation/reservation.component.html +33 -0
- package/src/app-ostbahn/reservation/reservation.component.ts +94 -0
- package/src/app-sokrates/app.component.css +0 -0
- package/src/app-sokrates/app.component.html +1 -0
- package/src/app-sokrates/app.component.ts +14 -0
- package/src/app-sokrates/app.config.ts +12 -0
- package/src/app-sokrates/app.routes.ts +12 -0
- package/src/app-sokrates/auth.guard.ts +29 -0
- package/src/app-sokrates/auth.interceptor.ts +14 -0
- package/src/app-sokrates/auth.service.ts +41 -0
- package/src/app-sokrates/domains/child.ts +11 -0
- package/src/app-sokrates/domains/connection.ts +22 -0
- package/src/app-sokrates/domains/customer.ts +17 -0
- package/src/app-sokrates/domains/reservationRequest.ts +14 -0
- package/src/app-sokrates/domains/reservationResponse.ts +16 -0
- package/src/app-sokrates/domains/station.ts +10 -0
- package/src/app-sokrates/http.service.ts +34 -0
- package/src/app-sokrates/login/login.component.css +0 -0
- package/src/app-sokrates/login/login.component.html +14 -0
- package/src/app-sokrates/login/login.component.ts +32 -0
- package/src/app-sokrates/overview/overview.component.css +0 -0
- package/src/app-sokrates/overview/overview.component.html +14 -0
- package/src/app-sokrates/overview/overview.component.ts +41 -0
- package/src/app-sokrates/reservation/reservation.component.css +0 -0
- package/src/app-sokrates/reservation/reservation.component.html +33 -0
- package/src/app-sokrates/reservation/reservation.component.ts +94 -0
package/package.json
CHANGED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<router-outlet></router-outlet>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {Component, signal} from '@angular/core';
|
|
2
|
+
import {Router, RouterOutlet} from '@angular/router';
|
|
3
|
+
import {AuthService} from './auth.service';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'app-root',
|
|
7
|
+
templateUrl: './app.component.html',
|
|
8
|
+
imports: [
|
|
9
|
+
RouterOutlet
|
|
10
|
+
],
|
|
11
|
+
styleUrl: './app.component.css'
|
|
12
|
+
})
|
|
13
|
+
export class AppComponent {
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ApplicationConfig } from '@angular/core';
|
|
2
|
+
import {provideRouter, withComponentInputBinding} from '@angular/router';
|
|
3
|
+
|
|
4
|
+
import { routes } from './app.routes';
|
|
5
|
+
import {provideHttpClient, withInterceptors} from '@angular/common/http';
|
|
6
|
+
import {authInterceptor} from './auth.interceptor';
|
|
7
|
+
|
|
8
|
+
export const appConfig: ApplicationConfig = {
|
|
9
|
+
providers: [
|
|
10
|
+
provideRouter(routes,withComponentInputBinding()),
|
|
11
|
+
provideHttpClient(withInterceptors([authInterceptor]))]
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Routes } from '@angular/router';
|
|
2
|
+
import {LoginComponent} from './login/login.component';
|
|
3
|
+
import {OverviewComponent} from './overview/overview.component';
|
|
4
|
+
import {ReservationComponent} from './reservation/reservation.component';
|
|
5
|
+
import {AuthGuard} from './auth.guard';
|
|
6
|
+
|
|
7
|
+
export const routes: Routes = [
|
|
8
|
+
{path: 'login', component: LoginComponent},
|
|
9
|
+
{path: 'book/:id', component: ReservationComponent, canActivate: [AuthGuard]},
|
|
10
|
+
{path: '', component: OverviewComponent},
|
|
11
|
+
{path: '**', redirectTo:'', pathMatch: "full"}
|
|
12
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ActivatedRouteSnapshot,
|
|
3
|
+
CanActivate,
|
|
4
|
+
CanActivateFn,
|
|
5
|
+
GuardResult,
|
|
6
|
+
MaybeAsync, Router,
|
|
7
|
+
RouterStateSnapshot
|
|
8
|
+
} from '@angular/router';
|
|
9
|
+
import {AuthService} from './auth.service';
|
|
10
|
+
import {Injectable} from '@angular/core';
|
|
11
|
+
|
|
12
|
+
@Injectable({
|
|
13
|
+
providedIn: 'root'
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export class AuthGuard implements CanActivate{
|
|
17
|
+
constructor(private router: Router, private auth:AuthService) {
|
|
18
|
+
}
|
|
19
|
+
canActivate() {
|
|
20
|
+
if (this.auth.isLoggedIn()){
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
this.router.navigate(['/login'])
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HttpInterceptorFn } from '@angular/common/http';
|
|
2
|
+
import {inject} from '@angular/core';
|
|
3
|
+
import {AuthService} from './auth.service';
|
|
4
|
+
|
|
5
|
+
export const authInterceptor: HttpInterceptorFn = (req, next) => {
|
|
6
|
+
const authService = inject(AuthService);
|
|
7
|
+
if (!authService.isLoggedIn())
|
|
8
|
+
return next(req);
|
|
9
|
+
const cloned = req.clone({
|
|
10
|
+
headers: req.headers.set('Authorization',
|
|
11
|
+
`Bearer ${authService.getToken()}`)
|
|
12
|
+
});
|
|
13
|
+
return next(cloned);
|
|
14
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {Injectable, signal} from '@angular/core';
|
|
2
|
+
import {HttpService} from './http.service';
|
|
3
|
+
import {HttpClient} from '@angular/common/http';
|
|
4
|
+
import {tap} from 'rxjs';
|
|
5
|
+
import {Router} from '@angular/router';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root',
|
|
9
|
+
})
|
|
10
|
+
export class AuthService {
|
|
11
|
+
_user = signal('')
|
|
12
|
+
private baseUrl = 'http://localhost:3000'
|
|
13
|
+
private static tokenKey: string = "token";
|
|
14
|
+
constructor(private httpClient : HttpClient, private router : Router) {
|
|
15
|
+
}
|
|
16
|
+
login(username: string, password: string) {
|
|
17
|
+
return this.httpClient
|
|
18
|
+
.post<{ token: string }>(`${this.baseUrl}/login`,
|
|
19
|
+
{ username: username, password: password })
|
|
20
|
+
.pipe(
|
|
21
|
+
tap(response => {
|
|
22
|
+
localStorage.setItem(AuthService.tokenKey, response.token);
|
|
23
|
+
this._user.set(username);
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
logout(): void {
|
|
29
|
+
localStorage.removeItem(AuthService.tokenKey);
|
|
30
|
+
this._user.set('');
|
|
31
|
+
this.router.navigate(['/login']);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
isLoggedIn(){
|
|
35
|
+
return !!localStorage.getItem(AuthService.tokenKey)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getToken() {
|
|
39
|
+
return localStorage.getItem(AuthService.tokenKey)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class Connection{
|
|
2
|
+
id: number;
|
|
3
|
+
fromStationId: number;
|
|
4
|
+
toStationId: number;
|
|
5
|
+
fromStationName: string;
|
|
6
|
+
toStationName:string;
|
|
7
|
+
date: string;
|
|
8
|
+
departureTime:string;
|
|
9
|
+
arrivalTime:string;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
constructor(id: number, fromStationId: number, toStationId: number, fromStationName: string, toStationName: string, date: string, departureTime: string, arrivalTime: string) {
|
|
13
|
+
this.id = id;
|
|
14
|
+
this.fromStationId = fromStationId;
|
|
15
|
+
this.toStationId = toStationId;
|
|
16
|
+
this.fromStationName = fromStationName;
|
|
17
|
+
this.toStationName = toStationName;
|
|
18
|
+
this.date = date;
|
|
19
|
+
this.departureTime = departureTime;
|
|
20
|
+
this.arrivalTime = arrivalTime;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
export class Customer{
|
|
3
|
+
id:number
|
|
4
|
+
username:string
|
|
5
|
+
name:string
|
|
6
|
+
password:string
|
|
7
|
+
role:string
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
constructor(id: number, username: string, name: string, password: string, role: string) {
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.username = username;
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.password = password;
|
|
15
|
+
this.role = role;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {Child} from './child';
|
|
2
|
+
|
|
3
|
+
export class ReservationRequest{
|
|
4
|
+
connectionId:number;
|
|
5
|
+
firstClass:boolean;
|
|
6
|
+
children:Child[]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
constructor(connectionId: number, firstClass: boolean, children: Child[]) {
|
|
10
|
+
this.connectionId = connectionId;
|
|
11
|
+
this.firstClass = firstClass;
|
|
12
|
+
this.children = children;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {Child} from './child';
|
|
2
|
+
|
|
3
|
+
export class ReservationResponse{
|
|
4
|
+
id:number;
|
|
5
|
+
connectionId:number;
|
|
6
|
+
firstClass:boolean;
|
|
7
|
+
children:Child[];
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
constructor(id: number, connectionId: number, firstClass: boolean, children: Child[]) {
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.connectionId = connectionId;
|
|
13
|
+
this.firstClass = firstClass;
|
|
14
|
+
this.children = children;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import {HttpClient} from '@angular/common/http';
|
|
3
|
+
import {Connection} from './domains/connection';
|
|
4
|
+
import {ReservationRequest} from './domains/reservationRequest';
|
|
5
|
+
import {ReservationResponse} from './domains/reservationResponse';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root',
|
|
9
|
+
})
|
|
10
|
+
export class HttpService {
|
|
11
|
+
baseurl = 'http://localhost:3000/'
|
|
12
|
+
constructor(private http:HttpClient) {
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getAllConnections(){
|
|
16
|
+
return this.http.get<Connection[]>(this.baseurl + "connections")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getConnection(connectionId: number) {
|
|
20
|
+
return this.http.get<Connection>(this.baseurl + "connections/" + connectionId)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
postReservation(reservation:ReservationRequest){
|
|
24
|
+
return this.http.post(this.baseurl + "reservations", reservation)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getAllReservations(){
|
|
28
|
+
return this.http.get<ReservationResponse[]>(this.baseurl+"reservations")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getReservationById(id:number){
|
|
32
|
+
return this.http.get<ReservationResponse>(this.baseurl+ "reservations/"+id)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<form [formGroup] = "loginForm" (ngSubmit)="login()">
|
|
2
|
+
@if (errorMessage() !== '') {
|
|
3
|
+
<p>{{errorMessage()}}</p>
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
<label for="username">Nutzername: </label>
|
|
7
|
+
<input type="text" id="username" formControlName="username">
|
|
8
|
+
|
|
9
|
+
<label for="password">Password: </label>
|
|
10
|
+
<input type="password" id="password" formControlName="password">
|
|
11
|
+
|
|
12
|
+
<button type="submit">Login</button>
|
|
13
|
+
|
|
14
|
+
</form>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {Component, signal} from '@angular/core';
|
|
2
|
+
import {AuthService} from '../auth.service';
|
|
3
|
+
import {Router} from '@angular/router';
|
|
4
|
+
import {FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'app-login',
|
|
8
|
+
imports: [
|
|
9
|
+
ReactiveFormsModule
|
|
10
|
+
],
|
|
11
|
+
templateUrl: './login.component.html',
|
|
12
|
+
styleUrl: './login.component.css',
|
|
13
|
+
})
|
|
14
|
+
export class LoginComponent {
|
|
15
|
+
errorMessage = signal('')
|
|
16
|
+
loginForm: FormGroup;
|
|
17
|
+
constructor(private auth:AuthService, private router: Router, private fb: FormBuilder) {
|
|
18
|
+
this.loginForm = new FormGroup({
|
|
19
|
+
username: new FormControl('demo@demo.com', Validators.required),
|
|
20
|
+
password: new FormControl('demo', Validators.required)
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
login() {
|
|
26
|
+
this.auth.login(this.loginForm.value.username, this.loginForm.value.password).subscribe({
|
|
27
|
+
next: () => {this.router.navigate(['/overview'])},
|
|
28
|
+
error: () => {this.errorMessage.set("Fehlerhafte Logindaten")}
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<h1>Connection overview</h1>
|
|
2
|
+
@if (logined()){
|
|
3
|
+
<button (click)="logout()">Logout</button>
|
|
4
|
+
} @else {
|
|
5
|
+
<button (click)="login()">Login</button>
|
|
6
|
+
}
|
|
7
|
+
<div>
|
|
8
|
+
@for (connection of connections(); track connection) {
|
|
9
|
+
<h5>Connection {{$index+1}}</h5>
|
|
10
|
+
<p>{{connection.fromStationName}} ===> {{connection.toStationName}}</p>
|
|
11
|
+
<a [routerLink]="['/book/', connection.id]">Buchen</a>
|
|
12
|
+
}
|
|
13
|
+
</div>
|
|
14
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {Component, OnInit, signal} from '@angular/core';
|
|
2
|
+
import {HttpService} from '../http.service';
|
|
3
|
+
import {Connection} from '../domains/connection';
|
|
4
|
+
import {Router, RouterLink} from '@angular/router';
|
|
5
|
+
import {AuthService} from '../auth.service';
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: 'app-overview',
|
|
9
|
+
imports: [
|
|
10
|
+
RouterLink
|
|
11
|
+
],
|
|
12
|
+
templateUrl: './overview.component.html',
|
|
13
|
+
styleUrl: './overview.component.css',
|
|
14
|
+
})
|
|
15
|
+
export class OverviewComponent implements OnInit{
|
|
16
|
+
logined = signal(false)
|
|
17
|
+
connections = signal<Connection[]>([])
|
|
18
|
+
constructor(private http:HttpService, private auth:AuthService, private router: Router) {
|
|
19
|
+
this.logined.set(auth.isLoggedIn())
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
ngOnInit() {
|
|
23
|
+
this.http.getAllConnections().subscribe(cs => {
|
|
24
|
+
this.connections.set(cs)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
logout(){
|
|
29
|
+
this.auth.logout();
|
|
30
|
+
this.router.navigate(['login'])
|
|
31
|
+
this.logined.set(false)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
login() {
|
|
35
|
+
this.router.navigate(['login'])
|
|
36
|
+
this.logined.set(true)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@if (detailTab()) {
|
|
2
|
+
<p>{{neuReservation().id}}</p>
|
|
3
|
+
<p>From: {{connection().fromStationName}}</p>
|
|
4
|
+
<p>TO: {{connection().toStationName}}</p>
|
|
5
|
+
<p>Date: {{connection().date}}</p>
|
|
6
|
+
<p>Children: {{neuReservation().children?.length}}</p>
|
|
7
|
+
<button (click)="renew()">Make Another Reservation</button>
|
|
8
|
+
} @else {
|
|
9
|
+
|
|
10
|
+
<h1>Train reservation</h1>
|
|
11
|
+
<p>Username</p>
|
|
12
|
+
<p>{{user()}}</p>
|
|
13
|
+
<form [formGroup]="reservationGroup" (ngSubmit)="reserve()">
|
|
14
|
+
<input type="checkbox" id="firstClassBox" formControlName="firstClassBox">
|
|
15
|
+
<label for="firstClassBox">First Class?</label>
|
|
16
|
+
|
|
17
|
+
<button type="button" (click)="addChild()">Add Child</button>
|
|
18
|
+
<div formArrayName="childrenArray">
|
|
19
|
+
@for (child of childrenArray.controls; track child){
|
|
20
|
+
<div [formGroupName]="$index">
|
|
21
|
+
<h5>Child {{$index+1}}</h5> <button type="button" (click)="removeChild($index)">Remove</button>
|
|
22
|
+
<label for="childName">Child Name</label>
|
|
23
|
+
<input id="childName" type="text" formControlName="name">
|
|
24
|
+
|
|
25
|
+
<label for="childAge">Child Age</label>
|
|
26
|
+
<input id="childAge" type="number" formControlName="age">
|
|
27
|
+
</div>
|
|
28
|
+
}
|
|
29
|
+
</div>
|
|
30
|
+
<button type="submit">Reserve</button>
|
|
31
|
+
|
|
32
|
+
</form>
|
|
33
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {Component, OnInit, signal} from '@angular/core';
|
|
2
|
+
import {ActivatedRoute} from '@angular/router';
|
|
3
|
+
import {HttpService} from '../http.service';
|
|
4
|
+
import {Connection} from '../domains/connection';
|
|
5
|
+
import {AuthService} from '../auth.service';
|
|
6
|
+
import {FormArray, FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
|
|
7
|
+
import {ReservationRequest} from '../domains/reservationRequest';
|
|
8
|
+
import {ReservationResponse} from '../domains/reservationResponse';
|
|
9
|
+
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'app-reservation',
|
|
12
|
+
imports: [
|
|
13
|
+
ReactiveFormsModule
|
|
14
|
+
],
|
|
15
|
+
templateUrl: './reservation.component.html',
|
|
16
|
+
styleUrl: './reservation.component.css',
|
|
17
|
+
})
|
|
18
|
+
export class ReservationComponent implements OnInit {
|
|
19
|
+
detailTab = signal(false)
|
|
20
|
+
connectionId = -1;
|
|
21
|
+
connection = signal<Connection>({} as Connection)
|
|
22
|
+
user = signal('')
|
|
23
|
+
reservationGroup: FormGroup;
|
|
24
|
+
neuReservation = signal<ReservationResponse>({} as ReservationResponse)
|
|
25
|
+
|
|
26
|
+
constructor(private route: ActivatedRoute, private api: HttpService, private auth: AuthService) {
|
|
27
|
+
this.user.set(this.auth._user())
|
|
28
|
+
this.reservationGroup = new FormGroup({
|
|
29
|
+
firstClassBox: new FormControl(false) ?? false,
|
|
30
|
+
childrenArray: new FormArray([]) ?? []
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get childrenArray() {
|
|
35
|
+
return this.reservationGroup.get('childrenArray') as FormArray
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
ngOnInit(): void {
|
|
39
|
+
this.route.paramMap.subscribe(params => {
|
|
40
|
+
this.connectionId = Number(params.get('id'));
|
|
41
|
+
|
|
42
|
+
if (this.connectionId) {
|
|
43
|
+
this.api.getConnection(this.connectionId).subscribe(
|
|
44
|
+
conn => this.connection.set(conn)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
addChild() {
|
|
51
|
+
this.childrenArray.push(new FormGroup({
|
|
52
|
+
name: new FormControl(''),
|
|
53
|
+
age: new FormControl(0)
|
|
54
|
+
}))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected removeChild($index: number) {
|
|
58
|
+
this.childrenArray.removeAt($index)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
reserve() {
|
|
62
|
+
let reservation: ReservationRequest = {
|
|
63
|
+
connectionId: this.connectionId,
|
|
64
|
+
firstClass: this.reservationGroup.get('firstClassBox')?.value ?? false,
|
|
65
|
+
children: this.childrenArray.value ?? []
|
|
66
|
+
}
|
|
67
|
+
console.log(reservation)
|
|
68
|
+
this.api.postReservation(reservation).subscribe(
|
|
69
|
+
{
|
|
70
|
+
next: () => {
|
|
71
|
+
let reservations: ReservationResponse[] = []
|
|
72
|
+
this.detailTab.set(true)
|
|
73
|
+
this.api.getAllReservations().subscribe(res => {
|
|
74
|
+
reservations = res;
|
|
75
|
+
if (reservations[reservations.length - 1]) {
|
|
76
|
+
this.api.getReservationById(reservations[reservations.length - 1].id).subscribe(reser => {
|
|
77
|
+
this.neuReservation.set(reser)
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
renew() {
|
|
89
|
+
this.reservationGroup.reset()
|
|
90
|
+
this.childrenArray.clear()
|
|
91
|
+
this.detailTab.set(false)
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<router-outlet></router-outlet>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {Component, signal} from '@angular/core';
|
|
2
|
+
import {Router, RouterOutlet} from '@angular/router';
|
|
3
|
+
import {AuthService} from './auth.service';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'app-root',
|
|
7
|
+
templateUrl: './app.component.html',
|
|
8
|
+
imports: [
|
|
9
|
+
RouterOutlet
|
|
10
|
+
],
|
|
11
|
+
styleUrl: './app.component.css'
|
|
12
|
+
})
|
|
13
|
+
export class AppComponent {
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ApplicationConfig } from '@angular/core';
|
|
2
|
+
import {provideRouter, withComponentInputBinding} from '@angular/router';
|
|
3
|
+
|
|
4
|
+
import { routes } from './app.routes';
|
|
5
|
+
import {provideHttpClient, withInterceptors} from '@angular/common/http';
|
|
6
|
+
import {authInterceptor} from './auth.interceptor';
|
|
7
|
+
|
|
8
|
+
export const appConfig: ApplicationConfig = {
|
|
9
|
+
providers: [
|
|
10
|
+
provideRouter(routes,withComponentInputBinding()),
|
|
11
|
+
provideHttpClient(withInterceptors([authInterceptor]))]
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Routes } from '@angular/router';
|
|
2
|
+
import {LoginComponent} from './login/login.component';
|
|
3
|
+
import {OverviewComponent} from './overview/overview.component';
|
|
4
|
+
import {ReservationComponent} from './reservation/reservation.component';
|
|
5
|
+
import {AuthGuard} from './auth.guard';
|
|
6
|
+
|
|
7
|
+
export const routes: Routes = [
|
|
8
|
+
{path: 'login', component: LoginComponent},
|
|
9
|
+
{path: 'book/:id', component: ReservationComponent, canActivate: [AuthGuard]},
|
|
10
|
+
{path: '', component: OverviewComponent},
|
|
11
|
+
{path: '**', redirectTo:'', pathMatch: "full"}
|
|
12
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ActivatedRouteSnapshot,
|
|
3
|
+
CanActivate,
|
|
4
|
+
CanActivateFn,
|
|
5
|
+
GuardResult,
|
|
6
|
+
MaybeAsync, Router,
|
|
7
|
+
RouterStateSnapshot
|
|
8
|
+
} from '@angular/router';
|
|
9
|
+
import {AuthService} from './auth.service';
|
|
10
|
+
import {Injectable} from '@angular/core';
|
|
11
|
+
|
|
12
|
+
@Injectable({
|
|
13
|
+
providedIn: 'root'
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export class AuthGuard implements CanActivate{
|
|
17
|
+
constructor(private router: Router, private auth:AuthService) {
|
|
18
|
+
}
|
|
19
|
+
canActivate() {
|
|
20
|
+
if (this.auth.isLoggedIn()){
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
this.router.navigate(['/login'])
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HttpInterceptorFn } from '@angular/common/http';
|
|
2
|
+
import {inject} from '@angular/core';
|
|
3
|
+
import {AuthService} from './auth.service';
|
|
4
|
+
|
|
5
|
+
export const authInterceptor: HttpInterceptorFn = (req, next) => {
|
|
6
|
+
const authService = inject(AuthService);
|
|
7
|
+
if (!authService.isLoggedIn())
|
|
8
|
+
return next(req);
|
|
9
|
+
const cloned = req.clone({
|
|
10
|
+
headers: req.headers.set('Authorization',
|
|
11
|
+
`Bearer ${authService.getToken()}`)
|
|
12
|
+
});
|
|
13
|
+
return next(cloned);
|
|
14
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {Injectable, signal} from '@angular/core';
|
|
2
|
+
import {HttpService} from './http.service';
|
|
3
|
+
import {HttpClient} from '@angular/common/http';
|
|
4
|
+
import {tap} from 'rxjs';
|
|
5
|
+
import {Router} from '@angular/router';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root',
|
|
9
|
+
})
|
|
10
|
+
export class AuthService {
|
|
11
|
+
_user = signal('')
|
|
12
|
+
private baseUrl = 'http://localhost:3000'
|
|
13
|
+
private static tokenKey: string = "token";
|
|
14
|
+
constructor(private httpClient : HttpClient, private router : Router) {
|
|
15
|
+
}
|
|
16
|
+
login(username: string, password: string) {
|
|
17
|
+
return this.httpClient
|
|
18
|
+
.post<{ token: string }>(`${this.baseUrl}/login`,
|
|
19
|
+
{ username: username, password: password })
|
|
20
|
+
.pipe(
|
|
21
|
+
tap(response => {
|
|
22
|
+
localStorage.setItem(AuthService.tokenKey, response.token);
|
|
23
|
+
this._user.set(username);
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
logout(): void {
|
|
29
|
+
localStorage.removeItem(AuthService.tokenKey);
|
|
30
|
+
this._user.set('');
|
|
31
|
+
this.router.navigate(['/login']);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
isLoggedIn(){
|
|
35
|
+
return !!localStorage.getItem(AuthService.tokenKey)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getToken() {
|
|
39
|
+
return localStorage.getItem(AuthService.tokenKey)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class Connection{
|
|
2
|
+
id: number;
|
|
3
|
+
fromStationId: number;
|
|
4
|
+
toStationId: number;
|
|
5
|
+
fromStationName: string;
|
|
6
|
+
toStationName:string;
|
|
7
|
+
date: string;
|
|
8
|
+
departureTime:string;
|
|
9
|
+
arrivalTime:string;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
constructor(id: number, fromStationId: number, toStationId: number, fromStationName: string, toStationName: string, date: string, departureTime: string, arrivalTime: string) {
|
|
13
|
+
this.id = id;
|
|
14
|
+
this.fromStationId = fromStationId;
|
|
15
|
+
this.toStationId = toStationId;
|
|
16
|
+
this.fromStationName = fromStationName;
|
|
17
|
+
this.toStationName = toStationName;
|
|
18
|
+
this.date = date;
|
|
19
|
+
this.departureTime = departureTime;
|
|
20
|
+
this.arrivalTime = arrivalTime;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
export class Customer{
|
|
3
|
+
id:number
|
|
4
|
+
username:string
|
|
5
|
+
name:string
|
|
6
|
+
password:string
|
|
7
|
+
role:string
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
constructor(id: number, username: string, name: string, password: string, role: string) {
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.username = username;
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.password = password;
|
|
15
|
+
this.role = role;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {Child} from './child';
|
|
2
|
+
|
|
3
|
+
export class ReservationRequest{
|
|
4
|
+
connectionId:number;
|
|
5
|
+
firstClass:boolean;
|
|
6
|
+
children:Child[]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
constructor(connectionId: number, firstClass: boolean, children: Child[]) {
|
|
10
|
+
this.connectionId = connectionId;
|
|
11
|
+
this.firstClass = firstClass;
|
|
12
|
+
this.children = children;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {Child} from './child';
|
|
2
|
+
|
|
3
|
+
export class ReservationResponse{
|
|
4
|
+
id:number;
|
|
5
|
+
connectionId:number;
|
|
6
|
+
firstClass:boolean;
|
|
7
|
+
children:Child[];
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
constructor(id: number, connectionId: number, firstClass: boolean, children: Child[]) {
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.connectionId = connectionId;
|
|
13
|
+
this.firstClass = firstClass;
|
|
14
|
+
this.children = children;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import {HttpClient} from '@angular/common/http';
|
|
3
|
+
import {Connection} from './domains/connection';
|
|
4
|
+
import {ReservationRequest} from './domains/reservationRequest';
|
|
5
|
+
import {ReservationResponse} from './domains/reservationResponse';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root',
|
|
9
|
+
})
|
|
10
|
+
export class HttpService {
|
|
11
|
+
baseurl = 'http://localhost:3000/'
|
|
12
|
+
constructor(private http:HttpClient) {
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getAllConnections(){
|
|
16
|
+
return this.http.get<Connection[]>(this.baseurl + "connections")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getConnection(connectionId: number) {
|
|
20
|
+
return this.http.get<Connection>(this.baseurl + "connections/" + connectionId)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
postReservation(reservation:ReservationRequest){
|
|
24
|
+
return this.http.post(this.baseurl + "reservations", reservation)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getAllReservations(){
|
|
28
|
+
return this.http.get<ReservationResponse[]>(this.baseurl+"reservations")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getReservationById(id:number){
|
|
32
|
+
return this.http.get<ReservationResponse>(this.baseurl+ "reservations/"+id)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<form [formGroup] = "loginForm" (ngSubmit)="login()">
|
|
2
|
+
@if (errorMessage() !== '') {
|
|
3
|
+
<p>{{errorMessage()}}</p>
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
<label for="username">Nutzername: </label>
|
|
7
|
+
<input type="text" id="username" formControlName="username">
|
|
8
|
+
|
|
9
|
+
<label for="password">Password: </label>
|
|
10
|
+
<input type="password" id="password" formControlName="password">
|
|
11
|
+
|
|
12
|
+
<button type="submit">Login</button>
|
|
13
|
+
|
|
14
|
+
</form>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {Component, signal} from '@angular/core';
|
|
2
|
+
import {AuthService} from '../auth.service';
|
|
3
|
+
import {Router} from '@angular/router';
|
|
4
|
+
import {FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'app-login',
|
|
8
|
+
imports: [
|
|
9
|
+
ReactiveFormsModule
|
|
10
|
+
],
|
|
11
|
+
templateUrl: './login.component.html',
|
|
12
|
+
styleUrl: './login.component.css',
|
|
13
|
+
})
|
|
14
|
+
export class LoginComponent {
|
|
15
|
+
errorMessage = signal('')
|
|
16
|
+
loginForm: FormGroup;
|
|
17
|
+
constructor(private auth:AuthService, private router: Router, private fb: FormBuilder) {
|
|
18
|
+
this.loginForm = new FormGroup({
|
|
19
|
+
username: new FormControl('demo@demo.com', Validators.required),
|
|
20
|
+
password: new FormControl('demo', Validators.required)
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
login() {
|
|
26
|
+
this.auth.login(this.loginForm.value.username, this.loginForm.value.password).subscribe({
|
|
27
|
+
next: () => {this.router.navigate(['/overview'])},
|
|
28
|
+
error: () => {this.errorMessage.set("Fehlerhafte Logindaten")}
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<h1>Connection overview</h1>
|
|
2
|
+
@if (logined()){
|
|
3
|
+
<button (click)="logout()">Logout</button>
|
|
4
|
+
} @else {
|
|
5
|
+
<button (click)="login()">Login</button>
|
|
6
|
+
}
|
|
7
|
+
<div>
|
|
8
|
+
@for (connection of connections(); track connection) {
|
|
9
|
+
<h5>Connection {{$index+1}}</h5>
|
|
10
|
+
<p>{{connection.fromStationName}} ===> {{connection.toStationName}}</p>
|
|
11
|
+
<a [routerLink]="['/book/', connection.id]">Buchen</a>
|
|
12
|
+
}
|
|
13
|
+
</div>
|
|
14
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {Component, OnInit, signal} from '@angular/core';
|
|
2
|
+
import {HttpService} from '../http.service';
|
|
3
|
+
import {Connection} from '../domains/connection';
|
|
4
|
+
import {Router, RouterLink} from '@angular/router';
|
|
5
|
+
import {AuthService} from '../auth.service';
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: 'app-overview',
|
|
9
|
+
imports: [
|
|
10
|
+
RouterLink
|
|
11
|
+
],
|
|
12
|
+
templateUrl: './overview.component.html',
|
|
13
|
+
styleUrl: './overview.component.css',
|
|
14
|
+
})
|
|
15
|
+
export class OverviewComponent implements OnInit{
|
|
16
|
+
logined = signal(false)
|
|
17
|
+
connections = signal<Connection[]>([])
|
|
18
|
+
constructor(private http:HttpService, private auth:AuthService, private router: Router) {
|
|
19
|
+
this.logined.set(auth.isLoggedIn())
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
ngOnInit() {
|
|
23
|
+
this.http.getAllConnections().subscribe(cs => {
|
|
24
|
+
this.connections.set(cs)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
logout(){
|
|
29
|
+
this.auth.logout();
|
|
30
|
+
this.router.navigate(['login'])
|
|
31
|
+
this.logined.set(false)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
login() {
|
|
35
|
+
this.router.navigate(['login'])
|
|
36
|
+
this.logined.set(true)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@if (detailTab()) {
|
|
2
|
+
<p>{{neuReservation().id}}</p>
|
|
3
|
+
<p>From: {{connection().fromStationName}}</p>
|
|
4
|
+
<p>TO: {{connection().toStationName}}</p>
|
|
5
|
+
<p>Date: {{connection().date}}</p>
|
|
6
|
+
<p>Children: {{neuReservation().children?.length}}</p>
|
|
7
|
+
<button (click)="renew()">Make Another Reservation</button>
|
|
8
|
+
} @else {
|
|
9
|
+
|
|
10
|
+
<h1>Train reservation</h1>
|
|
11
|
+
<p>Username</p>
|
|
12
|
+
<p>{{user()}}</p>
|
|
13
|
+
<form [formGroup]="reservationGroup" (ngSubmit)="reserve()">
|
|
14
|
+
<input type="checkbox" id="firstClassBox" formControlName="firstClassBox">
|
|
15
|
+
<label for="firstClassBox">First Class?</label>
|
|
16
|
+
|
|
17
|
+
<button type="button" (click)="addChild()">Add Child</button>
|
|
18
|
+
<div formArrayName="childrenArray">
|
|
19
|
+
@for (child of childrenArray.controls; track child){
|
|
20
|
+
<div [formGroupName]="$index">
|
|
21
|
+
<h5>Child {{$index+1}}</h5> <button type="button" (click)="removeChild($index)">Remove</button>
|
|
22
|
+
<label for="childName">Child Name</label>
|
|
23
|
+
<input id="childName" type="text" formControlName="name">
|
|
24
|
+
|
|
25
|
+
<label for="childAge">Child Age</label>
|
|
26
|
+
<input id="childAge" type="number" formControlName="age">
|
|
27
|
+
</div>
|
|
28
|
+
}
|
|
29
|
+
</div>
|
|
30
|
+
<button type="submit">Reserve</button>
|
|
31
|
+
|
|
32
|
+
</form>
|
|
33
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {Component, OnInit, signal} from '@angular/core';
|
|
2
|
+
import {ActivatedRoute} from '@angular/router';
|
|
3
|
+
import {HttpService} from '../http.service';
|
|
4
|
+
import {Connection} from '../domains/connection';
|
|
5
|
+
import {AuthService} from '../auth.service';
|
|
6
|
+
import {FormArray, FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
|
|
7
|
+
import {ReservationRequest} from '../domains/reservationRequest';
|
|
8
|
+
import {ReservationResponse} from '../domains/reservationResponse';
|
|
9
|
+
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'app-reservation',
|
|
12
|
+
imports: [
|
|
13
|
+
ReactiveFormsModule
|
|
14
|
+
],
|
|
15
|
+
templateUrl: './reservation.component.html',
|
|
16
|
+
styleUrl: './reservation.component.css',
|
|
17
|
+
})
|
|
18
|
+
export class ReservationComponent implements OnInit {
|
|
19
|
+
detailTab = signal(false)
|
|
20
|
+
connectionId = -1;
|
|
21
|
+
connection = signal<Connection>({} as Connection)
|
|
22
|
+
user = signal('')
|
|
23
|
+
reservationGroup: FormGroup;
|
|
24
|
+
neuReservation = signal<ReservationResponse>({} as ReservationResponse)
|
|
25
|
+
|
|
26
|
+
constructor(private route: ActivatedRoute, private api: HttpService, private auth: AuthService) {
|
|
27
|
+
this.user.set(this.auth._user())
|
|
28
|
+
this.reservationGroup = new FormGroup({
|
|
29
|
+
firstClassBox: new FormControl(false) ?? false,
|
|
30
|
+
childrenArray: new FormArray([]) ?? []
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get childrenArray() {
|
|
35
|
+
return this.reservationGroup.get('childrenArray') as FormArray
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
ngOnInit(): void {
|
|
39
|
+
this.route.paramMap.subscribe(params => {
|
|
40
|
+
this.connectionId = Number(params.get('id'));
|
|
41
|
+
|
|
42
|
+
if (this.connectionId) {
|
|
43
|
+
this.api.getConnection(this.connectionId).subscribe(
|
|
44
|
+
conn => this.connection.set(conn)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
addChild() {
|
|
51
|
+
this.childrenArray.push(new FormGroup({
|
|
52
|
+
name: new FormControl(''),
|
|
53
|
+
age: new FormControl(0)
|
|
54
|
+
}))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected removeChild($index: number) {
|
|
58
|
+
this.childrenArray.removeAt($index)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
reserve() {
|
|
62
|
+
let reservation: ReservationRequest = {
|
|
63
|
+
connectionId: this.connectionId,
|
|
64
|
+
firstClass: this.reservationGroup.get('firstClassBox')?.value ?? false,
|
|
65
|
+
children: this.childrenArray.value ?? []
|
|
66
|
+
}
|
|
67
|
+
console.log(reservation)
|
|
68
|
+
this.api.postReservation(reservation).subscribe(
|
|
69
|
+
{
|
|
70
|
+
next: () => {
|
|
71
|
+
let reservations: ReservationResponse[] = []
|
|
72
|
+
this.detailTab.set(true)
|
|
73
|
+
this.api.getAllReservations().subscribe(res => {
|
|
74
|
+
reservations = res;
|
|
75
|
+
if (reservations[reservations.length - 1]) {
|
|
76
|
+
this.api.getReservationById(reservations[reservations.length - 1].id).subscribe(reser => {
|
|
77
|
+
this.neuReservation.set(reser)
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
renew() {
|
|
89
|
+
this.reservationGroup.reset()
|
|
90
|
+
this.childrenArray.clear()
|
|
91
|
+
this.detailTab.set(false)
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
}
|