Skip to content

Commit 89cb0bb

Browse files
McNaBrylimcaaarlsamuelim01
authored
Enhance Login & Registration Pages (#57)
* Add UI enhancement to login and registration pages Add icons to the input field labels Remove primeNG password feedback and replace with password requirements list * Fix linting * Adjust styling for login and registration pages * Improve password requirements list * Remove weak password message * Conditionally render password list when user starts modifying the password field * Hide requirements and display a success message when user satisfies all requirements * Refactor code to render each requirement and improve naming for password validators * Fix linting * Fix nav bar Previously, the submenu's position was not relative to the body, this causes the submenu to be out of position * Update submenu to hide on scroll * Keep variables on top * Remove direct DOM manipulation * Add spinner when redirecting user to workspace --------- Co-authored-by: limcaaarl <[email protected]> Co-authored-by: Samuel Lim <[email protected]>
1 parent 6bf6136 commit 89cb0bb

18 files changed

+234
-68
lines changed

frontend/src/app/account/_validators/invalid-password.validator.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export const PASSWORD_INVALID = 'passwordInvalid';
66

77
export function invalidPasswordValidator(): ValidatorFn {
88
return (control: AbstractControl): ValidationErrors | null => {
9-
const weak = !PASSWORD_REGEX.test(control.value);
9+
const password = control.value;
10+
const weak = password && !PASSWORD_REGEX.test(password);
1011
return weak ? { [PASSWORD_INVALID]: true } : null;
1112
};
1213
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2+
3+
export const LOWERCASE_PASSWORD_REGEX = /^(?=.*[a-z])/;
4+
5+
export const PASSWORD_LOWERCASE = 'passwordLowercase';
6+
7+
export function lowercasePasswordValidator(): ValidatorFn {
8+
return (control: AbstractControl): ValidationErrors | null => {
9+
const missingLowercase = !LOWERCASE_PASSWORD_REGEX.test(control.value);
10+
return missingLowercase ? { [PASSWORD_LOWERCASE]: true } : null;
11+
};
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2+
3+
export const NUMERIC_PASSWORD_REGEX = /^(?=.*[0-9])/;
4+
5+
export const PASSWORD_NUMERIC = 'passwordNumeric';
6+
7+
export function numericPasswordValidator(): ValidatorFn {
8+
return (control: AbstractControl): ValidationErrors | null => {
9+
const missingNumeric = !NUMERIC_PASSWORD_REGEX.test(control.value);
10+
return missingNumeric ? { [PASSWORD_NUMERIC]: true } : null;
11+
};
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2+
3+
export const SHORT_PASSWORD_REGEX = /^(?=.{8,})/;
4+
5+
export const PASSWORD_SHORT = 'passwordShort';
6+
7+
export function shortPasswordValidator(): ValidatorFn {
8+
return (control: AbstractControl): ValidationErrors | null => {
9+
const short = !SHORT_PASSWORD_REGEX.test(control.value);
10+
return short ? { [PASSWORD_SHORT]: true } : null;
11+
};
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2+
3+
export const SPECIAL_PASSWORD_REGEX = /^(?=.*[!"#$%&'()*+,-.:;<=>?@\\/\\[\]^_`{|}~])/;
4+
5+
export const PASSWORD_SPECIAL = 'passwordSpecial';
6+
7+
export function specialPasswordValidator(): ValidatorFn {
8+
return (control: AbstractControl): ValidationErrors | null => {
9+
const missingSpecial = !SPECIAL_PASSWORD_REGEX.test(control.value);
10+
return missingSpecial ? { [PASSWORD_SPECIAL]: true } : null;
11+
};
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2+
3+
export const UPPERCASE_PASSWORD_REGEX = /^(?=.*[A-Z])/;
4+
5+
export const PASSWORD_UPPERCASE = 'passwordUppercase';
6+
7+
export function uppercasePasswordValidator(): ValidatorFn {
8+
return (control: AbstractControl): ValidationErrors | null => {
9+
const missingUppercase = !UPPERCASE_PASSWORD_REGEX.test(control.value);
10+
return missingUppercase ? { [PASSWORD_UPPERCASE]: true } : null;
11+
};
12+
}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2-
3-
export const STRONG_PASSWORD_REGEX =
4-
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})(?=.*[!"#$%&'()*+,-.:;<=>?@\\/\\[\]^_`{|}~])/;
2+
import { LOWERCASE_PASSWORD_REGEX } from './lowercase-password';
3+
import { UPPERCASE_PASSWORD_REGEX } from './uppercase-password';
4+
import { NUMERIC_PASSWORD_REGEX } from './numeric-password';
5+
import { SPECIAL_PASSWORD_REGEX } from './special-password';
6+
import { SHORT_PASSWORD_REGEX } from './short-password';
57

68
export const PASSWORD_WEAK = 'passwordWeak';
79

810
export function weakPasswordValidator(): ValidatorFn {
911
return (control: AbstractControl): ValidationErrors | null => {
10-
const weak = !STRONG_PASSWORD_REGEX.test(control.value);
12+
const weak = !(
13+
LOWERCASE_PASSWORD_REGEX.test(control.value) &&
14+
UPPERCASE_PASSWORD_REGEX.test(control.value) &&
15+
NUMERIC_PASSWORD_REGEX.test(control.value) &&
16+
SPECIAL_PASSWORD_REGEX.test(control.value) &&
17+
SHORT_PASSWORD_REGEX.test(control.value)
18+
);
1119
return weak ? { [PASSWORD_WEAK]: true } : null;
1220
};
1321
}

frontend/src/app/account/account.component.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
.layout-container {
2+
display: flex;
3+
flex-direction: column;
4+
min-height: calc(100vh - 80px);
5+
width: 100%;
6+
justify-content: center;
7+
align-items: center;
8+
padding: 1rem;
9+
}
10+
111
.container {
212
padding: 2rem;
313
background-color: var(--surface-section);
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
<div class="flex flex-column h-full w-full justify-content-center align-items-center p-2" style="margin-top: -80px">
2-
<h2 class="mb-2">Welcome to PeerPrep</h2>
1+
<div class="layout-container">
32
<router-outlet></router-outlet>
43
</div>

frontend/src/app/account/layout.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Router, RouterModule } from '@angular/router';
55
standalone: true,
66
imports: [RouterModule],
77
templateUrl: './layout.component.html',
8+
styleUrl: './account.component.css',
89
})
910
export class LayoutComponent {
1011
constructor(private router: Router) {}

0 commit comments

Comments
 (0)