Ajout de nouvelles pages pour les admins 2.0

This commit is contained in:
Guams 2025-02-04 20:24:03 +01:00
parent a7424178d4
commit 2921ecc303
32 changed files with 245 additions and 93 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

BIN
public/icon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -3,7 +3,8 @@
<p-dialog header="ATTENTION !" [modal]="true" [closable]="false" [visible]="isSessionExpired"> <p-dialog header="ATTENTION !" [modal]="true" [closable]="false" [visible]="isSessionExpired">
<span>Votre session a <strong>expiré</strong> ! Il va falloir se reconnecter.</span> <span>Votre session a <strong>expiré</strong> ! Il va falloir se reconnecter.</span>
<div class="expired-dialog"> <div class="expired-dialog">
<p-button severity="info" icon="pi pi-sign-out" label="OK, je me déconnecte" (onClick)="setSessionExpiredFalse()" routerLink="/logout"></p-button> <p-button severity="info" icon="pi pi-sign-out" label="OK, je me déconnecte" (onClick)="setSessionExpiredFalse()"
routerLink="/logout"></p-button>
</div> </div>
</p-dialog> </p-dialog>
} }

View File

@ -1,25 +0,0 @@
.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;
}

View File

@ -1,10 +0,0 @@
<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://x.com/Orabisss" target="_blank" class="footer-link">&#64;Orabisss</a> sur Twitter.</p>
<p class="footer-follow">Suivez-moi sur :</p>
<p class="footer-links">
<a href="https://x.com/Guams8" 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">&copy; 2024 Guams. Tous droits réservés.</p>
</footer>

View File

@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-footer',
standalone: true,
imports: [],
templateUrl: './footer.component.html',
styleUrl: './footer.component.css'
})
export class FooterComponent {
}

View File

