diff options
3 files changed, 85 insertions, 41 deletions
diff --git a/ufund-ui/src/app/components/signup/signup.component.css b/ufund-ui/src/app/components/signup/signup.component.css index 799cbd2..2fa5051 100644 --- a/ufund-ui/src/app/components/signup/signup.component.css +++ b/ufund-ui/src/app/components/signup/signup.component.css @@ -16,16 +16,27 @@  }  #bar { +    height: 5px;      width: 100%; -    height: 20px; -    -webkit-appearance: none;      appearance: none; -    border: none; -    border-radius: 10px;      overflow: hidden; -    background-color: red; +    margin-top: -5px;  } -#requirement2 { +#bar::-webkit-progress-bar { +    background-color: lightgray; +    transition: width 0.5s ease-in-out, background-color 0.5s ease-in-out; +} + +.color0::-webkit-progress-value { background: rgba(255, 0 ,0, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } +.color1::-webkit-progress-value { background: rgba(255, 0 ,0, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } +.color2::-webkit-progress-value { background: rgba(255, 165, 0, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } +.color3::-webkit-progress-value { background: rgba(255, 255, 0, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } +.color4::-webkit-progress-value { background: rgba(173, 255, 47, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } +.color5::-webkit-progress-value { background: rgba(50, 205, 50, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } +.color6::-webkit-progress-value { background: rgba(0, 128, 0, 1); transition: background-color 0.5s ease-in-out, width 0.5s ease-in-out; } + +#requirement2, #statusText, #passwordStatusText, #usernameStatusText {      color: red;  } + diff --git a/ufund-ui/src/app/components/signup/signup.component.html b/ufund-ui/src/app/components/signup/signup.component.html index 1b50d39..e078123 100644 --- a/ufund-ui/src/app/components/signup/signup.component.html +++ b/ufund-ui/src/app/components/signup/signup.component.html @@ -1,16 +1,13 @@  <p>Signup:</p> -<input placeholder="Username" type="text" #username> -<input placeholder="Password" type="password" (input)="checkPasswordStrength(password.value)" #password> -<button type="button" [disabled]="passwordStrongEnough | async" (click)="signup(username.value, password.value)">Create Account</button> - -<div id="requirement2" *ngIf="test"> {{test | async}} </div> - -<progress id="bar" [value]="strength | async" max="6">  </progress> - -<span *ngFor="let requirement of passwordRequirements"> -    <span id="requirement" *ngIf="passwordRequirements" [style.color]="color | async"> {{requirement}} </span> +<input placeholder="Username" type="text" (input)="comparePassword(username.value, confirmPass.value, password.value)" #username> +<span id="usernameStatusText" *ngIf="usernameStatusText">{{usernameStatusText | async}}</span> +<input placeholder="Password" type="password" (input)="comparePassword(username.value, confirmPass.value, password.value)" #password> +<progress [ngClass]="'color' + strength.getValue()" id="bar" [value]="strength | async" max="6">  </progress> +<span id="statusText" *ngIf="statusText">{{statusText | async}}</span> +<span *ngFor="let requirement of Object.values(passwordRequirements)"> +    <span id="requirement" *ngIf="passwordRequirements" [style.color]="requirement.value ? 'green' : 'red'"> {{requirement.title}} </span>  </span> - -<span *ngIf="statusText">{{statusText | async}}</span> -<span *ngIf="strength">{{strength | async}}</span> +<input placeholder="Confirm password" type="password" (input)="comparePassword(username.value, confirmPass.value, password.value)" #confirmPass> +<span id="passwordStatusText" *ngIf="passwordStatusText">{{passwordStatusText | async}}</span> +<button type="button" [disabled]="!(ableToCreateAccount | async)" (click)="signup(username.value, password.value)">Create Account</button>  <span *ngIf="showSuccessMessage | async">Account created <a routerLink="/login">Proceed to login</a></span> diff --git a/ufund-ui/src/app/components/signup/signup.component.ts b/ufund-ui/src/app/components/signup/signup.component.ts index 9532e42..b3432e6 100644 --- a/ufund-ui/src/app/components/signup/signup.component.ts +++ b/ufund-ui/src/app/components/signup/signup.component.ts @@ -1,23 +1,34 @@ -import { Component } from '@angular/core'; +import {Component, ElementRef, ViewChild} from '@angular/core';  import {UsersService} from '../../services/users.service';  import {Router} from '@angular/router';  import {BehaviorSubject} from 'rxjs'; +class PasswordRequirements { +    sixLong:   {title: string, value: boolean} = {title: 'Is 6 characters or longer', value: false} +    twelveLong:   {title: string, value: boolean} = {title: 'Is 12 characters or longer', value: false} +    lowercase: {title: string, value: boolean} = {title: 'Includes lowercase letter', value: false} +    uppercase: {title: string, value: boolean} = {title: 'Includes uppercase letter', value: false} +    number:    {title: string, value: boolean} = {title: 'Includes number'          , value: false} +    symbol:    {title: string, value: boolean} = {title: 'Includes symbol'          , value: false} +} +  @Component({    selector: 'app-signup',    standalone: false,    templateUrl: './signup.component.html',    styleUrl: './signup.component.css'  }) +  export class SignupComponent {      protected statusText = new BehaviorSubject("") +    protected passwordStatusText = new BehaviorSubject("") +    protected usernameStatusText = new BehaviorSubject("")      protected showSuccessMessage = new BehaviorSubject(false) -    protected passwordStrongEnough = new BehaviorSubject(true) -    passwordRequirements: String[] = [("❌ Password length"), ("❌ Lowercase letters")]; +    protected passwordStrongEnough = new BehaviorSubject(false) +    protected ableToCreateAccount = new BehaviorSubject(false) +    protected passwordRequirements: PasswordRequirements = new PasswordRequirements()      protected strength = new BehaviorSubject(0) -    protected color = new BehaviorSubject("red") -    protected test = new BehaviorSubject("Password does not meet requirements")      constructor(          protected usersService: UsersService, @@ -38,49 +49,74 @@ export class SignupComponent {          })      } +    comparePassword(username: string, passConfirm:string, password: string) { +        this.passwordStatusText.next("") +        this.usernameStatusText.next("") +        this.checkPasswordStrength(password); + +        if (username === "") { +            this.usernameStatusText.next("Username field can't be blank") +        } + +        if (!(password === passConfirm) && !!passConfirm) { +            this.passwordStatusText.next("Passwords don't match") +        } +        this.ableToCreateAccount.next(this.passwordStrongEnough.getValue() && password === passConfirm && !!username) +    } +      checkPasswordStrength(password: string) { -        this.passwordRequirements = [("❌ Password length"), ("❌ Lowercase letters")]; -        this.test.next("Password does not meet requirements") -        this.statusText.next("") -        this.passwordStrongEnough.next(true) -        this.color.next("red") +        this.strength.next(0) +        this.passwordRequirements = new PasswordRequirements() +        this.passwordStrongEnough.next(false)          if (password.match(/[^!-~]/g)) {              this.statusText.next("Invalid characters") +              return          } -        let strength = 0;          if (password.length > 6) { -            strength++ -            this.passwordRequirements[0] = "✅ Password length" -            this.color.next("green") +            this.passwordRequirements.sixLong.value = true          }          if (password.length > 12) { -            strength++ +            this.passwordRequirements.twelveLong.value = true          }          if (password.match(/[a-z]/g)) { -            strength++ +            this.passwordRequirements.lowercase.value = true          }          if (password.match(/[A-Z]/g)) { -            strength++ +            this.passwordRequirements.uppercase.value = true          }          if (password.match(/[0-9]/g)) { -            strength++ +            this.passwordRequirements.number.value = true          } -        if (password.match(/[!-/]/g)) { -            strength++ +        if (password.match(/[^A-Za-z0-9]/g)) { +            this.passwordRequirements.symbol.value = true          } +        let strength = 0 +        Object.values(this.passwordRequirements).forEach(k => { +            k.value && strength++ +        }) +          if (strength >= 5) { -            this.passwordStrongEnough.next(false) -            this.test.next("") +            this.passwordStrongEnough.next(true) +            this.statusText.next("") +        } else if (strength == 0) { +            this.statusText.next("") +        } else { +            this.statusText.next("Password does not meet requirements")          }          this.strength.next(strength)      } +    getColor() { +        return `rgba(${(this.strength.getValue()/7) * 255}, ${255 - (this.strength.getValue()/7) * 255}, 0)` +    } +      protected readonly length = length; +    protected readonly Object = Object;  }  let friendlyHttpStatus: {[key: number]: string} = {  | 
