Add login button to header

This commit is contained in:
akastijn 2025-07-04 21:14:45 +02:00
parent ebe66c87c0
commit 73916f0aae
5 changed files with 85 additions and 7 deletions

View File

@ -130,7 +130,19 @@
<li class="nav_li"><a class="nav_link2" target="_blank" href="https://alttd.com/blog/">Blog</a></li> <li class="nav_li"><a class="nav_link2" target="_blank" href="https://alttd.com/blog/">Blog</a></li>
</ul> </ul>
</li> </li>
<li class="nav_li" *ngIf="isAuthenticated">
<a [id]="getCurrentPageId(['particles'])"
class="nav_link fake_link" [ngClass]="active">Special</a>
<ul class="dropdown" *ngIf="hasAccess(['HEAD_MOD'])">
<li class="nav_li"><a class="nav_link2" [routerLink]="['/particles']">Particles</a></li>
</ul> </ul>
</li>
</ul>
<ng-container *ngIf="!isAuthenticated">
<button mat-button (click)="openLoginDialog()" style="color: white">
Login
</button>
</ng-container>
<app-theme></app-theme> <app-theme></app-theme>
</div> </div>
</nav> </nav>

View File

@ -1,7 +1,12 @@
import {Component, HostListener, Input} from '@angular/core'; import {Component, HostListener, Input, OnDestroy, OnInit} from '@angular/core';
import {CommonModule, NgOptimizedImage} from '@angular/common'; import {CommonModule, NgOptimizedImage} from '@angular/common';
import {ThemeComponent} from '@shared-components/theme/theme.component'; import {ThemeComponent} from '@shared-components/theme/theme.component';
import {RouterLink} from '@angular/router'; import {RouterLink} from '@angular/router';
import {AuthService} from '@services/auth.service';
import {Subscription} from 'rxjs';
import {LoginDialogComponent} from '@shared-components/login/login.component';
import {MatButton} from '@angular/material/button';
import {MatDialog} from '@angular/material/dialog';
@Component({ @Component({
standalone: true, standalone: true,
@ -9,13 +14,14 @@ import {RouterLink} from '@angular/router';
CommonModule, CommonModule,
ThemeComponent, ThemeComponent,
RouterLink, RouterLink,
NgOptimizedImage NgOptimizedImage,
MatButton
], ],
selector: 'app-header', selector: 'app-header',
templateUrl: './header.component.html', templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'] styleUrls: ['./header.component.scss']
}) })
export class HeaderComponent { export class HeaderComponent implements OnInit, OnDestroy {
@Input() current_page: string = ''; @Input() current_page: string = '';
@Input() background_image: string = ''; @Input() background_image: string = '';
@Input() height: string = ''; @Input() height: string = '';
@ -23,6 +29,24 @@ export class HeaderComponent {
public active: string = ''; public active: string = '';
public inverseYPos: number = 0; public inverseYPos: number = 0;
private subscription: Subscription | undefined;
public isAuthenticated: boolean = false;
constructor(protected authService: AuthService,
private dialog: MatDialog) {
}
ngOnInit(): void {
this.subscription = this.authService.isAuthenticated$.subscribe(isAuthenticated => {
this.isAuthenticated = isAuthenticated;
}
);
}
ngOnDestroy(): void {
this.subscription?.unsubscribe();
}
@HostListener('window:scroll', []) @HostListener('window:scroll', [])
onWindowScroll(): void { onWindowScroll(): void {
@ -59,4 +83,17 @@ export class HeaderComponent {
return ''; return '';
} }
} }
public openLoginDialog() {
const dialogRef = this.dialog.open(LoginDialogComponent, {
width: '400px',
})
dialogRef.afterClosed().subscribe(result => {
console.log(result);
});
}
public hasAccess(claims: string[]): boolean {
return this.authService.hasAccess(claims)
}
} }

View File

@ -112,4 +112,8 @@ export class AuthService {
const claims = this.userClaimsSubject.getValue(); const claims = this.userClaimsSubject.getValue();
return claims?.authorizations || []; return claims?.authorizations || [];
} }
public hasAccess(authorization: string[]): boolean {
return this.getUserAuthorizations().filter(entry => authorization.includes(entry)).length > 0;
}
} }

View File

@ -3,10 +3,19 @@
<form [formGroup]="loginForm"> <form [formGroup]="loginForm">
<mat-form-field appearance="fill" style="width: 100%"> <mat-form-field appearance="fill" style="width: 100%">
<mat-label>Enter your code</mat-label> <mat-label>Enter your code</mat-label>
<input matInput formControlName="code" type="text"> <input matInput formControlName="code" type="text" (keydown)="onKeyDown($event)">
<mat-error *ngIf="formHasError()"> <mat-error *ngIf="loginForm.get('code')?.errors?.['required']">
Code is required Code is required
</mat-error> </mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['minlength']">
Code must be 8 characters
</mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['maxlength']">
Code cannot exceed 8 characters
</mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['pattern']">
Code contains invalid characters
</mat-error>
</mat-form-field> </mat-form-field>
</form> </form>
</div> </div>

View File

@ -65,7 +65,23 @@ export class LoginDialogComponent {
}); });
} }
public formHasError() { onKeyDown(event: KeyboardEvent): void {
return this.loginForm.get('code')?.hasError('required'); if (event.key.length === 1 && event.key >= 'a' && event.key <= 'z') {
event.preventDefault();
const input = event.target as HTMLInputElement;
const start = input.selectionStart || 0;
const end = input.selectionEnd || 0;
const value = this.loginForm.get('code')?.value || '';
const newValue =
value.substring(0, start) +
event.key.toUpperCase() +
value.substring(end);
this.loginForm.get('code')?.setValue(newValue);
setTimeout(() => {
input.setSelectionRange(start + 1, start + 1);
});
}
} }
} }