Introduces a cancel order confirmation dialog and integrates it into the order flow. Refactors error and success components to support singular/plural seat messaging and retry actions. Updates navigation and button behaviors for better user experience. Fixes minor UI and logic issues in reservation, purchase, and conversion flows.
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { computed, Injectable, signal } from '@angular/core';
|
|
import { Sitzplatz } from '@infinimotion/model-frontend';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class SelectedSeatsService {
|
|
|
|
private selectedSeatsSignal = signal<Sitzplatz[]>([]);
|
|
private seatIsSelectableSignal = signal(true);
|
|
private committedSignal = signal(false);
|
|
private erroredSignal = signal(false);
|
|
private cancelledSignal = signal(false);
|
|
private debugSignal = signal(false);
|
|
private hadConflictSignal = signal(false);
|
|
|
|
readonly selectedSeats = this.selectedSeatsSignal.asReadonly();
|
|
readonly seatIsSelectable = this.seatIsSelectableSignal.asReadonly();
|
|
readonly committed = this.committedSignal.asReadonly();
|
|
readonly errored = this.erroredSignal.asReadonly();
|
|
readonly cancelled = this.cancelledSignal.asReadonly();
|
|
readonly debug = this.debugSignal.asReadonly();
|
|
readonly hadConflict = this.hadConflictSignal.asReadonly();
|
|
|
|
readonly totalSeats = computed(() => this.selectedSeats().length);
|
|
readonly totalPrice = computed(() => this.selectedSeats().reduce((sum, seat) => sum + seat.row.category.price, 0));
|
|
|
|
pushSelectedSeat(selectedSeat: Sitzplatz): void {
|
|
this.selectedSeatsSignal.update(seats => [...seats, selectedSeat]);
|
|
this.hadConflictSignal.set(false);
|
|
}
|
|
|
|
removeSelectedSeat(selectedSeat: Sitzplatz): void {
|
|
this.selectedSeatsSignal.update(seats => seats.filter(seat => seat.id !== selectedSeat.id));
|
|
this.hadConflictSignal.set(false);
|
|
}
|
|
|
|
getSeatsByCategory(categoryId: number): Sitzplatz[] {
|
|
return this.selectedSeats().filter(seat => seat.row.category.id === categoryId);
|
|
}
|
|
|
|
clearSelection(): void {
|
|
this.selectedSeatsSignal.set([]);
|
|
this.committedSignal.set(false);
|
|
this.cancelledSignal.set(false);
|
|
this.erroredSignal.set(false);
|
|
this.hadConflictSignal.set(false);
|
|
}
|
|
|
|
getSeatIsSelectable(): boolean{
|
|
return this.seatIsSelectable();
|
|
}
|
|
|
|
setSeatSelectable(selectable: boolean): void {
|
|
this.seatIsSelectableSignal.set(selectable);
|
|
if (selectable) {
|
|
this.committedSignal.set(false);
|
|
this.cancelledSignal.set(false);
|
|
this.erroredSignal.set(false);
|
|
}
|
|
}
|
|
|
|
commit(): void {
|
|
this.erroredSignal.set(false);
|
|
this.committedSignal.set(true);
|
|
}
|
|
|
|
error(): void {
|
|
this.erroredSignal.set(true);
|
|
}
|
|
|
|
cancel(): void {
|
|
this.erroredSignal.set(false);
|
|
this.cancelledSignal.set(true);
|
|
}
|
|
|
|
toggleDebug(): void {
|
|
this.debugSignal.update(debug => !debug);
|
|
}
|
|
|
|
isSeatSelected(seatId: number): boolean {
|
|
return this.selectedSeats().some(seat => seat.id === seatId);
|
|
}
|
|
|
|
setConflict(value: boolean): void {
|
|
this.hadConflictSignal.set(value);
|
|
}
|
|
}
|