jigrogerglbzefjkzeygfeu

This commit is contained in:
Guams 2024-12-21 19:52:27 +01:00
parent 0cd1121d70
commit 832119a4fc
18 changed files with 202 additions and 48 deletions

View File

@ -1 +1,2 @@
<router-outlet></router-outlet> <router-outlet></router-outlet>
<p-toast></p-toast>

View File

@ -1,19 +1,22 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {MenubarModule} from 'primeng/menubar'; import {MenubarModule} from 'primeng/menubar';
import {MenuItem} from 'primeng/api'; import {MenuItem, MessageService} from 'primeng/api';
import {FloatLabelModule} from 'primeng/floatlabel'; import {FloatLabelModule} from 'primeng/floatlabel';
import {CookieService} from 'ngx-cookie-service'; import {CookieService} from 'ngx-cookie-service';
import {ToastModule} from 'primeng/toast';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
standalone: true, standalone: true,
imports: [MenubarModule, FloatLabelModule], imports: [MenubarModule, FloatLabelModule, ToastModule],
providers: [
MessageService,
],
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrl: './app.component.css' styleUrl: './app.component.css'
}) })
export class AppComponent{ export class AppComponent{
items: MenuItem[] = []
constructor(private cookieService: CookieService) { constructor() {
} }
} }

View File

@ -3,10 +3,15 @@ import {LoginComponent} from './login/login.component';
import {HomeComponent} from './home/home.component'; import {HomeComponent} from './home/home.component';
import {RegisterComponent} from './register/register.component'; import {RegisterComponent} from './register/register.component';
import {LogoutComponent} from './logout/logout.component'; import {LogoutComponent} from './logout/logout.component';
import {NotFoundComponent} from './not-found/not-found.component';
import {authGuard} from './auth.guard';
import {ProfileComponent} from './profile/profile.component';
export const routes: Routes = [ export const routes: Routes = [
{path: '', component: HomeComponent}, {path: '', component: HomeComponent},
{path: 'login', component: LoginComponent}, {path: 'login', component: LoginComponent, canActivate: [authGuard]},
{path: 'register', component: RegisterComponent}, {path: 'register', component: RegisterComponent, canActivate: [authGuard]},
{path: 'logout', component: LogoutComponent} {path: 'logout', component: LogoutComponent},
{path: 'profile/:authorId', component: ProfileComponent},
{path: '**', component: NotFoundComponent}
]; ];

13
src/app/auth.guard.ts Normal file
View File

@ -0,0 +1,13 @@
import {CanActivateFn, Router} from '@angular/router';
import {inject} from '@angular/core';
import {CookieService} from 'ngx-cookie-service';
export const authGuard: CanActivateFn = (route, state) => {
const router = inject(Router);
const cookieService = inject(CookieService);
if (cookieService.get("author") !== '') {
router.navigate(['/']);
}
return true;
};

View File

@ -1,2 +1,2 @@
<img src="assets/banner.png" height="494" width="1494"/> <img src="assets/banner.png" height="494" width="1494"/>
<p-menubar [model]="items" /> <p-menubar [model]="items"></p-menubar>

View File

