diff --git a/package-lock.json b/package-lock.json index ea5c339..0002880 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@angular/material": "^20.2.9", "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", - "@infinimotion/model-frontend": "^0.0.85", + "@infinimotion/model-frontend": "^0.0.89", "@tailwindcss/postcss": "^4.1.14", "postcss": "^8.5.6", "rxjs": "~7.8.0", @@ -1298,9 +1298,9 @@ } }, "node_modules/@infinimotion/model-frontend": { - "version": "0.0.85", - "resolved": "https://git.infinimotion.de/api/packages/infinimotion/npm/%40infinimotion%2Fmodel-frontend/-/0.0.85/model-frontend-0.0.85.tgz", - "integrity": "sha512-QPiZNl//Y1JdxtXk+VScc67h1K664z68PUCXRff9fRf4IHlYXtqutc+ainK8vxOVSqqL6EEmDAtbLsRwrG6kRg==", + "version": "0.0.89", + "resolved": "https://git.infinimotion.de/api/packages/infinimotion/npm/%40infinimotion%2Fmodel-frontend/-/0.0.89/model-frontend-0.0.89.tgz", + "integrity": "sha512-lvvQy8RWs41Bz52uBgsUKkwn8teGlgxlmG8Rvsgkh+v1IMVWFWVQmfMS7Rznd0lCZRgK1ByihH80X9eAN12idA==", "license": "ISC" }, "node_modules/@inquirer/ansi": { diff --git a/package.json b/package.json index 5027aa3..a8410ad 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@angular/material": "^20.2.9", "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", - "@infinimotion/model-frontend": "^0.0.85", + "@infinimotion/model-frontend": "^0.0.89", "@tailwindcss/postcss": "^4.1.14", "postcss": "^8.5.6", "rxjs": "~7.8.0", diff --git a/src/app/app-module.ts b/src/app/app-module.ts index 140cb49..7bdff2c 100644 --- a/src/app/app-module.ts +++ b/src/app/app-module.ts @@ -12,6 +12,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatInputModule } from '@angular/material/input'; @@ -52,6 +53,8 @@ import { LoginDialog } from './login/login.dialog'; import { PerformanceInfoComponent } from './performance-info/performance-info.component'; import { ShoppingCartComponent } from './shopping-cart/shopping-cart.component'; import { OrderComponent } from './order/order.component'; +import { SeatSelectionComponent } from './seat-selection/seat-selection.component'; +import { NoSeatsInHallComponent } from './no-seats-in-hall/no-seats-in-hall.component'; @NgModule({ @@ -87,6 +90,8 @@ import { OrderComponent } from './order/order.component'; PerformanceInfoComponent, ShoppingCartComponent, OrderComponent, + SeatSelectionComponent, + NoSeatsInHallComponent, ], imports: [ AppRoutingModule, @@ -98,6 +103,7 @@ import { OrderComponent } from './order/order.component'; MatTabsModule, MatToolbarModule, MatProgressBarModule, + MatProgressSpinnerModule, MatSnackBarModule, MatAutocompleteModule, MatInputModule, diff --git a/src/app/no-seats-in-hall/no-seats-in-hall.component.css b/src/app/no-seats-in-hall/no-seats-in-hall.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/no-seats-in-hall/no-seats-in-hall.component.html b/src/app/no-seats-in-hall/no-seats-in-hall.component.html new file mode 100644 index 0000000..08cea86 --- /dev/null +++ b/src/app/no-seats-in-hall/no-seats-in-hall.component.html @@ -0,0 +1,7 @@ +
+ + brightness_alert + +

Huch?! Keine Sitzplätze?

+

Hast du ein Glück, Stehplätze sind kostenlos.

