Skip to content

Commit

Permalink
feat: Redesign error popover for sign in page (#3346)
Browse files Browse the repository at this point in the history
  • Loading branch information
bistaastha authored Dec 13, 2024
1 parent e8932a9 commit 5e0cc02
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 45 deletions.
21 changes: 14 additions & 7 deletions src/app/auth/sign-in/error/error.component.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
<div class="error-internal">
<div class="error-internal--header" id="sign-in--error-msg">
{{ header }}
<div class="error-internal__header" id="sign-in__error-msg">
<ion-icon
class="fy-icon-close error-internal__close-icon"
[src]="'/assets/svg/cross.svg'"
(click)="closePopover()"
></ion-icon>
<div class="error-internal__header__header-text">
{{ header }}
</div>
</div>
<div *ngIf="error" class="error-internal--details">
<div *ngIf="error" class="error-internal__details">
<div *ngIf="error.status === 401 && (error.data || error.message)">
This email address will be temporarily locked after 5 unsuccessful login attempts. Try
<a class="error-internal--redirect" (click)="routeTo(['/', 'auth', 'reset_password'])">resetting</a> your
This email address will be temporarily locked after 5 unsuccessful login attempts. Would you like to try
<a class="error-internal__redirect" (click)="routeTo(['/', 'auth', 'reset_password'])">resetting</a> your
password?
</div>

Expand All @@ -31,7 +38,7 @@
<div>Your organization has restricted Fyle access to its corporate network.</div>
</div>
</div>
<div class="error-internal--primary-cta">
<button mat-flat-button color="primary" (click)="tryAgainClicked()">TRY AGAIN</button>
<div class="error-internal__primary-cta">
<ion-button class="btn-primary" fill="clear" (click)="closePopover()">Try again</ion-button>
</div>
</div>
42 changes: 26 additions & 16 deletions src/app/auth/sign-in/error/error.component.scss
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
$details-color: #ababab;
@import '../../../../theme/colors.scss';

.error-internal {
&--header {
&__header {
font-size: 20px;
padding: 16px;
font-weight: 700;
}

&--details {
font-size: 16px;
padding: 0 16px;
font-weight: 500;
color: $details-color;
}
display: flex;
flex-direction: row;
border-bottom: 1px solid $grey-lighter;
gap: 12px;

&--primary-cta {
padding: 16px;
.mat-button-base {
&__header-text {
align-items: center;
justify-content: center;
width: 100%;
font-weight: 700;
min-height: 47px;
display: flex;
flex-direction: row;
}
}

&--redirect {
&__close-icon {
align-self: flex-start;
}

&__primary-cta {
padding: 0 16px 16px;
}

&__details {
font-size: 16px;
padding: 20px 16px;
color: $black;
}

&__redirect {
text-decoration: none;
}
}
20 changes: 10 additions & 10 deletions src/app/auth/sign-in/error/error.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ describe('ErrorComponent', () => {
});

it('should have a default header', () => {
expect(component.header).toEqual('Account does not Exist');
expect(component.header).toEqual('Account does not exist');
});

it('tryAgainClicked(): should dismiss the popover on try again button click', async () => {
const tryAgainBtn = getElementBySelector(fixture, '.error-internal--primary-cta button') as HTMLButtonElement;
it('closePopover(): should dismiss the popover on try again button click', async () => {
const tryAgainBtn = getElementBySelector(fixture, '.error-internal__primary-cta ion-button') as HTMLButtonElement;
click(tryAgainBtn);
fixture.detectChanges();
await fixture.whenStable();
Expand All @@ -59,18 +59,18 @@ describe('ErrorComponent', () => {
it('should display the correct error message for status 401 and data is present', () => {
component.error = { status: 401, data: { message: 'Invalid email or password' } };
fixture.detectChanges();
const errorMessage = getElementBySelector(fixture, '.error-internal--details');
const resetLink = getElementBySelector(fixture, '.error-internal--redirect');
const errorMessage = getElementBySelector(fixture, '.error-internal__details');
const resetLink = getElementBySelector(fixture, '.error-internal__redirect');
expect(getTextContent(errorMessage)).toContain(
'This email address will be temporarily locked after 5 unsuccessful login attempts. Try resetting your password?'
'This email address will be temporarily locked after 5 unsuccessful login attempts. Would you like to try resetting your password?'
);
expect(resetLink).toBeTruthy();
});

it('should display the correct error message for status 400', () => {
component.error = { status: 400 };
fixture.detectChanges();
const errorMessage = getElementBySelector(fixture, '.error-internal--details');
const errorMessage = getElementBySelector(fixture, '.error-internal__details');
expect(getTextContent(errorMessage)).toContain(
'Your account is not verified. Please request a verification link, if required'
);
Expand All @@ -79,7 +79,7 @@ describe('ErrorComponent', () => {
it('should display the correct error message for status 500', () => {
component.error = { status: 500 };
fixture.detectChanges();
const errorMessage = getElementBySelector(fixture, '.error-internal--details');
const errorMessage = getElementBySelector(fixture, '.error-internal__details');
const supportLink = getElementBySelector(fixture, 'a');
expect(getTextContent(errorMessage)).toContain(
'Please retry in a while. Send us a note to [email protected] if the problem persists.'
Expand All @@ -90,7 +90,7 @@ describe('ErrorComponent', () => {
it('should display the correct error message for status 433', () => {
component.error = { status: 433 };
fixture.detectChanges();
const errorMessage = getElementBySelector(fixture, '.error-internal--details');
const errorMessage = getElementBySelector(fixture, '.error-internal__details');
expect(getTextContent(errorMessage)).toContain(
'This email address is locked temporarily, as there are too many unsuccessful login attempts recently. Please retry later.'
);
Expand All @@ -99,7 +99,7 @@ describe('ErrorComponent', () => {
it('should display the correct error message for status 401 and no data or message is present', () => {
component.error = { status: 401 };
fixture.detectChanges();
const errorMessage = getElementBySelector(fixture, '.error-internal--details');
const errorMessage = getElementBySelector(fixture, '.error-internal__details');
expect(getTextContent(errorMessage)).toContain(
'Your organization has restricted Fyle access to its corporate network.'
);
Expand Down
13 changes: 5 additions & 8 deletions src/app/auth/sign-in/error/error.component.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input } from '@angular/core';
import { PopoverController } from '@ionic/angular';
import { Router } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
selector: 'app-error',
templateUrl: './error.component.html',
styleUrls: ['./error.component.scss'],
})
export class ErrorComponent implements OnInit {
@Input() header = 'Account does not Exist';
export class ErrorComponent {
@Input() header = 'Account does not exist';

@Input() error;

constructor(private popoverController: PopoverController, private router: Router) {}

ngOnInit() {}

async tryAgainClicked() {
async closePopover(): Promise<void> {
await this.popoverController.dismiss();
}

async routeTo(route: string[]) {
async routeTo(route: string[]): Promise<void> {
this.router.navigate(route);
await this.popoverController.dismiss();
}
Expand Down
3 changes: 1 addition & 2 deletions src/app/auth/sign-in/sign-in.page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ describe('SignInPage', () => {
fixture.detectChanges();
const emailError = fixture.debugElement.query(By.css('.sign-in__enter-email__error-message'));
expect(emailError).toBeDefined();
console.log(emailError);
expect(getTextContent(emailError.nativeElement)).toEqual('Please enter a valid email.');
});
});
Expand Down Expand Up @@ -305,7 +304,7 @@ describe('SignInPage', () => {
const errorPopoverSpy = jasmine.createSpyObj('errorPopover', ['present']);
popoverController.create.and.returnValue(errorPopoverSpy);

const header = 'Incorrect Email or Password';
const header = 'Incorrect email or password';

await component.handleError(null);

Expand Down
2 changes: 1 addition & 1 deletion src/app/auth/sign-in/sign-in.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class SignInPage implements OnInit {
}

async handleError(error: HttpErrorResponse): Promise<void> {
let header = 'Incorrect Email or Password';
let header = 'Incorrect email or password';

if (error?.status === 400) {
this.router.navigate(['/', 'auth', 'pending_verification', { email: this.fg.controls.email.value as string }]);
Expand Down
3 changes: 2 additions & 1 deletion src/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ ion-popover.dialog-popover {
left: 0 !important;
height: auto;
width: 100%;
border-radius: 0;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
}

.popover-viewport {
Expand Down

0 comments on commit 5e0cc02

Please sign in to comment.