Enhance staff application flow with email verification checks, refined error handling, and improved user feedback in frontend and backend.

This commit is contained in:
2025-09-27 20:00:44 +02:00
parent cdbf862ecf
commit 311d77fcb2
5 changed files with 69 additions and 60 deletions
@@ -67,7 +67,14 @@
<div class="valid-email">
<ng-container matSuffix>
<mat-icon>check</mat-icon>
<span>You have validated your email previously, and can continue to the next page!</span>
<span>You have validated your email previously.</span>
</ng-container>
</div>
} @else {
<div class="invalid-email">
<ng-container matSuffix>
<mat-icon>close</mat-icon>
<span>You have not used this email address before. Before going to the next page you will be asked to verify it.</span>
</ng-container>
</div>
}
@@ -107,7 +114,8 @@
<!-- PC Requirements -->
<div class="checkbox-field">
<mat-checkbox formControlName="meetsRequirements">
I confirm that I meet the PC requirements (able to record video at 30fps 720p or higher, and able to talk in voice chat)
I confirm that I meet the PC requirements (able to record video at 30fps 720p or higher, and able
to talk in voice chat)
</mat-checkbox>
@if (form.controls.meetsRequirements.invalid && form.controls.meetsRequirements.touched) {
<mat-error class="checkbox-error">
@@ -172,7 +180,8 @@
<label class="field-label">Available days for moderating:</label>
<div class="days-container">
@for (day of availableDays; track day) {
<div class="day-chip" [class.selected]="form.controls.availableDays.value.includes(day)" (click)="toggleDay(day)">
<div class="day-chip" [class.selected]="form.controls.availableDays.value.includes(day)"
(click)="toggleDay(day)">
{{ day }}
</div>
}
@@ -188,9 +197,9 @@
<mat-form-field appearance="fill" style="width: 100%;">
<mat-label>Available times (Your timezone: {{ userTimezone }})</mat-label>
<textarea matInput
formControlName="availableTimes"
placeholder="e.g., 6PM-10PM weekdays, 2PM-8PM weekends"
rows="2"></textarea>
formControlName="availableTimes"
placeholder="e.g., 6PM-10PM weekdays, 2PM-8PM weekends"
rows="2"></textarea>
@if (form.controls.availableTimes.invalid && form.controls.availableTimes.touched) {
<mat-error>
Available times are required
@@ -215,9 +224,9 @@
<mat-form-field appearance="fill" style="width: 100%;">
<mat-label>Previous experience (here or in other relevant places)</mat-label>
<textarea matInput
formControlName="previousExperience"
placeholder="Describe your previous experience"
rows="4"></textarea>
formControlName="previousExperience"
placeholder="Describe your previous experience"
rows="4"></textarea>
@if (form.controls.previousExperience.invalid && form.controls.previousExperience.touched) {
<mat-error>
@if (form.controls.previousExperience.errors?.['required']) {
@@ -233,9 +242,9 @@
<mat-form-field appearance="fill" style="width: 100%;">
<mat-label>Experience with plugins that players use on our server</mat-label>
<textarea matInput
formControlName="pluginExperience"
placeholder="Describe your experience with our server plugins"
rows="4"></textarea>
formControlName="pluginExperience"
placeholder="Describe your experience with our server plugins"
rows="4"></textarea>
@if (form.controls.pluginExperience.invalid && form.controls.pluginExperience.touched) {
<mat-error>
@if (form.controls.pluginExperience.errors?.['required']) {
@@ -251,9 +260,9 @@
<mat-form-field appearance="fill" style="width: 100%;">
<mat-label>What do you believe the expectations of a moderator are?</mat-label>
<textarea matInput
formControlName="moderatorExpectations"
placeholder="Describe what you think a moderator should do"
rows="4"></textarea>
formControlName="moderatorExpectations"
placeholder="Describe what you think a moderator should do"
rows="4"></textarea>
@if (form.controls.moderatorExpectations.invalid && form.controls.moderatorExpectations.touched) {
<mat-error>
@if (form.controls.moderatorExpectations.errors?.['required']) {
@@ -269,9 +278,9 @@
<mat-form-field appearance="fill" style="width: 100%;">
<mat-label>Additional Information (Optional)</mat-label>
<textarea matInput
formControlName="additionalInfo"
placeholder="Any additional information you'd like to share"
rows="4"></textarea>
formControlName="additionalInfo"
placeholder="Any additional information you'd like to share"
rows="4"></textarea>
</mat-form-field>
</div>
<button mat-raised-button (click)="onSubmit()"
@@ -99,6 +99,16 @@ main {
background-color: rgba(76, 175, 80, 0.1);
}
.invalid-email {
display: flex;
align-items: center;
color: #af4c4c;
margin: 10px 0;
padding: 8px 12px;
border-radius: 4px;
background-color: rgba(76, 175, 80, 0.1);
}
.valid-email mat-icon {
color: #4CAF50;
margin-right: 10px;
@@ -107,7 +107,7 @@ export class StaffApplicationComponent implements OnInit, OnDestroy, AfterViewIn
}),
availableTimes: new FormControl('', {
nonNullable: true,
validators: [Validators.required, Validators.maxLength(1000)]
validators: [Validators.required, Validators.maxLength(900)]
}),
previousExperience: new FormControl('', {
nonNullable: true,
@@ -234,10 +234,11 @@ export class StaffApplicationComponent implements OnInit, OnDestroy, AfterViewIn
const staffApplication: StaffApplication = this.mapToStaffApplication(this.form.getRawValue());
this.staffApplicationService.submitStaffApplication(staffApplication).subscribe(result => {
//TODO route to mail page
// Navigate to the sent page
if (!result.verified_mail) {
throw new Error('Submitted a form with an e-mail that was not verified.');
}
this.router.navigate(['/forms/sent'], {
state: {message: 'Your staff application has been submitted successfully. We will review your application and get back to you soon.'}
state: {message: result.message}
}).then();
})
}
@@ -321,7 +322,7 @@ export class StaffApplicationComponent implements OnInit, OnDestroy, AfterViewIn
joinDate: joinDateString,
weeklyPlaytime: Number(formData.weeklyPlaytime),
availableDays: formData.availableDays,
availableTimes: formData.availableTimes,
availableTimes: `Timezone: ${this.userTimezone}\nAvailable Times:${formData.availableTimes}`,
previousExperience: formData.previousExperience,
pluginExperience: formData.pluginExperience,
moderatorExpectations: formData.moderatorExpectations,