+
diff --git a/src/app/no-seats-in-hall/no-seats-in-hall.component.ts b/src/app/no-seats-in-hall/no-seats-in-hall.component.ts new file mode 100644 index 0000000..bf6ce88 --- /dev/null +++ b/src/app/no-seats-in-hall/no-seats-in-hall.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-no-seats-in-hall', + standalone: false, + templateUrl: './no-seats-in-hall.component.html', + styleUrl: './no-seats-in-hall.component.css' +}) +export class NoSeatsInHallComponent { + +} diff --git a/src/app/order/order.component.css b/src/app/order/order.component.css index 9008a3b..b19ef5b 100644 --- a/src/app/order/order.component.css +++ b/src/app/order/order.component.css @@ -1,3 +1,7 @@ mat-stepper { background: transparent !important; } + +::ng-deep .mat-horizontal-stepper-header{ + pointer-events: none !important; +} diff --git a/src/app/order/order.component.html b/src/app/order/order.component.html index 3d94d59..4f31b79 100644 --- a/src/app/order/order.component.html +++ b/src/app/order/order.component.html @@ -1,4 +1,15 @@
+ +@if (loadingService.loading$ | async){ +
+ +
+} +@else if (performance()) { + Warenkorb - @if (performance()) { - - } + -
- +
+ + @for (seatCategory of seatCategories(); track $index) { +
+ + } + @empty { + + } + +
+ + + + +
+

+ Tickets gesamt: +

+

+ 75,00 € +

+
+ +
+ +
@@ -46,4 +82,5 @@
+}
diff --git a/src/app/order/order.component.ts b/src/app/order/order.component.ts index 330041b..3f3b094 100644 --- a/src/app/order/order.component.ts +++ b/src/app/order/order.component.ts @@ -1,4 +1,5 @@ -import { Vorstellung } from '@infinimotion/model-frontend'; +import { LoadingService } from './../loading.service'; +import { Sitzkategorie, Vorstellung } from '@infinimotion/model-frontend'; import { Component, inject, input } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; @@ -10,8 +11,10 @@ import { FormBuilder, Validators } from '@angular/forms'; }) export class OrderComponent { performance = input(); + seatCategories = input.required(); private _formBuilder = inject(FormBuilder); + loadingService = inject(LoadingService); firstFormGroup = this._formBuilder.group({ firstCtrl: ['', Validators.required], diff --git a/src/app/performance-info/performance-info.component.html b/src/app/performance-info/performance-info.component.html index 4ed4613..06435e9 100644 --- a/src/app/performance-info/performance-info.component.html +++ b/src/app/performance-info/performance-info.component.html @@ -11,9 +11,9 @@

{{ getStartTimeString() }} • {{ performance().hall.name }}

-

{{ movie().title }}

+

{{ movie().title }}

- +
diff --git a/src/app/seat-selection/seat-selection.component.css b/src/app/seat-selection/seat-selection.component.css new file mode 100644 index 0000000..c206bd7 --- /dev/null +++ b/src/app/seat-selection/seat-selection.component.css @@ -0,0 +1,3 @@ +.seat-name { + color: var(--mat-sys-primary); +} diff --git a/src/app/seat-selection/seat-selection.component.html b/src/app/seat-selection/seat-selection.component.html new file mode 100644 index 0000000..853700b --- /dev/null +++ b/src/app/seat-selection/seat-selection.component.html @@ -0,0 +1,11 @@ +

{{ seatCategory().name }}

+
+
+ + {{ seatCategory().icon }} + +

{{ getPriceDisplay(seatCategory().price) }}

+
+

× 2

+

25.00 €

+
diff --git a/src/app/seat-selection/seat-selection.component.ts b/src/app/seat-selection/seat-selection.component.ts new file mode 100644 index 0000000..e9f0f8d --- /dev/null +++ b/src/app/seat-selection/seat-selection.component.ts @@ -0,0 +1,18 @@ +import { Component, input } from '@angular/core'; +import { Sitzkategorie } from '@infinimotion/model-frontend'; + +@Component({ + selector: 'app-seat-selection', + standalone: false, + templateUrl: './seat-selection.component.html', + styleUrl: './seat-selection.component.css' +}) +export class SeatSelectionComponent { + seatCategory = input.required(); + amount: number = 1; + + getPriceDisplay(price: number): string { + return `${(price / 100).toFixed(2)} €`; + } +} + diff --git a/src/app/theater-overlay/theater-overlay.component.html b/src/app/theater-overlay/theater-overlay.component.html index d709d18..c4c736e 100644 --- a/src/app/theater-overlay/theater-overlay.component.html +++ b/src/app/theater-overlay/theater-overlay.component.html @@ -4,6 +4,6 @@ - + diff --git a/src/app/theater-overlay/theater-overlay.component.ts b/src/app/theater-overlay/theater-overlay.component.ts index c8a0e35..0052b0a 100644 --- a/src/app/theater-overlay/theater-overlay.component.ts +++ b/src/app/theater-overlay/theater-overlay.component.ts @@ -2,7 +2,7 @@ import {Component, inject, OnInit} from '@angular/core'; import {HttpService} from '../http.service'; import {LoadingService} from '../loading.service'; import {catchError, forkJoin, of, tap} from 'rxjs'; -import {Sitzplatz, Vorstellung} from '@infinimotion/model-frontend'; +import {Sitzkategorie, Sitzplatz, Vorstellung} from '@infinimotion/model-frontend'; import {TheaterSeatState} from '../model/theater-seat-state.model'; import {ActivatedRoute} from '@angular/router'; @@ -19,6 +19,7 @@ export class TheaterOverlayComponent implements OnInit { showId!: number; seatsPerRow: { seat: Sitzplatz, state: TheaterSeatState }[][] = [] performance: Vorstellung | undefined; + seatCategories: Sitzkategorie[] = []; constructor(private route: ActivatedRoute) {} @@ -52,13 +53,26 @@ loadPerformanceAndSeats() { state: TheaterSeatState }[][] { let rows: { seat: Sitzplatz, state: TheaterSeatState }[][] = []; + const categoryMap = new Map(); + resp.seats.forEach(seat => { if (!rows[seat.row.position]) { rows[seat.row.position] = []; } - let state = resp.booked.find(other => other.id == seat.id) ? TheaterSeatState.BOOKED : resp.reserved.find(other => other.id == seat.id) ? TheaterSeatState.RESERVED : TheaterSeatState.AVAILABLE; + + let state = resp.booked.find(other => other.id == seat.id) ? TheaterSeatState.BOOKED + : resp.reserved.find(other => other.id == seat.id) ? TheaterSeatState.RESERVED + : TheaterSeatState.AVAILABLE; + rows[seat.row.position].push({seat: seat, state: state}); + + if (seat.row.category && !categoryMap.has(seat.row.category.id)) { + categoryMap.set(seat.row.category.id, seat.row.category); + } }); + + this.seatCategories = Array.from(categoryMap.values()).sort((a, b) => a.id - b.id); + rows = rows.filter(row => row.length > 0).sort((a, b) => a[0].seat.row.position - b[0].seat.row.position); rows.forEach(row => row.sort((a, b) => a.seat.position - b.seat.position)); return rows; diff --git a/src/index.html b/src/index.html index da193c0..2df19e0 100644 --- a/src/index.html +++ b/src/index.html @@ -8,6 +8,7 @@ +