Running Prettier in Project

This commit is contained in:
2023-10-14 19:17:28 -03:00
parent 3bdc66f8fb
commit b1b90f10d7
100 changed files with 18174 additions and 17212 deletions

View File

@@ -3,21 +3,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CallbackComponent } from './callback.component';
describe('CallbackComponent', () => {
let component: CallbackComponent;
let fixture: ComponentFixture<CallbackComponent>;
let component: CallbackComponent;
let fixture: ComponentFixture<CallbackComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CallbackComponent ]
})
.compileComponents();
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [CallbackComponent],
}).compileComponents();
fixture = TestBed.createComponent(CallbackComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fixture = TestBed.createComponent(CallbackComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -5,35 +5,32 @@ import { AuthService } from 'src/app/shared/auth/auth.service';
@Component({
selector: 'app-callback',
templateUrl: './callback.component.html',
styleUrls: ['./callback.component.css']
styleUrls: ['./callback.component.css'],
})
export class CallbackComponent implements OnInit {
constructor(private route: ActivatedRoute,
constructor(
private route: ActivatedRoute,
private router: Router,
private authService: AuthService) { }
private authService: AuthService,
) {}
ngOnInit(): void {
this.route.queryParams.subscribe(p => {
this.route.queryParams.subscribe((p) => {
let auth: 'google' | 'github' = p['auth'];
switch (auth) {
case "github":
this.authService.loginGithubUser(p)
break;
case "google":
this.authService.loginGoogleUser(p)
break;
default:
console.log(`Unimplemented auth: ${auth}`)
break;
case 'github':
this.authService.loginGithubUser(p);
break;
case 'google':
this.authService.loginGoogleUser(p);
break;
default:
console.log(`Unimplemented auth: ${auth}`);
break;
}
this.router.navigate(['/home'])
})
this.router.navigate(['/home']);
});
}
}

View File

@@ -1,3 +1,3 @@
<div class="error-box" *ngIf="errorMessage">
{{errorMessage}}
{{ errorMessage }}
</div>

View File

@@ -3,21 +3,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ErrorBoxComponent } from './error-box.component';
describe('ErrorBoxComponent', () => {
let component: ErrorBoxComponent;
let fixture: ComponentFixture<ErrorBoxComponent>;
let component: ErrorBoxComponent;
let fixture: ComponentFixture<ErrorBoxComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ErrorBoxComponent ]
})
.compileComponents();
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ErrorBoxComponent],
}).compileComponents();
fixture = TestBed.createComponent(ErrorBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fixture = TestBed.createComponent(ErrorBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,14 +1,13 @@
import {Component, Input} from '@angular/core';
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-error-box',
templateUrl: './error-box.component.html',
styleUrls: ['./error-box.component.css']
styleUrls: ['./error-box.component.css'],
})
export class ErrorBoxComponent {
export class ErrorBoxComponent {
@Input()
errorMessage: string|null = "Error, please try again later."
constructor() { }
errorMessage: string | null = 'Error, please try again later.';
constructor() {}
}

View File

@@ -1,28 +1,32 @@
<app-popup [state]="state"
(stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside">
<app-popup
[state]="state"
(stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside"
>
<div class="help-container container m-0 overflow-hidden">
<p>
This is a simple example project to demonstrate
User Authentication and Authorization using
<a href="https://spring.io/projects/spring-security" target="_blank">Spring Security</a>
This is a simple example project to demonstrate User Authentication
and Authorization using
<a href="https://spring.io/projects/spring-security" target="_blank"
>Spring Security</a
>
and
<a href="https://docs.spring.io/spring-security/reference/servlet/oauth2/" target="_blank">OAuth2</a>.
<a
href="https://docs.spring.io/spring-security/reference/servlet/oauth2/"
target="_blank"
>OAuth2</a
>.
<br/><br/>
<br /><br />
The only data stored is your email address, username and name.
This data is stored in a database and is used to authenticate you
and will not be used for any other purpose.
The only data stored is your email address, username and name. This
data is stored in a database and is used to authenticate you and
will not be used for any other purpose.
<br/><br/>
<br /><br />
All data can be deleted by clicking the "Delete Account" button
on the "My Profile" option.
All data can be deleted by clicking the "Delete Account" button on
the "My Profile" option.
</p>
</div>
</app-popup>

View File

@@ -3,21 +3,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HelpComponent } from './help.component';
describe('HelpComponent', () => {
let component: HelpComponent;
let fixture: ComponentFixture<HelpComponent>;
let component: HelpComponent;
let fixture: ComponentFixture<HelpComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ HelpComponent ]
})
.compileComponents();
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [HelpComponent],
}).compileComponents();
fixture = TestBed.createComponent(HelpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fixture = TestBed.createComponent(HelpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,22 +1,21 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-help',
templateUrl: './help.component.html',
styleUrls: ['./help.component.css']
styleUrls: ['./help.component.css'],
})
export class HelpComponent {
@Input()
state: boolean = false;
@Input()
state: boolean = false;
@Input()
ignoreClickOutside!: HTMLDivElement[];
ignoreClickOutside!: HTMLDivElement[];
@Output()
stateChange = new EventEmitter<boolean>();
stateChange = new EventEmitter<boolean>();
constructor() { }
constructor() {}
onStateChange(state: boolean) {
this.stateChange.emit(state);

View File

@@ -17,7 +17,7 @@
}
.authentication-body .btn {
background-color: #D8291C !important;
background-color: #d8291c !important;
text-decoration: none;
border-radius: 8px;
color: #ffffff;
@@ -67,7 +67,7 @@
border-bottom: 2px solid #7676769b;
}
.input-div:after {
content: '';
content: "";
left: 0;
right: 0;
width: 0;
@@ -81,11 +81,12 @@
.input-div:hover:after,
.input-div:has(input.form-control:focus):after {
width: 100%;
transition: .4s;
transition: 0.4s;
overflow: hidden;
}
.input-div > .form-control, .input-div > .form-control:hover{
.input-div > .form-control,
.input-div > .form-control:hover {
border: none;
border-color: inherit;
-webkit-box-shadow: none;
@@ -98,7 +99,7 @@
font-size: 17px;
color: #767676;
}
.input-div >.form-control:-webkit-autofill {
.input-div > .form-control:-webkit-autofill {
-webkit-text-fill-color: #767676;
box-shadow: 0 0 0px 1000px #ffffff inset;
-webkit-box-shadow: 0 0 0px 1000px #ffffff inset;
@@ -108,19 +109,16 @@
.input-div:hover > .form-control::placeholder,
.input-div:hover > .input-div-icon,
.input-div:has(input.form-control:focus) > .input-div-icon {
color: #D8291C;
transition: .3s;
color: #d8291c;
transition: 0.3s;
}
.input-div:hover > .form-control::placeholder,
.input-div:has(input.form-control:focus) > .form-control::placeholder {
font-weight: 500;
transition: .3s;
transition: 0.3s;
}
@media (min-width:767px) {
@media (min-width: 767px) {
.authentication-container {
min-width: 630px;
}
@@ -150,5 +148,4 @@
border-right: 2px solid #80808076;
height: 100%;
}
}

View File

@@ -1,41 +1,56 @@
<app-popup [state]="state"
<app-popup
[state]="state"
(stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside">
<div class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()">
<app-error-box [errorMessage]="errorMessage"
[@showErrorMessage]="showErrorMessage()">
[ignoreClickOutside]="ignoreClickOutside"
>
<div
class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()"
>
<app-error-box
[errorMessage]="errorMessage"
[@showErrorMessage]="showErrorMessage()"
>
</app-error-box>
<div class="container authentication-container"
[@hideAuthContainer]="hideErrorMessage()"
(@hideAuthContainer.done)="hideAuthContainer($event)">
<div
class="container authentication-container"
[@hideAuthContainer]="hideErrorMessage()"
(@hideAuthContainer.done)="hideAuthContainer($event)"
>
<div class="row">
<div class="col-lg-6 authentication-body">
<form [formGroup]="loginForm" (ngSubmit)="onLogin()">
<div class="input-div">
<fa-icon class="input-div-icon"
[icon]="_userIcon">
<fa-icon class="input-div-icon" [icon]="_userIcon">
</fa-icon>
<input type="text" id="username"
formControlName="username"
class="form-control"
placeholder="Username">
<input
type="text"
id="username"
formControlName="username"
class="form-control"
placeholder="Username"
/>
</div>
<div class="input-div">
<fa-icon class="input-div-icon"
[icon]="_passwordIcon">
<fa-icon
class="input-div-icon"
[icon]="_passwordIcon"
>
</fa-icon>
<input type="password" id="password"
formControlName="password"
class="form-control"
placeholder="Password">
<input
type="password"
id="password"
formControlName="password"
class="form-control"
placeholder="Password"
/>
</div>
<button class="btn"
[disabled]="loginForm.invalid"
type="submit">
<button
class="btn"
[disabled]="loginForm.invalid"
type="submit"
>
Login
</button>
</form>
@@ -44,30 +59,38 @@
<div class="line"></div>
</div>
<div class="col-lg-6 authentication-body">
<button mat-button
class="oauth-button d-flex justify-content-center align-items-center"
[disabled]="isCookieBlocked"
(click)="onGoogleLogin()">
<mat-icon *ngIf="!isCookieBlocked"
style="width: 50px; height:30px"
svgIcon="google-logo"></mat-icon>
<mat-icon *ngIf="isCookieBlocked"
style="width: 50px; height:30px"
svgIcon="google-disabled-logo"></mat-icon>
<button
mat-button
class="oauth-button d-flex justify-content-center align-items-center"
[disabled]="isCookieBlocked"
(click)="onGoogleLogin()"
>
<mat-icon
*ngIf="!isCookieBlocked"
style="width: 50px; height: 30px"
svgIcon="google-logo"
></mat-icon>
<mat-icon
*ngIf="isCookieBlocked"
style="width: 50px; height: 30px"
svgIcon="google-disabled-logo"
></mat-icon>
Login With Google
</button>
<button mat-button
class="oauth-button d-flex justify-content-center align-items-center"
[disabled]="isCookieBlocked"
(click)="onGithubLogin()">
<mat-icon style="width: 50px; height:30px"
svgIcon="github-logo"></mat-icon>
<button
mat-button
class="oauth-button d-flex justify-content-center align-items-center"
[disabled]="isCookieBlocked"
(click)="onGithubLogin()"
>
<mat-icon
style="width: 50px; height: 30px"
svgIcon="github-logo"
></mat-icon>
Login With Github
</button>
</div>
</div>
</div>
</div>
</app-popup>

View File

@@ -8,9 +8,8 @@ describe('LoginComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LoginComponent ]
})
.compileComponents();
declarations: [LoginComponent],
}).compileComponents();
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;

View File

@@ -1,24 +1,44 @@
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import {
AfterViewInit,
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
} from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { faLock, faUser } from '@fortawesome/free-solid-svg-icons';
import {Subscription} from 'rxjs';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/shared/auth/auth.service';
import { HttpError } from 'src/app/shared/model/httpError/httpError.model';
import HttpErrorChecker from 'src/app/shared/model/httpError/httpErrorChecker';
import UserChecker from 'src/app/shared/model/user/user.checker';
import { User } from 'src/app/shared/model/user/user.model';
import {animate, animateChild, group, query, state, style, transition, trigger} from "@angular/animations";
import {ValidatePasswordValidator} from "../../../shared/validators/validate-password.validator";
import {ValidateNotEmptyValidator} from "../../../shared/validators/validate-not-empty.validator";
import {NgcCookieConsentService, NgcStatusChangeEvent} from "ngx-cookieconsent";
import {CookieConsertService} from "../../../shared/cookie-consent/cookie-consert.service";
import {
animate,
animateChild,
group,
query,
state,
style,
transition,
trigger,
} from '@angular/animations';
import { ValidatePasswordValidator } from '../../../shared/validators/validate-password.validator';
import { ValidateNotEmptyValidator } from '../../../shared/validators/validate-not-empty.validator';
import {
NgcCookieConsentService,
NgcStatusChangeEvent,
} from 'ngx-cookieconsent';
import { CookieConsertService } from '../../../shared/cookie-consent/cookie-consert.service';
const GOOGLE_LOGO_SVG = "assets/img/providers/google.svg";
const GOOGLE_DISABLED_LOGO_SVG = "assets/img/providers/google-disabled.svg";
const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
const GOOGLE_LOGO_SVG = 'assets/img/providers/google.svg';
const GOOGLE_DISABLED_LOGO_SVG = 'assets/img/providers/google-disabled.svg';
const GITHUB_LOGO_SVG = 'assets/img/providers/github.svg';
@Component({
selector: 'app-login',
@@ -26,78 +46,66 @@ const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
styleUrls: ['./login.component.css'],
animations: [
trigger('resizeContainerForErrorMessage', [
state('hide',
state(
'hide',
style({
height: '100px',
width: '320px',
})
}),
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate('1s ease')
])
)
query('@*', animateChild(), { optional: true }),
animate('1s ease'),
]),
),
]),
trigger('showErrorMessage', [
state('show',
state(
'show',
style({
opacity: 1,
height: '100px',
width: '320px',
})
}),
),
state('hide',
state(
'hide',
style({
opacity: 0,
height: '0px',
width: '0px',
})
),
transition(
'* => show',
animate(
'500ms ease-in'
)
}),
),
transition('* => show', animate('500ms ease-in')),
]),
trigger('hideAuthContainer', [
state('hide',
state(
'hide',
style({
opacity: 0,
})
}),
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate(
'250ms ease-out'
)
])
)
query('@*', animateChild(), { optional: true }),
animate('250ms ease-out'),
]),
),
]),
]
],
})
export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
@Input()
state: boolean = false;
@Input()
state: boolean = false;
@Input()
ignoreClickOutside!: HTMLDivElement[];
ignoreClickOutside!: HTMLDivElement[];
@Output()
stateChange = new EventEmitter<boolean>();
stateChange = new EventEmitter<boolean>();
loginForm!: FormGroup;
@@ -121,39 +129,47 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
private cookieConsentService: CookieConsertService,
private changeDetectorRef: ChangeDetectorRef,
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer) {
private domSanitizer: DomSanitizer,
) {
this.matIconRegistry.addSvgIcon(
"google-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG)
'google-logo',
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG),
);
this.matIconRegistry.addSvgIcon(
"google-disabled-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_DISABLED_LOGO_SVG)
)
'google-disabled-logo',
this.domSanitizer.bypassSecurityTrustResourceUrl(
GOOGLE_DISABLED_LOGO_SVG,
),
);
this.matIconRegistry.addSvgIcon(
"github-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG)
'github-logo',
this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG),
);
}
ngOnInit(): void {
this.loginForm = new FormGroup({
'username': new FormControl(null, [Validators.required, ValidateNotEmptyValidator]),
'password': new FormControl(null, [Validators.required, ValidatePasswordValidator])
username: new FormControl(null, [
Validators.required,
ValidateNotEmptyValidator,
]),
password: new FormControl(null, [
Validators.required,
ValidatePasswordValidator,
]),
});
this.errorMessage = null;
this.authSubject = this.authService.authSubject.subscribe(
res => {
this.validateLogin(res);
}
);
this.authSubject = this.authService.authSubject.subscribe((res) => {
this.validateLogin(res);
});
this.cookieStatusChangeSubscription = this.cookieConsentService.cookieStatusChangeSubscription.subscribe(
(status: boolean) => {
this.isCookieBlocked = !status;
console.log("Cookie status: " + status);
}
);
this.cookieStatusChangeSubscription =
this.cookieConsentService.cookieStatusChangeSubscription.subscribe(
(status: boolean) => {
this.isCookieBlocked = !status;
console.log('Cookie status: ' + status);
},
);
if (this.isCookieBlocked) {
this.ccService.fadeIn();
@@ -176,8 +192,8 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
onLogin() {
let user: User = {
username: this.loginForm.controls['username'].value,
password: this.loginForm.controls['password'].value
}
password: this.loginForm.controls['password'].value,
};
this.authService.login(user);
}
@@ -191,11 +207,11 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
private validateLogin(res: User | HttpError | null) {
if (res && UserChecker.test(res)) {
this.closePopup()
} if (HttpErrorChecker.test(res)) {
this.closePopup();
}
if (HttpErrorChecker.test(res)) {
this.errorMessage = (<HttpError>res).details;
}
}
private closePopup() {
@@ -205,23 +221,22 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
public showErrorMessage(): string {
if (this.isShowErrorMessage) {
return "show";
return 'show';
}
return "hide";
return 'hide';
}
public hideErrorMessage(): string {
if (!!this.errorMessage) {
return "hide";
return 'hide';
}
return "show";
return 'show';
}
hideAuthContainer(event: any) {
if (event.toState === "hide") {
event.element.style.display = "none";
if (event.toState === 'hide') {
event.element.style.display = 'none';
this.isShowErrorMessage = true;
}
}
}

View File

@@ -36,7 +36,6 @@
}
.profile-options-container button {
text-decoration: none;
border-radius: 8px;
color: #ffffff;
@@ -55,9 +54,7 @@
background-color: rgba(216, 41, 28, 0.7) !important;
}
@media (min-width:767px) {
@media (min-width: 767px) {
.profile-options-container {
all: unset;
justify-content: space-around;
@@ -96,5 +93,4 @@
border-radius: 50px;
height: 100%;
}
}

View File

@@ -1,23 +1,28 @@
<app-popup [state]="state"
(stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside">
<div class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()">
<app-error-box [errorMessage]="errorMessage"
[@showErrorMessage]="showErrorMessage()">
<app-popup
[state]="state"
(stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside"
>
<div
class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()"
>
<app-error-box
[errorMessage]="errorMessage"
[@showErrorMessage]="showErrorMessage()"
>
</app-error-box>
<div class="container profile-options-container"
[@hideAuthContainer]="hideErrorMessage()"
(@hideAuthContainer.done)="hideAuthContainer($event)">
<div
class="container profile-options-container"
[@hideAuthContainer]="hideErrorMessage()"
(@hideAuthContainer.done)="hideAuthContainer($event)"
>
<div class="row profile-options-row">
<div class="btn-container">
<app-profile-picture-picker
(imageSent)="onProfilePictureSent($event)">
(imageSent)="onProfilePictureSent($event)"
>
</app-profile-picture-picker>
</div>
@@ -26,16 +31,11 @@
</div>
<div class="btn-container">
<button class="delete-btn"
(click)="onDeleteAccount()">
<button class="delete-btn" (click)="onDeleteAccount()">
Delete Account
</button>
</div>
</div>
</div>
</div>
</app-popup>

View File

@@ -3,21 +3,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyProfileComponent } from './my-profile.component';
describe('MyProfileComponent', () => {
let component: MyProfileComponent;
let fixture: ComponentFixture<MyProfileComponent>;
let component: MyProfileComponent;
let fixture: ComponentFixture<MyProfileComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MyProfileComponent ]
})
.compileComponents();
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MyProfileComponent],
}).compileComponents();
fixture = TestBed.createComponent(MyProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fixture = TestBed.createComponent(MyProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,18 +1,33 @@
import {ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {AuthService} from "../../../shared/auth/auth.service";
import {User} from "../../../shared/model/user/user.model";
import {animate, animateChild, group, query, state, style, transition, trigger} from "@angular/animations";
import {MatIconRegistry} from "@angular/material/icon";
import {DomSanitizer} from "@angular/platform-browser";
import {FormControl, FormGroup, Validators} from "@angular/forms";
import {ValidateNotEmptyValidator} from "../../../shared/validators/validate-not-empty.validator";
import {ValidatePasswordValidator} from "../../../shared/validators/validate-password.validator";
import {first, take} from "rxjs";
import UserChecker from "../../../shared/model/user/user.checker";
import HttpErrorChecker from "../../../shared/model/httpError/httpErrorChecker";
import {HttpError} from "../../../shared/model/httpError/httpError.model";
import {faFileUpload} from "@fortawesome/free-solid-svg-icons";
import {
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnInit,
Output,
} from '@angular/core';
import { AuthService } from '../../../shared/auth/auth.service';
import { User } from '../../../shared/model/user/user.model';
import {
animate,
animateChild,
group,
query,
state,
style,
transition,
trigger,
} from '@angular/animations';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ValidateNotEmptyValidator } from '../../../shared/validators/validate-not-empty.validator';
import { ValidatePasswordValidator } from '../../../shared/validators/validate-password.validator';
import { first, take } from 'rxjs';
import UserChecker from '../../../shared/model/user/user.checker';
import HttpErrorChecker from '../../../shared/model/httpError/httpErrorChecker';
import { HttpError } from '../../../shared/model/httpError/httpError.model';
import { faFileUpload } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'app-my-profile',
@@ -20,81 +35,69 @@ import {faFileUpload} from "@fortawesome/free-solid-svg-icons";
styleUrls: ['./my-profile.component.css'],
animations: [
trigger('resizeContainerForErrorMessage', [
state('hide',
state(
'hide',
style({
height: '100px',
width: '320px',
})
}),
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate('1s ease')
])
)
query('@*', animateChild(), { optional: true }),
animate('1s ease'),
]),
),
]),
trigger('showErrorMessage', [
state('show',
state(
'show',
style({
opacity: 1,
height: '100px',
width: '320px',
})
}),
),
state('hide',
state(
'hide',
style({
opacity: 0,
height: '0px',
width: '0px',
})
),
transition(
'* => show',
animate(
'500ms ease-in'
)
}),
),
transition('* => show', animate('500ms ease-in')),
]),
trigger('hideAuthContainer', [
state('hide',
state(
'hide',
style({
opacity: 0,
})
}),
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate(
'250ms ease-out'
)
])
)
query('@*', animateChild(), { optional: true }),
animate('250ms ease-out'),
]),
),
]),
]
],
})
export class MyProfileComponent implements OnInit {
@Input()
state: boolean = false;
@Input()
state: boolean = false;
user!: User | null;
@Input()
user!: User | null;
@Input()
ignoreClickOutside!: HTMLDivElement[];
ignoreClickOutside!: HTMLDivElement[];
@Output()
stateChange = new EventEmitter<boolean>();
stateChange = new EventEmitter<boolean>();
alterForm!: FormGroup;
@@ -102,15 +105,20 @@ export class MyProfileComponent implements OnInit {
isShowErrorMessage = false;
_fileIcon = faFileUpload
_fileIcon = faFileUpload;
constructor(private authService: AuthService) {
}
constructor(private authService: AuthService) {}
ngOnInit(): void {
this.alterForm = new FormGroup({
'username': new FormControl(null, [Validators.required, ValidateNotEmptyValidator]),
'password': new FormControl(null, [Validators.required, ValidatePasswordValidator])
username: new FormControl(null, [
Validators.required,
ValidateNotEmptyValidator,
]),
password: new FormControl(null, [
Validators.required,
ValidatePasswordValidator,
]),
});
this.errorMessage = null;
}
@@ -121,30 +129,30 @@ export class MyProfileComponent implements OnInit {
showErrorMessage(): string {
if (this.isShowErrorMessage) {
return "show";
return 'show';
}
return "hide";
return 'hide';
}
hideErrorMessage(): string {
if (!!this.errorMessage) {
return "hide";
return 'hide';
}
return "show";
return 'show';
}
onDeleteAccount() {
this.authService.deleteAccount().subscribe({
next: (response: any) => {
this.authService.logout();
}
})
},
});
this.closePopup();
}
hideAuthContainer(event: any) {
if (event.toState === "hide") {
event.element.style.display = "none";
if (event.toState === 'hide') {
event.element.style.display = 'none';
this.isShowErrorMessage = true;
}
}
@@ -158,5 +166,4 @@ export class MyProfileComponent implements OnInit {
private closePopup() {
this.onStateChange(false);
}
}

View File

@@ -1,20 +1,27 @@
<div class="btn-container">
<div class="input-group mb-3">
<div class="custom-file">
<input type="file"
class="custom-file-input"
id="inputProfilePicture"
aria-describedby="inputProfilePicture"
(change)="handleFileInput($event)">
<label class="custom-file-label"
for="inputProfilePicture">
{{isProfilePictureSelected ? getFileName() : 'Profile Picture'}}
<input
type="file"
class="custom-file-input"
id="inputProfilePicture"
aria-describedby="inputProfilePicture"
(change)="handleFileInput($event)"
/>
<label class="custom-file-label" for="inputProfilePicture">
{{
isProfilePictureSelected ? getFileName() : "Profile Picture"
}}
</label>
</div>
<div class="input-group-append">
<button class="btn btn-outline-secondary"
[disabled]="!isProfilePictureSelected"
(click)="uploadProfilePicture()">Upload</button>
<button
class="btn btn-outline-secondary"
[disabled]="!isProfilePictureSelected"
(click)="uploadProfilePicture()"
>
Upload
</button>
</div>
</div>
</div>

View File

@@ -3,21 +3,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ProfilePicturePickerComponent } from './profile-picture-picker.component';
describe('ProfilePicturePickerComponent', () => {
let component: ProfilePicturePickerComponent;
let fixture: ComponentFixture<ProfilePicturePickerComponent>;
let component: ProfilePicturePickerComponent;
let fixture: ComponentFixture<ProfilePicturePickerComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ProfilePicturePickerComponent ]
})
.compileComponents();
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ProfilePicturePickerComponent],
}).compileComponents();
fixture = TestBed.createComponent(ProfilePicturePickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fixture = TestBed.createComponent(ProfilePicturePickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,19 +1,18 @@
import {Component, EventEmitter, Output} from '@angular/core';
import {AuthService} from "../../../../shared/auth/auth.service";
import { Component, EventEmitter, Output } from '@angular/core';
import { AuthService } from '../../../../shared/auth/auth.service';
@Component({
selector: 'app-profile-picture-picker',
templateUrl: './profile-picture-picker.component.html',
styleUrls: ['./profile-picture-picker.component.css']
styleUrls: ['./profile-picture-picker.component.css'],
})
export class ProfilePicturePickerComponent {
export class ProfilePicturePickerComponent {
@Output()
imageSent = new EventEmitter<boolean>();
imageSent = new EventEmitter<boolean>();
private profilePicture!: File;
constructor(private authService: AuthService) { }
constructor(private authService: AuthService) {}
handleFileInput(event: Event) {
const element = event.currentTarget as HTMLInputElement;
@@ -35,5 +34,4 @@ export class ProfilePicturePickerComponent {
get isProfilePictureSelected(): boolean {
return !!this.profilePicture;
}
}

View File

@@ -22,7 +22,7 @@
}
.auth-body .btn {
background-color: #D8291C !important;
background-color: #d8291c !important;
text-decoration: none;
border-radius: 8px;
color: #ffffff;
@@ -70,7 +70,7 @@
border-bottom: 2px solid #7676769b;
}
.input-div:after {
content: '';
content: "";
left: 0;
right: 0;
width: 0;
@@ -84,11 +84,12 @@
.input-div:hover:after,
.input-div:has(input.form-control:focus):after {
width: 100%;
transition: .4s;
transition: 0.4s;
overflow: hidden;
}
.input-div > .form-control, .input-div > .form-control:focus {
.input-div > .form-control,
.input-div > .form-control:focus {
border: none;
border-color: inherit;
-webkit-box-shadow: none;
@@ -101,7 +102,7 @@
font-size: 17px;
color: #767676;
}
.input-div >.form-control:-webkit-autofill {
.input-div > .form-control:-webkit-autofill {
-webkit-text-fill-color: #767676;
box-shadow: 0 0 0px 1000px #ffffff inset;
-webkit-box-shadow: 0 0 0px 1000px #ffffff inset;
@@ -111,17 +112,16 @@
.input-div:hover > .form-control::placeholder,
.input-div:hover > .input-div-icon,
.input-div:has(input.form-control:focus) > .input-div-icon {
color: #D8291C;
transition: .3s;
color: #d8291c;
transition: 0.3s;
}
.input-div:hover > .form-control::placeholder,
.input-div:focus > .form-control::placeholder{
.input-div:focus > .form-control::placeholder {
font-weight: 500;
transition: .3s;
transition: 0.3s;
}
@media (min-width:767px) {
@media (min-width: 767px) {
.authentication-container {
min-width: 630px;
}
@@ -151,5 +151,4 @@
border-right: 2px solid #80808076;
height: 100%;
}
}

View File

@@ -1,60 +1,81 @@
<app-popup [state]="state"
<app-popup
[state]="state"
(stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside">
<div class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()">
<app-error-box [errorMessage]="errorMessage"
[@showErrorMessage]="showErrorMessage()">
[ignoreClickOutside]="ignoreClickOutside"
>
<div
class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()"
>
<app-error-box
[errorMessage]="errorMessage"
[@showErrorMessage]="showErrorMessage()"
>
</app-error-box>
<div class="container authentication-container"
[@hideAuthContainer]="hideErrorMessage()"
(@hideAuthContainer.done)="hideAuthContainer($event)">
<div
class="container authentication-container"
[@hideAuthContainer]="hideErrorMessage()"
(@hideAuthContainer.done)="hideAuthContainer($event)"
>
<div class="row">
<div class="col-lg-6 auth-body auth-body-form">
<form [formGroup]="signupForm" (ngSubmit)="onSignUp()">
<div class="input-div">
<fa-icon class="input-div-icon"
[icon]="_fullnameIcon">
<fa-icon
class="input-div-icon"
[icon]="_fullnameIcon"
>
</fa-icon>
<input type="text" id="fullname"
<input
type="text"
id="fullname"
formControlName="fullname"
class="form-control"
placeholder="Full Name">
placeholder="Full Name"
/>
</div>
<div class="input-div">
<fa-icon class="input-div-icon"
[icon]="_emailIcon">
<fa-icon class="input-div-icon" [icon]="_emailIcon">
</fa-icon>
<input type="text" id="email"
<input
type="text"
id="email"
formControlName="email"
class="form-control"
placeholder="Email">
placeholder="Email"
/>
</div>
<div class="input-div">
<fa-icon class="input-div-icon"
[icon]="_userIcon">
<fa-icon class="input-div-icon" [icon]="_userIcon">
</fa-icon>
<input type="text" id="username"
<input
type="text"
id="username"
formControlName="username"
class="form-control"
placeholder="Username">
placeholder="Username"
/>
</div>
<div class="input-div">
<fa-icon class="input-div-icon"
[icon]="_passwordIcon">
<fa-icon
class="input-div-icon"
[icon]="_passwordIcon"
>
</fa-icon>
<input type="password" id="password"
<input
type="password"
id="password"
formControlName="password"
class="form-control"
placeholder="Password">
placeholder="Password"
/>
</div>
<button class="btn"
[disabled]="!signupForm.valid"
type="submit">
<button
class="btn"
[disabled]="!signupForm.valid"
type="submit"
>
SignUp
</button>
</form>
@@ -63,24 +84,30 @@
<div class="line"></div>
</div>
<div class="col-lg-6 auth-body auth-body-links">
<button mat-button
class="oauth-button d-flex justify-content-center align-items-center"
(click)="onGoogleLogin()">
<mat-icon style="width: 50px; height:30px"
svgIcon="google-logo"></mat-icon>
<button
mat-button
class="oauth-button d-flex justify-content-center align-items-center"
(click)="onGoogleLogin()"
>
<mat-icon
style="width: 50px; height: 30px"
svgIcon="google-logo"
></mat-icon>
Login With Google
</button>
<button mat-button
class="oauth-button d-flex justify-content-center align-items-center"
(click)="onGithubLogin()">
<mat-icon style="width: 50px; height:30px"
svgIcon="github-logo"></mat-icon>
<button
mat-button
class="oauth-button d-flex justify-content-center align-items-center"
(click)="onGithubLogin()"
>
<mat-icon
style="width: 50px; height: 30px"
svgIcon="github-logo"
></mat-icon>
Login With Github
</button>
</div>
</div>
</div>
</div>
</app-popup>

View File

@@ -8,9 +8,8 @@ describe('SignupComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SignupComponent ]
})
.compileComponents();
declarations: [SignupComponent],
}).compileComponents();
fixture = TestBed.createComponent(SignupComponent);
component = fixture.componentInstance;

View File

@@ -2,21 +2,34 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { faEnvelope, faFingerprint, faLock, faUser } from '@fortawesome/free-solid-svg-icons';
import {
faEnvelope,
faFingerprint,
faLock,
faUser,
} from '@fortawesome/free-solid-svg-icons';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/shared/auth/auth.service';
import { HttpError } from 'src/app/shared/model/httpError/httpError.model';
import HttpErrorChecker from 'src/app/shared/model/httpError/httpErrorChecker';
import UserChecker from 'src/app/shared/model/user/user.checker';
import { User } from 'src/app/shared/model/user/user.model';
import {animate, animateChild, group, query, state, style, transition, trigger} from "@angular/animations";
import {ValidateEmailValidator} from "../../../shared/validators/validate-email.validator";
import {ValidatePasswordValidator} from "../../../shared/validators/validate-password.validator";
import {ValidateNotEmptyValidator} from "../../../shared/validators/validate-not-empty.validator";
import {
animate,
animateChild,
group,
query,
state,
style,
transition,
trigger,
} from '@angular/animations';
import { ValidateEmailValidator } from '../../../shared/validators/validate-email.validator';
import { ValidatePasswordValidator } from '../../../shared/validators/validate-password.validator';
import { ValidateNotEmptyValidator } from '../../../shared/validators/validate-not-empty.validator';
const GOOGLE_LOGO_SVG = "assets/img/providers/google.svg";
const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
const GOOGLE_LOGO_SVG = 'assets/img/providers/google.svg';
const GITHUB_LOGO_SVG = 'assets/img/providers/github.svg';
@Component({
selector: 'app-signup',
@@ -24,78 +37,66 @@ const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
styleUrls: ['./signup.component.css'],
animations: [
trigger('resizeContainerForErrorMessage', [
state('hide',
state(
'hide',
style({
height: '100px',
width: '320px',
})
}),
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate('1s ease')
])
)
query('@*', animateChild(), { optional: true }),
animate('1s ease'),
]),
),
]),
trigger('showErrorMessage', [
state('show',
state(
'show',
style({
opacity: 1,
height: '100px',
width: '320px',
})
}),
),
state('hide',
state(
'hide',
style({
opacity: 0,
height: '0px',
width: '0px',
})
),
transition(
'* => show',
animate(
'500ms ease-in'
)
}),
),
transition('* => show', animate('500ms ease-in')),
]),
trigger('hideAuthContainer', [
state('hide',
state(
'hide',
style({
opacity: 0,
})
}),
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate(
'250ms ease-out'
)
])
)
query('@*', animateChild(), { optional: true }),
animate('250ms ease-out'),
]),
),
]),
]
],
})
export class SignupComponent implements OnInit {
@Input()
state: boolean = false;
@Input()
state: boolean = false;
@Input()
ignoreClickOutside!: HTMLDivElement[];
ignoreClickOutside!: HTMLDivElement[];
@Output()
stateChange = new EventEmitter<boolean>();
stateChange = new EventEmitter<boolean>();
signupForm!: FormGroup;
@@ -113,34 +114,46 @@ export class SignupComponent implements OnInit {
_passwordIcon = faLock;
constructor(private authService: AuthService,
constructor(
private authService: AuthService,
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer) {
private domSanitizer: DomSanitizer,
) {
this.matIconRegistry.addSvgIcon(
"google-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG)
'google-logo',
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG),
);
this.matIconRegistry.addSvgIcon(
"github-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG)
'github-logo',
this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG),
);
}
ngOnInit(): void {
this.signupForm = new FormGroup({
'fullname': new FormControl(null, [Validators.required, ValidateNotEmptyValidator]),
fullname: new FormControl(null, [
Validators.required,
ValidateNotEmptyValidator,
]),
// Create a Email Validator
'email': new FormControl(null, [Validators.required, ValidateEmailValidator]),
'username': new FormControl(null, [Validators.required, ValidateNotEmptyValidator]),
email: new FormControl(null, [
Validators.required,
ValidateEmailValidator,
]),
username: new FormControl(null, [
Validators.required,
ValidateNotEmptyValidator,
]),
// Create a Password Validator
'password': new FormControl(null, [Validators.required, ValidatePasswordValidator])
password: new FormControl(null, [
Validators.required,
ValidatePasswordValidator,
]),
});
this.errorMessage = null;
this.authSubject = this.authService.authSubject.subscribe(
res => {
this.validateSignup(res);
}
);
this.authSubject = this.authService.authSubject.subscribe((res) => {
this.validateSignup(res);
});
}
onStateChange(state: boolean) {
@@ -152,8 +165,8 @@ export class SignupComponent implements OnInit {
name: this.signupForm.controls['fullname'].value,
email: this.signupForm.controls['email'].value,
username: this.signupForm.controls['username'].value,
password: this.signupForm.controls['password'].value
}
password: this.signupForm.controls['password'].value,
};
this.authService.signup(user);
}
@@ -167,11 +180,11 @@ export class SignupComponent implements OnInit {
private validateSignup(res: User | HttpError | null) {
if (res && UserChecker.test(res)) {
this.closePopup()
} if (HttpErrorChecker.test(res)) {
this.closePopup();
}
if (HttpErrorChecker.test(res)) {
this.errorMessage = (<HttpError>res).details;
}
}
private closePopup() {
@@ -181,24 +194,22 @@ export class SignupComponent implements OnInit {
public showErrorMessage(): string {
if (this.isShowErrorMessage) {
return "show";
return 'show';
}
return "hide";
return 'hide';
}
public hideErrorMessage(): string {
if (!!this.errorMessage) {
return "hide";
return 'hide';
}
return "show";
return 'show';
}
hideAuthContainer(event: any) {
if (event.toState === "hide") {
event.element.style.display = "none";
if (event.toState === 'hide') {
event.element.style.display = 'none';
this.isShowErrorMessage = true;
}
}
}