feat: create EmailRequestComponent and integrate into ForgotPasswordComponent to separate responsibilities
This commit is contained in:
parent
927e58dd10
commit
14bb6c520c
6 changed files with 143 additions and 43 deletions
|
|
@ -0,0 +1,36 @@
|
||||||
|
<div class="note">
|
||||||
|
<p>We will send you an email with instructions to reset your password.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||||
|
<div class="email-field">
|
||||||
|
<input
|
||||||
|
formControlName="email"
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
placeholder="Email Address"
|
||||||
|
autocomplete="email"
|
||||||
|
[class.error-border]="
|
||||||
|
form.controls['email'].invalid && form.controls['email'].touched
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<img class="email-icon" src="./assets/img/email.svg" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="error-container">
|
||||||
|
@if (form.controls['email'].touched && form.controls['email'].invalid) {
|
||||||
|
<div class="error-msg">
|
||||||
|
@if (form.controls['email'].errors?.['required']) {
|
||||||
|
<p role="alert">Please enter your email</p>
|
||||||
|
} @if (form.controls['email'].errors?.['invalidEmailFormat']) {
|
||||||
|
<p role="alert">This is not a valid email format</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-btn-large
|
||||||
|
[value]="'Send Email'"
|
||||||
|
[disabled]="form.invalid || form.disabled"
|
||||||
|
></app-btn-large>
|
||||||
|
</form>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@use "./../../../../../assets/style/backgrounds.scss" as *;
|
||||||
|
@use "./../../../../../assets/style/form.scss" as *;
|
||||||
|
@use "./../../../../../assets/style/auth-layout.scss" as *;
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { EmailRequestComponent } from './email-request.component';
|
||||||
|
|
||||||
|
describe('EmailRequestComponent', () => {
|
||||||
|
let component: EmailRequestComponent;
|
||||||
|
let fixture: ComponentFixture<EmailRequestComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [EmailRequestComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(EmailRequestComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
|
import { BtnLargeComponent } from '../../../../shared/components/buttons/btn-large/btn-large.component';
|
||||||
|
import {
|
||||||
|
FormBuilder,
|
||||||
|
FormGroup,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
Validators,
|
||||||
|
} from '@angular/forms';
|
||||||
|
import { ErrorService } from '../../../../services/error.service';
|
||||||
|
import { AuthService } from '../../../../services/auth.service';
|
||||||
|
import { emailFormatValidator } from '../../../../validators/email-format.validator';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-email-request',
|
||||||
|
imports: [BtnLargeComponent, FormsModule, ReactiveFormsModule],
|
||||||
|
templateUrl: './email-request.component.html',
|
||||||
|
styleUrl: './email-request.component.scss',
|
||||||
|
})
|
||||||
|
export class EmailRequestComponent implements OnInit {
|
||||||
|
@Output() submittedChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
form: FormGroup = new FormGroup({});
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private errorService: ErrorService,
|
||||||
|
private authService: AuthService,
|
||||||
|
private fb: FormBuilder
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.createForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
async onSubmit(): Promise<void> {
|
||||||
|
if (this.form.valid) {
|
||||||
|
const body = this.createFormRequestBody();
|
||||||
|
this.form.disable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.authService.forgotPassword(body);
|
||||||
|
this.emitFormSubmitted();
|
||||||
|
} catch (error) {
|
||||||
|
this.errorService.handleError(error);
|
||||||
|
} finally {
|
||||||
|
this.form.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createForm(): void {
|
||||||
|
this.form = this.fb.group({
|
||||||
|
email: ['', [Validators.required, emailFormatValidator()]],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private createFormRequestBody(): { email: string } {
|
||||||
|
return {
|
||||||
|
email: this.form.value.email.toLowerCase(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private emitFormSubmitted(): void {
|
||||||
|
this.submittedChange.emit(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,48 +2,9 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="headline">Forgot your password?</div>
|
<div class="headline">Forgot your password?</div>
|
||||||
@if (!queryEmail && !sendEmailSuccess && !queryEmailSuccess) {
|
@if (!queryEmail && !sendEmailSuccess && !queryEmailSuccess) {
|
||||||
<div class="note">
|
<app-email-request
|
||||||
<p>We will send you an email with instructions to reset your password.</p>
|
(submittedChange)="submittedChange($event)"
|
||||||
</div>
|
></app-email-request>
|
||||||
<form
|
|
||||||
#taskForm="ngForm"
|
|
||||||
(ngSubmit)="onSubmit(taskForm, email)"
|
|
||||||
onsubmit="return false"
|
|
||||||
>
|
|
||||||
<div class="email-field">
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
#email="ngModel"
|
|
||||||
placeholder="Email Address"
|
|
||||||
class="custom-input"
|
|
||||||
autocomplete="email"
|
|
||||||
[(ngModel)]="authData.email"
|
|
||||||
[class.error-border]="
|
|
||||||
(!email.valid && email.touched) ||
|
|
||||||
(email.touched &&
|
|
||||||
!isUserEmailValid(authData.email.toLowerCase()) &&
|
|
||||||
authData.email.length > 0)
|
|
||||||
"
|
|
||||||
(click)="this.errorService.clearError()"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<img class="email-icon" src="./assets/img/email.svg" />
|
|
||||||
</div>
|
|
||||||
<div class="error-msg">
|
|
||||||
@if (!email.valid && email.touched) {
|
|
||||||
<p>Please enter your email</p>
|
|
||||||
} @else { @if (email.touched && authData.email.length > 0 &&
|
|
||||||
!isUserEmailValid(authData.email.toLowerCase())) {
|
|
||||||
<p>This is not a valid email format</p>
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
<app-btn-large
|
|
||||||
[value]="'Send Email'"
|
|
||||||
[disabled]="!isUserEmailValid(authData.email) || authData.send"
|
|
||||||
></app-btn-large>
|
|
||||||
</form>
|
|
||||||
} @else { @if (sendEmailSuccess) {
|
} @else { @if (sendEmailSuccess) {
|
||||||
<div class="note">
|
<div class="note">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,18 @@ import { FormsModule, NgForm } from '@angular/forms';
|
||||||
import { ActivatedRoute, Params, RouterLink } from '@angular/router';
|
import { ActivatedRoute, Params, RouterLink } from '@angular/router';
|
||||||
import { AuthService } from '../../../services/auth.service';
|
import { AuthService } from '../../../services/auth.service';
|
||||||
import { ErrorService } from '../../../services/error.service';
|
import { ErrorService } from '../../../services/error.service';
|
||||||
|
import { EmailRequestComponent } from './email-request/email-request.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-forgot-password',
|
selector: 'app-forgot-password',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [CommonModule, BtnLargeComponent, FormsModule, RouterLink],
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
BtnLargeComponent,
|
||||||
|
FormsModule,
|
||||||
|
RouterLink,
|
||||||
|
EmailRequestComponent,
|
||||||
|
],
|
||||||
templateUrl: './forgot-password.component.html',
|
templateUrl: './forgot-password.component.html',
|
||||||
styleUrl: './forgot-password.component.scss',
|
styleUrl: './forgot-password.component.scss',
|
||||||
})
|
})
|
||||||
|
|
@ -43,6 +50,10 @@ export class ForgotPasswordComponent implements OnInit {
|
||||||
this.handleQueryParams();
|
this.handleQueryParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submittedChange(value: boolean): void {
|
||||||
|
this.sendEmailSuccess = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes to query parameters and sets internal flags based on them.
|
* Subscribes to query parameters and sets internal flags based on them.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue