aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortranstrike <transtrike@gmail.com>2021-01-31 12:58:44 +0200
committertranstrike <transtrike@gmail.com>2021-01-31 12:58:44 +0200
commit979a86a14cd658b5346279901ac8bca667c373d3 (patch)
tree9791cf02c0838a4d6392e3651f93eeed283acb57 /src
parent9d5f4628a3a75871b47ac6a9f9c0419748d9dfb8 (diff)
parentb8743cfdd0515e4d07ea5c926be1d9ade5340a91 (diff)
downloadDevHive-979a86a14cd658b5346279901ac8bca667c373d3.tar
DevHive-979a86a14cd658b5346279901ac8bca667c373d3.tar.gz
DevHive-979a86a14cd658b5346279901ac8bca667c373d3.zip
Username added to JWT; Promotion to Admin fixed
Diffstat (limited to 'src')
-rw-r--r--src/DevHive.Angular/src/app/app-constants.module.ts4
-rw-r--r--src/DevHive.Angular/src/app/components/feed/feed.component.css9
-rw-r--r--src/DevHive.Angular/src/app/components/feed/feed.component.html8
-rw-r--r--src/DevHive.Angular/src/app/components/feed/feed.component.ts36
-rw-r--r--src/DevHive.Angular/src/app/components/post/post.component.css4
-rw-r--r--src/DevHive.Angular/src/app/components/post/post.component.html8
-rw-r--r--src/DevHive.Angular/src/app/components/post/post.component.ts47
-rw-r--r--src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css28
-rw-r--r--src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html36
-rw-r--r--src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts12
-rw-r--r--src/DevHive.Angular/src/app/components/profile/profile.component.css15
-rw-r--r--src/DevHive.Angular/src/app/components/profile/profile.component.html9
-rw-r--r--src/DevHive.Angular/src/app/components/profile/profile.component.ts26
-rw-r--r--src/DevHive.Angular/src/app/components/success-bar/success-bar.component.ts5
-rw-r--r--src/DevHive.Angular/src/app/services/feed.service.ts46
-rw-r--r--src/DevHive.Angular/src/app/services/post.service.ts25
-rw-r--r--src/DevHive.Angular/src/models/post.ts63
-rw-r--r--src/DevHive.Angular/src/styles.css7
-rw-r--r--src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs1
-rw-r--r--src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.Designer.cs537
-rw-r--r--src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.cs145
-rw-r--r--src/DevHive.Data/Models/User.cs7
-rw-r--r--src/DevHive.Data/Repositories/CommentRepository.cs23
-rw-r--r--src/DevHive.Data/Repositories/FeedRepository.cs19
-rw-r--r--src/DevHive.Data/Repositories/PostRepository.cs25
-rw-r--r--src/DevHive.Services/Configurations/Mapping/CommentMappings.cs2
-rw-r--r--src/DevHive.Services/Configurations/Mapping/PostMappings.cs9
-rw-r--r--src/DevHive.Services/Interfaces/ICommentService.cs20
-rw-r--r--src/DevHive.Services/Interfaces/IFeedService.cs1
-rw-r--r--src/DevHive.Services/Interfaces/IPostService.cs10
-rw-r--r--src/DevHive.Services/Models/Comment/CreateCommentServiceModel.cs (renamed from src/DevHive.Services/Models/Post/Comment/CreateCommentServiceModel.cs)2
-rw-r--r--src/DevHive.Services/Models/Comment/ReadCommentServiceModel.cs (renamed from src/DevHive.Services/Models/Post/Comment/ReadCommentServiceModel.cs)2
-rw-r--r--src/DevHive.Services/Models/Comment/UpdateCommentServiceModel.cs (renamed from src/DevHive.Services/Models/Post/Comment/UpdateCommentServiceModel.cs)2
-rw-r--r--src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs2
-rw-r--r--src/DevHive.Services/Models/Post/CreatePostServiceModel.cs (renamed from src/DevHive.Services/Models/Post/Post/CreatePostServiceModel.cs)2
-rw-r--r--src/DevHive.Services/Models/Post/ReadPostServiceModel.cs (renamed from src/DevHive.Services/Models/Post/Post/ReadPostServiceModel.cs)4
-rw-r--r--src/DevHive.Services/Models/Post/UpdatePostServiceModel.cs (renamed from src/DevHive.Services/Models/Post/Post/UpdatePostServiceModel.cs)2
-rw-r--r--src/DevHive.Services/Services/CommentService.cs156
-rw-r--r--src/DevHive.Services/Services/FeedService.cs26
-rw-r--r--src/DevHive.Services/Services/PostService.cs72
-rw-r--r--src/DevHive.Services/Services/UserService.cs67
-rw-r--r--src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs3
-rw-r--r--src/DevHive.Web/Configurations/Mapping/CommentMappings.cs7
-rw-r--r--src/DevHive.Web/Configurations/Mapping/PostMappings.cs4
-rw-r--r--src/DevHive.Web/Controllers/CommentController.cs82
-rw-r--r--src/DevHive.Web/Controllers/FeedController.cs7
-rw-r--r--src/DevHive.Web/Controllers/PostController.cs67
-rw-r--r--src/DevHive.Web/Models/Comment/CreateCommentWebModel.cs (renamed from src/DevHive.Web/Models/Post/Comment/CreateCommentWebModel.cs)2
-rw-r--r--src/DevHive.Web/Models/Comment/ReadCommentWebModel.cs (renamed from src/DevHive.Web/Models/Post/Comment/ReadCommentWebModel.cs)2
-rw-r--r--src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs (renamed from src/DevHive.Web/Models/Post/Comment/UpdateCommentWebModel.cs)2
-rw-r--r--src/DevHive.Web/Models/Feed/ReadPageWebModel.cs2
-rw-r--r--src/DevHive.Web/Models/Post/CreatePostWebModel.cs (renamed from src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs)5
-rw-r--r--src/DevHive.Web/Models/Post/ReadPostWebModel.cs (renamed from src/DevHive.Web/Models/Post/Post/ReadPostWebModel.cs)4
-rw-r--r--src/DevHive.Web/Models/Post/UpdatePostWebModel.cs (renamed from src/DevHive.Web/Models/Post/Post/UpdatePostWebModel.cs)2
54 files changed, 1408 insertions, 305 deletions
diff --git a/src/DevHive.Angular/src/app/app-constants.module.ts b/src/DevHive.Angular/src/app/app-constants.module.ts
index 7552a5e..cbb1ec1 100644
--- a/src/DevHive.Angular/src/app/app-constants.module.ts
+++ b/src/DevHive.Angular/src/app/app-constants.module.ts
@@ -8,5 +8,9 @@ export class AppConstants {
public static API_LANGUAGE_URL = AppConstants.BASE_API_URL + '/Language';
public static API_TECHNOLOGY_URL = AppConstants.BASE_API_URL + '/Technology';
+ public static API_POST_URL = AppConstants.BASE_API_URL + '/Post';
+ public static API_FEED_URL = AppConstants.BASE_API_URL + '/Feed';
+
+ public static PAGE_SIZE = 5;
public static FALLBACK_PROFILE_ICON = 'assets/images/feed/profile-pic.png';
}
diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.css b/src/DevHive.Angular/src/app/components/feed/feed.component.css
index e22693e..f810e83 100644
--- a/src/DevHive.Angular/src/app/components/feed/feed.component.css
+++ b/src/DevHive.Angular/src/app/components/feed/feed.component.css
@@ -109,6 +109,15 @@
display: 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,
diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.html b/src/DevHive.Angular/src/app/components/feed/feed.component.html
index b82b189..e3c6e83 100644
--- a/src/DevHive.Angular/src/app/components/feed/feed.component.html
+++ b/src/DevHive.Angular/src/app/components/feed/feed.component.html
@@ -23,8 +23,12 @@
</a>
</nav>
<div id="posts" class="scroll-standalone">
- <div *ngFor="let post of posts" class="post">
- <app-post></app-post>
+ <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>
diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.ts b/src/DevHive.Angular/src/app/components/feed/feed.component.ts
index b027e5b..f260fd4 100644
--- a/src/DevHive.Angular/src/app/components/feed/feed.component.ts
+++ b/src/DevHive.Angular/src/app/components/feed/feed.component.ts
@@ -1,11 +1,12 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { User } from 'src/models/identity/user';
-import { PostComponent } from '../post/post.component';
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';
@Component({
selector: 'app-feed',
@@ -14,26 +15,24 @@ import {HttpErrorResponse} from '@angular/common/http';
})
export class FeedComponent implements OnInit {
private _title = 'Feed';
+ private _timeLoaded: string;
public dataArrived = false;
public user: User;
- public posts: PostComponent[];
+ public posts: Post[] = [];
- constructor(private _titleService: Title, private _router: Router, private _userService: UserService) {
+ constructor(private _titleService: Title, private _router: Router, private _userService: UserService, private _feedService: FeedService) {
this._titleService.setTitle(this._title);
}
ngOnInit(): void {
this.user = this._userService.getDefaultUser();
- this.posts = [
- new PostComponent(),
- new PostComponent(),
- new PostComponent(),
- new PostComponent(),
- ];
+ const now = new Date();
+ now.setHours(now.getHours() + 2); // accounting for eastern european timezone
+ this._timeLoaded = now.toISOString();
if (sessionStorage.getItem('UserCred')) {
this._userService.getUserFromSessionStorageRequest().subscribe(
- (res: object) => this.finishUserLoading(res),
+ (res: object) => this.loadFeed(res),
(err: HttpErrorResponse) => this.bailOnBadToken()
);
} else {
@@ -41,8 +40,21 @@ export class FeedComponent implements OnInit {
}
}
- private finishUserLoading(res: object): void {
+ private loadFeed(res: object): void {
Object.assign(this.user, res);
+
+ this._feedService.getUserFeedFromSessionStorageRequest(1, this._timeLoaded, AppConstants.PAGE_SIZE).subscribe(
+ (result: object) => {
+ this.posts = Object.values(result)[0];
+ this.finishUserLoading();
+ },
+ (err: HttpErrorResponse) => {
+ this.finishUserLoading();
+ }
+ );
+ }
+
+ private finishUserLoading(): void {
if (this.user.imageUrl === '') {
this.user.imageUrl = AppConstants.FALLBACK_PROFILE_ICON;
}
diff --git a/src/DevHive.Angular/src/app/components/post/post.component.css b/src/DevHive.Angular/src/app/components/post/post.component.css
index 5395eb2..c3e3caa 100644
--- a/src/DevHive.Angular/src/app/components/post/post.component.css
+++ b/src/DevHive.Angular/src/app/components/post/post.component.css
@@ -24,6 +24,10 @@ hr {
margin-bottom: .2em;
}
+.author:hover {
+ cursor: pointer;
+}
+
.author > img {
width: 2.2em;
height: 2.2em;
diff --git a/src/DevHive.Angular/src/app/components/post/post.component.html b/src/DevHive.Angular/src/app/components/post/post.component.html
index 487b785..8fbda35 100644
--- a/src/DevHive.Angular/src/app/components/post/post.component.html
+++ b/src/DevHive.Angular/src/app/components/post/post.component.html
@@ -1,6 +1,6 @@
-<div class="post rounded-border">
+<div class="post rounded-border" *ngIf="loaded">
<div class="content">
- <div class="author">
+ <div class="author" (click)="goToAuthorProfile()">
<img class="round-image" [src]="user.imageUrl">
<div class="author-info">
<div class="name">
@@ -12,10 +12,10 @@
</div>
</div>
<div class="message">
- Your opinion on my idea?
+ {{ post.message }}
</div>
<div class="timestamp">
- 17:41 - 27 Dec 2020
+ {{ timeCreated }}
</div>
</div>
<div class="rating">
diff --git a/src/DevHive.Angular/src/app/components/post/post.component.ts b/src/DevHive.Angular/src/app/components/post/post.component.ts
index 76a4873..7a6b5c0 100644
--- a/src/DevHive.Angular/src/app/components/post/post.component.ts
+++ b/src/DevHive.Angular/src/app/components/post/post.component.ts
@@ -1,7 +1,12 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
+import {Router} from '@angular/router';
import { Guid } from 'guid-typescript';
import {AppConstants} from 'src/app/app-constants.module';
+import {FeedService} from 'src/app/services/feed.service';
+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',
@@ -10,23 +15,39 @@ import { User } from 'src/models/identity/user';
})
export class PostComponent implements OnInit {
public user: User;
+ public post: Post;
public votesNumber: number;
+ public timeCreated: string;
+ public loaded = false;
+ @Input() paramId: string;
- constructor() {}
+ constructor(private _postService: PostService, private _userService: UserService, private _router: Router)
+ {}
ngOnInit(): void {
- // Fetch data in post service
- this.user = new User(
- Guid.create(),
- 'gosho_trapov',
- 'Gosho',
- 'Trapov',
- 'gotra@bg.com',
- AppConstants.FALLBACK_PROFILE_ICON,
- new Array(),
- new Array()
- );
+ 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.timeCreated = new Date(this.post.timeCreated).toLocaleString('en-GB');
+ this.loadUser();
+ }
+ );
this.votesNumber = 23;
}
+
+ 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]);
+ }
}
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
index 7e0978d..2aecef5 100644
--- 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
@@ -50,12 +50,40 @@ hr {
transform: translate(0, -1.2em);
}
+#all-languages, #all-technologies {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+#all-languages > *, #all-technologies > * {
+ width: fit-content;
+ margin-top: .1em;
+ margin-bottom: .1em;
+}
+
/* 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;
+}
+
#delete-account:hover {
color: indianred;
border-color: indianred !important;
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
index 16b537c..1b713d7 100644
--- 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
@@ -58,28 +58,42 @@
<label *ngIf="updateUserFormGroup.get('password')?.errors?.pattern" class="error">*At least 1 number</label>
</div>
</div>
- <button type="button" (click)="toggleLanguages()">Edit Languages</button>
+ <button type="button" class="submit-btn edit-btn" (click)="toggleLanguages()">▼ Edit Languages ▼</button>
<div *ngIf="showLanguages">
- Type in your desired languages, separated by a space.
- <input type="text" class="input-field" formControlName="languageInput" required>
+ <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 *ngFor="let lang of availableLanguages">
- {{ lang.name }}
+ <div id="all-languages">
+ <div class="user-language" *ngFor="let lang of availableLanguages">
+ {{ lang.name }}
+ </div>
</div>
</div>
- <button type="button" (click)="toggleTechnologies()">Edit Technologies</button>
+ <button type="button" class="submit-btn edit-btn" (click)="toggleTechnologies()">▼ Edit Technologies ▼</button>
<div *ngIf="showTechnologies">
- Type in your desired technologies, separated by a space.
- <input type="text" class="input-field" formControlName="technologyInput" required>
+ <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 *ngFor="let tech of availableTechnologies">
- {{ tech.name }}
+ <div id="all-technologies">
+ <div class="user-technology" *ngFor="let tech of availableTechnologies">
+ {{ tech.name }}
+ </div>
</div>
</div>
- <button class="submit-btn" type="submit">Update profile</button>
+ <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>
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
index 5be160e..e348b8b 100644
--- 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
@@ -126,8 +126,8 @@ export class ProfileSettingsComponent implements OnInit {
.then(value => this.updateUserFormGroup.patchValue({ technologyInput : value }));
this.updateUserFormGroup.valueChanges.subscribe(() => {
- this._successBar.hideMsg();
- this._errorBar.hideError();
+ this._successBar?.hideMsg();
+ this._errorBar?.hideError();
});
}
@@ -185,7 +185,9 @@ export class ProfileSettingsComponent implements OnInit {
// Transfer user input to objects of type { "name": "value" }
const actualLanguages = [];
for (const lName of names) {
- actualLanguages.push({ name : lName });
+ if (lName !== '') {
+ actualLanguages.push({ name : lName });
+ }
}
// Add the data to the form (to the value that is going to be sent)
@@ -211,7 +213,9 @@ export class ProfileSettingsComponent implements OnInit {
// Transfer user input to objects of type { "name": "value" }
const actualTechnologies = [];
for (const tName of names) {
- actualTechnologies.push({ name : tName });
+ if (tName !== '') {
+ actualTechnologies.push({ name : tName });
+ }
}
// Add the data to the form (to the value that is going to be sent)
diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.css b/src/DevHive.Angular/src/app/components/profile/profile.component.css
index 7d96624..f312ebd 100644
--- a/src/DevHive.Angular/src/app/components/profile/profile.component.css
+++ b/src/DevHive.Angular/src/app/components/profile/profile.component.css
@@ -74,16 +74,15 @@ hr {
align-items: center;
}
-.user-language, .user-technology {
- border-radius: .4em;
- background-color: lightgrey;
- padding: .2em;
- margin: 0 .2em;
-}
-
/* Posts */
-#posts {
+#no-posts {
width: 100%;
+ text-align: center;
+ color: gray;
+ margin-top: .2em;
}
+#posts {
+ width: 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
index 43d580f..ac0c07e 100644
--- a/src/DevHive.Angular/src/app/components/profile/profile.component.html
+++ b/src/DevHive.Angular/src/app/components/profile/profile.component.html
@@ -41,9 +41,14 @@
&nbsp;None
</div>
</div>
+ <hr>
<div id="posts">
- <hr>
- Posts go here
+ <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
index 69d7e72..7717505 100644
--- a/src/DevHive.Angular/src/app/components/profile/profile.component.ts
+++ b/src/DevHive.Angular/src/app/components/profile/profile.component.ts
@@ -7,6 +7,8 @@ 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';
@Component({
selector: 'app-profile',
@@ -18,10 +20,11 @@ export class ProfileComponent implements OnInit {
public loggedInUser = false;
public dataArrived = false;
public user: User;
+ public userPosts: Post[] = [];
public showNoLangMsg = false;
public showNoTechMsg = false;
- constructor(private _router: Router, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _location: Location)
+ constructor(private _router: Router, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _feedService: FeedService, private _location: Location)
{ }
private setDefaultUser(): void {
@@ -57,19 +60,34 @@ export class ProfileComponent implements OnInit {
private loadTechnologies(): void {
if (this.user.technologies.length > 0) {
- // When user has technologies, get their names and finally finish loading
+ // When user has technologies, get their names and then load posts
this._technologyService.getFullTechnologiesFromIncomplete(this.user.technologies)
.then(value => {
this.user.technologies = value;
- this.finishUserLoading();
+ this.loadPosts();
});
}
else {
this.showNoTechMsg = true;
- this.finishUserLoading();
+ this.loadPosts();
}
}
+ private loadPosts(): void {
+ const now = new Date();
+ now.setHours(now.getHours() + 2); // accounting for eastern europe timezone
+
+ this._feedService.getUserPostsRequest(this.user.userName, 1, now.toISOString(), AppConstants.PAGE_SIZE).subscribe(
+ (result: object) => {
+ this.userPosts = Object.values(result)[0];
+ this.finishUserLoading();
+ },
+ (err: HttpErrorResponse) => {
+ this.finishUserLoading();
+ }
+ );
+ }
+
private finishUserLoading(): void {
if (this.user.imageUrl === '') {
this.user.imageUrl = AppConstants.FALLBACK_PROFILE_ICON;
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
index 9a12c3a..f7db0e2 100644
--- 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
@@ -15,7 +15,10 @@ export class SuccessBarComponent implements OnInit {
}
showMsg(msg?: string | undefined): void {
- if (msg === undefined || msg.trim() === '') {
+ if (msg === undefined) {
+ this.successMsg = 'Success!';
+ }
+ else if (msg.trim() === '') {
this.successMsg = 'Success!';
}
else {
diff --git a/src/DevHive.Angular/src/app/services/feed.service.ts b/src/DevHive.Angular/src/app/services/feed.service.ts
new file mode 100644
index 0000000..cb82bcd
--- /dev/null
+++ b/src/DevHive.Angular/src/app/services/feed.service.ts
@@ -0,0 +1,46 @@
+import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
+import {Injectable} from '@angular/core';
+import {Guid} from 'guid-typescript';
+import {Observable} from 'rxjs';
+import {IJWTPayload} from 'src/interfaces/jwt-payload';
+import {AppConstants} from '../app-constants.module';
+import jwt_decode from 'jwt-decode';
+import {IUserCredentials} from 'src/interfaces/user-credentials';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FeedService {
+ constructor(private http: HttpClient) { }
+
+ getUserFeedFromSessionStorageRequest(pageNumber: number, firstTimeIssued: string, pageSize: number): Observable<object> {
+ const jwt: IJWTPayload = { token: sessionStorage.getItem('UserCred') ?? '' };
+ const userCred = jwt_decode<IUserCredentials>(jwt.token);
+ return this.getUserFeedRequest(userCred.ID, jwt.token, pageNumber, firstTimeIssued, pageSize);
+ }
+
+ getUserFeedRequest(userId: Guid, authToken: string, pageNumber: number, firstTimeIssued: string, pageSize: number): Observable<object> {
+ const body = {
+ pageNumber: pageNumber,
+ firstPageTimeIssued: firstTimeIssued,
+ pageSize: pageSize
+ };
+ const options = {
+ params: new HttpParams().set('UserId', userId.toString()),
+ headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken)
+ };
+ return this.http.post(AppConstants.API_FEED_URL + '/GetPosts', body, options);
+ }
+
+ getUserPostsRequest(userName: string, pageNumber: number, firstTimeIssued: string, pageSize: number): Observable<object> {
+ const body = {
+ pageNumber: pageNumber,
+ firstPageTimeIssued: firstTimeIssued,
+ pageSize: pageSize
+ };
+ const options = {
+ params: new HttpParams().set('UserName', userName)
+ };
+ return this.http.post(AppConstants.API_FEED_URL + '/GetUserPosts', body, options);
+ }
+}
diff --git a/src/DevHive.Angular/src/app/services/post.service.ts b/src/DevHive.Angular/src/app/services/post.service.ts
new file mode 100644
index 0000000..4cd96bc
--- /dev/null
+++ b/src/DevHive.Angular/src/app/services/post.service.ts
@@ -0,0 +1,25 @@
+import {HttpClient, HttpParams} from '@angular/common/http';
+import {Injectable} from '@angular/core';
+import {Guid} from 'guid-typescript';
+import {Observable} from 'rxjs';
+import {Post} from 'src/models/post';
+import {AppConstants} from '../app-constants.module';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PostService {
+ constructor(private http: HttpClient) { }
+
+ getDefaultPost(): Post {
+ return new Post(Guid.createEmpty(), 'Gosho', 'Trapov', 'gosho_trapov', 'Your opinion on my idea?', new Date());
+ }
+
+ getPostRequest(id: Guid): Observable<object> {
+ const options = {
+ params: new HttpParams().set('Id', id.toString())
+ };
+ return this.http.get(AppConstants.API_POST_URL, options);
+ }
+}
+
diff --git a/src/DevHive.Angular/src/models/post.ts b/src/DevHive.Angular/src/models/post.ts
new file mode 100644
index 0000000..2d7d79f
--- /dev/null
+++ b/src/DevHive.Angular/src/models/post.ts
@@ -0,0 +1,63 @@
+import {Guid} from 'guid-typescript';
+
+export class Post {
+ private _postId: Guid;
+ private _creatorFirstName: string;
+ private _creatorLastName: string;
+ private _creatorUsername: string;
+ private _message: string;
+ private _timeCreated: Date;
+ // _comments
+ // _files
+
+ constructor(postId: Guid, creatorFirstName: string, creatorLastName: string, creatorUsername: string, message: string, timeCreated: Date) {
+ this.postId = postId;
+ this.creatorFirstName = creatorFirstName;
+ this.creatorLastName = creatorLastName;
+ this.creatorUsername = creatorUsername;
+ this.message = message;
+ this.timeCreated = timeCreated;
+ }
+
+ public get postId(): Guid {
+ return this._postId;
+ }
+ public set postId(v: Guid) {
+ this._postId = v;
+ }
+
+ public get creatorFirstName(): string {
+ return this._creatorFirstName;
+ }
+ public set creatorFirstName(v: string) {
+ this._creatorFirstName = v;
+ }
+
+ public get creatorLastName(): string {
+ return this._creatorLastName;
+ }
+ public set creatorLastName(v: string) {
+ this._creatorLastName = v;
+ }
+
+ public get creatorUsername(): string {
+ return this._creatorUsername;
+ }
+ public set creatorUsername(v: string) {
+ this._creatorUsername = v;
+ }
+
+ public get message(): string {
+ return this._message;
+ }
+ public set message(v: string) {
+ this._message = v;
+ }
+
+ public get timeCreated(): Date {
+ return this._timeCreated;
+ }
+ public set timeCreated(v: Date) {
+ this._timeCreated = v;
+ }
+}
diff --git a/src/DevHive.Angular/src/styles.css b/src/DevHive.Angular/src/styles.css
index 1320795..aaa1bd5 100644
--- a/src/DevHive.Angular/src/styles.css
+++ b/src/DevHive.Angular/src/styles.css
@@ -73,6 +73,13 @@ input:focus, button:focus {
scrollbar-width: none; /* Firefox */
}
+.user-language, .user-technology {
+ border-radius: .4em;
+ background-color: lightgrey;
+ padding: .26em;
+ margin: 0 .2em;
+}
+
/* Inputs, the type found in login and register */
.input-selection {
diff --git a/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs
index e9fd48a..7262510 100644
--- a/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs
+++ b/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs
@@ -8,5 +8,6 @@ namespace DevHive.Data.Interfaces.Repositories
public interface IFeedRepository
{
Task<List<Post>> GetFriendsPosts(List<User> friendsList, DateTime firstRequestIssued, int pageNumber, int pageSize);
+ Task<List<Post>> GetUsersPosts(User user, DateTime firstRequestIssued, int pageNumber, int pageSize);
}
}
diff --git a/src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.Designer.cs b/src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.Designer.cs
new file mode 100644
index 0000000..1609c52
--- /dev/null
+++ b/src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.Designer.cs
@@ -0,0 +1,537 @@
+// <auto-generated />
+using System;
+using System.Collections.Generic;
+using DevHive.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ [DbContext(typeof(DevHiveContext))]
+ [Migration("20210130092813_CloudinaryFileUpload")]
+ partial class CloudinaryFileUpload
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityByDefaultColumns()
+ .HasAnnotation("Relational:MaxIdentifierLength", 63)
+ .HasAnnotation("ProductVersion", "5.0.1");
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Language", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Languages");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<List<string>>("FileUrls")
+ .HasColumnType("text[]");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Posts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Role", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Technology", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Technologies");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("ProfilePictureUrl")
+ .HasColumnType("text");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriends", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("FriendId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "FriendId");
+
+ b.HasIndex("FriendId");
+
+ b.ToTable("UserFriends");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.Property<Guid>("LanguagesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LanguagesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("LanguageUser");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.Property<Guid>("RolesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("RolesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("RoleUser");
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.Property<Guid>("TechnologiesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("TechnologiesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("TechnologyUser");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Comments")
+ .HasForeignKey("CreatorId");
+
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Comments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Creator");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Posts")
+ .HasForeignKey("CreatorId");
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany("Friends")
+ .HasForeignKey("UserId");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriends", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Friend")
+ .WithMany()
+ .HasForeignKey("FriendId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Friend");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Language", null)
+ .WithMany()
+ .HasForeignKey("LanguagesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RolesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Technology", null)
+ .WithMany()
+ .HasForeignKey("TechnologiesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Navigation("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("Friends");
+
+ b.Navigation("Posts");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.cs b/src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.cs
new file mode 100644
index 0000000..f691c9b
--- /dev/null
+++ b/src/DevHive.Data/Migrations/20210130092813_CloudinaryFileUpload.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace DevHive.Data.Migrations
+{
+ public partial class CloudinaryFileUpload : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Comments_Posts_PostId",
+ table: "Comments");
+
+ migrationBuilder.AlterColumn<Guid>(
+ name: "CreatorId",
+ table: "Posts",
+ type: "uuid",
+ nullable: true,
+ oldClrType: typeof(Guid),
+ oldType: "uuid");
+
+ migrationBuilder.AddColumn<List<string>>(
+ name: "FileUrls",
+ table: "Posts",
+ type: "text[]",
+ nullable: true);
+
+ migrationBuilder.AlterColumn<Guid>(
+ name: "PostId",
+ table: "Comments",
+ type: "uuid",
+ nullable: true,
+ oldClrType: typeof(Guid),
+ oldType: "uuid");
+
+ migrationBuilder.AlterColumn<Guid>(
+ name: "CreatorId",
+ table: "Comments",
+ type: "uuid",
+ nullable: true,
+ oldClrType: typeof(Guid),
+ oldType: "uuid");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Posts_CreatorId",
+ table: "Posts",
+ column: "CreatorId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Comments_CreatorId",
+ table: "Comments",
+ column: "CreatorId");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Comments_AspNetUsers_CreatorId",
+ table: "Comments",
+ column: "CreatorId",
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Comments_Posts_PostId",
+ table: "Comments",
+ column: "PostId",
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Posts_AspNetUsers_CreatorId",
+ table: "Posts",
+ column: "CreatorId",
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Comments_AspNetUsers_CreatorId",
+ table: "Comments");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Comments_Posts_PostId",
+ table: "Comments");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Posts_AspNetUsers_CreatorId",
+ table: "Posts");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Posts_CreatorId",
+ table: "Posts");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Comments_CreatorId",
+ table: "Comments");
+
+ migrationBuilder.DropColumn(
+ name: "FileUrls",
+ table: "Posts");
+
+ migrationBuilder.AlterColumn<Guid>(
+ name: "CreatorId",
+ table: "Posts",
+ type: "uuid",
+ nullable: false,
+ defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
+ oldClrType: typeof(Guid),
+ oldType: "uuid",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn<Guid>(
+ name: "PostId",
+ table: "Comments",
+ type: "uuid",
+ nullable: false,
+ defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
+ oldClrType: typeof(Guid),
+ oldType: "uuid",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn<Guid>(
+ name: "CreatorId",
+ table: "Comments",
+ type: "uuid",
+ nullable: false,
+ defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
+ oldClrType: typeof(Guid),
+ oldType: "uuid",
+ oldNullable: true);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Comments_Posts_PostId",
+ table: "Comments",
+ column: "PostId",
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+ }
+}
diff --git a/src/DevHive.Data/Models/User.cs b/src/DevHive.Data/Models/User.cs
index 2203554..da18c2f 100644
--- a/src/DevHive.Data/Models/User.cs
+++ b/src/DevHive.Data/Models/User.cs
@@ -16,15 +16,8 @@ namespace DevHive.Data.Models
public string ProfilePictureUrl { get; set; }
- /// <summary>
- /// Languages that the user uses or is familiar with
- /// </summary>
- // [Unique]
public HashSet<Language> Languages { get; set; } = new();
- /// <summary>
- /// Technologies that the user uses or is familiar with
- /// </summary>
public HashSet<Technology> Technologies { get; set; } = new();
public HashSet<Role> Roles { get; set; } = new();
diff --git a/src/DevHive.Data/Repositories/CommentRepository.cs b/src/DevHive.Data/Repositories/CommentRepository.cs
index d33b7bf..8ddc628 100644
--- a/src/DevHive.Data/Repositories/CommentRepository.cs
+++ b/src/DevHive.Data/Repositories/CommentRepository.cs
@@ -17,6 +17,14 @@ namespace DevHive.Data.Repositories
}
#region Read
+ public override async Task<Comment> GetByIdAsync(Guid id)
+ {
+ return await this._context.Comments
+ .Include(x => x.Creator)
+ .Include(x => x.Post)
+ .FirstOrDefaultAsync(x => x.Id == id);
+ }
+
public async Task<Comment> GetCommentByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated)
{
return await this._context.Comments
@@ -25,6 +33,21 @@ namespace DevHive.Data.Repositories
}
#endregion
+ #region Update
+ public override async Task<bool> EditAsync(Guid id, Comment newEntity)
+ {
+ Comment comment = await this.GetByIdAsync(id);
+
+ this._context
+ .Entry(comment)
+ .CurrentValues
+ .SetValues(newEntity);
+
+ return await this.SaveChangesAsync(this._context);
+ }
+ #endregion
+
+
#region Validations
public async Task<bool> DoesCommentExist(Guid id)
{
diff --git a/src/DevHive.Data/Repositories/FeedRepository.cs b/src/DevHive.Data/Repositories/FeedRepository.cs
index efcb8e0..d8170d0 100644
--- a/src/DevHive.Data/Repositories/FeedRepository.cs
+++ b/src/DevHive.Data/Repositories/FeedRepository.cs
@@ -25,11 +25,28 @@ namespace DevHive.Data.Repositories
List<Post> posts = await this._context.Posts
.Where(post => post.TimeCreated < firstRequestIssued)
.Where(p => friendsIds.Contains(p.Creator.Id))
- .OrderByDescending(x => x.TimeCreated)
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
+ // Ordering by descending can't happen in query, because it doesn't order it
+ // completely correctly (example: in query these two times are ordered
+ // like this: 2021-01-30T11:49:45, 2021-01-28T21:37:40.701244)
+ posts = posts.OrderByDescending(x => x.TimeCreated.ToFileTime()).ToList();
+ return posts;
+ }
+
+ public async Task<List<Post>> GetUsersPosts(User user, DateTime firstRequestIssued, int pageNumber, int pageSize)
+ {
+ List<Post> posts = await this._context.Posts
+ .Where(post => post.TimeCreated < firstRequestIssued)
+ .Where(p => p.Creator.Id == user.Id)
+ .Skip((pageNumber - 1) * pageSize)
+ .Take(pageSize)
+ .ToListAsync();
+
+ // Look at GetFriendsPosts on why this is done like this
+ posts = posts.OrderByDescending(x => x.TimeCreated.ToFileTime()).ToList();
return posts;
}
}
diff --git a/src/DevHive.Data/Repositories/PostRepository.cs b/src/DevHive.Data/Repositories/PostRepository.cs
index 78b40cd..07b5875 100644
--- a/src/DevHive.Data/Repositories/PostRepository.cs
+++ b/src/DevHive.Data/Repositories/PostRepository.cs
@@ -23,6 +23,7 @@ namespace DevHive.Data.Repositories
{
return await this._context.Posts
.Include(x => x.Comments)
+ .Include(x => x.Creator)
.FirstOrDefaultAsync(x => x.Id == id);
}
@@ -39,6 +40,30 @@ namespace DevHive.Data.Repositories
}
#endregion
+ #region Update
+ public override async Task<bool> EditAsync(Guid id, Post newEntity)
+ {
+ Post post = await this.GetByIdAsync(id);
+
+ this._context
+ .Entry(post)
+ .CurrentValues
+ .SetValues(newEntity);
+
+ post.FileUrls.Clear();
+ foreach(var fileUrl in newEntity.FileUrls)
+ post.FileUrls.Add(fileUrl);
+
+ post.Comments.Clear();
+ foreach(var comment in newEntity.Comments)
+ post.Comments.Add(comment);
+
+ this._context.Entry(post).State = EntityState.Modified;
+
+ return await this.SaveChangesAsync(this._context);
+ }
+ #endregion
+
#region Validations
public async Task<bool> DoesPostExist(Guid postId)
{
diff --git a/src/DevHive.Services/Configurations/Mapping/CommentMappings.cs b/src/DevHive.Services/Configurations/Mapping/CommentMappings.cs
index ac3c8f6..a43b64e 100644
--- a/src/DevHive.Services/Configurations/Mapping/CommentMappings.cs
+++ b/src/DevHive.Services/Configurations/Mapping/CommentMappings.cs
@@ -1,6 +1,6 @@
using DevHive.Data.Models;
using AutoMapper;
-using DevHive.Services.Models.Post.Comment;
+using DevHive.Services.Models.Comment;
namespace DevHive.Services.Configurations.Mapping
{
diff --git a/src/DevHive.Services/Configurations/Mapping/PostMappings.cs b/src/DevHive.Services/Configurations/Mapping/PostMappings.cs
index c7466d9..d36dbdd 100644
--- a/src/DevHive.Services/Configurations/Mapping/PostMappings.cs
+++ b/src/DevHive.Services/Configurations/Mapping/PostMappings.cs
@@ -1,6 +1,6 @@
using DevHive.Data.Models;
using AutoMapper;
-using DevHive.Services.Models.Post.Post;
+using DevHive.Services.Models.Post;
namespace DevHive.Services.Configurations.Mapping
{
@@ -17,10 +17,9 @@ namespace DevHive.Services.Configurations.Mapping
CreateMap<Post, ReadPostServiceModel>()
.ForMember(dest => dest.PostId, src => src.MapFrom(p => p.Id))
- .ForMember(dest => dest.CreatorFirstName, src => src.Ignore())
- .ForMember(dest => dest.CreatorLastName, src => src.Ignore())
- .ForMember(dest => dest.CreatorUsername, src => src.Ignore());
- //TODO: Map those here /\
+ .ForMember(dest => dest.CreatorFirstName, src => src.MapFrom(p => p.Creator.FirstName))
+ .ForMember(dest => dest.CreatorLastName, src => src.MapFrom(p => p.Creator.LastName))
+ .ForMember(dest => dest.CreatorUsername, src => src.MapFrom(p => p.Creator.UserName));
}
}
}
diff --git a/src/DevHive.Services/Interfaces/ICommentService.cs b/src/DevHive.Services/Interfaces/ICommentService.cs
new file mode 100644
index 0000000..e7409a8
--- /dev/null
+++ b/src/DevHive.Services/Interfaces/ICommentService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Threading.Tasks;
+using DevHive.Services.Models.Comment;
+
+namespace DevHive.Services.Interfaces
+{
+ public interface ICommentService
+ {
+ Task<Guid> AddComment(CreateCommentServiceModel createPostServiceModel);
+
+ Task<ReadCommentServiceModel> GetCommentById(Guid id);
+
+ Task<Guid> UpdateComment(UpdateCommentServiceModel updateCommentServiceModel);
+
+ Task<bool> DeleteComment(Guid id);
+
+ Task<bool> ValidateJwtForCreating(Guid userId, string rawTokenData);
+ Task<bool> ValidateJwtForComment(Guid commentId, string rawTokenData);
+ }
+}
diff --git a/src/DevHive.Services/Interfaces/IFeedService.cs b/src/DevHive.Services/Interfaces/IFeedService.cs
index 1edba5a..b507b3b 100644
--- a/src/DevHive.Services/Interfaces/IFeedService.cs
+++ b/src/DevHive.Services/Interfaces/IFeedService.cs
@@ -6,5 +6,6 @@ namespace DevHive.Services.Interfaces
public interface IFeedService
{
Task<ReadPageServiceModel> GetPage(GetPageServiceModel getPageServiceModel);
+ Task<ReadPageServiceModel> GetUserPage(GetPageServiceModel model);
}
}
diff --git a/src/DevHive.Services/Interfaces/IPostService.cs b/src/DevHive.Services/Interfaces/IPostService.cs
index 71b558c..d35acfd 100644
--- a/src/DevHive.Services/Interfaces/IPostService.cs
+++ b/src/DevHive.Services/Interfaces/IPostService.cs
@@ -1,26 +1,20 @@
using System;
using System.Threading.Tasks;
-using DevHive.Services.Models.Post.Comment;
-using DevHive.Services.Models.Post.Post;
+using DevHive.Services.Models.Post;
namespace DevHive.Services.Interfaces
{
- public interface IPostService
+ public interface IPostService
{
Task<Guid> CreatePost(CreatePostServiceModel createPostServiceModel);
- Task<Guid> AddComment(CreateCommentServiceModel createPostServiceModel);
Task<ReadPostServiceModel> GetPostById(Guid id);
- Task<ReadCommentServiceModel> GetCommentById(Guid id);
Task<Guid> UpdatePost(UpdatePostServiceModel updatePostServiceModel);
- Task<Guid> UpdateComment(UpdateCommentServiceModel updateCommentServiceModel);
Task<bool> DeletePost(Guid id);
- Task<bool> DeleteComment(Guid id);
Task<bool> ValidateJwtForCreating(Guid userId, string rawTokenData);
Task<bool> ValidateJwtForPost(Guid postId, string rawTokenData);
- Task<bool> ValidateJwtForComment(Guid commentId, string rawTokenData);
}
}
diff --git a/src/DevHive.Services/Models/Post/Comment/CreateCommentServiceModel.cs b/src/DevHive.Services/Models/Comment/CreateCommentServiceModel.cs
index 8d49659..30e919b 100644
--- a/src/DevHive.Services/Models/Post/Comment/CreateCommentServiceModel.cs
+++ b/src/DevHive.Services/Models/Comment/CreateCommentServiceModel.cs
@@ -1,6 +1,6 @@
using System;
-namespace DevHive.Services.Models.Post.Comment
+namespace DevHive.Services.Models.Comment
{
public class CreateCommentServiceModel
{
diff --git a/src/DevHive.Services/Models/Post/Comment/ReadCommentServiceModel.cs b/src/DevHive.Services/Models/Comment/ReadCommentServiceModel.cs
index 12e29a0..3196233 100644
--- a/src/DevHive.Services/Models/Post/Comment/ReadCommentServiceModel.cs
+++ b/src/DevHive.Services/Models/Comment/ReadCommentServiceModel.cs
@@ -1,6 +1,6 @@
using System;
-namespace DevHive.Services.Models.Post.Comment
+namespace DevHive.Services.Models.Comment
{
public class ReadCommentServiceModel
{
diff --git a/src/DevHive.Services/Models/Post/Comment/UpdateCommentServiceModel.cs b/src/DevHive.Services/Models/Comment/UpdateCommentServiceModel.cs
index 3827d4d..3b78200 100644
--- a/src/DevHive.Services/Models/Post/Comment/UpdateCommentServiceModel.cs
+++ b/src/DevHive.Services/Models/Comment/UpdateCommentServiceModel.cs
@@ -1,6 +1,6 @@
using System;
-namespace DevHive.Services.Models.Post.Comment
+namespace DevHive.Services.Models.Comment
{
public class UpdateCommentServiceModel
{
diff --git a/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs b/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs
index f291de7..95f6845 100644
--- a/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs
+++ b/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs
@@ -1,5 +1,5 @@
using System.Collections.Generic;
-using DevHive.Services.Models.Post.Post;
+using DevHive.Services.Models.Post;
namespace DevHive.Services.Models
{
diff --git a/src/DevHive.Services/Models/Post/Post/CreatePostServiceModel.cs b/src/DevHive.Services/Models/Post/CreatePostServiceModel.cs
index 8676f6c..304eb90 100644
--- a/src/DevHive.Services/Models/Post/Post/CreatePostServiceModel.cs
+++ b/src/DevHive.Services/Models/Post/CreatePostServiceModel.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
-namespace DevHive.Services.Models.Post.Post
+namespace DevHive.Services.Models.Post
{
public class CreatePostServiceModel
{
diff --git a/src/DevHive.Services/Models/Post/Post/ReadPostServiceModel.cs b/src/DevHive.Services/Models/Post/ReadPostServiceModel.cs
index f0a4fe5..04ec6bd 100644
--- a/src/DevHive.Services/Models/Post/Post/ReadPostServiceModel.cs
+++ b/src/DevHive.Services/Models/Post/ReadPostServiceModel.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
-using DevHive.Services.Models.Post.Comment;
+using DevHive.Services.Models.Comment;
using Microsoft.Extensions.FileProviders;
-namespace DevHive.Services.Models.Post.Post
+namespace DevHive.Services.Models.Post
{
public class ReadPostServiceModel
{
diff --git a/src/DevHive.Services/Models/Post/Post/UpdatePostServiceModel.cs b/src/DevHive.Services/Models/Post/UpdatePostServiceModel.cs
index 24b0b74..51b16bc 100644
--- a/src/DevHive.Services/Models/Post/Post/UpdatePostServiceModel.cs
+++ b/src/DevHive.Services/Models/Post/UpdatePostServiceModel.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
-namespace DevHive.Services.Models.Post.Post
+namespace DevHive.Services.Models.Post
{
public class UpdatePostServiceModel
{
diff --git a/src/DevHive.Services/Services/CommentService.cs b/src/DevHive.Services/Services/CommentService.cs
new file mode 100644
index 0000000..e0eb88a
--- /dev/null
+++ b/src/DevHive.Services/Services/CommentService.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using AutoMapper;
+using DevHive.Data.Models;
+using DevHive.Services.Models.Comment;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using DevHive.Services.Interfaces;
+using DevHive.Data.Interfaces.Repositories;
+using System.Linq;
+
+namespace DevHive.Services.Services
+{
+ public class CommentService : ICommentService
+ {
+ private readonly IUserRepository _userRepository;
+ private readonly IPostRepository _postRepository;
+ private readonly ICommentRepository _commentRepository;
+ private readonly IMapper _postMapper;
+
+ public CommentService(IUserRepository userRepository, IPostRepository postRepository, ICommentRepository commentRepository, IMapper postMapper)
+ {
+ this._userRepository = userRepository;
+ this._postRepository = postRepository;
+ this._commentRepository = commentRepository;
+ this._postMapper = postMapper;
+ }
+
+ #region Create
+ public async Task<Guid> AddComment(CreateCommentServiceModel createCommentServiceModel)
+ {
+ if (!await this._postRepository.DoesPostExist(createCommentServiceModel.PostId))
+ throw new ArgumentException("Post does not exist!");
+
+ Comment comment = this._postMapper.Map<Comment>(createCommentServiceModel);
+ comment.TimeCreated = DateTime.Now;
+
+ comment.Creator = await this._userRepository.GetByIdAsync(createCommentServiceModel.CreatorId);
+ comment.Post = await this._postRepository.GetByIdAsync(createCommentServiceModel.PostId);
+
+ bool success = await this._commentRepository.AddAsync(comment);
+ if (success)
+ {
+ Comment newComment = await this._commentRepository
+ .GetCommentByIssuerAndTimeCreatedAsync(comment.Creator.Id, comment.TimeCreated);
+
+ return newComment.Id;
+ }
+ else
+ return Guid.Empty;
+ }
+ #endregion
+
+ #region Read
+ public async Task<ReadCommentServiceModel> GetCommentById(Guid id)
+ {
+ Comment comment = await this._commentRepository.GetByIdAsync(id) ??
+ throw new ArgumentException("The comment does not exist");
+
+ User user = await this._userRepository.GetByIdAsync(comment.Creator.Id) ??
+ throw new ArgumentException("The user does not exist");
+
+ ReadCommentServiceModel readCommentServiceModel = this._postMapper.Map<ReadCommentServiceModel>(comment);
+ readCommentServiceModel.IssuerFirstName = user.FirstName;
+ readCommentServiceModel.IssuerLastName = user.LastName;
+ readCommentServiceModel.IssuerUsername = user.UserName;
+
+ return readCommentServiceModel;
+ }
+ #endregion
+
+ #region Update
+ public async Task<Guid> UpdateComment(UpdateCommentServiceModel updateCommentServiceModel)
+ {
+ if (!await this._commentRepository.DoesCommentExist(updateCommentServiceModel.CommentId))
+ throw new ArgumentException("Comment does not exist!");
+
+ Comment comment = this._postMapper.Map<Comment>(updateCommentServiceModel);
+ comment.TimeCreated = DateTime.Now;
+
+ comment.Creator = await this._userRepository.GetByIdAsync(updateCommentServiceModel.CreatorId);
+ comment.Post = await this._postRepository.GetByIdAsync(updateCommentServiceModel.PostId);
+
+ bool result = await this._commentRepository.EditAsync(updateCommentServiceModel.CommentId, comment);
+
+ if (result)
+ return (await this._commentRepository.GetByIdAsync(updateCommentServiceModel.CommentId)).Id;
+ else
+ return Guid.Empty;
+ }
+ #endregion
+
+ #region Delete
+ public async Task<bool> DeleteComment(Guid id)
+ {
+ if (!await this._commentRepository.DoesCommentExist(id))
+ throw new ArgumentException("Comment does not exist!");
+
+ Comment comment = await this._commentRepository.GetByIdAsync(id);
+ return await this._commentRepository.DeleteAsync(comment);
+ }
+ #endregion
+
+ #region Validations
+ public async Task<bool> ValidateJwtForCreating(Guid userId, string rawTokenData)
+ {
+ User user = await this.GetUserForValidation(rawTokenData);
+
+ return user.Id == userId;
+ }
+
+ public async Task<bool> ValidateJwtForComment(Guid commentId, string rawTokenData)
+ {
+ Comment comment = await this._commentRepository.GetByIdAsync(commentId) ??
+ throw new ArgumentException("Comment does not exist!");
+ User user = await this.GetUserForValidation(rawTokenData);
+
+ //If user made the comment
+ if (comment.Creator.Id == user.Id)
+ return true;
+ //If user is admin
+ else if (user.Roles.Any(x => x.Name == Role.AdminRole))
+ return true;
+ else
+ return false;
+ }
+
+ private async Task<User> GetUserForValidation(string rawTokenData)
+ {
+ JwtSecurityToken jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7));
+
+ Guid jwtUserId = Guid.Parse(this.GetClaimTypeValues("ID", jwt.Claims).First());
+ //HashSet<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims);
+
+ User user = await this._userRepository.GetByIdAsync(jwtUserId) ??
+ throw new ArgumentException("User does not exist!");
+
+ return user;
+ }
+
+
+ private List<string> GetClaimTypeValues(string type, IEnumerable<Claim> claims)
+ {
+ List<string> toReturn = new();
+
+ foreach (var claim in claims)
+ if (claim.Type == type)
+ toReturn.Add(claim.Value);
+
+ return toReturn;
+ }
+ #endregion
+ }
+}
+
diff --git a/src/DevHive.Services/Services/FeedService.cs b/src/DevHive.Services/Services/FeedService.cs
index c17861d..37d653c 100644
--- a/src/DevHive.Services/Services/FeedService.cs
+++ b/src/DevHive.Services/Services/FeedService.cs
@@ -7,7 +7,7 @@ using DevHive.Data.Interfaces.Repositories;
using DevHive.Data.Models;
using DevHive.Services.Interfaces;
using DevHive.Services.Models;
-using DevHive.Services.Models.Post.Post;
+using DevHive.Services.Models.Post;
namespace DevHive.Services.Services
{
@@ -54,5 +54,29 @@ namespace DevHive.Services.Services
return readPageServiceModel;
}
+
+ public async Task<ReadPageServiceModel> GetUserPage(GetPageServiceModel model) {
+ User user = null;
+
+ if (!string.IsNullOrEmpty(model.Username))
+ user = await this._userRepository.GetByUsernameAsync(model.Username);
+ else
+ throw new ArgumentException("Invalid given data!");
+
+ if (user == null)
+ throw new ArgumentException("User doesn't exist!");
+
+ List<Post> posts = await this._feedRepository
+ .GetUsersPosts(user, model.FirstRequestIssued, model.PageNumber, model.PageSize);
+
+ if (posts.Count <= 0)
+ throw new ArgumentException("User hasn't posted anything yet!");
+
+ ReadPageServiceModel readPageServiceModel = new();
+ foreach (Post post in posts)
+ readPageServiceModel.Posts.Add(this._mapper.Map<ReadPostServiceModel>(post));
+
+ return readPageServiceModel;
+ }
}
}
diff --git a/src/DevHive.Services/Services/PostService.cs b/src/DevHive.Services/Services/PostService.cs
index 7ce7b58..0eaac94 100644
--- a/src/DevHive.Services/Services/PostService.cs
+++ b/src/DevHive.Services/Services/PostService.cs
@@ -3,8 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using DevHive.Data.Models;
-using DevHive.Services.Models.Post.Comment;
-using DevHive.Services.Models.Post.Post;
+using DevHive.Services.Models.Post;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using DevHive.Services.Interfaces;
@@ -13,7 +12,7 @@ using System.Linq;
namespace DevHive.Services.Services
{
- public class PostService : IPostService
+ public class PostService : IPostService
{
private readonly ICloudService _cloudService;
private readonly IUserRepository _userRepository;
@@ -55,29 +54,6 @@ namespace DevHive.Services.Services
else
return Guid.Empty;
}
-
- public async Task<Guid> AddComment(CreateCommentServiceModel createCommentServiceModel)
- {
- if (!await this._postRepository.DoesPostExist(createCommentServiceModel.PostId))
- throw new ArgumentException("Post does not exist!");
-
- Comment comment = this._postMapper.Map<Comment>(createCommentServiceModel);
- comment.TimeCreated = DateTime.Now;
-
- comment.Creator = await this._userRepository.GetByIdAsync(createCommentServiceModel.CreatorId);
- comment.Post = await this._postRepository.GetByIdAsync(createCommentServiceModel.PostId);
-
- bool success = await this._commentRepository.AddAsync(comment);
- if (success)
- {
- Comment newComment = await this._commentRepository
- .GetCommentByIssuerAndTimeCreatedAsync(comment.Creator.Id, comment.TimeCreated);
-
- return newComment.Id;
- }
- else
- return Guid.Empty;
- }
#endregion
#region Read
@@ -96,22 +72,6 @@ namespace DevHive.Services.Services
return readPostServiceModel;
}
-
- public async Task<ReadCommentServiceModel> GetCommentById(Guid id)
- {
- Comment comment = await this._commentRepository.GetByIdAsync(id) ??
- throw new ArgumentException("The comment does not exist");
-
- User user = await this._userRepository.GetByIdAsync(comment.Creator.Id) ??
- throw new ArgumentException("The user does not exist");
-
- ReadCommentServiceModel readCommentServiceModel = this._postMapper.Map<ReadCommentServiceModel>(comment);
- readCommentServiceModel.IssuerFirstName = user.FirstName;
- readCommentServiceModel.IssuerLastName = user.LastName;
- readCommentServiceModel.IssuerUsername = user.UserName;
-
- return readCommentServiceModel;
- }
#endregion
#region Update
@@ -146,25 +106,6 @@ namespace DevHive.Services.Services
else
return Guid.Empty;
}
-
- public async Task<Guid> UpdateComment(UpdateCommentServiceModel updateCommentServiceModel)
- {
- if (!await this._commentRepository.DoesCommentExist(updateCommentServiceModel.CommentId))
- throw new ArgumentException("Comment does not exist!");
-
- Comment comment = this._postMapper.Map<Comment>(updateCommentServiceModel);
- comment.TimeCreated = DateTime.Now;
-
- comment.Creator = await this._userRepository.GetByIdAsync(updateCommentServiceModel.CreatorId);
- comment.Post = await this._postRepository.GetByIdAsync(updateCommentServiceModel.PostId);
-
- bool result = await this._commentRepository.EditAsync(updateCommentServiceModel.CommentId, comment);
-
- if (result)
- return (await this._commentRepository.GetByIdAsync(updateCommentServiceModel.CommentId)).Id;
- else
- return Guid.Empty;
- }
#endregion
#region Delete
@@ -185,15 +126,6 @@ namespace DevHive.Services.Services
return await this._postRepository.DeleteAsync(post);
}
-
- public async Task<bool> DeleteComment(Guid id)
- {
- if (!await this._commentRepository.DoesCommentExist(id))
- throw new ArgumentException("Comment does not exist!");
-
- Comment comment = await this._commentRepository.GetByIdAsync(id);
- return await this._commentRepository.DeleteAsync(comment);
- }
#endregion
#region Validations
diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs
index ea53f1a..c2c42e0 100644
--- a/src/DevHive.Services/Services/UserService.cs
+++ b/src/DevHive.Services/Services/UserService.cs
@@ -53,7 +53,7 @@ namespace DevHive.Services.Services
if (user.PasswordHash != PasswordModifications.GeneratePasswordHash(loginModel.Password))
throw new ArgumentException("Incorrect password!");
- return new TokenModel(WriteJWTSecurityToken(user.Id, user.Roles));
+ return new TokenModel(WriteJWTSecurityToken(user.Id, user.UserName, user.Roles));
}
public async Task<TokenModel> RegisterUser(RegisterServiceModel registerModel)
@@ -78,7 +78,7 @@ namespace DevHive.Services.Services
await this._userRepository.AddAsync(user);
- return new TokenModel(WriteJWTSecurityToken(user.Id, user.Roles));
+ return new TokenModel(WriteJWTSecurityToken(user.Id, user.UserName, user.Roles));
}
#endregion
@@ -107,8 +107,6 @@ namespace DevHive.Services.Services
{
await this.ValidateUserOnUpdate(updateUserServiceModel);
- await this.ValidateUserCollections(updateUserServiceModel);
-
User user = await this.PopulateModel(updateUserServiceModel);
bool successful = await this._userRepository.EditAsync(updateUserServiceModel.Id, user);
@@ -190,62 +188,13 @@ namespace DevHive.Services.Services
throw new ArgumentException("Username already exists!");
}
- private async Task ValidateUserCollections(UpdateUserServiceModel updateUserServiceModel)
- {
- //Do NOT allow a user to change his roles, unless he is an Admin
- bool isAdmin = (await this._userRepository.GetByIdAsync(updateUserServiceModel.Id))
- .Roles.Any(r => r.Name == Role.AdminRole);
-
- if (isAdmin)
- {
- // Roles
- foreach (var role in updateUserServiceModel.Roles)
- {
- Role returnedRole = await this._roleRepository.GetByNameAsync(role.Name) ??
- throw new ArgumentException($"Role {role.Name} does not exist!");
- }
- }
- //Preserve original user roles
- else
- {
- HashSet<Role> roles = (await this._userRepository.GetByIdAsync(updateUserServiceModel.Id)).Roles;
-
- foreach (var role in roles)
- {
- Role returnedRole = await this._roleRepository.GetByNameAsync(role.Name) ??
- throw new ArgumentException($"Role {role.Name} does not exist!");
- }
- }
-
- // Friends
- foreach (var friend in updateUserServiceModel.Friends)
- {
- User returnedFriend = await this._userRepository.GetByUsernameAsync(friend.UserName) ??
- throw new ArgumentException($"User {friend.UserName} does not exist!");
- }
-
- // Languages
- foreach (var language in updateUserServiceModel.Languages)
- {
- Language returnedLanguage = await this._languageRepository.GetByNameAsync(language.Name) ??
- throw new ArgumentException($"Language {language.Name} does not exist!");
- }
-
- // Technology
- foreach (var technology in updateUserServiceModel.Technologies)
- {
- Technology returnedTechnology = await this._technologyRepository.GetByNameAsync(technology.Name) ??
- throw new ArgumentException($"Technology {technology.Name} does not exist!");
- }
- }
-
- private string WriteJWTSecurityToken(Guid userId, HashSet<Role> roles)
+ private string WriteJWTSecurityToken(Guid userId, string username, HashSet<Role> roles)
{
byte[] signingKey = Encoding.ASCII.GetBytes(_jwtOptions.Secret);
-
HashSet<Claim> claims = new()
{
new Claim("ID", $"{userId}"),
+ new Claim("Username", username),
};
foreach (var role in roles)
@@ -269,12 +218,12 @@ namespace DevHive.Services.Services
#endregion
#region Misc
- public async Task<Guid> SuperSecretPromotionToAdmin(Guid userId)
+ public async Task<TokenModel> SuperSecretPromotionToAdmin(Guid userId)
{
User user = await this._userRepository.GetByIdAsync(userId) ??
throw new ArgumentException("User does not exist! Can't promote shit in this country...");
- if (!await this._roleRepository.DoesNameExist("Admin"))
+ if (!await this._roleRepository.DoesNameExist(Role.AdminRole))
{
Role adminRole = new()
{
@@ -290,7 +239,9 @@ namespace DevHive.Services.Services
user.Roles.Add(admin);
await this._userRepository.EditAsync(user.Id, user);
- return admin.Id;
+ User newUser = await this._userRepository.GetByIdAsync(userId);
+
+ return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles);
}
private async Task<User> PopulateModel(UpdateUserServiceModel updateUserServiceModel)
diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs
index 46e67ee..22df311 100644
--- a/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs
+++ b/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs
@@ -7,7 +7,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace DevHive.Web.Configurations.Extensions
{
- public static class ConfigureDependencyInjection
+ public static class ConfigureDependencyInjection
{
public static void DependencyInjectionConfiguration(this IServiceCollection services, IConfiguration configuration)
{
@@ -25,6 +25,7 @@ namespace DevHive.Web.Configurations.Extensions
services.AddTransient<ITechnologyService, TechnologyService>();
services.AddTransient<IUserService, UserService>();
services.AddTransient<IPostService, PostService>();
+ services.AddTransient<ICommentService, CommentService>();
services.AddTransient<IFeedService, FeedService>();
services.AddTransient<ICloudService, CloudinaryService>(options =>
new CloudinaryService(
diff --git a/src/DevHive.Web/Configurations/Mapping/CommentMappings.cs b/src/DevHive.Web/Configurations/Mapping/CommentMappings.cs
index a28ee16..b8d6829 100644
--- a/src/DevHive.Web/Configurations/Mapping/CommentMappings.cs
+++ b/src/DevHive.Web/Configurations/Mapping/CommentMappings.cs
@@ -1,6 +1,6 @@
using AutoMapper;
-using DevHive.Services.Models.Post.Comment;
-using DevHive.Web.Models.Post.Comment;
+using DevHive.Services.Models.Comment;
+using DevHive.Web.Models.Comment;
namespace DevHive.Web.Configurations.Mapping
{
@@ -15,6 +15,3 @@ namespace DevHive.Web.Configurations.Mapping
}
}
}
-
-
-
diff --git a/src/DevHive.Web/Configurations/Mapping/PostMappings.cs b/src/DevHive.Web/Configurations/Mapping/PostMappings.cs
index bc7bc06..a5b46ee 100644
--- a/src/DevHive.Web/Configurations/Mapping/PostMappings.cs
+++ b/src/DevHive.Web/Configurations/Mapping/PostMappings.cs
@@ -1,6 +1,6 @@
using AutoMapper;
-using DevHive.Services.Models.Post.Post;
-using DevHive.Web.Models.Post.Post;
+using DevHive.Services.Models.Post;
+using DevHive.Web.Models.Post;
namespace DevHive.Web.Configurations.Mapping
{
diff --git a/src/DevHive.Web/Controllers/CommentController.cs b/src/DevHive.Web/Controllers/CommentController.cs
new file mode 100644
index 0000000..ebcb87a
--- /dev/null
+++ b/src/DevHive.Web/Controllers/CommentController.cs
@@ -0,0 +1,82 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using AutoMapper;
+using System;
+using DevHive.Web.Models.Comment;
+using DevHive.Services.Models.Comment;
+using Microsoft.AspNetCore.Authorization;
+using DevHive.Services.Interfaces;
+
+namespace DevHive.Web.Controllers
+{
+ [ApiController]
+ [Route("/api/[controller]")]
+ [Authorize(Roles = "User,Admin")]
+ public class CommentController {
+ private readonly ICommentService _commentService;
+ private readonly IMapper _commentMapper;
+
+ public CommentController(ICommentService commentService, IMapper commentMapper)
+ {
+ this._commentService = commentService;
+ this._commentMapper = commentMapper;
+ }
+
+ [HttpPost]
+ public async Task<IActionResult> AddComment(Guid userId, [FromBody] CreateCommentWebModel createCommentWebModel, [FromHeader] string authorization)
+ {
+ if (!await this._commentService.ValidateJwtForCreating(userId, authorization))
+ return new UnauthorizedResult();
+
+ CreateCommentServiceModel createCommentServiceModel =
+ this._commentMapper.Map<CreateCommentServiceModel>(createCommentWebModel);
+ createCommentServiceModel.CreatorId = userId;
+
+ Guid id = await this._commentService.AddComment(createCommentServiceModel);
+
+ return id == Guid.Empty ?
+ new BadRequestObjectResult("Could not create comment!") :
+ new OkObjectResult(new { Id = id });
+ }
+
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task<IActionResult> GetCommentById(Guid id)
+ {
+ ReadCommentServiceModel readCommentServiceModel = await this._commentService.GetCommentById(id);
+ ReadCommentWebModel readCommentWebModel = this._commentMapper.Map<ReadCommentWebModel>(readCommentServiceModel);
+
+ return new OkObjectResult(readCommentWebModel);
+ }
+
+ [HttpPut]
+ public async Task<IActionResult> UpdateComment(Guid userId, [FromBody] UpdateCommentWebModel updateCommentWebModel, [FromHeader] string authorization)
+ {
+ if (!await this._commentService.ValidateJwtForComment(updateCommentWebModel.CommentId, authorization))
+ return new UnauthorizedResult();
+
+ UpdateCommentServiceModel updateCommentServiceModel =
+ this._commentMapper.Map<UpdateCommentServiceModel>(updateCommentWebModel);
+ updateCommentServiceModel.CreatorId = userId;
+
+ Guid id = await this._commentService.UpdateComment(updateCommentServiceModel);
+
+ return id == Guid.Empty ?
+ new BadRequestObjectResult("Unable to update comment!") :
+ new OkObjectResult(new { Id = id });
+ }
+
+ [HttpDelete]
+ public async Task<IActionResult> DeleteComment(Guid id, [FromHeader] string authorization)
+ {
+ if (!await this._commentService.ValidateJwtForComment(id, authorization))
+ return new UnauthorizedResult();
+
+ return await this._commentService.DeleteComment(id) ?
+ new OkResult() :
+ new BadRequestObjectResult("Could not delete Comment");
+ }
+
+ }
+}
+
diff --git a/src/DevHive.Web/Controllers/FeedController.cs b/src/DevHive.Web/Controllers/FeedController.cs
index 4fd3ae9..2f14cf3 100644
--- a/src/DevHive.Web/Controllers/FeedController.cs
+++ b/src/DevHive.Web/Controllers/FeedController.cs
@@ -23,7 +23,7 @@ namespace DevHive.Web.Controllers
this._mapper = mapper;
}
- [HttpGet]
+ [HttpPost]
[Route("GetPosts")]
public async Task<IActionResult> GetPosts(Guid userId, [FromBody] GetPageWebModel getPageWebModel)
{
@@ -36,14 +36,15 @@ namespace DevHive.Web.Controllers
return new OkObjectResult(readPageWebModel);
}
- [HttpGet]
+ [HttpPost]
[Route("GetUserPosts")]
+ [AllowAnonymous]
public async Task<IActionResult> GetUserPosts(string username, [FromBody] GetPageWebModel getPageWebModel)
{
GetPageServiceModel getPageServiceModel = this._mapper.Map<GetPageServiceModel>(getPageWebModel);
getPageServiceModel.Username = username;
- ReadPageServiceModel readPageServiceModel = await this._feedService.GetPage(getPageServiceModel);
+ ReadPageServiceModel readPageServiceModel = await this._feedService.GetUserPage(getPageServiceModel);
ReadPageWebModel readPageWebModel = this._mapper.Map<ReadPageWebModel>(readPageServiceModel);
return new OkObjectResult(readPageWebModel);
diff --git a/src/DevHive.Web/Controllers/PostController.cs b/src/DevHive.Web/Controllers/PostController.cs
index fe71519..53adfce 100644
--- a/src/DevHive.Web/Controllers/PostController.cs
+++ b/src/DevHive.Web/Controllers/PostController.cs
@@ -2,16 +2,14 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using AutoMapper;
using System;
-using DevHive.Web.Models.Post.Post;
-using DevHive.Services.Models.Post.Post;
-using DevHive.Web.Models.Post.Comment;
-using DevHive.Services.Models.Post.Comment;
+using DevHive.Web.Models.Post;
+using DevHive.Services.Models.Post;
using Microsoft.AspNetCore.Authorization;
using DevHive.Services.Interfaces;
namespace DevHive.Web.Controllers
{
- [ApiController]
+ [ApiController]
[Route("/api/[controller]")]
[Authorize(Roles = "User,Admin")]
public class PostController
@@ -42,24 +40,6 @@ namespace DevHive.Web.Controllers
new BadRequestObjectResult("Could not create post!") :
new OkObjectResult(new { Id = id });
}
-
- [HttpPost]
- [Route("Comment")]
- public async Task<IActionResult> AddComment(Guid userId, [FromBody] CreateCommentWebModel createCommentWebModel, [FromHeader] string authorization)
- {
- if (!await this._postService.ValidateJwtForCreating(userId, authorization))
- return new UnauthorizedResult();
-
- CreateCommentServiceModel createCommentServiceModel =
- this._postMapper.Map<CreateCommentServiceModel>(createCommentWebModel);
- createCommentServiceModel.CreatorId = userId;
-
- Guid id = await this._postService.AddComment(createCommentServiceModel);
-
- return id == Guid.Empty ?
- new BadRequestObjectResult("Could not create comment!") :
- new OkObjectResult(new { Id = id });
- }
#endregion
#region Read
@@ -72,17 +52,6 @@ namespace DevHive.Web.Controllers
return new OkObjectResult(postWebModel);
}
-
- [HttpGet]
- [Route("Comment")]
- [AllowAnonymous]
- public async Task<IActionResult> GetCommentById(Guid id)
- {
- ReadCommentServiceModel readCommentServiceModel = await this._postService.GetCommentById(id);
- ReadCommentWebModel readCommentWebModel = this._postMapper.Map<ReadCommentWebModel>(readCommentServiceModel);
-
- return new OkObjectResult(readCommentWebModel);
- }
#endregion
#region Update
@@ -102,24 +71,6 @@ namespace DevHive.Web.Controllers
new BadRequestObjectResult("Unable to update post!") :
new OkObjectResult(new { Id = id });
}
-
- [HttpPut]
- [Route("Comment")]
- public async Task<IActionResult> UpdateComment(Guid userId, [FromBody] UpdateCommentWebModel updateCommentWebModel, [FromHeader] string authorization)
- {
- if (!await this._postService.ValidateJwtForComment(updateCommentWebModel.CommentId, authorization))
- return new UnauthorizedResult();
-
- UpdateCommentServiceModel updateCommentServiceModel =
- this._postMapper.Map<UpdateCommentServiceModel>(updateCommentWebModel);
- updateCommentServiceModel.CreatorId = userId;
-
- Guid id = await this._postService.UpdateComment(updateCommentServiceModel);
-
- return id == Guid.Empty ?
- new BadRequestObjectResult("Unable to update comment!") :
- new OkObjectResult(new { Id = id });
- }
#endregion
#region Delete
@@ -133,18 +84,6 @@ namespace DevHive.Web.Controllers
new OkResult() :
new BadRequestObjectResult("Could not delete Comment");
}
-
- [HttpDelete]
- [Route("Comment")]
- public async Task<IActionResult> DeleteComment(Guid id, [FromHeader] string authorization)
- {
- if (!await this._postService.ValidateJwtForComment(id, authorization))
- return new UnauthorizedResult();
-
- return await this._postService.DeleteComment(id) ?
- new OkResult() :
- new BadRequestObjectResult("Could not delete Comment");
- }
#endregion
}
}
diff --git a/src/DevHive.Web/Models/Post/Comment/CreateCommentWebModel.cs b/src/DevHive.Web/Models/Comment/CreateCommentWebModel.cs
index 85c67bf..8b2bf8d 100644
--- a/src/DevHive.Web/Models/Post/Comment/CreateCommentWebModel.cs
+++ b/src/DevHive.Web/Models/Comment/CreateCommentWebModel.cs
@@ -2,7 +2,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
-namespace DevHive.Web.Models.Post.Comment
+namespace DevHive.Web.Models.Comment
{
public class CreateCommentWebModel
{
diff --git a/src/DevHive.Web/Models/Post/Comment/ReadCommentWebModel.cs b/src/DevHive.Web/Models/Comment/ReadCommentWebModel.cs
index 5320c3c..4d3aff7 100644
--- a/src/DevHive.Web/Models/Post/Comment/ReadCommentWebModel.cs
+++ b/src/DevHive.Web/Models/Comment/ReadCommentWebModel.cs
@@ -1,6 +1,6 @@
using System;
-namespace DevHive.Web.Models.Post.Comment
+namespace DevHive.Web.Models.Comment
{
public class ReadCommentWebModel
{
diff --git a/src/DevHive.Web/Models/Post/Comment/UpdateCommentWebModel.cs b/src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs
index cb1c60a..b5d7970 100644
--- a/src/DevHive.Web/Models/Post/Comment/UpdateCommentWebModel.cs
+++ b/src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs
@@ -1,6 +1,6 @@
using System;
-namespace DevHive.Web.Models.Post.Comment
+namespace DevHive.Web.Models.Comment
{
public class UpdateCommentWebModel
{
diff --git a/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs b/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs
index 40d29c9..839aaa6 100644
--- a/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs
+++ b/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs
@@ -1,5 +1,5 @@
using System.Collections.Generic;
-using DevHive.Web.Models.Post.Post;
+using DevHive.Web.Models.Post;
namespace DevHive.Web.Controllers
{
diff --git a/src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs b/src/DevHive.Web/Models/Post/CreatePostWebModel.cs
index e35a813..256055a 100644
--- a/src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs
+++ b/src/DevHive.Web/Models/Post/CreatePostWebModel.cs
@@ -1,12 +1,11 @@
-using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http;
-namespace DevHive.Web.Models.Post.Post
+namespace DevHive.Web.Models.Post
{
- public class CreatePostWebModel
+ public class CreatePostWebModel
{
[NotNull]
[Required]
diff --git a/src/DevHive.Web/Models/Post/Post/ReadPostWebModel.cs b/src/DevHive.Web/Models/Post/ReadPostWebModel.cs
index 5d4da31..1d2669e 100644
--- a/src/DevHive.Web/Models/Post/Post/ReadPostWebModel.cs
+++ b/src/DevHive.Web/Models/Post/ReadPostWebModel.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
-using DevHive.Web.Models.Post.Comment;
+using DevHive.Web.Models.Comment;
using Microsoft.AspNetCore.Http;
-namespace DevHive.Web.Models.Post.Post
+namespace DevHive.Web.Models.Post
{
public class ReadPostWebModel
{
diff --git a/src/DevHive.Web/Models/Post/Post/UpdatePostWebModel.cs b/src/DevHive.Web/Models/Post/UpdatePostWebModel.cs
index ac84d2c..a0c9b61 100644
--- a/src/DevHive.Web/Models/Post/Post/UpdatePostWebModel.cs
+++ b/src/DevHive.Web/Models/Post/UpdatePostWebModel.cs
@@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http;
-namespace DevHive.Web.Models.Post.Post
+namespace DevHive.Web.Models.Post
{
public class UpdatePostWebModel
{