Add ticket validation route and update navbar

Introduces new routes for ticket validation accessible to employees and updates the navbar to display navigation items based on user roles. Also adds role-based tooltips and icons to the navbar, and removes unnecessary finalize import in pay-for-order component.
This commit is contained in:
2025-11-26 18:32:23 +01:00
parent a17c97e629
commit 9e2e5c5a1d
4 changed files with 45 additions and 17 deletions

View File

@@ -13,6 +13,7 @@ import { StatisticsComponent } from './statistics/statistics.component';
import { PricelistComponent } from './pricelist/pricelist.component'; import { PricelistComponent } from './pricelist/pricelist.component';
import { TheaterLayoutDesignerComponent } from './theater-layout-designer/theater-layout-designer.component'; import { TheaterLayoutDesignerComponent } from './theater-layout-designer/theater-layout-designer.component';
import { TestComponent } from './test/test.component'; import { TestComponent } from './test/test.component';
import { TicketValidationComponent } from './ticket-validation/ticket-validation.component';
const routes: Routes = [ const routes: Routes = [
// Seiten ohne Layout // Seiten ohne Layout
@@ -55,6 +56,18 @@ const routes: Routes = [
data: { roles: ['admin'] }, // Array von erlaubten Rollen. Derzeit gäbe es 'admin' und 'employee' data: { roles: ['admin'] }, // Array von erlaubten Rollen. Derzeit gäbe es 'admin' und 'employee'
}, },
{ path: 'prices', component: PricelistComponent }, { path: 'prices', component: PricelistComponent },
{
path: 'employee/validation/ticket',
component: TicketValidationComponent,
canActivate: [AuthGuard],
data: { roles: ['employee'] },
},
{
path: 'employee/validation/ticket/:ticketId',
component: TicketValidationComponent,
canActivate: [AuthGuard],
data: { roles: ['employee'] },
},
], ],
}, },

View File

@@ -1,23 +1,31 @@
<nav class="navbar bg-white-50 border-r border-gray-300"> <nav class="navbar bg-white-50 border-r border-gray-300">
<ul class="nav-list grid grid-cols-1 p-2"> <ul class="nav-list grid grid-cols-1 p-2">
@for (item of navItems; track item.path) { @for (item of navItems; track item.path) {
<li class="relative group"> <li class="relative group text-gray-500">
<a [routerLink]="[item.path]" <a [routerLink]="item.path"
routerLinkActive="active" routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }" [routerLinkActiveOptions]="{ exact: true }"
class="relative block text-2xl px-3 py-2 pl-5 gradient-text"> class="relative block text-2xl px-2 py-2 pl-2 gradient-text"
>
<!-- Pfeil links --> <!-- Pfeil links -->
<span class=" <!-- <span class="
absolute left-2 top-1/2 -translate-y-1/2 absolute left-2 top-1/2 -translate-y-1/2
w-0 h-0 border-t-4 border-b-4 border-l-6 border-t-transparent border-b-transparent border-l-indigo-500 w-0 h-0 border-t-4 border-b-4 border-l-6 border-t-transparent border-b-transparent border-l-indigo-500
opacity-0 transition-all duration-300 opacity-0 transition-all duration-300
group-hover:opacity-100 group-hover:opacity-100
group-[.active]:opacity-100 group-[.active]:opacity-100
group-hover:-translate-x-1 group-hover:-translate-x-1
"></span> "></span> -->
{{ item.label }} {{ item.label }}
@if (item.auth && !item.auth.includes(currentUser()?.role!)) {
<mat-icon style="font-size: 18px; width: 18px; height: 18px;" class="pt-0.5" matTooltipPosition="above" [matTooltip]="getAuthTooltip(item.auth[0])">lock</mat-icon>
} @else if (item.auth && item.auth.includes(currentUser()?.role!)) {
<mat-icon style="font-size: 18px; width: 18px; height: 18px;" class="pt-0.5" matTooltipPosition="above" [matTooltip]="getAuthTooltip(item.auth[0])">lock_open</mat-icon>
}
</a> </a>
</li> </li>
} }

View File

@@ -1,5 +1,5 @@
import { AuthService } from './../auth.service'; import { AuthService, User, UserRole } from './../auth.service';
import { Component, inject, computed, OnInit } from '@angular/core'; import { Component, inject, computed } from '@angular/core';
@Component({ @Component({
selector: 'app-navbar', selector: 'app-navbar',
@@ -8,19 +8,28 @@ import { Component, inject, computed, OnInit } from '@angular/core';
styleUrl: './navbar.component.css', styleUrl: './navbar.component.css',
}) })
export class NavbarComponent { export class NavbarComponent {
navItems: { label: string; path: string }[] = [ navItems: { label: string; path: string; auth: UserRole[] | null }[] = [
{ label: 'Programm', path: '/schedule' }, { label: 'Programm', path: '/schedule', auth: null },
{ label: 'Preise', path: '/prices' }, { label: 'Preise', path: '/prices', auth: null },
{ label: 'Bezahlen', path: '/checkout/order' }, { label: 'Bezahlen', path: '/checkout/order', auth: null },
{ label: 'Film importieren', path: '/admin/movie-importer' }, { label: 'Einlasskontrolle', path: '/employee/validation/ticket', auth: ['employee'] },
{ label: 'Statistiken', path: '/admin/statistics' }, { label: 'Film importieren', path: '/admin/movie-importer', auth: ['admin']},
{ label: 'Saal-Designer', path: '/admin/designer' }, { label: 'Statistiken', path: '/admin/statistics', auth: ['admin'] },
{ label: 'Saal-Designer', path: '/admin/designer', auth: ['admin'] },
]; ];
private auth = inject(AuthService); private auth = inject(AuthService);
currentUser = computed(() => this.auth.user()); currentUser = computed(() => this.auth.user());
getAuthTooltip(role: UserRole): string {
return `Es werden ${this.getAuthDisplayName(role)} Berechtigungen benötigt.`
}
private getAuthDisplayName(identifier: UserRole) {
return this.auth.getUserDataByRole(identifier)?.displayName;
}
logout() { logout() {
this.auth.logout(); this.auth.logout();
} }

View File

@@ -3,7 +3,7 @@ import { FormControl, Validators } from '@angular/forms';
import { LoadingService } from '../loading.service'; import { LoadingService } from '../loading.service';
import { HttpService } from '../http.service'; import { HttpService } from '../http.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { catchError, finalize, map, of, take } from 'rxjs'; import { catchError, map, of, take } from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
@Component({ @Component({
@@ -38,14 +38,12 @@ export class PayForOrderComponent implements OnInit {
} }
if (error) { if (error) {
// Warte einen Tick, damit Angular das FormControl initialisiert hat
setTimeout(() => { setTimeout(() => {
this.formControl.clearValidators(); this.formControl.clearValidators();
this.formControl.setErrors({ [error]: true }); this.formControl.setErrors({ [error]: true });
this.formControl.markAsTouched(); this.formControl.markAsTouched();
}); });
// Bei erster Änderung: Validatoren wieder aktivieren
this.formControl.valueChanges.pipe( this.formControl.valueChanges.pipe(
take(1), take(1),
takeUntilDestroyed(this.destroyRef) takeUntilDestroyed(this.destroyRef)