aboutsummaryrefslogtreecommitdiff
path: root/src/app/components/profile
diff options
context:
space:
mode:
authortranstrike <transtrike@gmail.com>2021-02-12 19:04:53 +0200
committertranstrike <transtrike@gmail.com>2021-02-12 19:04:53 +0200
commitbcd88af53b1a920d728ec98b45daa9ac2e2c0917 (patch)
treefd27eef086822b0f02f74364cac0b940956d2458 /src/app/components/profile
parent1d1f05e3f74d70a558b4847a9107afa7952131cf (diff)
downloadDevHive-Angular-bcd88af53b1a920d728ec98b45daa9ac2e2c0917.tar
DevHive-Angular-bcd88af53b1a920d728ec98b45daa9ac2e2c0917.tar.gz
DevHive-Angular-bcd88af53b1a920d728ec98b45daa9ac2e2c0917.zip
Moved from DevHive
Diffstat (limited to 'src/app/components/profile')
-rw-r--r--src/app/components/profile/profile.component.css105
-rw-r--r--src/app/components/profile/profile.component.html60
-rw-r--r--src/app/components/profile/profile.component.ts203
3 files changed, 368 insertions, 0 deletions
diff --git a/src/app/components/profile/profile.component.css b/src/app/components/profile/profile.component.css
new file mode 100644
index 0000000..ebcd406
--- /dev/null
+++ b/src/app/components/profile/profile.component.css
@@ -0,0 +1,105 @@
+* {
+ box-sizing: border-box;
+}
+
+#content {
+ max-width: 22em;
+ justify-content: start;
+}
+
+hr {
+ width: calc(100% - 1em);
+ color: black;
+ border: 1px solid black;
+}
+
+form {
+ width: 100%;
+}
+
+/* Navigation bar (for loggedin user) */
+
+#navigation {
+ display: flex;
+ width: 100%;
+}
+
+.submit-btn {
+ flex: 1;
+ margin-top: 0;
+ margin-left: .5em;
+ font-size: inherit;
+}
+
+#navigation > .submit-btn:first-child {
+ margin-left: 0;
+}
+
+/* Top card */
+
+#main-info {
+ display: flex;
+ width: 100%;
+ margin-bottom: .25em
+}
+
+#main-info > img {
+ width: 5em;
+ height: 5em;
+}
+
+#other-main-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+}
+
+#other-main-info > * {
+ font-size: 1.4em;
+}
+
+#other-main-info *:nth-child(1) {
+ margin-top: auto;
+}
+
+#other-main-info *:nth-last-child(1) {
+ margin-bottom: auto;
+}
+
+#add-friend, #loggedin-password {
+ flex: 0 !important;
+ margin-top: .4em;
+ max-width: 8em;
+ font-size: .6em !important;
+}
+
+#loggedin-password {
+ max-width: 100%;
+}
+
+/* Languages and technologies */
+
+.secondary-info {
+ margin-top: .25em;
+ margin-bottom: .25em;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+}
+
+/* Posts */
+
+#no-posts {
+ width: 100%;
+ text-align: center;
+ color: gray;
+ margin-top: .2em;
+}
+
+#posts {
+ width: 100%;
+ height: 100%;
+}
diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html
new file mode 100644
index 0000000..0e5f633
--- /dev/null
+++ b/src/app/components/profile/profile.component.html
@@ -0,0 +1,60 @@
+<app-loading *ngIf="!dataArrived"></app-loading>
+
+<div id="content" *ngIf="dataArrived">
+ <nav id="navigation">
+ <button class="submit-btn" (click)="goBack()">ᐊ Back</button>
+ <button class="submit-btn" (click)="navigateToSettings()" *ngIf="isTheLoggedInUser">Settings</button>
+ <button class="submit-btn" (click)="navigateToAdminPanel()" *ngIf="isTheLoggedInUser && isAdminUser">Panel</button>
+ <button class="submit-btn" (click)="logout()" *ngIf="isTheLoggedInUser">Logout</button>
+ </nav>
+ <hr>
+ <div class="scroll-standalone" (scroll)="onScroll($event)">
+ <div id="main-info" class="rounded-border">
+ <img class="round-image" [src]="user.profilePictureURL" alt=""/>
+ <div id="other-main-info">
+ <div id="name">
+ {{ user.firstName }} {{ user.lastName }}
+ </div>
+ <div id="username">
+ @{{ user.userName }}
+ </div>
+ <form [formGroup]="updateFrienship" (ngSubmit)="modifyFriend()" *ngIf="!isTheLoggedInUser && isUserLoggedIn">
+ <button id="add-friend" type="submit" class="submit-btn">{{ friendOfUser ? 'Unfriend' : 'Add friend' }}</button>
+ <br>
+ <input id="loggedin-password" type="password" formControlName="password" class="input-field" *ngIf="updatingFriendship" placeholder="Type in password to confirm">
+ </form>
+ </div>
+ </div>
+ <div class="secondary-info rounded-border">
+ Languages:
+ <div *ngFor="let lang of user.languages">
+ <div class="user-language">
+ {{ lang.name }}
+ </div>
+ </div>
+ <div *ngIf="user.languages.length === 0">
+ &nbsp;None
+ </div>
+ </div>
+ <div class="secondary-info rounded-border">
+ Technologies:
+ <div *ngFor="let tech of user.technologies">
+ <div class="user-language">
+ {{ tech.name }}
+ </div>
+ </div>
+ <div *ngIf="user.technologies.length === 0">
+ &nbsp;None
+ </div>
+ </div>
+ <hr>
+ <div id="posts">
+ <div id="no-posts" *ngIf="userPosts.length === 0">
+ {{ user.firstName }} {{ user.lastName }} hasn't posted anything yet!
+ </div>
+ <div *ngFor="let userPost of userPosts">
+ <app-post [paramId]="userPost.postId.toString()"></app-post>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/src/app/components/profile/profile.component.ts b/src/app/components/profile/profile.component.ts
new file mode 100644
index 0000000..bbf8585
--- /dev/null
+++ b/src/app/components/profile/profile.component.ts
@@ -0,0 +1,203 @@
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { UserService } from 'src/app/services/user.service';
+import { User } from 'src/models/identity/user';
+import { AppConstants } from 'src/app/app-constants.module';
+import { HttpErrorResponse } from '@angular/common/http';
+import { Location } from '@angular/common';
+import { LanguageService } from 'src/app/services/language.service';
+import { TechnologyService } from 'src/app/services/technology.service';
+import { Post } from 'src/models/post';
+import { FeedService } from 'src/app/services/feed.service';
+import { TokenService } from 'src/app/services/token.service';
+import { Title } from '@angular/platform-browser';
+import { Friend } from 'src/models/identity/friend';
+import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
+
+@Component({
+ selector: 'app-profile',
+ templateUrl: './profile.component.html',
+ styleUrls: ['./profile.component.css']
+})
+export class ProfileComponent implements OnInit {
+ private _title = 'Profile';
+ private _urlUsername: string;
+ private _timeLoaded: string;
+ private _currentPage: number;
+ public isTheLoggedInUser = false;
+ public isUserLoggedIn = false;
+ public isAdminUser = false;
+ public dataArrived = false;
+ public friendOfUser = false;
+ public updatingFriendship = false;
+ public user: User;
+ public userPosts: Post[];
+ public updateFrienship: FormGroup;
+
+ constructor(private _titleService: Title, private _fb: FormBuilder, private _router: Router, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _feedService: FeedService, private _location: Location, private _tokenService: TokenService) {
+ this._titleService.setTitle(this._title);
+ }
+
+ private setDefaultUser(): void {
+ this.user = this._userService.getDefaultUser();
+ }
+
+ ngOnInit(): void {
+ this._urlUsername = this._router.url.substring(9);
+
+ const now = new Date();
+ now.setHours(now.getHours() + 2); // accounting for eastern europe timezone
+ this._timeLoaded = now.toISOString();
+ this._currentPage = 1;
+
+ this.user = this._userService.getDefaultUser();
+ this.userPosts = [];
+
+ this.updateFrienship = this._fb.group({
+ password: new FormControl('')
+ });
+
+ this._userService.getUserByUsernameRequest(this._urlUsername).subscribe(
+ (res: object) => {
+ Object.assign(this.user, res);
+ this.isAdminUser = this.user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME);
+ this.loadLanguages();
+ },
+ (err: HttpErrorResponse) => {
+ this._router.navigate(['/not-found']);
+ }
+ );
+ }
+
+ private loadLanguages(): void {
+ if (this.user.languages.length > 0) {
+ // When user has languages, get their names and load technologies
+ this._languageService.getFullLanguagesFromIncomplete(this.user.languages).then(value => {
+ this.user.languages = value;
+ this.loadTechnologies();
+ });
+ }
+ else {
+ this.loadTechnologies();
+ }
+ }
+
+ private loadTechnologies(): void {
+ if (this.user.technologies.length > 0) {
+ // When user has technologies, get their names and then load posts
+ this._technologyService.getFullTechnologiesFromIncomplete(this.user.technologies).then(value => {
+ this.user.technologies = value;
+ this.loadPosts();
+ });
+ }
+ else {
+ this.loadPosts();
+ }
+ }
+
+ private loadPosts(): void {
+ this._feedService.getUserPostsRequest(this.user.userName, this._currentPage++, this._timeLoaded, AppConstants.PAGE_SIZE).subscribe(
+ (result: object) => {
+ const resultArr: Post[] = Object.values(result)[0];
+ this.userPosts.push(...resultArr);
+ this.finishUserLoading();
+ },
+ (err: HttpErrorResponse) => {
+ this._currentPage = -1;
+ this.finishUserLoading();
+ }
+ );
+ }
+
+ private finishUserLoading(): void {
+ if (sessionStorage.getItem('UserCred')) {
+ this.isUserLoggedIn = true;
+ const userFromToken: User = this._userService.getDefaultUser();
+
+ this._userService.getUserFromSessionStorageRequest().subscribe(
+ (tokenRes: object) => {
+ Object.assign(userFromToken, tokenRes);
+
+ if (userFromToken.friends.map(x => x.userName).includes(this._urlUsername)) {
+ this.friendOfUser = true;
+ }
+ if (userFromToken.userName === this._urlUsername) {
+ this.isTheLoggedInUser = true;
+ }
+ this.dataArrived = true;
+ },
+ (err: HttpErrorResponse) => {
+ this.logout();
+ }
+ );
+ }
+ else {
+ this.dataArrived = true;
+ }
+ }
+
+ goBack(): void {
+ this._router.navigate(['/']);
+ }
+
+ navigateToAdminPanel(): void {
+ this._router.navigate(['/admin-panel']);
+ }
+
+ navigateToSettings(): void {
+ this._router.navigate([this._router.url + '/settings']);
+ }
+
+ logout(): void {
+ this._tokenService.logoutUserFromSessionStorage();
+
+ // Reload the page
+ this._router.routeReuseStrategy.shouldReuseRoute = () => false;
+ this._router.onSameUrlNavigation = 'reload';
+ this._router.navigate([this._router.url]);
+ }
+
+ modifyFriend(): void {
+ if (this.updatingFriendship) {
+ this.dataArrived = false;
+
+ this._userService.getUserFromSessionStorageRequest().subscribe(
+ (result: object) => {
+ const loggedInUser: User = result as User;
+
+ if (this.friendOfUser) {
+ loggedInUser.friends = loggedInUser.friends.filter(x => x.userName !== this.user.userName);
+ }
+ else {
+ const newFriend = new Friend();
+ newFriend.userName = this.user.userName;
+ loggedInUser.friends.push(newFriend);
+ }
+
+ this._userService.putBareUserFromSessionStorageRequest(loggedInUser, this.updateFrienship.get('password')?.value).subscribe(
+ (resultUpdate: object) => {
+ this.reloadPage();
+ },
+ (err: HttpErrorResponse) => {
+ this._router.navigate(['/']);
+ }
+ );
+ }
+ );
+ }
+ this.updatingFriendship = !this.updatingFriendship;
+ }
+
+ onScroll(event: any): void {
+ // Detects when the element has reached the bottom, thx https://stackoverflow.com/a/50038429/12036073
+ if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight && this._currentPage > 0) {
+ this.loadPosts();
+ }
+ }
+
+ private reloadPage(): void {
+ this._router.routeReuseStrategy.shouldReuseRoute = () => false;
+ this._router.onSameUrlNavigation = 'reload';
+ this._router.navigate([this._router.url]);
+ }
+}