Initial Implementation of Profile Pictures

This commit is contained in:
2023-08-21 02:46:50 -03:00
parent 9b8d0e248f
commit 1328ca7c4c
13 changed files with 130 additions and 67 deletions

View File

@@ -1,10 +1,10 @@
import { animate, state, style, transition, trigger } from '@angular/animations';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { faEdit, faQuestionCircle, faSignOutAlt, faUser } from '@fortawesome/free-solid-svg-icons';
import { Subscription, timeout } from 'rxjs';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/shared/auth/auth.service';
import UserChecker from 'src/app/shared/model/user/user.checker';
import { User } from 'src/app/shared/model/user/user.model';
import {User} from "../../shared/model/user/user.model";
import UserChecker from "../../shared/model/user/user.checker";
@Component({
selector: 'app-header-dropdown',
@@ -57,6 +57,7 @@ export class HeaderDropdownComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.userSubscription = this.authService.authSubject.subscribe(
res => {
console.log(UserChecker.test(res));
if (res && UserChecker.test(res)) {
this.user = <User>res;
} else {

View File

@@ -56,6 +56,11 @@
width: 45px;
}
.profile-picture {
border-radius: 50%;
border: 2px solid #ffffff;
}
.profile .profile-btn {
display: flex;
border: 5px solid #ffffff;
@@ -63,10 +68,10 @@
justify-content: center;
align-items: center;
color: #ffffff;
height: 45px;
width: 45px;
height: 50px;
width: 50px;
}
.profile .profile-btn fa-icon {
font-size: 25px;
font-size: 28px;
}

View File

@@ -16,7 +16,13 @@
#profile>
<div class="profile-btn"
(click)="onProfileButtonClicked()">
<fa-icon class="fas fa-user" [icon]="userIcon"></fa-icon>
<fa-icon *ngIf="!loggedUser || !(loggedUser.profilePictureUrl)"
class="fas fa-user" [icon]="userIcon"></fa-icon>
<img *ngIf="!!loggedUser && !!(loggedUser.profilePictureUrl)"
class="profile-picture"
[ngSrc]="loggedUser.profilePictureUrl"
width="50" height="50"
alt="Profile Picture" priority/>
</div>
</div>
</div>

View File

@@ -1,13 +1,17 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import {Component, EventEmitter, OnDestroy, OnInit, Output} from '@angular/core';
import { faUser } from '@fortawesome/free-solid-svg-icons';
import { SliderItemComponent } from 'src/app/shared/components/slider-item/slider-item.component';
import UserChecker from "../../../shared/model/user/user.checker";
import {User} from "../../../shared/model/user/user.model";
import {AuthService} from "../../../shared/auth/auth.service";
import {Subscription} from "rxjs";
@Component({
selector: 'app-nav-slider',
templateUrl: './nav-slider.component.html',
styleUrls: ['./nav-slider.component.css']
})
export class NavSliderComponent extends SliderItemComponent {
export class NavSliderComponent extends SliderItemComponent implements OnInit, OnDestroy {
userIcon = faUser;
@@ -18,13 +22,34 @@ export class NavSliderComponent extends SliderItemComponent {
{ page: "About", link: "/home" }
]
loggedUser!: User | null;
private userSubscription!: Subscription;
@Output()
profileButtonClicked = new EventEmitter();
constructor() {
constructor(private authService: AuthService) {
super();
}
ngOnInit(): void {
this.userSubscription = this.authService.authSubject.subscribe(
res => {
console.log(UserChecker.test(res));
if (res && UserChecker.test(res)) {
this.loggedUser = <User>res;
} else {
this.loggedUser = null;
}
}
)
}
ngOnDestroy(): void {
this.userSubscription.unsubscribe();
}
onProfileButtonClicked() {
this.profileButtonClicked.emit();
}

View File

@@ -136,6 +136,11 @@ app-header-slider {
cursor: pointer;
}
.profile-picture {
border-radius: 50%;
border: 2px solid #ffffff;
}
.profile .profile-btn {
display: flex;
border: 5px solid #ffffff;
@@ -143,8 +148,8 @@ app-header-slider {
justify-content: center;
align-items: center;
color: #ffffff;
height: 45px;
width: 45px;
height: 50px;
width: 50px;
}
.profile .dropdown {
@@ -153,7 +158,7 @@ app-header-slider {
}
.profile .profile-btn fa-icon {
font-size: 25px;
font-size: 28px;
}
.burger-container {

View File

@@ -16,8 +16,15 @@
<div class="profile" #profileDropdown>
<div class="profile-btn" (click)="toogleProfileDropdown()" #profileBtn>
<fa-icon class="fas fa-user" [icon]="userIcon"></fa-icon>
<fa-icon *ngIf="!loggedUser || !(loggedUser.profilePictureUrl)"
class="fas fa-user" [icon]="userIcon"></fa-icon>
<img *ngIf="!!loggedUser && !!(loggedUser.profilePictureUrl)"
class="profile-picture"
[ngSrc]="loggedUser.profilePictureUrl"
width="50" height="50"
alt="Profile Picture" priority/>
</div>
<app-header-dropdown
class="dropdown"
(clickOutside)="closeDropdown()"
@@ -57,14 +64,3 @@
</div>
</div>
<div class="header-spacer"></div>
<!-- <app-login
*ngIf="loginPopupState"
[(state)]="loginPopupState"
[ignoreClickOutside]="[profileBtn, profileDropdown, user]">
</app-login>
<app-signup
[(state)]="signupPopupState"
[ignoreClickOutside]="[profileBtn, profileDropdown, user]">
</app-signup> -->

View File

@@ -1,14 +1,18 @@
import { Component, ComponentRef, ElementRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import {Component, ComponentRef, ElementRef, OnDestroy, OnInit, ViewChild, ViewContainerRef} from '@angular/core';
import { faUser } from '@fortawesome/free-solid-svg-icons';
import { LoginComponent } from './header-popup/login/login.component';
import { SignupComponent } from './header-popup/signup/signup.component';
import {AuthService} from "../shared/auth/auth.service";
import UserChecker from "../shared/model/user/user.checker";
import {User} from "../shared/model/user/user.model";
import {Subscription} from "rxjs";
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent {
export class HeaderComponent implements OnInit, OnDestroy {
userIcon = faUser;
@@ -28,11 +32,32 @@ export class HeaderComponent {
@ViewChild('user')
userElementRef!: ElementRef;
loggedUser!: User | null;
private userSubscription!: Subscription;
private loginComponent!: ComponentRef<LoginComponent>;
private signupComponent!: ComponentRef<SignupComponent>;
constructor(private viewContainerRef: ViewContainerRef) { }
constructor(private viewContainerRef: ViewContainerRef, private authService: AuthService) { }
ngOnInit(): void {
this.userSubscription = this.authService.authSubject.subscribe(
res => {
console.log(UserChecker.test(res));
if (res && UserChecker.test(res)) {
this.loggedUser = <User>res;
} else {
this.loggedUser = null;
}
}
)
}
ngOnDestroy(): void {
this.userSubscription.unsubscribe();
}
public toogleProfileDropdown(): void {

View File

@@ -12,7 +12,7 @@ export const HttpError = t.iface([], {
"timestamp": "string",
});
const HttpErrorTI: t.ITypeSuite = {
const exportedTypeSuite: t.ITypeSuite = {
HttpError,
};
export default HttpErrorTI;
export default exportedTypeSuite;

View File

@@ -1,5 +1,5 @@
import { createCheckers } from "ts-interface-checker";
import HttpErrorTI from "./httpError.model-ti";
import HttpError from "./httpError.model-ti";
const HttpErrorChecker = createCheckers(HttpErrorTI)['HttpError'];
const HttpErrorChecker = createCheckers(HttpError)['HttpError'];
export default HttpErrorChecker;

View File

@@ -1,6 +1,6 @@
import { createCheckers } from "ts-interface-checker";
import TokenTI from "../token/token.model-ti";
import UserTI from "./user.model-ti";
import User from "./user.model-ti";
import Token from "../token/token.model-ti";
const UserChecker = createCheckers(UserTI, TokenTI)['User'];
const UserChecker = createCheckers(User, Token)['User'];
export default UserChecker;

View File

@@ -10,14 +10,13 @@ export const User = t.iface([], {
"email": t.opt("string"),
"username": "string",
"password": t.opt("string"),
"profilePictureUrl": t.opt("string"),
"accessToken": t.opt("Token"),
"refreshToken": t.opt("Token"),
"authorities": t.opt(t.array(t.iface([], {
"authority": "string",
}))),
"roles": t.opt(t.array("string")),
});
const UserTI: t.ITypeSuite = {
const exportedTypeSuite: t.ITypeSuite = {
User,
};
export default UserTI;
export default exportedTypeSuite;

View File

@@ -6,8 +6,9 @@ export interface User {
email?: string,
username: string,
password?: string,
profilePictureUrl?: string,
accessToken?: Token,
refreshToken?: Token,
authorities?: Array<{authority: string}>,
roles?: Array<string>,
validateAccessToken?: () => Token | undefined;
};