diff --git a/src/app/guards/admin.guard.ts b/src/app/guards/admin.guard.ts
new file mode 100644
index 0000000..2508747
--- /dev/null
+++ b/src/app/guards/admin.guard.ts
@@ -0,0 +1,18 @@
+import {CanActivateFn, Router} from '@angular/router';
+import {inject} from '@angular/core';
+import {CookieService} from 'ngx-cookie-service';
+import {Author} from '../models/author';
+
+export const adminGuard: CanActivateFn = (route, state) => {
+ const router = inject(Router);
+ const cookieService = inject(CookieService);
+
+ if (cookieService.get("author") !== '') {
+ if (JSON.parse(cookieService.get("author")).role !== 'ADMIN')
+ {
+ router.navigate(['/']);
+ }
+ }
+
+ return true;
+};
diff --git a/src/app/guards/writer.guard.ts b/src/app/guards/writer.guard.ts
new file mode 100644
index 0000000..6bb0526
--- /dev/null
+++ b/src/app/guards/writer.guard.ts
@@ -0,0 +1,17 @@
+import {CanActivateFn, Router} from '@angular/router';
+import {inject} from '@angular/core';
+import {CookieService} from 'ngx-cookie-service';
+
+export const writerGuard: CanActivateFn = (route, state) => {
+ const router = inject(Router);
+ const cookieService = inject(CookieService);
+
+ if (cookieService.get("author") !== '') {
+ if (JSON.parse(cookieService.get("author")).role !== 'WRITER' && JSON.parse(cookieService.get("author")).role !== 'ADMIN')
+ {
+ router.navigate(['/']);
+ }
+ }
+
+ return true;
+};
diff --git a/src/app/new-post/new-post.component.css b/src/app/new-post/new-post.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/new-post/new-post.component.html b/src/app/new-post/new-post.component.html
new file mode 100644
index 0000000..8e8c432
--- /dev/null
+++ b/src/app/new-post/new-post.component.html
@@ -0,0 +1,23 @@
+
+
+
+
diff --git a/src/app/new-post/new-post.component.ts b/src/app/new-post/new-post.component.ts
new file mode 100644
index 0000000..3a3f34d
--- /dev/null
+++ b/src/app/new-post/new-post.component.ts
@@ -0,0 +1,100 @@
+import {Component, OnDestroy} from '@angular/core';
+import {HeaderComponent} from '../header/header.component';
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
+import {InputTextModule} from 'primeng/inputtext';
+import {InputTextareaModule} from 'primeng/inputtextarea';
+import {FileSelectEvent, FileUploadModule} from 'primeng/fileupload';
+import {mergeMap, Subscription, switchMap} from 'rxjs';
+import {Post} from '../models/post';
+import {PostService} from '../services/post.service';
+import {CookieService} from 'ngx-cookie-service';
+import {MessageService} from 'primeng/api';
+import {EditorModule} from 'primeng/editor';
+import {AuthorService} from '../services/author.service';
+import {Author} from '../models/author';
+
+@Component({
+ selector: 'app-new-post',
+ standalone: true,
+ imports: [
+ HeaderComponent,
+ ReactiveFormsModule,
+ InputTextModule,
+ InputTextareaModule,
+ FileUploadModule,
+ EditorModule
+ ],
+ templateUrl: './new-post.component.html',
+ styleUrl: './new-post.component.css'
+})
+export class NewPostComponent implements OnDestroy {
+ subs: Subscription[] = []
+ actualAuthor: Author | undefined;
+ uploadedFile: File | undefined;
+ form: FormGroup = new FormGroup({
+ description: new FormControl('', [Validators.required, Validators.maxLength(512)]),
+ title: new FormControl('', [Validators.required, Validators.maxLength(50)]),
+ body: new FormControl('', [Validators.required]),
+ category: new FormControl('', [Validators.required, Validators.maxLength(50)]),
+ });
+
+ constructor(private postService: PostService,
+ private cookieService: CookieService,
+ private authorService: AuthorService,
+ private messageService: MessageService,) {
+ this.actualAuthor = JSON.parse(this.cookieService.get("author"));
+ }
+
+ onSelected(event: FileSelectEvent) {
+ if (event.currentFiles && event.currentFiles.length > 0) {
+ this.uploadedFile = event.currentFiles[0];
+ }
+ }
+
+ onSubmit() {
+ const formData = this.form.value;
+
+ if (this.uploadedFile) {
+ const postToPost: any = { // LOL
+ body: formData.body as string,
+ description: formData.description as string,
+ title: formData.title as string,
+ category: formData.category as string
+ };
+
+ this.subs.push(
+ this.postService.createPost(postToPost, this.cookieService.get("token")).pipe(
+ mergeMap(post =>
+ this.authorService.attributePost(this.actualAuthor?.id, post.id, this.cookieService.get("token")).pipe(
+ mergeMap((_) =>
+ this.postService.changeIllustration(post.id, this.uploadedFile, this.cookieService.get("token"))
+ )
+ )
+ )
+ ).subscribe({
+ next: () => {
+ console.log('Post créé, attribué et illustration changée avec succès.');
+ },
+ error: (err) => {
+ this.failureMessage('Erreur', err.message);
+ }
+ })
+ );
+ }
+ }
+
+ failureMessage(summary: string, detail: string): void {
+ this.messageService.add({
+ severity: 'error',
+ summary: summary,
+ detail: detail,
+ life: 3000,
+ closable: false
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.subs.forEach(sub => sub.unsubscribe());
+ }
+
+}
diff --git a/src/app/services/author.service.ts b/src/app/services/author.service.ts
index 12a4f7f..a5996b8 100644
--- a/src/app/services/author.service.ts
+++ b/src/app/services/author.service.ts
@@ -23,7 +23,16 @@ export class AuthorService {
return this.httpClient.get("http://localhost:8080/api/authors/me", {'headers': headers});
}
- getAuthor(id: string | null): Observable {
+ attributePost(authorId: string | undefined, postId: bigint, token: string) {
+ const httpOptions = {
+ headers: new HttpHeaders({
+ 'Authorization': `Bearer ${token}`
+ })
+ };
+ return this.httpClient.put(`http://localhost:8080/api/authors/${authorId}/posts`, postId, httpOptions);
+ }
+
+ getAuthor(id: string | undefined): Observable {
if (id) {
return this.httpClient.get("http://localhost:8080/api/authors/" + id);
} else {
diff --git a/src/app/services/post.service.ts b/src/app/services/post.service.ts
index 7138f07..929d91c 100644
--- a/src/app/services/post.service.ts
+++ b/src/app/services/post.service.ts
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs';
import {Post} from '../models/post';
-import {HttpClient} from '@angular/common/http';
+import {HttpClient, HttpHeaders} from '@angular/common/http';
@Injectable({
providedIn: 'root'
@@ -11,6 +11,25 @@ export class PostService {
constructor(private httpClient: HttpClient) {}
list(): Observable {
- return this.httpClient.get("http://localhost:8080/api/posts");
+ return this.httpClient.get(this.url);
}
+
+ createPost(post: any, token: string | undefined): Observable {
+ const httpOptions = {
+ headers: new HttpHeaders({
+ 'Authorization': `Bearer ${token}`
+ })
+ };
+ return this.httpClient.post(this.url, post, httpOptions);
+ }
+
+ changeIllustration(id: bigint, image: File | undefined, token: string): Observable {
+ const httpOptions = {
+ headers: new HttpHeaders({
+ 'Authorization': `Bearer ${token}`
+ })
+ };
+ return this.httpClient.put(`${this.url}/${id}`, image, httpOptions);
+ }
+
}
diff --git a/src/styles.css b/src/styles.css
index 4d9e7e7..e0eb2ba 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -1,2 +1,4 @@
@import '../node_modules/primeng/resources/themes/lara-light-indigo/theme.css';
@import '../node_modules/primeicons/primeicons.css';
+@import '../node_modules/quill/dist/quill.bubble.css';
+@import '../node_modules/quill/dist/quill.snow.css';