diff --git a/src/main/ts-v7/src/app/app.module.ts b/src/main/ts-v7/src/app/app.module.ts index c8ec347..d7309da 100755 --- a/src/main/ts-v7/src/app/app.module.ts +++ b/src/main/ts-v7/src/app/app.module.ts @@ -14,6 +14,9 @@ import { appRoutes } from './app.routing'; // Guard import { AuthGuard } from './core/guards/auth.guard'; +// Interceptor +import { UnauthorizedInterceptor } from './core/interceptors/unauthorized.interceptor'; + // Components import { AppComponent } from './app.component'; import { HeaderComponent } from './header/header.component'; @@ -24,6 +27,7 @@ import { MyPostsComponent } from './posts/myPosts/my-posts.component'; import { AccountSettingsComponent } from './account-settings/account-settings.component'; import { ChangePasswordComponent } from './account-settings/change-password/change-password.component'; import { ProfilEditionComponent } from './account-settings/profil-edition/profil-edition.component'; +import { PostComponent } from './posts/post.component'; // Reusable components import { PostCardComponent } from './core/post-card/post-card.component'; @@ -37,7 +41,7 @@ import { LoginService } from './login/login.service'; import { MyPostsService } from './posts/myPosts/my-posts.service'; import { ChangePasswordService } from './account-settings/change-password/change-password.service'; import { ProfilEditionService } from './account-settings/profil-edition/profil-edition.service'; -import { UnauthorizedInterceptor } from './core/interceptors/unauthorized.interceptor'; +import { PostService } from './posts/post.service'; @NgModule({ declarations: [ @@ -51,7 +55,8 @@ import { UnauthorizedInterceptor } from './core/interceptors/unauthorized.interc MyPostsComponent, AccountSettingsComponent, ChangePasswordComponent, - ProfilEditionComponent + ProfilEditionComponent, + PostComponent ], imports: [ BrowserModule, @@ -74,6 +79,7 @@ import { UnauthorizedInterceptor } from './core/interceptors/unauthorized.interc MyPostsService, ChangePasswordService, ProfilEditionService, + PostService, { provide: HTTP_INTERCEPTORS, useClass: UnauthorizedInterceptor, multi: true } ], bootstrap: [AppComponent] diff --git a/src/main/ts-v7/src/app/app.routing.ts b/src/main/ts-v7/src/app/app.routing.ts index 7208af0..303d3bf 100755 --- a/src/main/ts-v7/src/app/app.routing.ts +++ b/src/main/ts-v7/src/app/app.routing.ts @@ -9,6 +9,7 @@ import { MyPostsComponent } from './posts/myPosts/my-posts.component'; import { AccountSettingsComponent } from './account-settings/account-settings.component'; import { ChangePasswordComponent } from './account-settings/change-password/change-password.component'; import { ProfilEditionComponent } from './account-settings/profil-edition/profil-edition.component'; +import { PostComponent } from './posts/post.component'; export const appRoutes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, @@ -19,5 +20,6 @@ export const appRoutes: Routes = [ { path: 'accountSettings', component: AccountSettingsComponent, canActivate: [AuthGuard] }, { path: 'changePassword', component: ChangePasswordComponent, canActivate: [AuthGuard] }, { path: 'profilEdit', component: ProfilEditionComponent, canActivate: [AuthGuard] }, + { path: 'posts/:postKey', component: PostComponent }, { path: '**', redirectTo: '/home' } ]; diff --git a/src/main/ts-v7/src/app/posts/post.component.html b/src/main/ts-v7/src/app/posts/post.component.html new file mode 100644 index 0000000..220815d --- /dev/null +++ b/src/main/ts-v7/src/app/posts/post.component.html @@ -0,0 +1,67 @@ +
+ +
+ Post image + + + + + +
+

{{post.title}}

+

{{post.description}}

+
+
+
+ +
+ + Article écrit par {{post.author.name}} + ({{post.creationDate | date:'HH:mm:ss dd/MM/yyyy'}}) + +
+
+ + +
+ diff --git a/src/main/ts-v7/src/app/posts/post.component.ts b/src/main/ts-v7/src/app/posts/post.component.ts new file mode 100644 index 0000000..91bf943 --- /dev/null +++ b/src/main/ts-v7/src/app/posts/post.component.ts @@ -0,0 +1,106 @@ +import { Component, OnInit, SecurityContext, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { HttpErrorResponse } from '@angular/common/http'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; + +import { Post, User } from '../core/entities'; +import { PostService } from './post.service'; +import { AuthService } from '../core/services/auth.service'; + +declare let Prism: any; + +@Component({ + selector: 'app-post', + templateUrl: './post.component.html', + styles: [` + .author-img { + width: 60px; + height: 60px; + border-radius: 50%; + margin-right: 15px; + } + .card .card-data { + padding: 15px; + background-color: #f5f5f5; + } + #content { + margin-bottom: 50px; + } + .creation-date-area { + color: #bdbdbd; + font-style: italic; + } + `] +}) +export class PostComponent implements OnInit { + post: Post = new Post('', '', '', '', '', null, new User('', '', '', '', '', null, null, ''), null); + loaded: boolean; + notFound: boolean; + owned: boolean; + + @ViewChild('alertDelete') alertDelete; + + postDeletionFailed: boolean; + + constructor( + private activatedRoute: ActivatedRoute, + private router: Router, + private postService: PostService, + private sanitizer: DomSanitizer, + private authService: AuthService + ) { + this.loaded = false; + this.owned = false; + this.postDeletionFailed = false; + } + + ngOnInit(): void { + this.postService.getPost(this.activatedRoute.snapshot.paramMap.get('postKey')).subscribe(post => { + this.post = post; + this.loaded = true; + this.owned = this.isOwned(); + setTimeout(() => { + Prism.highlightAll(); + }, 100); + }, error => { + if (error instanceof HttpErrorResponse && error.status === 404) { + this.notFound = true; + } + }); + } + + private isOwned(): boolean { + let result = false; + + const connectedUser = this.authService.getUser(); + if (connectedUser) { + result = this.post.author.key === connectedUser.key; + } + + return result; + } + + getContent(): SafeHtml { + return this.sanitizer.sanitize(SecurityContext.HTML, this.post.text); + } + + getAvatarUrl(): string { + return this.post.author.image + ? `./api/images/loadAvatar/${this.post.author.image}` + : './assets/images/default_user.png'; + } + + deletePost(): void { + this.postDeletionFailed = false; + + this.postService.deletePost(this.post).subscribe(() => { + this.alertDelete.hide(); + this.router.navigate(['/myPosts']); + }, error => { + this.postDeletionFailed = true; + setTimeout(() => { + this.postDeletionFailed = false; + }, 3500); + }); + } +} diff --git a/src/main/ts-v7/src/app/posts/post.service.ts b/src/main/ts-v7/src/app/posts/post.service.ts new file mode 100644 index 0000000..e2630d3 --- /dev/null +++ b/src/main/ts-v7/src/app/posts/post.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Post } from '../core/entities'; + +@Injectable() +export class PostService { + + constructor(private http: HttpClient) {} + + getPost(postKey: string): Observable { + return this.http.get(`/api/posts/${postKey}`); + } + + deletePost(postToDelete: Post): Observable { + return this.http.delete(`/api/posts/${postToDelete.key}`); + } +}