@ -1,23 +1,27 @@
import { Component } from '@angular/core'; import {Component} from '@angular/core';
import {CookieService} from 'ngx-cookie-service'; import {CookieService} from 'ngx-cookie-service';
import {MenuItem} from 'primeng/api'; import {MenuItem} from 'primeng/api';
import {MenubarModule} from 'primeng/menubar'; import {MenubarModule} from 'primeng/menubar';
import {RouterOutlet} from '@angular/router'; import {ToastModule} from 'primeng/toast';
import {Author} from '../model/author';
@Component({ @Component({
selector: 'app-header', selector: 'app-header',
standalone: true, standalone: true,
imports: [ imports: [
MenubarModule, MenubarModule,
RouterOutlet ToastModule
], ],
templateUrl: './header.component.html', templateUrl: './header.component.html',
styleUrl: './header.component.css' styleUrl: './header.component.css'
}) })
export class HeaderComponent { export class HeaderComponent {
actualAuthor: Author | undefined;
items: MenuItem[] = []; items: MenuItem[] = [];
constructor(private cookieService: CookieService) { constructor(private cookieService: CookieService) {
if (this.cookieService.get('author')) { if (this.cookieService.get('author')) {
this.actualAuthor = JSON.parse(this.cookieService.get('author'));
this.items = [ this.items = [
{ {
label: 'Accueil', label: 'Accueil',
@ -25,14 +29,36 @@ export class HeaderComponent {
routerLink: '/' routerLink: '/'
}, },
{ {
label: 'Se déconnecter', label: 'Mes posts',
icon: 'pi pi-sign-out', icon: 'pi pi-file-edit',
routerLink: '/logout' items: [
{
label: 'Ajouter un post',
icon: 'pi pi-plus',
routerLink: 'new-post'
},
{
label: 'Voir mes posts',
icon: 'pi pi-eye',
routerLink: ['posts', `${this.actualAuthor?.id}`]
}
]
}, },
{ {
label: 'Mon profil', label: `${this.actualAuthor?.name.toUpperCase()}`,
icon: 'pi pi-user', icon: 'pi pi-user',
routerLink: '/me' items: [
{
label: 'Voir mon profil',
icon: 'pi pi-user',
routerLink: [`/profile`, `${this.actualAuthor?.id}`]
},
{
label: 'Se déconnecter',
icon: 'pi pi-sign-out',
routerLink: '/logout'
}
]
} }
]; ];
} else { } else {
@ -43,14 +69,20 @@ export class HeaderComponent {
routerLink: '/' routerLink: '/'
}, },
{ {
label: 'Se connecter', label: "S'authentifier",
icon: 'pi pi-sign-in', icon: 'pi pi-sign-in',
routerLink: '/login' items: [
}, {
{ label: 'Se connecter',
label: "S'inscrire", icon: 'pi pi-sign-in',
icon: 'pi pi-user-plus', routerLink: '/login'
routerLink: '/register' },
{
label: "S'inscrire",
icon: 'pi pi-user-plus',
routerLink: '/register'
}
]
} }
]; ];
} }

View File

@ -1,5 +1,4 @@
<app-header></app-header> <app-header></app-header>
<p-toast></p-toast>
<div class="main-content"> <div class="main-content">
<article> <article>
<img class="blog-img" src="data:image/jpeg;base64,image " alt="article image"> <img class="blog-img" src="data:image/jpeg;base64,image " alt="article image">
@ -10,7 +9,7 @@
beaucoup d'aspects du manga comme la mémoire humaine, la spontanéité des uns qui vient en opposition avec beaucoup d'aspects du manga comme la mémoire humaine, la spontanéité des uns qui vient en opposition avec
l'hypocrisie des autres et plein d'autres thèmes ! Disclaimer : Tout comme mon post sur l'hypocrisie des autres et plein d'autres thèmes ! Disclaimer : Tout comme mon post sur
"Persona 3 Reload - Episode Aigis", je spoil l'intégralité de l'oeuvre.</p> "Persona 3 Reload - Episode Aigis", je spoil l'intégralité de l'oeuvre.</p>
<p-button label="Lire la suite"/> <p-button (click)="successMessage('salut', 'grgtr')" label="Lire la suite"/>
<div> <div>
<p-avatar label="G" shape="circle" styleClass="mr-2" size="large"/> <p-avatar label="G" shape="circle" styleClass="mr-2" size="large"/>
<em>Guams</em> <em>Guams</em>

View File

@ -1,12 +1,11 @@
import {Component, OnDestroy} from '@angular/core'; import {Component, OnDestroy} from '@angular/core';
import {AvatarModule} from 'primeng/avatar'; import {AvatarModule} from 'primeng/avatar';
import {Button, ButtonDirective} from 'primeng/button'; import {Button} from 'primeng/button';
import {AuthorService} from '../services/author.service'; import {AuthorService} from '../services/author.service';
import {Author} from '../model/author'; import {Author} from '../model/author';
import {JsonPipe} from '@angular/common'; import {JsonPipe} from '@angular/common';
import {Subscription} from 'rxjs'; import {Subscription} from 'rxjs';
import {PostService} from '../services/post.service'; import {MessageService} from 'primeng/api';
import {Header, MessageService} from 'primeng/api';
import {HeaderComponent} from '../header/header.component'; import {HeaderComponent} from '../header/header.component';
import {ToastModule} from 'primeng/toast'; import {ToastModule} from 'primeng/toast';
import {CookieService} from 'ngx-cookie-service'; import {CookieService} from 'ngx-cookie-service';
@ -21,9 +20,6 @@ import {CookieService} from 'ngx-cookie-service';
ToastModule, ToastModule,
JsonPipe JsonPipe
], ],
providers: [
MessageService,
],
templateUrl: './home.component.html', templateUrl: './home.component.html',
styleUrl: './home.component.css' styleUrl: './home.component.css'
}) })
@ -34,17 +30,13 @@ export class HomeComponent implements OnDestroy {
constructor( constructor(
private authorService: AuthorService, private authorService: AuthorService,
private postService: PostService,
private messageService: MessageService, private messageService: MessageService,
private cookieService: CookieService) { private cookieService: CookieService) {
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'));
if (this.cookieService.get("just-authenticated")) {
this.successMessage('Connecté avec succès', `Heureux de vous revoir ${this.actualAuthor?.name}`);
}
} }
this.subs.push(authorService.list() this.subs.push(this.authorService.list()
.subscribe({ .subscribe({
next: (authors: Author[]) => this.authors = authors, next: (authors: Author[]) => this.authors = authors,
error: (err) => console.error(err.message), error: (err) => console.error(err.message),
@ -56,7 +48,7 @@ export class HomeComponent implements OnDestroy {
severity: 'success', severity: 'success',
summary: summary, summary: summary,
detail: detail, detail: detail,
life: 1500, life: 3000,
closable: false closable: false
}); });
} }

View File

@ -1,4 +1,3 @@
<p-toast></p-toast>
<app-header></app-header> <app-header></app-header>
<label for="username">Nom d'utilisateur</label> <label for="username">Nom d'utilisateur</label>
<input id="username" placeholder="Jean Zay" pInputText [(ngModel)]="name"/> <input id="username" placeholder="Jean Zay" pInputText [(ngModel)]="name"/>

View File

@ -1,4 +1,4 @@
import {Component, CUSTOM_ELEMENTS_SCHEMA, OnDestroy} from '@angular/core'; import {ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, OnDestroy} from '@angular/core';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {InputTextModule} from 'primeng/inputtext'; import {InputTextModule} from 'primeng/inputtext';
import {Button} from 'primeng/button'; import {Button} from 'primeng/button';
@ -24,10 +24,7 @@ import {Router} from '@angular/router';
HeaderComponent HeaderComponent
], ],
templateUrl: './login.component.html', templateUrl: './login.component.html',
styleUrl: './login.component.css', styleUrl: './login.component.css'
providers: [
MessageService,
]
}) })
export class LoginComponent implements OnDestroy { export class LoginComponent implements OnDestroy {
name: string = ""; name: string = "";
@ -46,13 +43,18 @@ export class LoginComponent implements OnDestroy {
this.subs.push this.subs.push
( (
this.authorService.login(this.name, this.password).pipe( this.authorService.login(this.name, this.password).pipe(
switchMap((tokenObj: any) => this.authorService.me(tokenObj.token))) switchMap((tokenObj: any) => {
this.cookieService.set("token", tokenObj.token);
return this.authorService.me(tokenObj.token)
}))
.subscribe({ .subscribe({
next: (author: Author) => { next: (author: Author) => {
this.cookieService.set("author", JSON.stringify(author)); this.cookieService.set("author", JSON.stringify(author));
this.cookieService.set("just-authenticated", "true"); this.cookieService.set("just-authenticated", "true");
this.getAuthorCookie(); this.getAuthorCookie();
this.router.navigate(['/']); this.router.navigate(['/']).then(() => {
this.successMessage('Connecté avec succès', 'Heureux de vous revoir ' + this.actualAuthor?.name)
});
}, },
error: (err) => this.failureMessage('Erreur de connexion', err.message) error: (err) => this.failureMessage('Erreur de connexion', err.message)
}) })
@ -67,12 +69,22 @@ export class LoginComponent implements OnDestroy {
this.actualAuthor = JSON.parse(this.cookieService.get("author")); this.actualAuthor = JSON.parse(this.cookieService.get("author"));
} }
successMessage(summary: string, detail: string): void {
this.messageService.add({
severity: 'success',
summary: summary,
detail: detail,
life: 3000,
closable: false
});
}
failureMessage(summary: string, detail: string): void { failureMessage(summary: string, detail: string): void {
this.messageService.add({ this.messageService.add({
severity: 'error', severity: 'error',
summary: summary, summary: summary,
detail: detail, detail: detail,
life: 1500, life: 3000,
closable: false closable: false
}); });
} }

View File

@ -2,6 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {CookieService} from 'ngx-cookie-service'; import {CookieService} from 'ngx-cookie-service';
import {HeaderComponent} from '../header/header.component'; import {HeaderComponent} from '../header/header.component';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {MessageService} from 'primeng/api';
@Component({ @Component({
selector: 'app-logout', selector: 'app-logout',
@ -15,10 +16,21 @@ import {Router} from '@angular/router';
export class LogoutComponent implements OnInit{ export class LogoutComponent implements OnInit{
constructor(private cookiesService: CookieService, constructor(private cookiesService: CookieService,
private messageService: MessageService,
private router: Router) { } private router: Router) { }
ngOnInit(): void { ngOnInit(): void {
this.cookiesService.deleteAll(); this.cookiesService.deleteAll();
this.router.navigate(['/']); this.router.navigate(['/']).then(() => this.successMessage('Déconnexion', 'Vous avez été deconnecté avec succès'));
}
successMessage(summary: string, detail: string): void {
this.messageService.add({
severity: 'success',
summary: summary,
detail: detail,
life: 3000,
closable: false
});
} }
} }

View File

@ -0,0 +1,3 @@
<h1>Erreur 404</h1>
<h2>Il semblerait que vous vous soyez trompé !</h2>
<a routerLink="/">Revenir à la page d'accueil</a>

View File

@ -0,0 +1,15 @@
import { Component } from '@angular/core';
import {RouterLink} from '@angular/router';
@Component({
selector: 'app-not-found',
standalone: true,
imports: [
RouterLink
],
templateUrl: './not-found.component.html',
styleUrl: './not-found.component.css'
})
export class NotFoundComponent {
}

View File

View File

@ -0,0 +1,14 @@
<app-header></app-header>
{{ concernedAuthor | json }}
<p-card header='Profil de {{ concernedAuthor?.name }}' subheader="role : {{ concernedAuthor?.role }}">
<p class="m-0">
<p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/amyelsner.png" class="mr-2" size="xlarge" shape="circle" />
<p-button label="Voir les posts de l'utilisateur"></p-button>
@if (concernedAuthor?.id === actualAuthor?.id) {
<p-button label="Mettre à jour les données du profil"/>
<p-button label="Changer le mot de passe"/>
}
</p>
</p-card>

View File

@ -0,0 +1,47 @@
import {Component, OnDestroy} from '@angular/core';
import {HeaderComponent} from '../header/header.component';
import {ActivatedRoute, Router} from '@angular/router';
import {CookieService} from 'ngx-cookie-service';
import {Author} from '../model/author';
import {Subscription} from 'rxjs';
import {AuthorService} from '../services/author.service';
import {JsonPipe} from '@angular/common';
import {AvatarModule} from 'primeng/avatar';
import {CardModule} from 'primeng/card';
import {Button} from 'primeng/button';
@Component({
selector: 'app-profile',
standalone: true,
imports: [
HeaderComponent,
JsonPipe,
AvatarModule,
CardModule,
Button
],
templateUrl: './profile.component.html',
styleUrl: './profile.component.css'
})
export class ProfileComponent implements OnDestroy{
actualAuthor: Author | undefined;
concernedAuthor: Author | undefined;
subs: Subscription[] = [];
constructor(private route: ActivatedRoute,
private authorService: AuthorService,
private cookieService: CookieService) {
this.route.paramMap.subscribe(params => {
this.subs.push(this.authorService.getAuthor(params.get('authorId')).subscribe(author => {
this.concernedAuthor = author;
}));
})
if (this.cookieService.get('author')) {
this.actualAuthor = JSON.parse(this.cookieService.get("author"));
}
}
ngOnDestroy(): void {
this.subs.forEach(sub => sub.unsubscribe());
}
}

View File

@ -20,7 +20,14 @@ export class AuthorService {
me(token: string): Observable<Author> { me(token: string): Observable<Author> {
const headers = new HttpHeaders().set("Authorization", "Bearer " + token); const headers = new HttpHeaders().set("Authorization", "Bearer " + token);
console.log(headers)
return this.httpClient.get<Author>("http://localhost:8080/api/authors/me", {'headers': headers}); return this.httpClient.get<Author>("http://localhost:8080/api/authors/me", {'headers': headers});
} }
getAuthor(id: string | null): Observable<Author> {
if (id) {
return this.httpClient.get<Author>("http://localhost:8080/api/authors/" + id);
} else {
throw new Error("Not Found");
}
}
} }