diff options
Diffstat (limited to 'src/DevHive.Angular/src/app/components')
48 files changed, 0 insertions, 3132 deletions
diff --git a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css deleted file mode 100644 index 1f98e20..0000000 --- a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css +++ /dev/null @@ -1,42 +0,0 @@ -#content { - max-width: 22em; - justify-content: start; -} - -hr { - width: calc(100% - 1em); - color: black; - border: 1px solid black; -} - -#navigation { - width: 100%; - display: flex; -} - -#navigation > * { - flex: 1; - margin-left: .4em; -} - -.submit-btn:first-of-type { - margin-left: 0 !important; -} - -#all-languages, #all-technologies { - display: flex; - flex-wrap: wrap; -} - -.flexbox { - display: flex; -} - -.flexbox > * { - flex: 1; - margin-left: 1em; -} - -.flexbox > *:first-child { - margin-left: 0; -} diff --git a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html deleted file mode 100644 index 980f12c..0000000 --- a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html +++ /dev/null @@ -1,85 +0,0 @@ -<!-- <app-loading *ngIf="!dataArrived"></app-loading> --> - -<div id="content" *ngIf="!dataArrived"> - <nav id="navigation"> - <button class="submit-btn" (click)="backToProfile()">ᐊ Back to profile</button> - <button class="submit-btn" (click)="backToFeed()">ᐊ Back to feed</button> - <button class="submit-btn" (click)="logout()">Logout</button> - </nav> - <hr> - <div class="scroll-standalone"> - <app-success-bar></app-success-bar> - <app-error-bar></app-error-bar> - - <button type="button" class="submit-btn edit-btn" (click)="toggleLanguages()">▼ Edit Languages ▼</button> - <form [formGroup]="languageForm" (ngSubmit)="submitLanguages()" *ngIf="showLanguages"> - <div class="input-selection"> - <label>Create language:</label> - <input type="text" class="input-field" formControlName="languageCreate" placeholder="New language name"> - </div> - <label>Update language:</label> - <div class="flexbox input-selection"> - <input type="text" class="input-field" formControlName="updateLanguageOldName" placeholder="Old language name"> - <input type="text" class="input-field" formControlName="updateLanguageNewName" placeholder="New language name"> - </div> - <label>Delete language:</label> - <div class="flexbox input-selection"> - <input type="text" class="input-field" formControlName="deleteLanguageName" placeholder="Language name"> - </div> - <button class="submit-btn" type="submit">Modify languages</button> - <hr> - Available languages: - <div id="all-languages"> - <div class="user-language" *ngFor="let lang of availableLanguages"> - {{ lang.name }} - </div> - </div> - <hr> - </form> - - <button type="button" class="submit-btn edit-btn" (click)="toggleTechnologies()">▼ Edit Technologies ▼</button> - <form [formGroup]="technologyForm" (ngSubmit)="submitTechnologies()" *ngIf="showTechnologies"> - <div class="input-selection"> - <label>Create technology:</label> - <input type="text" class="input-field" formControlName="technologyCreate" placeholder="New technology name"> - </div> - <label>Update technology:</label> - <div class="flexbox input-selection"> - <input type="text" class="input-field" formControlName="updateTechnologyOldName" placeholder="Old technology name"> - <input type="text" class="input-field" formControlName="updateTechnologyNewName" placeholder="New technology name"> - </div> - <label>Delete technology:</label> - <div class="flexbox input-selection"> - <input type="text" class="input-field" formControlName="deleteTechnologyName" placeholder="Technology name"> - </div> - <button class="submit-btn" type="submit">Modify technologies</button> - <hr> - Available technologies: - <div id="all-technologies"> - <div class="user-technology" *ngFor="let tech of availableTechnologies"> - {{ tech.name }} - </div> - </div> - <hr> - </form> - - <button type="button" class="submit-btn delete-btn" (click)="toggleDeletions()">▼ Deletions ▼</button> - <form [formGroup]="deleteForm" (ngSubmit)="submitDelete()" *ngIf="showDeletions"> - <div class="input-selection"> - <label>Delete user by Id:</label> - <input type="text" class="input-field" formControlName="deleteUser" placeholder="User Id"> - </div> - - <div class="input-selection"> - <label>Delete post by Id:</label> - <input type="text" class="input-field" formControlName="deletePost" placeholder="Post Id"> - </div> - <div class="input-selection"> - <label>Delete comment by Id:</label> - <input type="text" class="input-field" formControlName="deleteComment" placeholder="Comment Id"> - </div> - <button class="submit-btn" type="submit">Delete</button> - <hr> - </form> - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts deleted file mode 100644 index 99c0721..0000000 --- a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts +++ /dev/null @@ -1,334 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; -import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; -import { Guid } from 'guid-typescript'; -import { AppConstants } from 'src/app/app-constants.module'; -import { CommentService } from 'src/app/services/comment.service'; -import { LanguageService } from 'src/app/services/language.service'; -import { PostService } from 'src/app/services/post.service'; -import { TechnologyService } from 'src/app/services/technology.service'; -import { TokenService } from 'src/app/services/token.service'; -import { UserService } from 'src/app/services/user.service'; -import { User } from 'src/models/identity/user'; -import { Language } from 'src/models/language'; -import { Technology } from 'src/models/technology'; -import { ErrorBarComponent } from '../error-bar/error-bar.component'; -import { SuccessBarComponent } from '../success-bar/success-bar.component'; - -@Component({ - selector: 'app-admin-panel-page', - templateUrl: './admin-panel-page.component.html', - styleUrls: ['./admin-panel-page.component.css'] -}) -export class AdminPanelPageComponent implements OnInit { - private _title = 'Admin Panel'; - @ViewChild(ErrorBarComponent) private _errorBar: ErrorBarComponent; - @ViewChild(SuccessBarComponent) private _successBar: SuccessBarComponent; - public dataArrived = false; - public showLanguages = false; - public showTechnologies = false; - public showDeletions = false; - public availableLanguages: Language[]; - public availableTechnologies: Technology[]; - public languageForm: FormGroup; - public technologyForm: FormGroup; - public deleteForm: FormGroup; - - constructor(private _titleService: Title, private _router: Router, private _fb: FormBuilder, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _tokenService: TokenService, private _postService: PostService, private _commentService: CommentService) { - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - if (!this._tokenService.getTokenFromSessionStorage()) { - this._router.navigate(['/login']); - return; - } - - this._userService.getUserFromSessionStorageRequest().subscribe( - (result: object) => { - const user = result as User; - if (!user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME)) { - this._router.navigate(['/login']); - } - }, - (err: HttpErrorResponse) => { - this._router.navigate(['/login']); - } - ); - - this.languageForm = this._fb.group({ - languageCreate: new FormControl(''), - updateLanguageOldName: new FormControl(''), - updateLanguageNewName: new FormControl(''), - deleteLanguageName: new FormControl('') - }); - - this.languageForm.valueChanges.subscribe(() => { - this._successBar?.hideMsg(); - this._errorBar?.hideError(); - }); - - this.technologyForm = this._fb.group({ - technologyCreate: new FormControl(''), - updateTechnologyOldName: new FormControl(''), - updateTechnologyNewName: new FormControl(''), - deleteTechnologyName: new FormControl('') - }); - - this.technologyForm.valueChanges.subscribe(() => { - this._successBar?.hideMsg(); - this._errorBar?.hideError(); - }); - - this.deleteForm = this._fb.group({ - deleteUser: new FormControl(''), - deletePost: new FormControl(''), - deleteComment: new FormControl('') - }); - - this.deleteForm.valueChanges.subscribe(() => { - this._successBar?.hideMsg(); - this._errorBar?.hideError(); - }); - - this.loadAvailableLanguages(); - this.loadAvailableTechnologies(); - } - - // Navigation - - backToProfile(): void { - this._router.navigate(['/profile/' + this._tokenService.getUsernameFromSessionStorageToken()]); - } - - backToFeed(): void { - this._router.navigate(['/']); - } - - logout(): void { - this._tokenService.logoutUserFromSessionStorage(); - this._router.navigate(['/login']); - } - - // Language modifying - - toggleLanguages(): void { - this.showLanguages = !this.showLanguages; - } - - submitLanguages(): void { - this.tryCreateLanguage(); - this.tryUpdateLanguage(); - this.tryDeleteLanguage(); - } - - private tryCreateLanguage(): void { - const languageCreate: string = this.languageForm.get('languageCreate')?.value; - - if (languageCreate !== '' && languageCreate !== null) { - this._languageService.createLanguageWithSessionStorageRequest(languageCreate.trim()).subscribe( - (result: object) => { - this.languageModifiedSuccess('Successfully updated languages!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private tryUpdateLanguage(): void { - const updateLanguageOldName: string = this.languageForm.get('updateLanguageOldName')?.value; - const updateLanguageNewName: string = this.languageForm.get('updateLanguageNewName')?.value; - - if (updateLanguageOldName !== '' && updateLanguageOldName !== null && updateLanguageNewName !== '' && updateLanguageNewName !== null) { - const langId = this.availableLanguages.filter(x => x.name === updateLanguageOldName.trim())[0].id; - - this._languageService.putLanguageWithSessionStorageRequest(langId, updateLanguageNewName.trim()).subscribe( - (result: object) => { - this.languageModifiedSuccess('Successfully updated languages!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private tryDeleteLanguage(): void { - const deleteLanguageName: string = this.languageForm.get('deleteLanguageName')?.value; - - if (deleteLanguageName !== '' && deleteLanguageName !== null) { - const langId = this.availableLanguages.filter(x => x.name === deleteLanguageName.trim())[0].id; - - this._languageService.deleteLanguageWithSessionStorageRequest(langId).subscribe( - (result: object) => { - this.languageModifiedSuccess('Successfully deleted language!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private languageModifiedSuccess(successMsg: string): void { - this.languageForm.reset(); - this._successBar.showMsg(successMsg); - this.loadAvailableLanguages(); - } - - private loadAvailableLanguages(): void { - this._languageService.getAllLanguagesWithSessionStorageRequest().subscribe( - (result: object) => { - this.availableLanguages = result as Language[]; - } - ); - } - - // Technology modifying - - toggleTechnologies(): void { - this.showTechnologies = !this.showTechnologies; - } - - submitTechnologies(): void { - this.tryCreateTechnology(); - this.tryUpdateTechnology(); - this.tryDeleteTechnology(); - } - - private tryCreateTechnology(): void { - const technologyCreate: string = this.technologyForm.get('technologyCreate')?.value; - - if (technologyCreate !== '' && technologyCreate !== null) { - this._technologyService.createTechnologyWithSessionStorageRequest(technologyCreate.trim()).subscribe( - (result: object) => { - this.technologyModifiedSuccess('Successfully updated technologies!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private tryUpdateTechnology(): void { - const updateTechnologyOldName: string = this.technologyForm.get('updateTechnologyOldName')?.value; - const updateTechnologyNewName: string = this.technologyForm.get('updateTechnologyNewName')?.value; - - if (updateTechnologyOldName !== '' && updateTechnologyOldName !== null && updateTechnologyNewName !== '' && updateTechnologyNewName !== null) { - const techId = this.availableTechnologies.filter(x => x.name === updateTechnologyOldName.trim())[0].id; - - this._technologyService.putTechnologyWithSessionStorageRequest(techId, updateTechnologyNewName.trim()).subscribe( - (result: object) => { - this.technologyModifiedSuccess('Successfully updated technologies!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private tryDeleteTechnology(): void { - const deleteTechnologyName: string = this.technologyForm.get('deleteTechnologyName')?.value; - - if (deleteTechnologyName !== '' && deleteTechnologyName !== null) { - const techId = this.availableTechnologies.filter(x => x.name === deleteTechnologyName.trim())[0].id; - - this._technologyService.deleteTechnologyWithSessionStorageRequest(techId).subscribe( - (result: object) => { - this.technologyModifiedSuccess('Successfully deleted technology!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private technologyModifiedSuccess(successMsg: string): void { - this.technologyForm.reset(); - this._successBar.showMsg(successMsg); - this.loadAvailableTechnologies(); - } - - private loadAvailableTechnologies(): void { - this._technologyService.getAllTechnologiesWithSessionStorageRequest().subscribe( - (result: object) => { - this.availableTechnologies = result as Technology[]; - } - ); - } - - // Deletions - - toggleDeletions(): void { - this.showDeletions = !this.showDeletions; - } - - submitDelete(): void { - this.tryDeleteUser(); - this.tryDeletePost(); - this.tryDeleteComment(); - } - - private tryDeleteUser(): void { - const deleteUser: string = this.deleteForm.get('deleteUser')?.value; - - if (deleteUser !== '' && deleteUser !== null) { - const userId: Guid = Guid.parse(deleteUser); - - this._userService.deleteUserRequest(userId, this._tokenService.getTokenFromSessionStorage()).subscribe( - (result: object) => { - this.deletionSuccess('Successfully deleted user!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private tryDeletePost(): void { - const deletePost: string = this.deleteForm.get('deletePost')?.value; - - if (deletePost !== '' && deletePost !== null) { - const postId: Guid = Guid.parse(deletePost); - - this._postService.deletePostRequest(postId, this._tokenService.getTokenFromSessionStorage()).subscribe( - (result: object) => { - this.deletionSuccess('Successfully deleted user!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private tryDeleteComment(): void { - const deleteComment: string = this.deleteForm.get('deleteComment')?.value; - - if (deleteComment !== '' && deleteComment !== null) { - const commentId: Guid = Guid.parse(deleteComment); - - this._commentService.deleteCommentWithSessionStorage(commentId).subscribe( - (result: object) => { - this.deletionSuccess('Successfully deleted comment!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - } - - private deletionSuccess(successMsg: string): void { - this.deleteForm.reset(); - this._successBar.showMsg(successMsg); - } -} diff --git a/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.css b/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.css deleted file mode 100644 index b886bc1..0000000 --- a/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.css +++ /dev/null @@ -1,27 +0,0 @@ -#content { - justify-content: flex-start !important; -} - -#content > * { - width: 100%; -} - -.many-buttons { - width: 100%; - display: flex; -} - -.many-buttons > * { - flex: 1; - margin-right: .3em; -} - -.many-buttons > *:last-of-type { - margin-right: 0; -} - -.submit-btn { - max-width: 98%; - margin: 0 auto; - margin-bottom: .5em; -} diff --git a/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.html b/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.html deleted file mode 100644 index 2d110d6..0000000 --- a/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.html +++ /dev/null @@ -1,14 +0,0 @@ -<app-loading *ngIf="!loaded"></app-loading> - -<div id="content" *ngIf="loaded"> - <button class="submit-btn" type="submit" (click)="toPost()">ᐊ Back to post</button> - <app-comment [paramId]="commentId.toString()"></app-comment> - <div class="many-buttons" *ngIf="editable"> - <button class="submit-btn" (click)="editComment()">Edit comment</button> - <button class="submit-btn delete-btn" (click)="deleteComment()">Delete comment</button> - </div> - <form [formGroup]="editCommentFormGroup" (ngSubmit)="editComment()"> - <input type="text" *ngIf="editingComment" placeholder="New comment message" class="input-field" formControlName="newCommentMessage"> - <input type="submit" style="display: none" /> - </form> -<div> diff --git a/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.ts b/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.ts deleted file mode 100644 index bd4cfe5..0000000 --- a/src/DevHive.Angular/src/app/components/comment-page/comment-page.component.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; -import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; -import { Guid } from 'guid-typescript'; -import { CommentService } from 'src/app/services/comment.service'; -import { TokenService } from 'src/app/services/token.service'; -import { Comment } from 'src/models/comment'; - -@Component({ - selector: 'app-comment-page', - templateUrl: './comment-page.component.html', - styleUrls: ['./comment-page.component.css'] -}) -export class CommentPageComponent implements OnInit { - private _title = 'Comment'; - public loaded = false; - public loggedIn = false; - public editable = false; - public editingComment = false; - public commentId: Guid; - public comment: Comment; - public editCommentFormGroup: FormGroup; - - constructor(private _titleService: Title, private _router: Router, private _fb: FormBuilder, private _tokenService: TokenService, private _commentService: CommentService){ - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - this.loggedIn = this._tokenService.getTokenFromSessionStorage() !== ''; - this.commentId = Guid.parse(this._router.url.substring(9)); - - // Gets the post and the logged in user and compares them, - // to determine if the current post is made by the user - this._commentService.getCommentRequest(this.commentId).subscribe( - (result: object) => { - this.comment = result as Comment; - if (this.loggedIn) { - this.editable = this.comment.issuerUsername === this._tokenService.getUsernameFromSessionStorageToken(); - } - this.loaded = true; - }, - (err: HttpErrorResponse) => { - this._router.navigate(['/not-found']); - } - ); - - this.editCommentFormGroup = this._fb.group({ - newCommentMessage: new FormControl('') - }); - } - - toPost(): void { - this._router.navigate(['/post/' + this.comment.postId]); - } - - editComment(): void { - if (this._tokenService.getTokenFromSessionStorage() === '') { - this._router.navigate(['/login']); - return; - } - - if (this.editingComment) { - const newMessage = this.editCommentFormGroup.get('newCommentMessage')?.value; - if (newMessage !== '') { - console.log(this.commentId); - this._commentService.putCommentWithSessionStorageRequest(this.commentId, this.comment.postId, newMessage).subscribe( - (result: object) => { - this.reloadPage(); - } - ); - } - } - this.editingComment = !this.editingComment; - } - - deleteComment(): void { - this._commentService.deleteCommentWithSessionStorage(this.commentId).subscribe( - (result: object) => { - this.toPost(); - } - ); - } - - private reloadPage(): void { - this._router.routeReuseStrategy.shouldReuseRoute = () => false; - this._router.onSameUrlNavigation = 'reload'; - this._router.navigate([this._router.url]); - } -} diff --git a/src/DevHive.Angular/src/app/components/comment/comment.component.css b/src/DevHive.Angular/src/app/components/comment/comment.component.css deleted file mode 100644 index d82f10e..0000000 --- a/src/DevHive.Angular/src/app/components/comment/comment.component.css +++ /dev/null @@ -1,59 +0,0 @@ -.comment { - display: flex; - width: 100%; - - margin: .5em auto; - box-sizing: border-box; - padding: .5em; - background-color: var(--card-bg); -} - -.comment:first-child { - margin-top: 0; -} - -/* Author */ - -.author { - display: flex; - margin-bottom: .2em; -} - -.author:hover { - cursor: pointer; -} - -.author > img { - width: 1.7em; - height: 1.7em; - margin-right: .2em; -} - -.author-info > .name { - font-size: .8em; -} - -.author-info > .handle { - font-size: .6em; - color: gray; -} - -/* Content */ - -.content { - flex: 1; -} - -.message { - margin: .3em 0; - word-break: break-all; -} - -.timestamp { - font-size: .5em; - color: gray; -} - -.message:hover, .timestamp:hover { - cursor: pointer; -} diff --git a/src/DevHive.Angular/src/app/components/comment/comment.component.html b/src/DevHive.Angular/src/app/components/comment/comment.component.html deleted file mode 100644 index 718e25c..0000000 --- a/src/DevHive.Angular/src/app/components/comment/comment.component.html +++ /dev/null @@ -1,23 +0,0 @@ -<app-loading *ngIf="!loaded"></app-loading> - -<div class="comment rounded-border" *ngIf="loaded"> - <div class="content"> - <div class="author" (click)="goToAuthorProfile()"> - <img class="round-image" [src]="user.profilePictureURL"> - <div class="author-info"> - <div class="name"> - {{ user.firstName }} {{ user.lastName }} - </div> - <div class="handle"> - @{{ user.userName }} - </div> - </div> - </div> - <div class="message" (click)="goToCommentPage()"> - {{ comment.message }} - </div> - <div class="timestamp" (click)="goToCommentPage()"> - {{ timeCreated }} - </div> - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/comment/comment.component.ts b/src/DevHive.Angular/src/app/components/comment/comment.component.ts deleted file mode 100644 index 5076769..0000000 --- a/src/DevHive.Angular/src/app/components/comment/comment.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { Guid } from 'guid-typescript'; -import { CommentService } from 'src/app/services/comment.service'; -import { UserService } from 'src/app/services/user.service'; -import { Comment } from 'src/models/comment'; -import { User } from 'src/models/identity/user'; - -@Component({ - selector: 'app-comment', - templateUrl: './comment.component.html', - styleUrls: ['./comment.component.css'] -}) -export class CommentComponent implements OnInit { - public loaded = false; - public user: User; - public comment: Comment; - public timeCreated: string; - @Input() paramId: string; - - constructor(private _router: Router, private _commentService: CommentService, private _userService: UserService) - { } - - ngOnInit(): void { - this.comment = this._commentService.getDefaultComment(); - this.user = this._userService.getDefaultUser(); - - this._commentService.getCommentRequest(Guid.parse(this.paramId)).subscribe( - (result: object) => { - Object.assign(this.comment, result); - - this.timeCreated = new Date(this.comment.timeCreated).toLocaleString('en-GB'); - this.loadUser(); - } - ); - } - - private loadUser(): void { - this._userService.getUserByUsernameRequest(this.comment.issuerUsername).subscribe( - (result: object) => { - Object.assign(this.user, result); - this.loaded = true; - } - ); - } - - goToAuthorProfile(): void { - this._router.navigate(['/profile/' + this.comment.issuerUsername]); - } - - goToCommentPage(): void { - this._router.navigate(['/comment/' + this.comment.commentId]); - } -} diff --git a/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.css b/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.css deleted file mode 100644 index 8f8edd9..0000000 --- a/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.css +++ /dev/null @@ -1,12 +0,0 @@ -#error-bar { - box-sizing: border-box; - width: 100%; - background-color: var(--failure); - color: white; - padding: .2em; - text-align: center; -} - -#error-bar:empty { - display: none; -} diff --git a/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.html b/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.html deleted file mode 100644 index f1995ab..0000000 --- a/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.html +++ /dev/null @@ -1 +0,0 @@ -<div id="error-bar">{{errorMsg}}</div> diff --git a/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.ts b/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.ts deleted file mode 100644 index 111bac8..0000000 --- a/src/DevHive.Angular/src/app/components/error-bar/error-bar.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { IApiError } from 'src/interfaces/api-error'; - -@Component({ - selector: 'app-error-bar', - templateUrl: './error-bar.component.html', - styleUrls: ['./error-bar.component.css'] -}) -export class ErrorBarComponent implements OnInit { - public errorMsg = ''; - - constructor() - { } - - ngOnInit(): void { - this.hideError(); - } - - showError(error: HttpErrorResponse): void { - const test: IApiError = { - type: '', - title: 'Error!', - status: 0, - traceId: '' - }; - Object.assign(test, error.error); - this.errorMsg = test.title; - } - - hideError(): void { - this.errorMsg = ''; - } -} diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.css b/src/DevHive.Angular/src/app/components/feed/feed.component.css deleted file mode 100644 index cb155c6..0000000 --- a/src/DevHive.Angular/src/app/components/feed/feed.component.css +++ /dev/null @@ -1,179 +0,0 @@ -#feed-page { - height: 100%; - max-width: 40em; - box-sizing: border-box; - border: .5em solid var(--bg-color); - - margin: 0 auto; - - display: flex; -} - -@media screen and (max-width: 750px) { - #profile-bar { - display: none !important; - } - #top-bar-profile-pic { - display: initial; - } -} -@media screen and (min-width: 750px) { - #profile-bar { - display: initial; - } - #top-bar-profile-pic { - display: none !important; - } -} - -/* Content */ - -#feed-content { - flex: 1; - display: flex; - flex-direction: column; -} - -/* Profile bar */ - -#profile-bar { - width: 20%; - height: fit-content; - display: flex; - flex-direction: column; - align-items: center; - - box-sizing: border-box; - background-color: var(--bg-color); - - margin-right: .5em; - padding-bottom: 1em; - padding: .5em; - border-radius: .6em; -} - -#profile-bar-profile-pic { - width: 7em; - height: 7em; - box-sizing: border-box; - padding: .5em; -} - -#profile-bar-name { - text-align: center; -} - -#profile-bar-username { - margin: .5em 0; -} - -#profile-bar > #profile-info { - display: flex; - flex-direction: column; - align-items: center; -} - -/* Top bar */ - -#top-bar { - display: flex; - flex-direction: column; - width: 98%; - margin: 0 auto; - margin-bottom: .5em; - box-sizing: border-box; -} - -#top-bar-profile-pic { - height: 2.5em; - width: 2.5em; - margin-right: .5em; -} - -#top-bar-profile-pic > img { - height: inherit; - width: inherit; -} - -#top-bar-open-chat { - /* Until implemented */ - display: none; -} - -#main-content { - display: flex; -} - -/* Create post */ - -#create-post-form { - width: 100%; - position: relative; - display: flex; - flex-direction: column; - box-sizing: border-box; -} - -#form-inputs { - display: flex; -} - -#top-bar-create-post { - flex: 1; - font-size: inherit; - width: 100%; - height: 100%; - margin: 0 auto; - box-sizing: border-box; - border: 2px solid var(--bg-color); - border-radius: .6em; -} - -#file-upload { - font-size: inherit; - color: transparent; - width: 1.5em; - height: 1.5em; -} - -#file-upload:hover { - cursor: pointer; -} - -#file-upload::-webkit-file-upload-button { - visibility: hidden; -} - -#attachment-img { - height: 1.5em; - width: 1.5em; - position: absolute; - right: .4em; - pointer-events: none; -} - -/* Posts */ - -#no-posts-msg { - width: 100%; - margin-top: 1em; - color: gray; - text-align: center; -} - -/* Elements, that act as buttons */ - -#profile-bar > #profile-info:hover, -#top-bar-profile-pic:hover { - cursor: pointer; -} - -/* Can't copy text from */ - -#profile-bar, -.vote { - -webkit-user-select: none; /* Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+/Edge */ - user-select: none; /* Standard */ -} diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.html b/src/DevHive.Angular/src/app/components/feed/feed.component.html deleted file mode 100644 index 1a03dcc..0000000 --- a/src/DevHive.Angular/src/app/components/feed/feed.component.html +++ /dev/null @@ -1,52 +0,0 @@ -<app-loading *ngIf="!dataArrived"></app-loading> - -<div id="feed-page" *ngIf="dataArrived"> - <nav id="profile-bar" class="round-image rounded-border"> - <div id="profile-info" (click)="goToProfile()"> - <img id="profile-bar-profile-pic" class="round-image" [src]="user.profilePictureURL" alt=""/> - <div id="profile-bar-name"> - {{ user.firstName }} {{ user.lastName }} - </div> - <div id="profile-bar-username"> - @{{ user.userName }} - </div> - </div> - <button class="submit-btn" (click)="goToSettings()">Settings</button> - <button class="submit-btn" (click)="logout()">Logout</button> - </nav> - <div id="feed-content"> - <nav id="top-bar"> - <div id="main-content"> - <img id="top-bar-profile-pic" class="round-image" [src]="user.profilePictureURL" alt="" (click)="goToProfile()"> - <form id="create-post-form" class="rounded-border" [formGroup]="createPostFormGroup" (ngSubmit)="createPost()"> - <div id="form-inputs"> - <input id="top-bar-create-post" type="text" formControlName="newPostMessage" placeholder="What's on your mind?"/> - <input type="submit" style="display: none" /> <!-- You need this element, so when you press enter the request is sent --> - <img id="attachment-img" src="assets/images/paper-clip.png"> - <input id="file-upload" type="file" formControlName="fileUpload" (change)="onFileUpload($event)" multiple> - </div> - <div class="form-attachments"> - <div *ngFor="let file of files" class="form-attachment"> - {{ file.name ? file.name : 'Attachment' }} - <div class="remove-form-attachment" (click)="removeAttachment(file.name)"> - ☒ - </div> - </div> - </div> - </form> - <a id="top-bar-open-chat" href=""> - <img src="assets/images/feed/chat-pic.png" alt=""/> - </a> - </div> - </nav> - <div id="posts" class="scroll-standalone" (scroll)="onScroll($event)"> - <div id="no-posts-msg" *ngIf="posts.length === 0"> - None of your friends have posted anything yet!<br> - Try refreshing your page! - </div> - <div *ngFor="let friendPost of posts" class="post"> - <app-post [paramId]="friendPost.postId.toString()"></app-post> - </div> - </div> - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.ts b/src/DevHive.Angular/src/app/components/feed/feed.component.ts deleted file mode 100644 index b412b3c..0000000 --- a/src/DevHive.Angular/src/app/components/feed/feed.component.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; -import { User } from 'src/models/identity/user'; -import { UserService } from '../../services/user.service'; -import { AppConstants } from 'src/app/app-constants.module'; -import { HttpErrorResponse } from '@angular/common/http'; -import { FeedService } from 'src/app/services/feed.service'; -import { Post } from 'src/models/post'; -import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; -import { PostService } from 'src/app/services/post.service'; -import { TokenService } from 'src/app/services/token.service'; - -@Component({ - selector: 'app-feed', - templateUrl: './feed.component.html', - styleUrls: ['./feed.component.css'] -}) -export class FeedComponent implements OnInit { - private _title = 'Feed'; - private _timeLoaded: string; // we send the time to the api as a string - private _currentPage: number; - public dataArrived = false; - public user: User; - public posts: Post[]; - public createPostFormGroup: FormGroup; - public files: File[]; - - constructor(private _titleService: Title, private _fb: FormBuilder, private _router: Router, private _userService: UserService, private _feedService: FeedService, private _postService: PostService, private _tokenService: TokenService) { - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - if (!this._tokenService.getTokenFromSessionStorage()) { - this._router.navigate(['/login']); - return; - } - - this._currentPage = 1; - this.posts = []; - this.user = this._userService.getDefaultUser(); - this.files = []; - - const now = new Date(); - now.setHours(now.getHours() + 2); // accounting for eastern european timezone - this._timeLoaded = now.toISOString(); - - this.createPostFormGroup = this._fb.group({ - newPostMessage: new FormControl(''), - fileUpload: new FormControl('') - }); - - this._userService.getUserFromSessionStorageRequest().subscribe( - (res: object) => { - Object.assign(this.user, res); - this.loadFeed(); - }, - (err: HttpErrorResponse) => { - this.logout(); - } - ); - } - - private loadFeed(): void { - this._feedService.getUserFeedFromSessionStorageRequest(this._currentPage++, this._timeLoaded, AppConstants.PAGE_SIZE).subscribe( - (result: object) => { - this.posts.push(...Object.values(result)[0]); - this.finishUserLoading(); - }, - (err) => { - this.finishUserLoading(); - } - ); - } - - private finishUserLoading(): void { - this.dataArrived = true; - } - - goToProfile(): void { - this._router.navigate(['/profile/' + this.user.userName]); - } - - goToSettings(): void { - this._router.navigate(['/profile/' + this.user.userName + '/settings']); - } - - logout(): void { - this._tokenService.logoutUserFromSessionStorage(); - this._router.navigate(['/login']); - } - - onFileUpload(event: any): void { - this.files.push(...event.target.files); - this.createPostFormGroup.get('fileUpload')?.reset(); - } - - removeAttachment(fileName: string): void { - this.files = this.files.filter(x => x.name !== fileName); - } - - createPost(): void { - const postMessage = this.createPostFormGroup.get('newPostMessage')?.value; - this.dataArrived = false; - - this._postService.createPostWithSessionStorageRequest(postMessage, this.files).subscribe( - (result: object) => { - this.goToProfile(); - }, - (err: HttpErrorResponse) => { - this.dataArrived = true; - } - ); - } - - 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.loadFeed(); - } - } -} diff --git a/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.css b/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.css deleted file mode 100644 index e69de29..0000000 --- a/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.css +++ /dev/null diff --git a/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.html b/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.html deleted file mode 100644 index 7392a21..0000000 --- a/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.html +++ /dev/null @@ -1,8 +0,0 @@ -<div class="kaleidoscope"> - <ng-container *ngComponentOutlet="component"></ng-container> - <app-login *ngIf="logged!"></app-login> - <app-register *ngIf="!logged!"></app-register> - <!-- <app-feed></app-feed> --> - <script>var logged = false;</script> - <!-- to be fixed tomorow --> -</div>
\ No newline at end of file diff --git a/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.ts b/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.ts deleted file mode 100644 index 1c5cda1..0000000 --- a/src/DevHive.Angular/src/app/components/kaleidoscope/kaleidoscope.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { LoginComponent } from '../login/login.component'; - -@Component({ - selector: 'app-kaleidoscope', - templateUrl: './kaleidoscope.component.html', - styleUrls: ['./kaleidoscope.component.css'] -}) -export class KaleidoscopeComponent implements OnInit { - - public _component: Component; - - constructor(loginComponent: LoginComponent) { - this._component = loginComponent as Component; - } - - ngOnInit(): void { - - } - - assignComponent(component: Component) { - this._component = component; - } -} diff --git a/src/DevHive.Angular/src/app/components/loading/loading.component.css b/src/DevHive.Angular/src/app/components/loading/loading.component.css deleted file mode 100644 index e69de29..0000000 --- a/src/DevHive.Angular/src/app/components/loading/loading.component.css +++ /dev/null diff --git a/src/DevHive.Angular/src/app/components/loading/loading.component.html b/src/DevHive.Angular/src/app/components/loading/loading.component.html deleted file mode 100644 index 8440f4e..0000000 --- a/src/DevHive.Angular/src/app/components/loading/loading.component.html +++ /dev/null @@ -1,3 +0,0 @@ -<div id="content"> - Loading... -</div> diff --git a/src/DevHive.Angular/src/app/components/loading/loading.component.ts b/src/DevHive.Angular/src/app/components/loading/loading.component.ts deleted file mode 100644 index e203484..0000000 --- a/src/DevHive.Angular/src/app/components/loading/loading.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-loading', - templateUrl: './loading.component.html', - styleUrls: ['./loading.component.css'] -}) -export class LoadingComponent implements OnInit { - - constructor() - { } - - ngOnInit(): void { - } -} diff --git a/src/DevHive.Angular/src/app/components/login/login.component.css b/src/DevHive.Angular/src/app/components/login/login.component.css deleted file mode 100644 index 766522e..0000000 --- a/src/DevHive.Angular/src/app/components/login/login.component.css +++ /dev/null @@ -1,32 +0,0 @@ -* { - transition: .2s; -} - -form { - width: 100%; -} - -#content hr { - width: 100%; - border: 1px solid black; - box-sizing: border-box; -} - -.input-selection:nth-of-type(1) { - margin-top: 1.2em; -} - -.submit-btn { - margin-bottom: .2em; -} - -.redirect-to-register { - color: var(--focus-color); - background-color: var(--bg-color); - border-color: var(--focus-color); -} - -.redirect-to-register:hover { - border-color: black !important; - color: black; -} diff --git a/src/DevHive.Angular/src/app/components/login/login.component.html b/src/DevHive.Angular/src/app/components/login/login.component.html deleted file mode 100644 index 13f9bbf..0000000 --- a/src/DevHive.Angular/src/app/components/login/login.component.html +++ /dev/null @@ -1,30 +0,0 @@ -<div id="content"> - <div class="title">Login</div> - - <form [formGroup]="loginUserFormGroup" (ngSubmit)="onSubmit()"> - <hr> - - <div class="input-selection"> - <input type="text" placeholder="Username" class="input-field" formControlName="username" required> - <label class="input-field-label">Username</label> - - <div class="input-errors"> - <label *ngIf="loginUserFormGroup.get('username')?.errors?.required" class="error">*Required</label> - </div> - </div> - - <div class="input-selection"> - <input type="password" placeholder="Password" class="input-field" formControlName="password" required> - <label class="input-field-label">Password</label> - - <div class="input-errors"> - <label *ngIf="loginUserFormGroup.get('password')?.errors?.required" class="error">*Required</label> - </div> - </div> - - <hr> - <button class="submit-btn" type="submit">Submit</button> - <app-error-bar></app-error-bar> - </form> - <button class="submit-btn redirect-to-register" (click)="onRedirectRegister()">New to DevHive? Register instead</button> -</div> diff --git a/src/DevHive.Angular/src/app/components/login/login.component.ts b/src/DevHive.Angular/src/app/components/login/login.component.ts deleted file mode 100644 index c3fb79c..0000000 --- a/src/DevHive.Angular/src/app/components/login/login.component.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormGroup, FormBuilder, Validators, FormControl, AbstractControl } from '@angular/forms'; -import { Router } from '@angular/router'; -import { Title } from '@angular/platform-browser'; -import { UserService } from 'src/app/services/user.service'; -import { HttpErrorResponse } from '@angular/common/http'; -import { ErrorBarComponent } from '../error-bar/error-bar.component'; -import { TokenService } from 'src/app/services/token.service'; - -@Component({ - selector: 'app-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.css'] -}) -export class LoginComponent implements OnInit { - @ViewChild(ErrorBarComponent) private _errorBar: ErrorBarComponent; - private _title = 'Login'; - public loginUserFormGroup: FormGroup; - - constructor(private _titleService: Title, private _fb: FormBuilder, private _router: Router, private _userService: UserService, private _tokenService: TokenService) { - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - this.loginUserFormGroup = this._fb.group({ - username: new FormControl('', [ - Validators.required - ]), - password: new FormControl('', [ - Validators.required - ]) - }); - } - - onSubmit(): void { - this._errorBar.hideError(); - this._userService.loginUserRequest(this.loginUserFormGroup).subscribe( - (res: object) => { - this._tokenService.setUserTokenToSessionStorage(res); - this._router.navigate(['/']); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - - onRedirectRegister(): void { - this._router.navigate(['/register']); - } - - get username(): AbstractControl | null { - return this.loginUserFormGroup.get('username'); - } - - get password(): AbstractControl | null { - return this.loginUserFormGroup.get('password'); - } -} diff --git a/src/DevHive.Angular/src/app/components/not-found/not-found.component.css b/src/DevHive.Angular/src/app/components/not-found/not-found.component.css deleted file mode 100644 index ef6231d..0000000 --- a/src/DevHive.Angular/src/app/components/not-found/not-found.component.css +++ /dev/null @@ -1,23 +0,0 @@ -#content { - font-size: 1.3em; -} - -#content hr { - width: 100%; - border: 1px solid black; - box-sizing: border-box; -} - -#back-btns { - width: 100%; - display: flex; -} - -#back-btns > * { - flex: 1; - margin-right: .2em; -} - -#back-btns > *:nth-last-child(1) { - margin-right: 0; -} diff --git a/src/DevHive.Angular/src/app/components/not-found/not-found.component.html b/src/DevHive.Angular/src/app/components/not-found/not-found.component.html deleted file mode 100644 index 8394810..0000000 --- a/src/DevHive.Angular/src/app/components/not-found/not-found.component.html +++ /dev/null @@ -1,10 +0,0 @@ -<div id="content"> - <div class="title"> - Page not found! - </div> - <hr> - <div id="back-btns"> - <button class="submit-btn" type="submit" (click)="backToFeed()">Back to feed</button> - <button class="submit-btn" type="submit" (click)="backToLogin()">Back to login</button> - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/not-found/not-found.component.ts b/src/DevHive.Angular/src/app/components/not-found/not-found.component.ts deleted file mode 100644 index b1f8cc1..0000000 --- a/src/DevHive.Angular/src/app/components/not-found/not-found.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'app-not-found', - templateUrl: './not-found.component.html', - styleUrls: ['./not-found.component.css'] -}) -export class NotFoundComponent implements OnInit { - private _title = 'Not Found!'; - - constructor(private _titleService: Title, private _router: Router) { - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - } - - backToFeed(): void { - this._router.navigate(['/']); - } - - backToLogin(): void { - this._router.navigate(['/login']); - } -} diff --git a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.css b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.css deleted file mode 100644 index 572cc99..0000000 --- a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.css +++ /dev/null @@ -1,75 +0,0 @@ -/* Attachment */ - -.attachment { - border: 2px solid black; - border-top: 0; - border-radius: 0 0 .6em .6em; - padding: .4em; - padding-top: 1em; - margin-top: calc(-0.8em - 2px); -} - -.clickable { - width: 100%; - height: 100%; - display: flex; -} - -.clickable:hover { - cursor: pointer; -} - -.attachment-name { - flex: 1; -} - -.attachment-type { - margin-left: .2em; -} - -/* Full attachment */ - -.show-full-attachment { - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background-color: #000000AF; - display: flex; - justify-content: center; - align-items: center; - z-index: 2; -} - -.show-full-attachment > * { - max-height: 100vh; - max-width: 100vw; -} - -.attachment-download { - max-width: 420px !important; - margin: 0 .4em; - text-decoration: none; - color: white; - border-color: white; - background-color: black; -} - -.attachment-download:hover { - background-color: white; - color: var(--focus-color); -} - -.close { - position: fixed; - top: .2em; - right: .2em; - font-size: 2em; - color: whitesmoke; -} - -.close:hover { - color: var(--failure); - cursor: pointer; -} diff --git a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html deleted file mode 100644 index 4d381d1..0000000 --- a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html +++ /dev/null @@ -1,18 +0,0 @@ -<div class="attachment"> - <div class="clickable" (click)="toggleShowFull()"> - <div class="attachment-name"> - {{ fileName }} - </div> - <div class="attachment-type"> - {{ fileType }} - </div> - </div> -</div> - -<div class="show-full-attachment" *ngIf="showFull" (click)="toggleShowFull()"> - <img class="attachment-img" *ngIf="isImage" src="{{paramURL}}"> - <a class="attachment-download submit-btn" *ngIf="!isImage" href="{{paramURL}}">Download attachment</a> - <div class="close"> - ☒ - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts deleted file mode 100644 index 1d00def..0000000 --- a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-post-attachment', - templateUrl: './post-attachment.component.html', - styleUrls: ['./post-attachment.component.css'] -}) -export class PostAttachmentComponent implements OnInit { - @Input() paramURL: string; - public isImage = false; - public showFull = false; - public fileName: string; - public fileType: string; - - constructor() - { } - - ngOnInit(): void { - this.isImage = this.paramURL.includes('image') && !this.paramURL.endsWith('pdf'); - this.fileType = this.isImage ? 'img' : 'raw'; - this.fileName = this.paramURL.match('(?<=\/)(?:.(?!\/))+$')?.pop() ?? 'Attachment'; - } - - toggleShowFull(): void { - this.showFull = !this.showFull; - } -} diff --git a/src/DevHive.Angular/src/app/components/post-page/post-page.component.css b/src/DevHive.Angular/src/app/components/post-page/post-page.component.css deleted file mode 100644 index 3eec851..0000000 --- a/src/DevHive.Angular/src/app/components/post-page/post-page.component.css +++ /dev/null @@ -1,62 +0,0 @@ -#content { - justify-content: flex-start !important; -} - -#content > * { - width: 100%; -} - -.many-buttons { - width: 100%; - display: flex; -} - -.many-buttons > * { - flex: 1; - margin-right: .3em; -} - -.many-buttons > *:last-of-type { - margin-right: 0; -} - -#editPost { - display: flex; - position: relative; -} - -#new-message-input { - flex: 1; - box-sizing: border-box; -} - -#file-upload { - font-size: inherit; - color: transparent; - width: 1.99em; - height: 1.99em; - margin-left: .3em; -} - -#file-upload:hover { - cursor: pointer; -} - -#file-upload::-webkit-file-upload-button { - visibility: hidden; -} - -#attachment-img { - height: 1.99em; - width: 1.99em; - position: absolute; - right: 0; - pointer-events: none; -} - - -.submit-btn { - max-width: 98%; - margin: 0 auto; - margin-bottom: .5em; -} diff --git a/src/DevHive.Angular/src/app/components/post-page/post-page.component.html b/src/DevHive.Angular/src/app/components/post-page/post-page.component.html deleted file mode 100644 index 8665865..0000000 --- a/src/DevHive.Angular/src/app/components/post-page/post-page.component.html +++ /dev/null @@ -1,37 +0,0 @@ -<app-loading *ngIf="!dataArrived"></app-loading> - -<div id="content" *ngIf="dataArrived"> - <div class="many-buttons" *ngIf="loggedIn"> - <button class="submit-btn" type="submit" (click)="backToFeed()">ᐊ Back to feed</button> - <button class="submit-btn" type="submit" (click)="backToProfile()">ᐊ Back to profile</button> - </div> - <button class="submit-btn" type="submit" (click)="toLogin()" *ngIf="!loggedIn">Login</button> - <app-post [paramId]="postId.toString()"></app-post> - <div class="many-buttons" *ngIf="editable"> - <button class="submit-btn" (click)="editPost()">Edit post</button> - <button class="submit-btn delete-btn" (click)="deletePost()">Delete post</button> - </div> - <form id="editPost" [formGroup]="editPostFormGroup" *ngIf="editingPost" (ngSubmit)="editPost()"> - <input id="new-message-input" type="text" placeholder="New post message" class="input-field" formControlName="newPostMessage"> - <img id="attachment-img" src="assets/images/paper-clip.png"> - <input id="file-upload" type="file" formControlName="fileUpload" (change)="onFileUpload($event)" multiple> - <input type="submit" style="display: none" /> - </form> - <div class="form-attachments" *ngIf="editingPost"> - <div *ngFor="let file of files" class="form-attachment"> - {{ file.name ? file.name : 'Attachment' }} - <div class="remove-form-attachment" (click)="removeAttachment(file.name)"> - ☒ - </div> - </div> - </div> - <form [formGroup]="addCommentFormGroup" (ngSubmit)="addComment()"> - <input type="text" placeholder="Add comment" class="input-field" formControlName="newComment"> - <input type="submit" style="display: none" /> - </form> - <div> - <div class="comment" *ngFor="let comm of post?.comments"> - <app-comment [paramId]="comm.id.toString()"></app-comment> - </div> - </div> -<div> diff --git a/src/DevHive.Angular/src/app/components/post-page/post-page.component.ts b/src/DevHive.Angular/src/app/components/post-page/post-page.component.ts deleted file mode 100644 index 413ff80..0000000 --- a/src/DevHive.Angular/src/app/components/post-page/post-page.component.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; -import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; -import { Guid } from 'guid-typescript'; -import { CommentService } from 'src/app/services/comment.service'; -import { PostService } from 'src/app/services/post.service'; -import { TokenService } from 'src/app/services/token.service'; -import { Post } from 'src/models/post'; -import { CloudinaryService } from 'src/app/services/cloudinary.service'; - -@Component({ - selector: 'app-post-page', - templateUrl: './post-page.component.html', - styleUrls: ['./post-page.component.css'] -}) -export class PostPageComponent implements OnInit { - private _title = 'Post'; - public dataArrived = false; - public loggedIn = false; - public editable = false; - public editingPost = false; - public postId: Guid; - public post: Post; - public files: File[]; - public editPostFormGroup: FormGroup; - public addCommentFormGroup: FormGroup; - - constructor(private _titleService: Title, private _router: Router, private _fb: FormBuilder, private _tokenService: TokenService, private _postService: PostService, private _commentService: CommentService, private _cloudinaryService: CloudinaryService){ - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - this.loggedIn = this._tokenService.getTokenFromSessionStorage() !== ''; - this.postId = Guid.parse(this._router.url.substring(6)); - this.files = []; - - // Gets the post and the logged in user and compares them, - // to determine if the current post is made by the user - this._postService.getPostRequest(this.postId).subscribe( - (result: object) => { - this.post = result as Post; - this.post.fileURLs = Object.values(result)[7]; - if (this.loggedIn) { - this.editable = this.post.creatorUsername === this._tokenService.getUsernameFromSessionStorageToken(); - } - if (this.post.fileURLs.length > 0) { - this.loadFiles(); - } - else { - this.dataArrived = true; - } - }, - (err: HttpErrorResponse) => { - this._router.navigate(['/not-found']); - } - ); - - this.editPostFormGroup = this._fb.group({ - newPostMessage: new FormControl(''), - fileUpload: new FormControl('') - }); - - this.addCommentFormGroup = this._fb.group({ - newComment: new FormControl('') - }); - } - - private loadFiles(): void { - for (const fileURL of this.post.fileURLs) { - this._cloudinaryService.getFileRequest(fileURL).subscribe( - (result: object) => { - const file = result as File; - const tmp = { - name: fileURL.match('(?<=\/)(?:.(?!\/))+$')?.pop() ?? 'Attachment' - }; - - Object.assign(file, tmp); - this.files.push(file); - - if (this.files.length === this.post.fileURLs.length) { - this.dataArrived = true; - } - } - ); - } - } - - backToFeed(): void { - this._router.navigate(['/']); - } - - backToProfile(): void { - this._router.navigate(['/profile/' + this._tokenService.getUsernameFromSessionStorageToken()]); - } - - toLogin(): void { - this._router.navigate(['/login']); - } - - onFileUpload(event: any): void { - this.files.push(...event.target.files); - this.editPostFormGroup.get('fileUpload')?.reset(); - } - - removeAttachment(fileName: string): void { - this.files = this.files.filter(x => x.name !== fileName); - } - - editPost(): void { - if (this._tokenService.getTokenFromSessionStorage() === '') { - this.toLogin(); - return; - } - - if (this.editingPost) { - let newMessage = this.editPostFormGroup.get('newPostMessage')?.value; - if (newMessage === '') { - newMessage = this.post.message; - } - this._postService.putPostWithSessionStorageRequest(this.postId, newMessage, this.files).subscribe( - (result: object) => { - this.reloadPage(); - } - ); - this.dataArrived = false; - } - this.editingPost = !this.editingPost; - } - - addComment(): void { - if (!this.loggedIn) { - this._router.navigate(['/login']); - return; - } - - const newComment = this.addCommentFormGroup.get('newComment')?.value; - if (newComment !== '' && newComment !== null) { - this._commentService.createCommentWithSessionStorageRequest(this.postId, newComment).subscribe( - (result: object) => { - this.editPostFormGroup.reset(); - this.reloadPage(); - } - ); - } - } - - deletePost(): void { - this._postService.deletePostWithSessionStorage(this.postId).subscribe( - (result: object) => { - this._router.navigate(['/profile/' + this._tokenService.getUsernameFromSessionStorageToken()]); - } - ); - } - - private reloadPage(): void { - this._router.routeReuseStrategy.shouldReuseRoute = () => false; - this._router.onSameUrlNavigation = 'reload'; - this._router.navigate([this._router.url]); - } -} diff --git a/src/DevHive.Angular/src/app/components/post/post.component.css b/src/DevHive.Angular/src/app/components/post/post.component.css deleted file mode 100644 index 1b88c7d..0000000 --- a/src/DevHive.Angular/src/app/components/post/post.component.css +++ /dev/null @@ -1,134 +0,0 @@ -.post { - display: flex; - width: 98%; - - margin: .5em auto; - box-sizing: border-box; - padding: .5em; - background-color: var(--card-bg); - position: relative; -} - -.post:first-child { - margin-top: 0; -} - -hr { - border: 1px solid black; - width: 90%; -} - -/* Author */ - -.author { - display: flex; - margin-bottom: .2em; -} - -.author:hover { - cursor: pointer; -} - -.author > img { - width: 2.2em; - height: 2.2em; - margin-right: .2em; -} - -.author-info > .handle { - font-size: .9em; - color: gray; -} - -/* Content */ - -.content { - flex: 1; -} - -.message { - margin: .3em 0; - word-break: break-all; -} - -.bottom-post { - font-size: .5em; - color: gray; - display: flex; - align-items: center; -} - -.separator { - margin: 0 .5em; -} - -.comment-count { - font-size: 1em; -} - -.comment-count > img { - height: .8em; -} - -.message:hover, .timestamp:hover { - cursor: pointer; -} - -/* Rating */ - -/* Temporary, until ratings are implemented fully */ -.rating { - display: none !important; -} - -.rating { - display: flex; - flex-direction: column; - align-items: center; - min-height: 4.4em; - margin: auto -.1em auto 0; -} - -.score { - flex: 1; - display: flex; - align-items: center; -} - - -.vote { - display: flex; - align-items: center; - flex: 1; - - background: var(--card-bg); - font-size: 1em; - - border: 1px solid var(--card-bg); - box-sizing: border-box; - border-radius: .2em; - - } - -.vote:hover { - border: 1px solid var(--focus-color); - color: var(--focus-color); - cursor: pointer; -} - -/* Attachments */ - -.attachments { - display: flex; - width: 98%; - margin: -.3em auto .5em auto; - flex-wrap: wrap; -} - -.attachments:empty { - display: none; -} - -.attachments > * { - flex: 1; -} diff --git a/src/DevHive.Angular/src/app/components/post/post.component.html b/src/DevHive.Angular/src/app/components/post/post.component.html deleted file mode 100644 index bc0d84a..0000000 --- a/src/DevHive.Angular/src/app/components/post/post.component.html +++ /dev/null @@ -1,49 +0,0 @@ -<app-loading *ngIf="!loaded"></app-loading> - -<div class="post rounded-border" *ngIf="loaded"> - <div class="content"> - <div class="author" (click)="goToAuthorProfile()"> - <img class="round-image" [src]="user.profilePictureURL"> - <div class="author-info"> - <div class="name"> - {{ user.firstName }} {{ user.lastName }} - </div> - <div class="handle"> - @{{ user.userName }} - </div> - </div> - </div> - <div class="message" (click)="goToPostPage()"> - {{ post.message }} - </div> - <div class="bottom-post" (click)="goToPostPage()"> - <div class="timestamp"> - {{ timeCreated }} - </div> - <div class="separator"> - ║ - </div> - <div class="comment-count"> - {{ post.comments.length }} - <img src="assets/images/comment.png"> - </div> - </div> - - </div> - <div class="rating"> - <button class="vote"> - ᐃ - </button> - <div class="score"> - {{ votesNumber }} - </div> - <button class="vote"> - ᐁ - </button> - </div> -</div> -<div class="attachments"> - <div *ngFor="let fileURL of post.fileURLs"> - <app-post-attachment class="no-events" [paramURL]="fileURL"></app-post-attachment> - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/post/post.component.ts b/src/DevHive.Angular/src/app/components/post/post.component.ts deleted file mode 100644 index 387f56f..0000000 --- a/src/DevHive.Angular/src/app/components/post/post.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { Guid } from 'guid-typescript'; -import { PostService } from 'src/app/services/post.service'; -import { UserService } from 'src/app/services/user.service'; -import { User } from 'src/models/identity/user'; -import { Post } from 'src/models/post'; - -@Component({ - selector: 'app-post', - templateUrl: './post.component.html', - styleUrls: ['./post.component.css'], -}) -export class PostComponent implements OnInit { - public loaded = false; - public user: User; - public post: Post; - public votesNumber: number; - public timeCreated: string; - @Input() paramId: string; - - constructor(private _postService: PostService, private _userService: UserService, private _router: Router) - { } - - ngOnInit(): void { - this.post = this._postService.getDefaultPost(); - this.user = this._userService.getDefaultUser(); - - this._postService.getPostRequest(Guid.parse(this.paramId)).subscribe( - (result: object) => { - Object.assign(this.post, result); - this.post.fileURLs = Object.values(result)[7]; - this.votesNumber = 23; - - this.timeCreated = new Date(this.post.timeCreated).toLocaleString('en-GB'); - this.loadUser(); - } - ); - } - - private loadUser(): void { - this._userService.getUserByUsernameRequest(this.post.creatorUsername).subscribe( - (result: object) => { - Object.assign(this.user, result); - this.loaded = true; - } - ); - } - - goToAuthorProfile(): void { - this._router.navigate(['/profile/' + this.user.userName]); - } - - goToPostPage(): void { - this._router.navigate(['/post/' + this.post.postId]); - } -} diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css deleted file mode 100644 index 1c07d9f..0000000 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css +++ /dev/null @@ -1,124 +0,0 @@ -* { - box-sizing: border-box; -} - -#content { - max-width: 22em; - justify-content: start; -} - -form { - width: 100%; -} - -hr { - width: calc(100% - 1em); - color: black; - border: 1px solid black; -} - -/* Navigation bar (for loggedin user) */ - -#navigation { - display: flex; - width: 100%; -} - -#navigation > .submit-btn { - flex: 1; - margin-top: 0; - margin-left: .5em; - font-size: inherit; -} - -#navigation > .submit-btn:nth-of-type(1) { - margin-left: 0; -} - -/* Form */ - -#update-profile-picture { - display: flex; - align-items: center; - justify-content: center; - padding: 0 .5em; - flex-wrap: wrap; -} - -#profile-picture { - width: 5em; - height: 5em; -} - -#submit-file { - display: flex; - flex-direction: column; - align-items: center; - padding: 1em; -} - -#upload-file:hover { - cursor: inherit; -} - -#upload-file > input:hover { - cursor: pointer; -} - -#upload-file > input::-webkit-file-upload-button { - visibility: hidden; -} - -#update-user { - margin-top: 1.1em; -} - -.input-field { - border-color: var(--focus-color) !important; - caret-color: var(--focus-color); - border-width: 2px !important; - margin-top: -1px !important; -} - -.input-field-label { - font-size: .7em; - color: var(--focus-color); - transform: translate(0, -1.2em); -} - -#all-languages, #all-technologies { - display: flex; - flex-wrap: wrap; -} - -/* Buttons */ - -.edit-btn { - border-radius: 0 !important; - color: var(--focus-color); - background-color: white; - border-color: var(--focus-color); -} - -.edit-btn:hover { - color: white; - background-color: black; - border-color: black !important; -} - -.submit-btn { - margin-bottom: .5em; -} - -#update-profile-btn { - margin-top: 1em; -} - -#confirm-delete { - box-sizing: border-box; - width: 100%; - background-color: var(--failure); - color: white; - padding: .2em; - text-align: center; -} diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html deleted file mode 100644 index 502697d..0000000 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html +++ /dev/null @@ -1,116 +0,0 @@ -<app-loading *ngIf="!dataArrived"></app-loading> - -<div id="content" *ngIf="dataArrived"> - <nav id="navigation"> - <button class="submit-btn" (click)="goToProfile()">ᐊ Back</button> - <button class="submit-btn" (click)="navigateToAdminPanel()" *ngIf="isAdminUser">Panel</button> - <button class="submit-btn" (click)="logout()">Logout</button> - </nav> - <hr> - <div class="scroll-standalone"> - <form id="update-profile-picture" [formGroup]="updateProfilePictureFormGroup" (ngSubmit)="updateProfilePicture()"> - <img id="profile-picture" class="round-image" [src]="user.profilePictureURL"> - <div id="submit-file"> - <div id="upload-file" class="submit-btn"> - <input type="file" accept="image/*" formControlName="fileUpload" (change)="onFileUpload($event)"> - </div> - <button class="submit-btn" type="submit">Update profile picture</button> - </div> - </form> - <hr> - <form id="update-user" [formGroup]="updateUserFormGroup" (ngSubmit)="onSubmit()"> - <div class="input-selection"> - <input type="text" class="input-field" formControlName="firstName" required> - <label class="input-field-label">First Name</label> - - <div class="input-errors"> - <label *ngIf="updateUserFormGroup.get('firstName')?.errors?.required" class="error">*Required</label> - <label *ngIf="updateUserFormGroup.get('firstName')?.errors?.minlength" class="error">*Minimum 3 characters</label> - </div> - </div> - - <div class="input-selection"> - <input type="text" class="input-field" formControlName="lastName" required> - <label class="input-field-label">Last Name</label> - - <div class="input-errors"> - <label *ngIf="updateUserFormGroup.get('lastName')?.errors?.required" class="error">*Required</label> - <label *ngIf="updateUserFormGroup.get('lastName')?.errors?.minlength" class="error">*Minimum 3 characters</label> - </div> - </div> - - <div class="input-selection"> - <input type="text" class="input-field" formControlName="username" required> - <label class="input-field-label">Username</label> - - <div class="input-errors"> - <label *ngIf="updateUserFormGroup.get('username')?.errors?.required" class="error">*Required</label> - <label *ngIf="updateUserFormGroup.get('username')?.errors?.minlength" class="error">*Minimum 3 characters</label> - </div> - </div> - - <div class="input-selection"> - <input type="text" class="input-field" formControlName="email" required> - <label class="input-field-label">Email</label> - - <div class="input-errors"> - <label *ngIf="updateUserFormGroup.get('email')?.errors?.required" class="error">*Required</label> - <label *ngIf="updateUserFormGroup.get('email')?.errors?.email" class="error">*Invalid email</label> - </div> - </div> - - <div class="input-selection"> - <input type="password" class="input-field" formControlName="password" required> - <label class="input-field-label">Password</label> - - <div class="input-errors"> - <label *ngIf="updateUserFormGroup.get('password')?.errors?.required" class="error">*Required</label> - <label *ngIf="updateUserFormGroup.get('password')?.errors?.minlength" class="error">*Minimum 3 characters</label> - <label *ngIf="updateUserFormGroup.get('password')?.errors?.pattern" class="error">*At least 1 number</label> - </div> - </div> - <button type="button" class="submit-btn edit-btn" (click)="toggleLanguages()">▼ Edit Languages ▼</button> - <div *ngIf="showLanguages"> - <div class="input-selection"> - <input type="text" class="input-field" formControlName="languageInput" required> - - <div class="input-errors"> - <label class="error">Type in your desired languages, separated by a space</label> - </div> - </div> - Available languages: - <div id="all-languages"> - <div class="user-language" *ngFor="let lang of availableLanguages"> - {{ lang.name }} - </div> - </div> - </div> - - <button type="button" class="submit-btn edit-btn" (click)="toggleTechnologies()">▼ Edit Technologies ▼</button> - <div *ngIf="showTechnologies"> - <div class="input-selection"> - <input type="text" class="input-field" formControlName="technologyInput" required> - - <div class="input-errors"> - <label class="error">Type in your desired technologies, separated by a space</label> - </div> - </div> - Available technologies: - <div id="all-technologies"> - <div class="user-technology" *ngFor="let tech of availableTechnologies"> - {{ tech.name }} - </div> - </div> - </div> - - <button id="update-profile-btn" class="submit-btn" type="submit">Update profile</button> - <app-success-bar></app-success-bar> - <app-error-bar></app-error-bar> - </form> - <hr> - <div id="confirm-delete" *ngIf="deleteAccountConfirm"> - Are you sure you want to delete your account?<br>This is permanent! - </div> - <button class="submit-btn delete-btn" (click)="deleteAccount()">Delete account</button> - </div> -</div> diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts deleted file mode 100644 index a484665..0000000 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts +++ /dev/null @@ -1,307 +0,0 @@ -import { Location } from '@angular/common'; -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { LanguageService } from 'src/app/services/language.service'; -import { UserService } from 'src/app/services/user.service'; -import { TechnologyService } from 'src/app/services/technology.service'; -import { User } from 'src/models/identity/user'; -import { ErrorBarComponent } from '../error-bar/error-bar.component'; -import { SuccessBarComponent } from '../success-bar/success-bar.component'; -import { Language } from 'src/models/language'; -import { Technology } from 'src/models/technology'; -import { TokenService } from 'src/app/services/token.service'; -import { Title } from '@angular/platform-browser'; -import { AppConstants } from 'src/app/app-constants.module'; - -@Component({ - selector: 'app-profile-settings', - templateUrl: './profile-settings.component.html', - styleUrls: ['./profile-settings.component.css'] -}) -export class ProfileSettingsComponent implements OnInit { - private _title = 'Profile Settings'; - @ViewChild(ErrorBarComponent) private _errorBar: ErrorBarComponent; - @ViewChild(SuccessBarComponent) private _successBar: SuccessBarComponent; - private _urlUsername: string; - public isAdminUser = false; - public dataArrived = false; - public deleteAccountConfirm = false; - public showLanguages = false; - public showTechnologies = false; - public updateUserFormGroup: FormGroup; - public updateProfilePictureFormGroup: FormGroup; - public newProfilePicture: File; - public user: User; - public availableLanguages: Language[]; - public availableTechnologies: Technology[]; - - constructor(private _titleService: Title, private _router: Router, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _tokenService: TokenService, private _fb: FormBuilder, private _location: Location) { - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - this._urlUsername = this._router.url.substring(9); - this._urlUsername = this._urlUsername.substring(0, this._urlUsername.length - 9); - - this.user = this._userService.getDefaultUser(); - this.availableLanguages = []; - this.availableTechnologies = []; - this.newProfilePicture = new File([], ''); - - 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.finishUserLoading(); - }, - (err: HttpErrorResponse) => { - this._router.navigate(['/not-found']); - } - ); - - this._languageService.getAllLanguagesWithSessionStorageRequest().subscribe( - (result: object) => { - this.availableLanguages = result as Language[]; - } - ); - this._technologyService.getAllTechnologiesWithSessionStorageRequest().subscribe( - (result: object) => { - this.availableTechnologies = result as Technology[]; - } - ); - } - - private finishUserLoading(): void { - if (sessionStorage.getItem('UserCred')) { - const userFromToken: User = this._userService.getDefaultUser(); - - this._userService.getUserFromSessionStorageRequest().subscribe( - (tokenRes: object) => { - Object.assign(userFromToken, tokenRes); - - if (userFromToken.userName === this._urlUsername) { - this.initForms(); - this.dataArrived = true; - } - else { - this.goToProfile(); - } - }, - (err: HttpErrorResponse) => { - this.logout(); - } - ); - } - else { - this.goToProfile(); - } - } - - private initForms(): void { - this.updateUserFormGroup = this._fb.group({ - firstName: new FormControl(this.user.firstName, [ - Validators.required, - Validators.minLength(3) - ]), - lastName: new FormControl(this.user.lastName, [ - Validators.required, - Validators.minLength(3) - ]), - username: new FormControl(this.user.userName, [ - Validators.required, - Validators.minLength(3) - ]), - email: new FormControl(this.user.email, [ - Validators.required, - Validators.email, - ]), - password: new FormControl('', [ - Validators.required, - Validators.minLength(3), - Validators.pattern('.*[0-9].*') // Check if password contains atleast one number - ]), - - // For language we have two different controls, - // the first one is used for input, the other one for sending data - // because if we edit the control for input, - // we're also gonna change the input field in the HTML - languageInput: new FormControl(''), // The one for input - languages: new FormControl(''), // The one that is sent - - // For technologies it's the same as it is with languages - technologyInput: new FormControl(''), - technologies: new FormControl('') - }); - - this.getLanguagesForShowing().then(value => { - this.updateUserFormGroup.patchValue({ languageInput : value }); - }); - - this.getTechnologiesForShowing().then(value => { - this.updateUserFormGroup.patchValue({ technologyInput : value }); - }); - - this.updateProfilePictureFormGroup = this._fb.group({ - fileUpload: new FormControl('') - }); - - this.updateUserFormGroup.valueChanges.subscribe(() => { - this._successBar?.hideMsg(); - this._errorBar?.hideError(); - }); - } - - private getLanguagesForShowing(): Promise<string> { - return new Promise(resolve => { - this._languageService.getFullLanguagesFromIncomplete(this.user.languages).then(value => { - this.user.languages = value; - resolve(value.map(x => x.name).join(' ')); - }); - }); - } - - private getTechnologiesForShowing(): Promise<string> { - return new Promise(resolve => { - this._technologyService.getFullTechnologiesFromIncomplete(this.user.technologies).then(value => { - this.user.technologies = value; - resolve(value.map(x => x.name).join(' ')); - }); - }); - } - - onFileUpload(event: any): void { - this.newProfilePicture = event.target.files[0]; - } - - updateProfilePicture(): void { - if (this.newProfilePicture.size === 0) { - return; - } - - this._userService.putProfilePictureFromSessionStorageRequest(this.newProfilePicture).subscribe( - (result: object) => { - this.reloadPage(); - } - ); - this.dataArrived = false; - } - - onSubmit(): void { - this._successBar.hideMsg(); - this._errorBar.hideError(); - - this.patchLanguagesControl(); - this.patchTechnologiesControl(); - - this._userService.putUserFromSessionStorageRequest(this.updateUserFormGroup, this.user.roles, this.user.friends).subscribe( - (result: object) => { - this._successBar.showMsg('Profile updated successfully!'); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - - private patchLanguagesControl(): void { - // Get user input - const langControl = this.updateUserFormGroup.get('languageInput')?.value as string ?? ''; - - if (langControl === '') { - // Add the data to the form (to the value that is going to be sent) - this.updateUserFormGroup.patchValue({ - languages : [] - }); - } - else { - const names = langControl.split(' '); - - // Transfer user input to objects of type { "name": "value" } - const actualLanguages = []; - for (const lName of names) { - if (lName !== '') { - actualLanguages.push({ name : lName }); - } - } - - // Add the data to the form (to the value that is going to be sent) - this.updateUserFormGroup.patchValue({ - languages : actualLanguages - }); - } - } - - private patchTechnologiesControl(): void { - // Get user input - const techControl = this.updateUserFormGroup.get('technologyInput')?.value as string ?? ''; - - if (techControl === '') { - // Add the data to the form (to the value that is going to be sent) - this.updateUserFormGroup.patchValue({ - technologies : [] - }); - } - else { - const names = techControl.split(' '); - - // Transfer user input to objects of type { "name": "value" } - const actualTechnologies = []; - for (const tName of names) { - if (tName !== '') { - actualTechnologies.push({ name : tName }); - } - } - - // Add the data to the form (to the value that is going to be sent) - this.updateUserFormGroup.patchValue({ - technologies : actualTechnologies - }); - } - } - - goToProfile(): void { - this._router.navigate([this._router.url.substring(0, this._router.url.length - 9)]); - } - - navigateToAdminPanel(): void { - this._router.navigate(['/admin-panel']); - } - - logout(): void { - this._tokenService.logoutUserFromSessionStorage(); - this.goToProfile(); - } - - toggleLanguages(): void { - this.showLanguages = !this.showLanguages; - } - - toggleTechnologies(): void { - this.showTechnologies = !this.showTechnologies; - } - - deleteAccount(): void { - if (this.deleteAccountConfirm) { - this._userService.deleteUserFromSessionStorageRequest().subscribe( - (res: object) => { - this.logout(); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - this.dataArrived = false; - } - else { - this.deleteAccountConfirm = true; - } - } - - private reloadPage(): void { - this._router.routeReuseStrategy.shouldReuseRoute = () => false; - this._router.onSameUrlNavigation = 'reload'; - this._router.navigate([this._router.url]); - } -} diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.css b/src/DevHive.Angular/src/app/components/profile/profile.component.css deleted file mode 100644 index ebcd406..0000000 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.css +++ /dev/null @@ -1,105 +0,0 @@ -* { - 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/DevHive.Angular/src/app/components/profile/profile.component.html b/src/DevHive.Angular/src/app/components/profile/profile.component.html deleted file mode 100644 index 0e5f633..0000000 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.html +++ /dev/null @@ -1,60 +0,0 @@ -<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"> - 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"> - 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/DevHive.Angular/src/app/components/profile/profile.component.ts b/src/DevHive.Angular/src/app/components/profile/profile.component.ts deleted file mode 100644 index bbf8585..0000000 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.ts +++ /dev/null @@ -1,203 +0,0 @@ -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]); - } -} diff --git a/src/DevHive.Angular/src/app/components/register/register.component.css b/src/DevHive.Angular/src/app/components/register/register.component.css deleted file mode 100644 index 93d8006..0000000 --- a/src/DevHive.Angular/src/app/components/register/register.component.css +++ /dev/null @@ -1,40 +0,0 @@ -/* A lot of stuff are moved to the global styles! */ - -* { - transition: 0.2s; -} - -form { - width: 100%; -} - -@media screen and (max-height: 630px) { - #content { - height: fit-content !important; - } -} - -#content hr { - width: 100%; - border: 1px solid black; - box-sizing: border-box; -} - -.input-selection:nth-of-type(1) { - margin-top: 1.2em; -} - -.submit-btn { - margin-bottom: .2em; -} - -.redirect-to-login { - color: var(--focus-color); - background-color: var(--bg-color); - border-color: var(--focus-color); -} - -.redirect-to-login:hover { - border-color: black !important; - color: black; -} diff --git a/src/DevHive.Angular/src/app/components/register/register.component.html b/src/DevHive.Angular/src/app/components/register/register.component.html deleted file mode 100644 index 4e67e0e..0000000 --- a/src/DevHive.Angular/src/app/components/register/register.component.html +++ /dev/null @@ -1,65 +0,0 @@ -<div id="content"> - <div class="title">Register</div> - - <form [formGroup]="registerUserFormGroup" (ngSubmit)="onSubmit()"> - <hr> - <!-- Value: {{ registerUserFormGroup.value | json }} - <hr> --> - - <div class="input-selection"> - <input type="text" placeholder="Goshko, is that u?" class="input-field" formControlName="firstName" required> - <label class="input-field-label">First Name</label> - - <div class="input-errors"> - <label *ngIf="registerUserFormGroup.get('firstName')?.errors?.required" class="error">*Required</label> - <label *ngIf="registerUserFormGroup.get('firstName')?.errors?.minlength" class="error">*Minimum 3 characters</label> - </div> - </div> - - <div class="input-selection"> - <input type="text" placeholder="Trapov? Really??" class="input-field" formControlName="lastName" required> - <label class="input-field-label">Last Name</label> - - <div class="input-errors"> - <label *ngIf="registerUserFormGroup.get('lastName')?.errors?.required" class="error">*Required</label> - <label *ngIf="registerUserFormGroup.get('lastName')?.errors?.minlength" class="error">*Minimum 3 characters</label> - </div> - </div> - - <div class="input-selection"> - <input type="text" placeholder="Think of something cool to flex on other kids" class="input-field" formControlName="username" required> - <label class="input-field-label">Username</label> - - <div class="input-errors"> - <label *ngIf="registerUserFormGroup.get('username')?.errors?.required" class="error">*Required</label> - <label *ngIf="registerUserFormGroup.get('username')?.errors?.minlength" class="error">*Minimum 3 characters</label> - </div> - </div> - - <div class="input-selection"> - <input type="text" placeholder="You expect an email joke? I have none, mail me one" class="input-field" formControlName="email" required> - <label class="input-field-label">Email</label> - - <div class="input-errors"> - <label *ngIf="registerUserFormGroup.get('email')?.errors?.required" class="error">*Required</label> - <label *ngIf="registerUserFormGroup.get('email')?.errors?.email" class="error">*Invalid email</label> - </div> - </div> - - <div class="input-selection"> - <input type="password" placeholder="Make sure it's long & strong (just like my d***)" class="input-field" formControlName="password" required> - <label class="input-field-label">Password</label> - - <div class="input-errors"> - <label *ngIf="registerUserFormGroup.get('password')?.errors?.required" class="error">*Required</label> - <label *ngIf="registerUserFormGroup.get('password')?.errors?.minlength" class="error">*Minimum 3 characters</label> - <label *ngIf="registerUserFormGroup.get('password')?.errors?.pattern" class="error">*At least 1 number</label> - </div> - </div> - - <hr> - <button class="submit-btn" type="submit">Submit</button> - <app-error-bar></app-error-bar> - </form> - <button class="submit-btn redirect-to-login" (click)="onRedirectLogin()">Already have an account? Login here</button> -</div> diff --git a/src/DevHive.Angular/src/app/components/register/register.component.ts b/src/DevHive.Angular/src/app/components/register/register.component.ts deleted file mode 100644 index 36eaa55..0000000 --- a/src/DevHive.Angular/src/app/components/register/register.component.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit, ViewChild } from '@angular/core'; -import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; -import { TokenService } from 'src/app/services/token.service'; -import { UserService } from 'src/app/services/user.service'; -import { ErrorBarComponent } from '../error-bar/error-bar.component'; - -@Component({ - selector: 'app-register', - templateUrl: './register.component.html', - styleUrls: ['./register.component.css'] -}) -export class RegisterComponent implements OnInit { - @ViewChild(ErrorBarComponent) private _errorBar: ErrorBarComponent; - private _title = 'Register'; - public registerUserFormGroup: FormGroup; - - constructor(private _titleService: Title, private _fb: FormBuilder, private _router: Router, private _userService: UserService, private _tokenService: TokenService) { - this._titleService.setTitle(this._title); - } - - ngOnInit(): void { - this.registerUserFormGroup = this._fb.group({ - firstName: new FormControl('', [ - Validators.required, - Validators.minLength(3) - ]), - lastName: new FormControl('', [ - Validators.required, - Validators.minLength(3) - ]), - username: new FormControl('', [ - Validators.required, - Validators.minLength(3) - ]), - email: new FormControl('', [ - Validators.required, - Validators.email, - ]), - password: new FormControl('', [ - Validators.required, - Validators.minLength(3), - Validators.pattern('.*[0-9].*') // Check if password contains atleast one number - ]), - }); - - // this.registerUserFormGroup.valueChanges.subscribe(console.log); - } - - onSubmit(): void { - this._userService.registerUserRequest(this.registerUserFormGroup).subscribe( - res => { - this._tokenService.setUserTokenToSessionStorage(res); - this._router.navigate(['/']); - }, - (err: HttpErrorResponse) => { - this._errorBar.showError(err); - } - ); - } - onRedirectLogin(): void { - this._router.navigate(['/login']); - } - - get firstName(): AbstractControl | null { - return this.registerUserFormGroup.get('firstName'); - } - - get lastName(): AbstractControl | null { - return this.registerUserFormGroup.get('lastName'); - } - - get username(): AbstractControl | null { - return this.registerUserFormGroup.get('username'); - } - - get email(): AbstractControl | null { - return this.registerUserFormGroup.get('email'); - } - - get password(): AbstractControl | null { - return this.registerUserFormGroup.get('password'); - } -} diff --git a/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.css b/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.css deleted file mode 100644 index bee634d..0000000 --- a/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.css +++ /dev/null @@ -1,11 +0,0 @@ -#success-bar { - width: 100%; - background-color: var(--success); - color: white; - padding: .2em; - text-align: center; -} - -#success-bar:empty { - display: none; -} diff --git a/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.html b/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.html deleted file mode 100644 index 026e955..0000000 --- a/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.html +++ /dev/null @@ -1 +0,0 @@ -<div id="success-bar">{{successMsg}}</div> diff --git a/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.ts b/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.ts deleted file mode 100644 index f7c7e54..0000000 --- a/src/DevHive.Angular/src/app/components/success-bar/success-bar.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-success-bar', - templateUrl: './success-bar.component.html', - styleUrls: ['./success-bar.component.css'] -}) -export class SuccessBarComponent implements OnInit { - public successMsg = ''; - - constructor() - { } - - ngOnInit(): void { - this.hideMsg(); - } - - showMsg(msg?: string | undefined): void { - if (msg === undefined) { - this.successMsg = 'Success!'; - } - else if (msg.trim() === '') { - this.successMsg = 'Success!'; - } - else { - this.successMsg = msg; - } - } - - hideMsg(): void { - this.successMsg = ''; - } -} |
