Add email verification functionality, including backend support, email handling, and user interface integration.

This commit is contained in:
2025-08-23 21:46:10 +02:00
parent da17cf9696
commit 641083732d
26 changed files with 878 additions and 57 deletions
@@ -1,6 +1,16 @@
import {AfterViewInit, Component, ElementRef, OnInit, Renderer2, signal} from '@angular/core';
import {
AfterViewInit,
Component,
computed,
ElementRef,
inject,
OnDestroy,
OnInit,
Renderer2,
signal
} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {AppealsService, HistoryService, MinecraftAppeal, PunishmentHistory} from '@api';
import {AppealsService, EmailEntry, HistoryService, MailService, MinecraftAppeal, PunishmentHistory} from '@api';
import {HeaderComponent} from '@header/header.component';
import {NgOptimizedImage} from '@angular/common';
import {MatButtonModule} from '@angular/material/button';
@@ -28,19 +38,23 @@ import {HistoryFormatService} from '@pages/reference/bans/history-format.service
templateUrl: './appeal.component.html',
styleUrl: './appeal.component.scss'
})
export class AppealComponent implements OnInit, AfterViewInit {
export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
public form: FormGroup<Appeal>;
private mailService = inject(MailService);
private historyFormatService = inject(HistoryFormatService);
private appealsService = inject(AppealsService);
private historyService = inject(HistoryService);
public authService = inject(AuthService);
private resizeObserver: ResizeObserver | null = null;
private boundHandleResize: any;
protected form: FormGroup<Appeal>;
protected history = signal<PunishmentHistory[] | null>(null);
protected selectedPunishment = signal<PunishmentHistory | null>(null);
private emails = signal<EmailEntry[]>([]);
protected verifiedEmails = computed(() => this.emails().filter(email => email.verified));
constructor(
private historyFormatService: HistoryFormatService,
private appealApi: AppealsService,
private historyApi: HistoryService,
protected authService: AuthService,
private elementRef: ElementRef,
private renderer: Renderer2
) {
@@ -48,6 +62,9 @@ export class AppealComponent implements OnInit, AfterViewInit {
email: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.email]}),
appeal: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.minLength(10)]})
});
this.mailService.getUserEmails().subscribe(emails => {
this.emails.set(emails);
})
}
ngOnInit() {
@@ -55,7 +72,7 @@ export class AppealComponent implements OnInit, AfterViewInit {
if (uuid === null) {
throw new Error('JWT subject is null, are you logged in?');
}
this.historyApi.getAllHistoryForUUID(uuid).subscribe(history => {
this.historyService.getAllHistoryForUUID(uuid).subscribe(history => {
this.history.set(history.filter(item => this.historyFormatService.isActive(item)));
})
}
@@ -149,7 +166,7 @@ export class AppealComponent implements OnInit, AfterViewInit {
username: this.authService.username()!,
uuid: uuid
}
this.appealApi.submitMinecraftAppeal(appeal).subscribe()
this.appealsService.submitMinecraftAppeal(appeal).subscribe()
}
public currentPageIndex: number = 0;