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:
@@ -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'] },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user