@ -112,7 +112,6 @@ export class PostFormComponent implements OnDestroy {
).subscribe({ ).subscribe({
next: (_) => { next: (_) => {
this.successMessage('Succès', 'Post mis à jour avec succès') this.successMessage('Succès', 'Post mis à jour avec succès')
console.log(this.body);
}, },
error: (err) => this.failureMessage('Erreur', err.message) error: (err) => this.failureMessage('Erreur', err.message)
}) })
@ -130,7 +129,6 @@ export class PostFormComponent implements OnDestroy {
).subscribe({ ).subscribe({
next: () => { next: () => {
this.router.navigate(['/']).then(() => { this.router.navigate(['/']).then(() => {
console.log(this.body);
this.successMessage('Succès', 'Post créé avec succès') this.successMessage('Succès', 'Post créé avec succès')
}); });
}, },

View File

@ -7,11 +7,11 @@
<span class="desc">{{ description }}</span> <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"> <a routerLink="/profile/{{ authorId }}" class="user-profile">
@if (authorProfilePicture !== "") { @if (authorProfilePicture) {
<p-avatar image="data:image/jpeg;base64,{{ authorProfilePicture }}" shape="circle" styleClass="mr-2" <p-avatar image="data:image/jpeg;base64,{{ authorProfilePicture }}" shape="circle" styleClass="mr-2"
size="xlarge"></p-avatar> size="xlarge"></p-avatar>
} @else { } @else {
<p-avatar label="{{ username.charAt(0).toUpperCase() }}" styleClass="mr-2" size="xlarge"></p-avatar> <p-avatar label="{{ username.charAt(0).toUpperCase() }}" shape="circle" styleClass="mr-2" size="xlarge"></p-avatar>
} }
<span style="font-size: 20px;">{{ username }}</span> <span style="font-size: 20px;">{{ username }}</span>
</a> </a>

View File

@ -8,7 +8,7 @@
<label for="passwordConfirm">Confirmez le mot de passe</label> <label for="passwordConfirm">Confirmez le mot de passe</label>
<input type="password"[(ngModel)]="passwordConfirm" id="passwordConfirm" pInputText formControlName="passwordConfirm"/> <input type="password"[(ngModel)]="passwordConfirm" id="passwordConfirm" pInputText formControlName="passwordConfirm"/>
<label for="role">Rôle de l'utilisateur</label> <label for="role">Rôle de l'utilisateur</label>
<p-selectButton id="role" [options]="roles" [(ngModel)]="role" optionLabel="name" optionValue="value" <p-selectButton [disabled]="!adminForm" id="role" [options]="roles" [(ngModel)]="role" optionLabel="name" optionValue="value"
formControlName="role"/> formControlName="role"/>
<p-button class="send-button" type="submit" label="S'inscrire"></p-button> <p-button class="send-button" type="submit" label="S'inscrire"></p-button>
</form> </form>

View File

@ -1,5 +1,4 @@
import {Component, Input, OnDestroy, OnInit} from '@angular/core'; import {Component, EventEmitter, Input, OnDestroy, Output} from '@angular/core';
import {HeaderComponent} from '../header/header.component';
import {Subscription} from 'rxjs'; import {Subscription} from 'rxjs';
import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms';
import {InputTextModule} from 'primeng/inputtext'; import {InputTextModule} from 'primeng/inputtext';
@ -8,12 +7,13 @@ import {Button} from 'primeng/button';
import {AuthorService} from '../../services/author.service'; import {AuthorService} from '../../services/author.service';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {MessageService} from 'primeng/api'; import {MessageService} from 'primeng/api';
import {Author} from '../../models/author';
import {AuthService} from '../../auth.service';
@Component({ @Component({
selector: 'app-register-form', selector: 'app-register-form',
standalone: true, standalone: true,
imports: [ imports: [
HeaderComponent,
ReactiveFormsModule, ReactiveFormsModule,
InputTextModule, InputTextModule,
SelectButtonModule, SelectButtonModule,
@ -25,6 +25,7 @@ import {MessageService} from 'primeng/api';
}) })
export class RegisterFormComponent implements OnDestroy { export class RegisterFormComponent implements OnDestroy {
@Input() username: string = ""; @Input() username: string = "";
@Output() createdAuthor: EventEmitter<Author> = new EventEmitter();
@Input() password: string = ""; @Input() password: string = "";
@Input() passwordConfirm: string = ""; @Input() passwordConfirm: string = "";
@Input() role: string = "READER" @Input() role: string = "READER"
@ -35,17 +36,22 @@ export class RegisterFormComponent implements OnDestroy {
]; ];
subs: Subscription[] = []; subs: Subscription[] = [];
form: FormGroup; form: FormGroup;
actualAuthor: Author | undefined;
constructor(private formBuilder: FormBuilder, constructor(private formBuilder: FormBuilder,
private authorService: AuthorService, private authorService: AuthorService,
private router: Router, private router: Router,
private messageService: MessageService private messageService: MessageService,
private authService: AuthService,
) { ) {
if (!(this.authService.isSessionExpired()) && this.authService.isAuthenticated()) {
this.actualAuthor = this.authService.getAuthenticatedAuthor();
}
this.form = this.formBuilder.group({ this.form = this.formBuilder.group({
username: ['', [Validators.required, Validators.maxLength(255)]], username: ['', [Validators.required, Validators.maxLength(255)]],
password: ['', [Validators.required, Validators.maxLength(50)]], password: ['', [Validators.required, Validators.maxLength(50)]],
passwordConfirm: ['', [Validators.required, Validators.maxLength(50)]], passwordConfirm: ['', [Validators.required, Validators.maxLength(50)]],
role: [{value: 'READER', disabled: !this.adminForm}, [Validators.required, Validators.maxLength(10)]], role: [{value: 'READER'}, [Validators.required, Validators.maxLength(10)]],
}); });
} }
@ -71,8 +77,20 @@ export class RegisterFormComponent implements OnDestroy {
onSubmit() { onSubmit() {
if (this.form.valid && this.password === this.passwordConfirm) { if (this.form.valid && this.password === this.passwordConfirm) {
if (this.adminForm) { if (this.adminForm && this.actualAuthor) {
this.authorService.createAccountAdmin(this.username, this.password, this.role); //TODO à finir this.authorService.createAccountAdmin(
this.username,
this.password,
this.role,
this.authService.getAuthenticatedAuthorToken()).subscribe({
next: (author: Author) => {
this.successMessage('Succès', `Auteur ${author.name} créé avec succès`);
this.createdAuthor.emit(author);
},
error: (err) => {
this.failureMessage("Erreur", err.message);
}
});
} else { } else {
this.subs.push(this.authorService.createAccount(this.username, this.password).subscribe({ this.subs.push(this.authorService.createAccount(this.username, this.password).subscribe({
next: () => this.router.navigate(['/login']).then(() => this.successMessage('Succès', 'Utilisateur créé avec succès')), next: () => this.router.navigate(['/login']).then(() => this.successMessage('Succès', 'Utilisateur créé avec succès')),
@ -80,6 +98,8 @@ export class RegisterFormComponent implements OnDestroy {
})); }));
} }
} else {
this.failureMessage('Erreur', 'Le formulaire n\'est pas complet ou les mot de passes ne correspondent pas');
} }
} }

View File

@ -0,0 +1,7 @@
.add-button {
display: flex;
justify-content: flex-end;
margin-top: 2rem;
margin-right: 2rem;
margin-bottom: 2rem;
}

View File

@ -1,2 +1,61 @@
<app-header></app-header> <app-header></app-header>
<p>admin-authors works!</p> <div class="add-button">
<p-button (click)="createAuthorDialogVisibility=true" icon="pi pi-plus" label="Ajouter un auteur"></p-button>
<p-dialog header='Ajouter un auteur' [modal]="true" [(visible)]="createAuthorDialogVisibility">
<app-register-form (createdAuthor)="closeCreateAuthorDialog($event)" [adminForm]="true">
</app-register-form>
</p-dialog>
</div>
<p-table showGridlines
stripedRows
[value]="authors">
<ng-template pTemplate="header">
<tr>
<th>ID</th>
<th>Nom</th>
<th>Photo de profil</th>
<th>Role</th>
<th></th>
<th></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-author let-rowIndex="rowIndex">
<tr>
<td>{{ author.id }}</td>
<td>{{ author.name }}</td>
<td>
@if (author.profilePicture) {
<p-avatar image="data:image/jpeg;base64,{{ author.profilePicture }}" size="large" shape="circle"/>
} @else {
<p-avatar label="{{ author.name.charAt(0).toUpperCase() }}" size="large" shape="circle"/>
}
</td>
<td>{{ author.role }}</td>
<td>
<p-button icon="pi pi-pencil" (click)="openDialog(updateDialogVisibility, rowIndex)" severity="warning"
label="Modifier"/>
<p-dialog header='Modifier "{{ author.name }}"' [modal]="true" [(visible)]="updateDialogVisibility[rowIndex]">
<app-register-form [adminForm]="true" [username]="author.name">
</app-register-form>
</p-dialog>
</td>
<td>
<p-button icon="pi pi-trash" (click)="openDialog(deleteDialogVisibility, rowIndex)" severity="danger"
label="Supprimer"/>
<p-dialog header='Êtes-vous sur de bien vouloir supprimer "{{ author.name }}"' [modal]="true"
[(visible)]="deleteDialogVisibility[rowIndex]">
<div class="delete-dialog">
<p-button label="Annuler"
icon="pi pi-times"
severity="info"
(click)="closeDialog(deleteDialogVisibility, rowIndex)"/>
<p-button (click)="deleteAuthor(author.id, rowIndex)"
label="Oui" icon="pi pi-trash"
severity="danger"/>
</div>
</p-dialog>
</td>
</tr>
</ng-template>
</p-table>

View File

@ -1,15 +1,88 @@
import { Component } from '@angular/core'; import {Component, OnDestroy} from '@angular/core';
import {HeaderComponent} from '../../components/header/header.component'; import {HeaderComponent} from '../../components/header/header.component';
import {TableModule} from 'primeng/table';
import {AuthService} from '../../auth.service';
import {AuthorService} from '../../services/author.service';
import {Author} from '../../models/author';
import {Subscription} from 'rxjs';
import {MessageService} from 'primeng/api';
import {AvatarModule} from 'primeng/avatar';
import {Button} from 'primeng/button';
import {DialogModule} from 'primeng/dialog';
import {RegisterFormComponent} from '../../components/register-form/register-form.component';
@Component({ @Component({
selector: 'app-admin-authors', selector: 'app-admin-authors',
standalone: true, standalone: true,
imports: [ imports: [
HeaderComponent HeaderComponent,
TableModule,
AvatarModule,
Button,
DialogModule,
RegisterFormComponent,
], ],
templateUrl: './admin-authors.component.html', templateUrl: './admin-authors.component.html',
styleUrl: './admin-authors.component.css' styleUrl: './admin-authors.component.css'
}) })
export class AdminAuthorsComponent { export class AdminAuthorsComponent implements OnDestroy{
authors: Author[] = [];
createAuthorDialogVisibility: boolean = false;
updateDialogVisibility: boolean[] = [];
deleteDialogVisibility: boolean[] = [];
subs: Subscription[] = [];
constructor(private authService: AuthService,
private authorService: AuthorService,
private messageService: MessageService) {
this.authorService.list().subscribe({
next: (authors: Author[]) => {
this.authors = authors;
},
error: (error: Error) => {
this.failureMessage("Erreur", error.message)
}
})
}
closeCreateAuthorDialog(author: Author): void {
this.authors.push(author);
this.createAuthorDialogVisibility = false;
}
successMessage(summary: string, detail: string): void {
this.messageService.add({
severity: 'success',
summary: summary,
detail: detail,
life: 3000,
closable: false
});
}
deleteAuthor(authorId: string, rowIndex: number): void {
}
openDialog(dialogBooleanTab: boolean[], index: number) {
dialogBooleanTab[index] = true;
}
closeDialog(dialogBooleanTab: boolean[], index: number) {
dialogBooleanTab[index] = false;
}
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());
}
} }

View File

@ -16,4 +16,3 @@
<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>

View File

@ -7,7 +7,6 @@ import {ToastModule} from 'primeng/toast';
import {PostService} from '../../services/post.service'; import {PostService} from '../../services/post.service';
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 {AuthorWithPost} from '../../models/author-with-post';
import {FooterComponent} from '../../components/footer/footer.component';
import {AuthService} from '../../auth.service'; import {AuthService} from '../../auth.service';
@Component({ @Component({
@ -18,7 +17,6 @@ import {AuthService} from '../../auth.service';
HeaderComponent, HeaderComponent,
ToastModule, ToastModule,
PostHomeComponent, PostHomeComponent,
FooterComponent
], ],
templateUrl: './home.component.html', templateUrl: './home.component.html',
styleUrl: './home.component.css' styleUrl: './home.component.css'

View File

@ -17,4 +17,3 @@
/> />
</div> </div>
</div> </div>
<app-footer></app-footer>

View File

@ -10,7 +10,6 @@ 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';
import {ConfigurationService} from '../../configuration.service'; import {ConfigurationService} from '../../configuration.service';
import {DateTime} from 'luxon'; import {DateTime} from 'luxon';
@ -23,7 +22,6 @@ import {DateTime} from 'luxon';
Button, Button,
ToastModule, ToastModule,
HeaderComponent, HeaderComponent,
FooterComponent
], ],
templateUrl: './login.component.html', templateUrl: './login.component.html',
styleUrl: './login.component.css' styleUrl: './login.component.css'

View File

@ -21,8 +21,7 @@ export class LogoutComponent implements OnInit{
private router: Router, private router: Router,
private configurationService: ConfigurationService,) { } private configurationService: ConfigurationService,) { }
ngOnInit(): void { ngOnInit(): void {
console.log(this.cookieService.getAll()) const routes: string[] = ['/', '/login', '/register', '/logout', '/profile', '/post', '/new-post', '/admin']
const routes: string[] = ['/', '/login', '/register', '/logout', '/profile', '/post', '/new-post']
Object.keys(this.cookieService.getAll()).forEach(key => { Object.keys(this.cookieService.getAll()).forEach(key => {
routes.forEach(route => { routes.forEach(route => {
this.cookieService.delete(key, route, this.configurationService.getServerAddress()); this.cookieService.delete(key, route, this.configurationService.getServerAddress());

View File

@ -66,4 +66,3 @@
</tr> </tr>
</ng-template> </ng-template>
</p-table> </p-table>
<app-footer></app-footer>

View File

@ -13,7 +13,6 @@ 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';
import {AuthService} from '../../auth.service'; import {AuthService} from '../../auth.service';
@Component({ @Component({
@ -28,7 +27,6 @@ import {AuthService} from '../../auth.service';
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'

View File

@ -1,3 +1,2 @@
<app-header></app-header> <app-header></app-header>
<app-post-form [actualAuthor]="actualAuthor"/> <app-post-form [actualAuthor]="actualAuthor"/>
<app-footer></app-footer>

View File

@ -12,7 +12,6 @@ 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';
import {AuthService} from '../../auth.service'; import {AuthService} from '../../auth.service';
@Component({ @Component({
@ -26,7 +25,6 @@ import {AuthService} from '../../auth.service';
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'

View File

@ -70,7 +70,6 @@
<p>{{ comment.content }}</p> <p>{{ comment.content }}</p>
} }
</div> </div>
<app-footer></app-footer>
} @else { } @else {
<h1>Loading...</h1> <h1>Loading...</h1>
} }

View File

@ -13,7 +13,6 @@ import {CardModule} from 'primeng/card';
import {SafeHtmlPipe} from '../../pipes/safe-html-pipe'; import {SafeHtmlPipe} from '../../pipes/safe-html-pipe';
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';
import {Button} from 'primeng/button'; import {Button} from 'primeng/button';
import {DialogModule} from 'primeng/dialog'; import {DialogModule} from 'primeng/dialog';
import {AuthService} from '../../auth.service'; import {AuthService} from '../../auth.service';
@ -28,7 +27,6 @@ import {AuthService} from '../../auth.service';
CardModule, CardModule,
SafeHtmlPipe, SafeHtmlPipe,
CommentFormComponent, CommentFormComponent,
FooterComponent,
Button, Button,
DialogModule DialogModule
], ],

View File

@ -32,4 +32,3 @@
} @else { } @else {
<h1>Loading...</h1> <h1>Loading...</h1>
} }
<app-footer></app-footer>

View File

@ -9,7 +9,6 @@ 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';
import {AuthService} from '../../auth.service'; import {AuthService} from '../../auth.service';
@Component({ @Component({
@ -22,7 +21,6 @@ import {AuthService} from '../../auth.service';
Button, Button,
DialogModule, DialogModule,
UpdateProfileFormComponent, UpdateProfileFormComponent,
FooterComponent
], ],
templateUrl: './profile.component.html', templateUrl: './profile.component.html',
styleUrl: './profile.component.css' styleUrl: './profile.component.css'

View File

@ -1,3 +1,2 @@
<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>

View File

@ -1,8 +1,6 @@
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',
@ -10,8 +8,6 @@ import {FooterComponent} from '../../components/footer/footer.component';
imports: [ imports: [
HeaderComponent, HeaderComponent,
RegisterFormComponent, RegisterFormComponent,
Footer,
FooterComponent
], ],
templateUrl: './register.component.html', templateUrl: './register.component.html',
styleUrl: './register.component.css' styleUrl: './register.component.css'

View File

@ -83,7 +83,12 @@ export class AuthorService {
return this.httpClient.post<Author>(`${this.apiUrl}/register`, {name: username, password: password}) return this.httpClient.post<Author>(`${this.apiUrl}/register`, {name: username, password: password})
} }
createAccountAdmin(username: string, password: string, role: string): Observable<Author> { createAccountAdmin(username: string, password: string, role: string, token: string): Observable<Author> {
return this.httpClient.post<Author>(`${this.apiUrl}/register`, {name: username, password: password, role: role}) const httpOptions = {
headers: new HttpHeaders({
'Authorization': `Bearer ${token}`
})
}
return this.httpClient.post<Author>(`${this.apiUrl}/register/admin`, {name: username, password: password, role: role}, httpOptions);
} }
} }

View File

@ -64,7 +64,6 @@ export class PostService {
'Authorization': `Bearer ${token}` 'Authorization': `Bearer ${token}`
}) })
}; };
console.log(image);
return this.httpClient.put<Post>(`${this.apiUrl}/${id}/illustration`, formData, httpOptions); return this.httpClient.put<Post>(`${this.apiUrl}/${id}/illustration`, formData, httpOptions);
} else { } else {
throw new Error('Image doesn\'t exist'); throw new Error('Image doesn\'t exist');

View File

@ -5,9 +5,19 @@
<title>A BON ENTENDEUR</title> <title>A BON ENTENDEUR</title>
<base href="/"> <base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="icon.jpg">
</head> </head>
<body> <body>
<app-root></app-root> <app-root></app-root>
<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://x.com/Orabisss" target="_blank" class="footer-link">&#64;Orabisss</a> sur Twitter.</p>
<p class="footer-follow">Suivez-moi sur :</p>
<p class="footer-links">
<a href="https://x.com/Guams8" 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">&copy; 2024 Guams. Tous droits réservés.</p>
</footer>
</body> </body>
</html> </html>

View File

@ -2,3 +2,54 @@
@import '../node_modules/primeicons/primeicons.css'; @import '../node_modules/primeicons/primeicons.css';
@import '../node_modules/quill/dist/quill.bubble.css'; @import '../node_modules/quill/dist/quill.bubble.css';
@import '../node_modules/quill/dist/quill.snow.css'; @import '../node_modules/quill/dist/quill.snow.css';
body {
min-height: 1920px;
}
.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;
}
html, body {
height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
app-root {
flex: 1;
display: flex;
flex-direction: column;
}
.footer {
width: 100%;
text-align: center;
padding: 10px;
background: #222;
color: white;
}
.footer-link {
color: #1e90ff;
text-decoration: none;
margin: 0 10px;
}
.footer-link:hover {
text-decoration: underline;
}