Improve email verification flow by adding verified email pre-fill, validation handling, and dialog-based verification support.
This commit is contained in:
@@ -75,10 +75,14 @@
|
||||
<section class="formPage">
|
||||
<div class="description">
|
||||
<h2>Please enter your email.</h2>
|
||||
<p style="font-style: italic">It does not have to be your minecraft email.</p>
|
||||
<p style="font-style: italic">It does not have to be your minecraft email. You will have to verify
|
||||
it</p>
|
||||
<mat-form-field appearance="fill" style="width: 100%;">
|
||||
<mat-label>Email</mat-label>
|
||||
<input matInput formControlName="email" placeholder="Email">
|
||||
<input matInput
|
||||
formControlName="email"
|
||||
placeholder="Email"
|
||||
[defaultValue]="verifiedEmails().length > 0 ? verifiedEmails()[0] : ''">
|
||||
@if (form.controls.email.invalid && form.controls.email.touched) {
|
||||
<mat-error>
|
||||
@if (form.controls.email.errors?.['required']) {
|
||||
@@ -90,7 +94,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<button mat-raised-button (click)="nextPage()" [disabled]="form.controls.email.invalid">
|
||||
<button mat-raised-button (click)="validateMailOrNextPage()" [disabled]="form.controls.email.invalid">
|
||||
Next
|
||||
</button>
|
||||
</section>
|
||||
|
||||
@@ -21,6 +21,8 @@ import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {HistoryFormatService} from '@pages/reference/bans/history-format.service';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {SentComponent} from '@pages/forms/sent/sent.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-appeal',
|
||||
@@ -52,7 +54,11 @@ export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
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));
|
||||
protected verifiedEmails = computed(() => this.emails()
|
||||
.filter(email => email.verified)
|
||||
.map(email => email.email.toLowerCase()));
|
||||
protected validatedMail = signal<boolean>(false);
|
||||
protected dialog = inject(MatDialog);
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
@@ -64,7 +70,12 @@ export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
});
|
||||
this.mailService.getUserEmails().subscribe(emails => {
|
||||
this.emails.set(emails);
|
||||
})
|
||||
});
|
||||
this.form.valueChanges.subscribe(() => {
|
||||
if (this.form.getRawValue().email.toLowerCase() in this.verifiedEmails()) {
|
||||
this.validatedMail.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -202,6 +213,21 @@ export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
onPunishmentSelected($event: PunishmentHistory) {
|
||||
this.selectedPunishment.set($event);
|
||||
}
|
||||
|
||||
protected validateMailOrNextPage() {
|
||||
if (this.validatedMail()) {
|
||||
this.nextPage();
|
||||
return;
|
||||
}
|
||||
const dialogRef = this.dialog.open(SentComponent, {
|
||||
data: {email: this.form.getRawValue().email},
|
||||
});
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result === true) {
|
||||
this.validatedMail.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface Appeal {
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import {Component, inject, Input, input, signal} from '@angular/core';
|
||||
import {Component, Inject, inject, input, signal} from '@angular/core';
|
||||
import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms';
|
||||
import {MatInput, MatLabel} from '@angular/material/input';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
import {MailService, SubmitEmail, VerifyCode} from '@api';
|
||||
import {AuthService} from '@services/auth.service';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle} from '@angular/material/dialog';
|
||||
import {
|
||||
MAT_DIALOG_DATA,
|
||||
MatDialogActions,
|
||||
MatDialogContent,
|
||||
MatDialogRef,
|
||||
MatDialogTitle
|
||||
} from '@angular/material/dialog';
|
||||
import {interval, Subscription} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
@@ -38,10 +44,11 @@ export class SentComponent {
|
||||
|
||||
private mailService = inject(MailService);
|
||||
private authService = inject(AuthService);
|
||||
protected readonly email: string;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<SentComponent>,
|
||||
@Input() public email: string
|
||||
@Inject(MAT_DIALOG_DATA) public data: InputMail
|
||||
) {
|
||||
this.form = new FormGroup({
|
||||
code: new FormControl('', {
|
||||
@@ -49,6 +56,8 @@ export class SentComponent {
|
||||
validators: [Validators.required, Validators.minLength(6), Validators.maxLength(6)]
|
||||
})
|
||||
});
|
||||
this.email = data.email;
|
||||
this.mailService.submitEmailForVerification({email: this.email.toLowerCase()}).subscribe();
|
||||
}
|
||||
|
||||
public onSubmit() {
|
||||
@@ -81,7 +90,6 @@ export class SentComponent {
|
||||
|
||||
this.mailService.resendVerificationEmail(submitEmail).subscribe({
|
||||
next: (response) => {
|
||||
// Start cooldown timer
|
||||
this.startResendCooldown();
|
||||
},
|
||||
error: (error) => {
|
||||
@@ -147,3 +155,7 @@ interface VerifyMailData {
|
||||
verified: boolean;
|
||||
mail: string;
|
||||
}
|
||||
|
||||
interface InputMail {
|
||||
email: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user