création et visualisation des commentaires (un css un peu rustre...)
This commit is contained in:
parent
2017b16d4c
commit
0109a54356
@ -0,0 +1,5 @@
|
|||||||
|
.textarea {
|
||||||
|
width: 50rem;
|
||||||
|
height: 8rem;
|
||||||
|
resize: none;
|
||||||
|
}
|
@ -1 +1,4 @@
|
|||||||
<p>comment-form works!</p>
|
<form [formGroup]="commentForm" (ngSubmit)="onSubmit()">
|
||||||
|
<textarea class="textarea" [(ngModel)]="commentForm.value.content" maxlength="512" formControlName="content" id="desc" pInputTextarea></textarea>
|
||||||
|
<p-button [disabled]="commentForm.invalid" type="submit" label="Envoyer"></p-button>
|
||||||
|
</form>
|
||||||
|
@ -1,12 +1,77 @@
|
|||||||
import { Component } from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
|
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
|
||||||
|
import {InputTextareaModule} from 'primeng/inputtextarea';
|
||||||
|
import {Button} from 'primeng/button';
|
||||||
|
import {CommentService} from '../../services/comment.service';
|
||||||
|
import {CookieService} from 'ngx-cookie-service';
|
||||||
|
import {Author} from '../../models/author';
|
||||||
|
import {Subscription} from 'rxjs';
|
||||||
|
import {Comment} from '../../models/comment';
|
||||||
|
import {MessageService} from 'primeng/api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-comment-form',
|
selector: 'app-comment-form',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [],
|
imports: [
|
||||||
|
ReactiveFormsModule,
|
||||||
|
InputTextareaModule,
|
||||||
|
Button
|
||||||
|
],
|
||||||
templateUrl: './comment-form.component.html',
|
templateUrl: './comment-form.component.html',
|
||||||
styleUrl: './comment-form.component.css'
|
styleUrl: './comment-form.component.css'
|
||||||
})
|
})
|
||||||
export class CommentFormComponent {
|
export class CommentFormComponent {
|
||||||
|
commentForm = new FormGroup({
|
||||||
|
content: new FormControl<string>('', [Validators.required, Validators.maxLength(512)]),
|
||||||
|
});
|
||||||
|
@Input({required: true}) postId: bigint = BigInt(1);
|
||||||
|
@Output() commentToEmit = new EventEmitter<Comment>();
|
||||||
|
subs: Subscription[] = [];
|
||||||
|
|
||||||
|
constructor(private commentService: CommentService,
|
||||||
|
private cookieService: CookieService,
|
||||||
|
private messageService: MessageService,) {
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
let token: string = this.cookieService.get("token");
|
||||||
|
let author: Author = this.cookieService.get("author") ? JSON.parse(this.cookieService.get("author")) : undefined;
|
||||||
|
if (this.commentForm.valid && author && token && this.commentForm.value.content) {
|
||||||
|
// get l'image de profile après avoir créé le commentaire
|
||||||
|
this.subs.push(this.commentService.create(this.commentForm.value.content, this.postId, author.id, token).subscribe({
|
||||||
|
next: (comment: Comment) => {
|
||||||
|
comment.authorId = author.id;
|
||||||
|
comment.authorName = author.name;
|
||||||
|
comment.profilePicture = author.profilePicture;
|
||||||
|
comment.authorRole = author.role;
|
||||||
|
this.commentForm.value.content = "";
|
||||||
|
this.commentToEmit.emit(comment);
|
||||||
|
this.successMessage("Succès", "Commentaire créé avec succès");
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
this.failureMessage("Erreur d'envois", error.message);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
successMessage(summary: string, detail: string): void {
|
||||||
|
this.messageService.add({
|
||||||
|
severity: 'success',
|
||||||
|
summary,
|
||||||
|
detail,
|
||||||
|
life: 3000,
|
||||||
|
closable: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
failureMessage(summary: string, detail: string): void {
|
||||||
|
this.messageService.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary,
|
||||||
|
detail,
|
||||||
|
life: 3000,
|
||||||
|
closable: false
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
25
src/app/components/footer/footer.component.css
Normal file
25
src/app/components/footer/footer.component.css
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.footer {
|
||||||
|
background-color: #1c1c1c;
|
||||||
|
color: #f1f1f1;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-creator,
|
||||||
|
.footer-banner,
|
||||||
|
.footer-follow,
|
||||||
|
.footer-links,
|
||||||
|
.footer-copyright {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
color: #1e90ff;
|
||||||
|
text-decoration: none;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
10
src/app/components/footer/footer.component.html
Normal file
10
src/app/components/footer/footer.component.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<footer class="footer">
|
||||||
|
<p class="footer-creator">Site web réalisé par <strong>Guams</strong>.</p>
|
||||||
|
<p class="footer-banner">Bannière réalisée par <a href="https://twitter.com/Orabiss" target="_blank" class="footer-link">@Orabiss</a> sur Twitter.</p>
|
||||||
|
<p class="footer-follow">Suivez-moi sur :</p>
|
||||||
|
<p class="footer-links">
|
||||||
|
<a href="https://x.com/Orabisss" target="_blank" class="footer-link">Twitter</a>
|
||||||
|
<a href="https://github.com/Guamss" target="_blank" class="footer-link">GitHub</a>
|
||||||
|
</p>
|
||||||
|
<p class="footer-copyright">© 2024 Guams. Tous droits réservés.</p>
|
||||||
|
</footer>
|
12
src/app/components/footer/footer.component.ts
Normal file
12
src/app/components/footer/footer.component.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-footer',
|
||||||
|
standalone: true,
|
||||||
|
imports: [],
|
||||||
|
templateUrl: './footer.component.html',
|
||||||
|
styleUrl: './footer.component.css'
|
||||||
|
})
|
||||||
|
export class FooterComponent {
|
||||||
|
|
||||||
|
}
|
@ -1,17 +1,16 @@
|
|||||||
import { Component, Input, OnDestroy } from '@angular/core';
|
import {Component, Input, OnDestroy} from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import {InputTextModule} from 'primeng/inputtext';
|
||||||
import { InputTextareaModule } from 'primeng/inputtextarea';
|
import {InputTextareaModule} from 'primeng/inputtextarea';
|
||||||
import { FileSelectEvent, FileUploadModule } from 'primeng/fileupload';
|
import {FileSelectEvent, FileUploadModule} from 'primeng/fileupload';
|
||||||
import {mergeMap, Subscription} from 'rxjs';
|
import {mergeMap, Subscription} from 'rxjs';
|
||||||
import { PostService } from '../../services/post.service';
|
import {PostService} from '../../services/post.service';
|
||||||
import { CookieService } from 'ngx-cookie-service';
|
import {CookieService} from 'ngx-cookie-service';
|
||||||
import { MessageService } from 'primeng/api';
|
import {MessageService} from 'primeng/api';
|
||||||
import { EditorModule } from 'primeng/editor';
|
import {EditorModule} from 'primeng/editor';
|
||||||
import { Router } from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {Author} from '../../models/author';
|
import {Author} from '../../models/author';
|
||||||
import {AuthorService} from '../../services/author.service';
|
import {AuthorService} from '../../services/author.service';
|
||||||
import {JsonPipe} from '@angular/common';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-post-form',
|
selector: 'app-post-form',
|
||||||
@ -21,8 +20,7 @@ import {JsonPipe} from '@angular/common';
|
|||||||
InputTextModule,
|
InputTextModule,
|
||||||
InputTextareaModule,
|
InputTextareaModule,
|
||||||
FileUploadModule,
|
FileUploadModule,
|
||||||
EditorModule,
|
EditorModule
|
||||||
JsonPipe
|
|
||||||
],
|
],
|
||||||
templateUrl: './post-form.component.html',
|
templateUrl: './post-form.component.html',
|
||||||
styleUrls: ['./post-form.component.css']
|
styleUrls: ['./post-form.component.css']
|
||||||
@ -41,8 +39,8 @@ export class PostFormComponent implements OnDestroy {
|
|||||||
editorModules = {
|
editorModules = {
|
||||||
toolbar: [
|
toolbar: [
|
||||||
['bold', 'italic', 'underline', 'code'], // Styles de texte
|
['bold', 'italic', 'underline', 'code'], // Styles de texte
|
||||||
[{ header: [2, false] }], // Permet d'ajouter un `<h2>`
|
[{header: [2, false]}], // Permet d'ajouter un `<h2>`
|
||||||
[{ list: 'ordered' }, { list: 'bullet' }], // Listes
|
[{list: 'ordered'}, {list: 'bullet'}], // Listes
|
||||||
['link', 'image', 'video'], // Ajout de liens et images
|
['link', 'image', 'video'], // Ajout de liens et images
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -6,3 +6,33 @@ img {
|
|||||||
display: block;
|
display: block;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-profile {
|
||||||
|
display: flex;
|
||||||
|
align-self: flex-start;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
text-align: justify;
|
||||||
|
text-justify: inter-word;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
@ -1,8 +1,19 @@
|
|||||||
<p-card>
|
<p-card>
|
||||||
<img src="data:image/jpeg;base64,{{ illustration }}"/>
|
<img src="data:image/jpeg;base64,{{ illustration }}"/>
|
||||||
|
<div class="content">
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
<p>{{ category }}</p>
|
<span>{{ category }}</span>
|
||||||
<em>Publié le {{ date | date : "dd/MM/yyyy à HH:mm" }}</em>
|
<em>Publié le {{ date | date : "dd/MM/yyyy à HH:mm" }}</em>
|
||||||
<p>{{ description }}</p>
|
<span class="desc">{{ description }}</span>
|
||||||
<p-button routerLink="post/{{ postId }}" label="Lire la suite"/>
|
<p-button routerLink="post/{{ postId }}" label="Lire la suite"/>
|
||||||
|
<a routerLink="/profile/{{ authorId }}" class="user-profile">
|
||||||
|
@if (authorProfilePicture !== "") {
|
||||||
|
<p-avatar image="data:image/jpeg;base64,{{ authorProfilePicture }}" shape="circle" styleClass="mr-2"
|
||||||
|
size="xlarge"></p-avatar>
|
||||||
|
} @else {
|
||||||
|
<p-avatar label="{{ username.charAt(0).toUpperCase() }}" styleClass="mr-2" size="xlarge"></p-avatar>
|
||||||
|
}
|
||||||
|
<span style="font-size: 20px;">{{ username }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</p-card>
|
</p-card>
|
||||||
|
@ -3,6 +3,7 @@ import {Button} from 'primeng/button';
|
|||||||
import {CardModule} from 'primeng/card';
|
import {CardModule} from 'primeng/card';
|
||||||
import {DatePipe} from '@angular/common';
|
import {DatePipe} from '@angular/common';
|
||||||
import {RouterLink} from '@angular/router';
|
import {RouterLink} from '@angular/router';
|
||||||
|
import {AvatarModule} from 'primeng/avatar';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-post-home',
|
selector: 'app-post-home',
|
||||||
@ -11,12 +12,15 @@ import {RouterLink} from '@angular/router';
|
|||||||
Button,
|
Button,
|
||||||
CardModule,
|
CardModule,
|
||||||
DatePipe,
|
DatePipe,
|
||||||
RouterLink
|
RouterLink,
|
||||||
|
AvatarModule
|
||||||
],
|
],
|
||||||
templateUrl: './post-home.component.html',
|
templateUrl: './post-home.component.html',
|
||||||
styleUrl: './post-home.component.css'
|
styleUrl: './post-home.component.css'
|
||||||
})
|
})
|
||||||
export class PostHomeComponent {
|
export class PostHomeComponent {
|
||||||
|
@Input() authorProfilePicture: string = '';
|
||||||
|
@Input() authorId: string = '';
|
||||||
@Input() postId: bigint = BigInt(0);
|
@Input() postId: bigint = BigInt(0);
|
||||||
@Input() title: string = '';
|
@Input() title: string = '';
|
||||||
@Input() illustration: string = '';
|
@Input() illustration: string = '';
|
||||||
@ -24,7 +28,6 @@ export class PostHomeComponent {
|
|||||||
@Input() date: Date | undefined;
|
@Input() date: Date | undefined;
|
||||||
@Input() description: string = '';
|
@Input() description: string = '';
|
||||||
@Input() username: string = '';
|
@Input() username: string = '';
|
||||||
@Input() avatar: string = '';
|
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
}
|
}
|
||||||
|
14
src/app/models/author-with-post.ts
Normal file
14
src/app/models/author-with-post.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export interface AuthorWithPost {
|
||||||
|
authorId: string;
|
||||||
|
authorName: string;
|
||||||
|
authorProfilePicture: string;
|
||||||
|
role: string;
|
||||||
|
postId: bigint;
|
||||||
|
postDescription: string;
|
||||||
|
postIllustration: string;
|
||||||
|
postTitle: string;
|
||||||
|
postBody: string;
|
||||||
|
postCategory: string;
|
||||||
|
postPublicationDate: Date;
|
||||||
|
postIsUpdated: boolean;
|
||||||
|
}
|
@ -5,3 +5,9 @@
|
|||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
@if (posts.length) {
|
@if (posts.length) {
|
||||||
@for (post of posts; track post.id) {
|
@for (post of posts; track post.postId) {
|
||||||
<app-post-home [illustration]="post.illustration"
|
<app-post-home [illustration]="post.postIllustration"
|
||||||
[date]="post.publicationDate"
|
[date]="post.postPublicationDate"
|
||||||
[postId]="post.id"
|
[postId]="post.postId"
|
||||||
[category]="post.category"
|
[category]="post.postCategory"
|
||||||
[title]="post.title"
|
[title]="post.postTitle"
|
||||||
[username]="'Guams'"
|
[username]="post.authorName"
|
||||||
[description]="post.description"/>
|
[description]="post.postDescription"
|
||||||
|
[authorId]="post.authorId"
|
||||||
|
[authorProfilePicture]="post.authorProfilePicture"/>
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
<h1>Aucun post n'a été créé pour l'instant</h1>
|
<h1>Aucun post n'a été créé pour l'instant</h1>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
<app-footer></app-footer>
|
||||||
|
@ -12,6 +12,8 @@ import {CookieService} from 'ngx-cookie-service';
|
|||||||
import {PostService} from '../../services/post.service';
|
import {PostService} from '../../services/post.service';
|
||||||
import {Post} from '../../models/post';
|
import {Post} from '../../models/post';
|
||||||
import {PostHomeComponent} from '../../components/post-home/post-home.component';
|
import {PostHomeComponent} from '../../components/post-home/post-home.component';
|
||||||
|
import {AuthorWithPost} from '../../models/author-with-post';
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
@ -20,14 +22,15 @@ import {PostHomeComponent} from '../../components/post-home/post-home.component'
|
|||||||
AvatarModule,
|
AvatarModule,
|
||||||
HeaderComponent,
|
HeaderComponent,
|
||||||
ToastModule,
|
ToastModule,
|
||||||
PostHomeComponent
|
PostHomeComponent,
|
||||||
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './home.component.html',
|
templateUrl: './home.component.html',
|
||||||
styleUrl: './home.component.css'
|
styleUrl: './home.component.css'
|
||||||
})
|
})
|
||||||
export class HomeComponent implements OnDestroy {
|
export class HomeComponent implements OnDestroy {
|
||||||
actualAuthor: Author | undefined;
|
actualAuthor: Author | undefined;
|
||||||
posts: Post[] = []
|
posts: AuthorWithPost[] = []
|
||||||
subs: Subscription[] = []
|
subs: Subscription[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -37,12 +40,12 @@ export class HomeComponent implements OnDestroy {
|
|||||||
if (this.cookieService.get('author')) {
|
if (this.cookieService.get('author')) {
|
||||||
this.actualAuthor = JSON.parse(this.cookieService.get('author'));
|
this.actualAuthor = JSON.parse(this.cookieService.get('author'));
|
||||||
}
|
}
|
||||||
this.subs.push(this.postService.list()
|
this.subs.push(this.postService.listWithAuthors()
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (posts: Post[]) => this.posts = posts.sort((a, b) => {
|
next: (posts: AuthorWithPost[]) => this.posts = posts.sort((a, b) => {
|
||||||
if (a.publicationDate < b.publicationDate) {
|
if (a.postPublicationDate > b.postPublicationDate) {
|
||||||
return -1
|
return -1
|
||||||
} else if (a.publicationDate > b.publicationDate) {
|
} else if (a.postPublicationDate < b.postPublicationDate) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
@ -16,3 +16,4 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<app-footer></app-footer>
|
||||||
|
@ -10,6 +10,7 @@ import {Subscription, switchMap} from 'rxjs';
|
|||||||
import { CookieService } from 'ngx-cookie-service';
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
import {HeaderComponent} from '../../components/header/header.component';
|
import {HeaderComponent} from '../../components/header/header.component';
|
||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
@ -19,7 +20,8 @@ import {Router} from '@angular/router';
|
|||||||
InputTextModule,
|
InputTextModule,
|
||||||
Button,
|
Button,
|
||||||
ToastModule,
|
ToastModule,
|
||||||
HeaderComponent
|
HeaderComponent,
|
||||||
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
styleUrl: './login.component.css'
|
styleUrl: './login.component.css'
|
||||||
|
@ -20,9 +20,8 @@ export class LogoutComponent implements OnInit{
|
|||||||
private router: Router) { }
|
private router: Router) { }
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// this.cookiesService.deleteAll("/", "localhost"); // deleteAll est bugué
|
// this.cookiesService.deleteAll("/", "localhost"); // deleteAll est bugué
|
||||||
this.cookiesService.delete('author')
|
this.cookiesService.delete('author', '/', 'localhost')
|
||||||
this.cookiesService.delete('just-authenticated')
|
this.cookiesService.delete('token', '/', 'localhost')
|
||||||
this.cookiesService.delete('token')
|
|
||||||
this.router.navigate(['/']).then(() => this.successMessage('Déconnexion', 'Vous avez été deconnecté avec succès'));
|
this.router.navigate(['/']).then(() => this.successMessage('Déconnexion', 'Vous avez été deconnecté avec succès'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,3 +66,4 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</p-table>
|
</p-table>
|
||||||
|
<app-footer></app-footer>
|
||||||
|
@ -14,6 +14,7 @@ import {InputTextModule} from 'primeng/inputtext';
|
|||||||
import {PostHomeComponent} from '../../components/post-home/post-home.component';
|
import {PostHomeComponent} from '../../components/post-home/post-home.component';
|
||||||
import {PostService} from '../../services/post.service';
|
import {PostService} from '../../services/post.service';
|
||||||
import {PostFormComponent} from "../../components/post-form/post-form.component";
|
import {PostFormComponent} from "../../components/post-form/post-form.component";
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-my-posts',
|
selector: 'app-my-posts',
|
||||||
@ -26,7 +27,8 @@ import {PostFormComponent} from "../../components/post-form/post-form.component"
|
|||||||
DialogModule,
|
DialogModule,
|
||||||
InputTextModule,
|
InputTextModule,
|
||||||
PostHomeComponent,
|
PostHomeComponent,
|
||||||
PostFormComponent
|
PostFormComponent,
|
||||||
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './my-posts.component.html',
|
templateUrl: './my-posts.component.html',
|
||||||
styleUrl: './my-posts.component.css'
|
styleUrl: './my-posts.component.css'
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<app-post-form [actualAuthor]="actualAuthor"/>
|
<app-post-form [actualAuthor]="actualAuthor"/>
|
||||||
|
<app-footer></app-footer>
|
||||||
|
@ -14,6 +14,7 @@ import {AuthorService} from '../../services/author.service';
|
|||||||
import {Author} from '../../models/author';
|
import {Author} from '../../models/author';
|
||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {PostFormComponent} from '../../components/post-form/post-form.component';
|
import {PostFormComponent} from '../../components/post-form/post-form.component';
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-new-post',
|
selector: 'app-new-post',
|
||||||
@ -25,7 +26,8 @@ import {PostFormComponent} from '../../components/post-form/post-form.component'
|
|||||||
InputTextareaModule,
|
InputTextareaModule,
|
||||||
FileUploadModule,
|
FileUploadModule,
|
||||||
EditorModule,
|
EditorModule,
|
||||||
PostFormComponent
|
PostFormComponent,
|
||||||
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './new-post.component.html',
|
templateUrl: './new-post.component.html',
|
||||||
styleUrl: './new-post.component.css'
|
styleUrl: './new-post.component.css'
|
||||||
|
@ -15,6 +15,7 @@ em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep p {
|
::ng-deep p {
|
||||||
|
word-break: break-word;
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
text-justify: inter-word;
|
text-justify: inter-word;
|
||||||
}
|
}
|
||||||
@ -58,6 +59,8 @@ em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.commentaires {
|
.commentaires {
|
||||||
|
margin: auto;
|
||||||
|
width: 45%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<div class="title-div">
|
@if (concernedPost) {
|
||||||
|
<div class="title-div">
|
||||||
<h1>{{ concernedPost?.title }}</h1>
|
<h1>{{ concernedPost?.title }}</h1>
|
||||||
<em>Publié le {{ concernedPost?.publicationDate | date: "dd/MM/yyyy à HH:mm" }}</em>
|
<em>Publié le {{ concernedPost.publicationDate | date: "dd/MM/yyyy à HH:mm" }}</em>
|
||||||
</div>
|
</div>
|
||||||
<div [innerHTML]="concernedPost?.body | safeHtml" class="body-content"></div>
|
<div [innerHTML]="concernedPost.body | safeHtml" class="body-content"></div>
|
||||||
<div class="commentaires">
|
<div class="commentaires">
|
||||||
<h1>Commentaires</h1>
|
<h1>Commentaires</h1>
|
||||||
@if (actualAuthor) {
|
@if (actualAuthor) {
|
||||||
{{actualAuthor | json}}
|
<app-comment-form [postId]="concernedPost.id" (commentToEmit)="addNewCommentToList($event)"></app-comment-form>
|
||||||
<app-comment-form></app-comment-form>
|
|
||||||
}
|
}
|
||||||
@for (comment of comments; track comment.id) {
|
@for (comment of comments; track comment.id) {
|
||||||
@if (comment.profilePicture) {
|
@if (comment.profilePicture) {
|
||||||
<div class="comment-div">
|
<div class="comment-div">
|
||||||
<p-avatar image="data:image/jpeg;base64,{{ comment.profilePicture }}" styleClass="mr-2" size="large"></p-avatar>
|
<p-avatar image="data:image/jpeg;base64,{{ comment.profilePicture }}" shape="circle" styleClass="mr-2"
|
||||||
|
size="large"></p-avatar>
|
||||||
<em>{{ comment.authorName }}</em>
|
<em>{{ comment.authorName }}</em>
|
||||||
<p class="{{ comment.authorRole }}">- {{ comment.authorRole }}</p>
|
<p class="{{ comment.authorRole }}">- {{ comment.authorRole }}</p>
|
||||||
@if (comment.isUpdated) {
|
@if (comment.isUpdated) {
|
||||||
@ -36,4 +37,8 @@
|
|||||||
}
|
}
|
||||||
<p>{{ comment.content }}</p>
|
<p>{{ comment.content }}</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
<app-footer></app-footer>
|
||||||
|
} @else {
|
||||||
|
<h1>Loading...</h1>
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@ import {forkJoin, Subscription} from 'rxjs';
|
|||||||
import {Post} from '../../models/post';
|
import {Post} from '../../models/post';
|
||||||
import {PostService} from '../../services/post.service';
|
import {PostService} from '../../services/post.service';
|
||||||
import {HeaderComponent} from '../../components/header/header.component';
|
import {HeaderComponent} from '../../components/header/header.component';
|
||||||
import {DatePipe, JsonPipe} from '@angular/common';
|
import {DatePipe} from '@angular/common';
|
||||||
import {CommentService} from '../../services/comment.service';
|
import {CommentService} from '../../services/comment.service';
|
||||||
import {MessageService} from 'primeng/api';
|
import {MessageService} from 'primeng/api';
|
||||||
import {Comment} from '../../models/comment';
|
import {Comment} from '../../models/comment';
|
||||||
@ -14,6 +14,7 @@ import {SafeHtmlPipe} from '../../pipes/safe-html-pipe';
|
|||||||
import {CookieService} from 'ngx-cookie-service';
|
import {CookieService} from 'ngx-cookie-service';
|
||||||
import {Author} from '../../models/author';
|
import {Author} from '../../models/author';
|
||||||
import {CommentFormComponent} from '../../components/comment-form/comment-form.component';
|
import {CommentFormComponent} from '../../components/comment-form/comment-form.component';
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-post',
|
selector: 'app-post',
|
||||||
@ -25,7 +26,7 @@ import {CommentFormComponent} from '../../components/comment-form/comment-form.c
|
|||||||
CardModule,
|
CardModule,
|
||||||
SafeHtmlPipe,
|
SafeHtmlPipe,
|
||||||
CommentFormComponent,
|
CommentFormComponent,
|
||||||
JsonPipe
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './post.component.html',
|
templateUrl: './post.component.html',
|
||||||
styleUrl: './post.component.css'
|
styleUrl: './post.component.css'
|
||||||
@ -56,10 +57,11 @@ export class PostComponent {
|
|||||||
next: res => {
|
next: res => {
|
||||||
res.post.body = res.post.body.replace(/ /g, ' ')
|
res.post.body = res.post.body.replace(/ /g, ' ')
|
||||||
this.concernedPost = res.post;
|
this.concernedPost = res.post;
|
||||||
|
this.sortCommentList(res.comment)
|
||||||
this.comments = res.comment.sort((a, b) => {
|
this.comments = res.comment.sort((a, b) => {
|
||||||
if (a.commentDate < b.commentDate) {
|
if (a.commentDate > b.commentDate) {
|
||||||
return -1
|
return -1
|
||||||
} else if (a.commentDate > b.commentDate) {
|
} else if (a.commentDate < b.commentDate) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@ -74,6 +76,22 @@ export class PostComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addNewCommentToList(comment: Comment) {
|
||||||
|
this.comments.push(comment);
|
||||||
|
this.sortCommentList(this.comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
sortCommentList(comments: Comment[]) {
|
||||||
|
comments.sort((a, b) => {
|
||||||
|
if (a.commentDate > b.commentDate) {
|
||||||
|
return -1
|
||||||
|
} else if (a.commentDate < b.commentDate) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
failureMessage(summary: string, detail: string): void {
|
failureMessage(summary: string, detail: string): void {
|
||||||
this.messageService.add({
|
this.messageService.add({
|
||||||
severity: 'error',
|
severity: 'error',
|
||||||
|
@ -37,3 +37,4 @@
|
|||||||
} @else {
|
} @else {
|
||||||
<h1>Loading...</h1>
|
<h1>Loading...</h1>
|
||||||
}
|
}
|
||||||
|
<app-footer></app-footer>
|
||||||
|
@ -10,6 +10,7 @@ import {CardModule} from 'primeng/card';
|
|||||||
import {Button} from 'primeng/button';
|
import {Button} from 'primeng/button';
|
||||||
import {DialogModule} from 'primeng/dialog';
|
import {DialogModule} from 'primeng/dialog';
|
||||||
import {UpdateProfileFormComponent} from '../../components/update-profile-form/update-profile-form.component';
|
import {UpdateProfileFormComponent} from '../../components/update-profile-form/update-profile-form.component';
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-profile',
|
selector: 'app-profile',
|
||||||
@ -20,7 +21,8 @@ import {UpdateProfileFormComponent} from '../../components/update-profile-form/u
|
|||||||
CardModule,
|
CardModule,
|
||||||
Button,
|
Button,
|
||||||
DialogModule,
|
DialogModule,
|
||||||
UpdateProfileFormComponent
|
UpdateProfileFormComponent,
|
||||||
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './profile.component.html',
|
templateUrl: './profile.component.html',
|
||||||
styleUrl: './profile.component.css'
|
styleUrl: './profile.component.css'
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<app-register-form [adminForm]="false"></app-register-form>
|
<app-register-form [adminForm]="false"></app-register-form>
|
||||||
|
<app-footer></app-footer>
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {HeaderComponent} from '../../components/header/header.component';
|
import {HeaderComponent} from '../../components/header/header.component';
|
||||||
import {RegisterFormComponent} from '../../components/register-form/register-form.component';
|
import {RegisterFormComponent} from '../../components/register-form/register-form.component';
|
||||||
|
import {Footer} from "primeng/api";
|
||||||
|
import {FooterComponent} from '../../components/footer/footer.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-register',
|
selector: 'app-register',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
HeaderComponent,
|
HeaderComponent,
|
||||||
RegisterFormComponent
|
RegisterFormComponent,
|
||||||
|
Footer,
|
||||||
|
FooterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './register.component.html',
|
templateUrl: './register.component.html',
|
||||||
styleUrl: './register.component.css'
|
styleUrl: './register.component.css'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {HttpClient} from '@angular/common/http';
|
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {Comment} from '../models/comment';
|
import {Comment} from '../models/comment';
|
||||||
|
|
||||||
@ -14,8 +14,13 @@ export class CommentService {
|
|||||||
return this.httpClient.get<Comment[]>(`${this.url}/posts/${postId}`);
|
return this.httpClient.get<Comment[]>(`${this.url}/posts/${postId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
create(content: string, postId: bigint, authorId: string): Observable<Comment> {
|
create(content: string, postId: bigint, authorId: string, token: string): Observable<Comment> {
|
||||||
return this.httpClient.post<Comment>(`${this.url}/posts/${postId}`, {postId: postId, authorId: authorId, content: content});
|
const httpOptions = {
|
||||||
|
headers: new HttpHeaders({
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return this.httpClient.post<Comment>(`${this.url}/posts/${postId}`, {postId: postId, authorId: authorId, content: content}, httpOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {Post} from '../models/post';
|
import {Post} from '../models/post';
|
||||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||||
|
import {AuthorWithPost} from '../models/author-with-post';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -14,6 +15,10 @@ export class PostService {
|
|||||||
return this.httpClient.get<Post[]>(this.url);
|
return this.httpClient.get<Post[]>(this.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listWithAuthors(): Observable<AuthorWithPost[]> {
|
||||||
|
return this.httpClient.get<AuthorWithPost[]>(`${this.url}/authors`);
|
||||||
|
}
|
||||||
|
|
||||||
getPost(id: bigint) {
|
getPost(id: bigint) {
|
||||||
return this.httpClient.get<Post>(`${this.url}/${id}`);
|
return this.httpClient.get<Post>(`${this.url}/${id}`);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user