diff --git a/src/app/interfaces/apiResponse.ts b/src/app/interfaces/apiResponse.ts new file mode 100644 index 0000000..48d3273 --- /dev/null +++ b/src/app/interfaces/apiResponse.ts @@ -0,0 +1,5 @@ +export interface ApiResponse { + code: string, + message: string, + data: T +} \ No newline at end of file diff --git a/src/app/interfaces/user.ts b/src/app/interfaces/user.ts index a8fdcd8..49bd4e9 100644 --- a/src/app/interfaces/user.ts +++ b/src/app/interfaces/user.ts @@ -4,9 +4,19 @@ export interface User { roles: string[] } -//TODO: Passer a une gestion par roles et non par un booléen isAdmin + export interface LoggedUser { email: string, token: string, roles: string[] } + +export interface UserToRegister { + email: string, + pseudo: string, + password: string, + passwordConfirm: string, + cityCode: string, + city: string, + phone: string, +} diff --git a/src/app/pages/login/login.ts b/src/app/pages/login/login.ts index 7d2e188..5bcb797 100644 --- a/src/app/pages/login/login.ts +++ b/src/app/pages/login/login.ts @@ -1,5 +1,6 @@ import { Component, inject, signal, Signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { firstValueFrom } from 'rxjs'; import { Router } from '@angular/router'; @@ -22,15 +23,21 @@ export class Login { constructor(private readonly userService: Auth, private readonly router: Router){ } - login() { + async login() { const userToConnect : User = {email: this.email(), password: this.password(),roles: []} - const loginSuccess = this.userService.login(userToConnect) - if(loginSuccess){ + try{ + const loginSuccess =await firstValueFrom(this.userService.login(userToConnect)); + if(loginSuccess){ this.router.navigate(['/profile']); } else { this.errorMessage.set('Email ou mot de passe incorrect'); } + }catch (error) { + console.error('Erreur lors du login:', error); + this.errorMessage.set('Une erreur est survenue. Veuillez réessayer.'); + } + } updateEmail(event: Event) { diff --git a/src/app/pages/register/register.html b/src/app/pages/register/register.html index 900bc2b..a969b74 100644 --- a/src/app/pages/register/register.html +++ b/src/app/pages/register/register.html @@ -1,18 +1,33 @@ -
-
+
Register
- +
- +
- + +
+
+ +
+
+ +
+
+ +
+
+
+ + @if (errorMessage()) { +

{{ errorMessage() }}

+ }
diff --git a/src/app/pages/register/register.ts b/src/app/pages/register/register.ts index df57134..f4c94e1 100644 --- a/src/app/pages/register/register.ts +++ b/src/app/pages/register/register.ts @@ -1,52 +1,58 @@ import { Component, inject, Signal, signal } from '@angular/core'; -import { User } from '../../interfaces/user'; -import { FormsModule } from '@angular/forms'; +import { User, UserToRegister } from '../../interfaces/user'; +import { FormGroup, FormBuilder, Validator, ReactiveFormsModule, Validators } from '@angular/forms'; import { Router, RouterLink } from '@angular/router'; import { Auth } from '../../services/auth'; +import { firstValueFrom } from 'rxjs'; + @Component({ selector: 'app-register', - imports: [FormsModule], + imports: [ReactiveFormsModule], templateUrl: './register.html', styleUrl: './register.css', }) + export class Register { - email = signal(''); - password = signal(''); - passwordConfirm = signal(''); + registerForm: FormGroup; errorMessage = signal(''); - constructor(private readonly userService: Auth, - private readonly router: Router) { + constructor( + private readonly userService: Auth, + private readonly router: Router, + private fb: FormBuilder) { + this.registerForm = this.fb.group({ + email: ['', [Validators.required, Validators.email]], + pseudo:['', [Validators.required, Validators.minLength(2)]], + password: ['', [Validators.required, Validators.minLength(2)]], + passwordConfirm: ['', Validators.required], + cityCode: ['', Validators.required], + city:['',Validators.required], + phone: ['',Validators.required] + }); } - OnSubmit() { - if (this.password() == this.passwordConfirm()) { - console.log(this.email()); - const userToRegister: User = {email: this.email(), password: this.password(), roles: ['ADMIN']} - const register = this.userService.register(userToRegister) - - if(register){ - this.router.navigate(["/login"]) - } - else { - this.errorMessage.set('Email ou mot de passe incorrect'); - } + async OnSubmit() { + if (this.registerForm.invalid) { + this.errorMessage.set('Veuillez remplir tous les champs correctement.'); + return; } + + const user: UserToRegister = this.registerForm.value; + //appel au service register + try{ + const registerSuccess: boolean = await firstValueFrom(this.userService.register(user)) + if(registerSuccess){ + this.router.navigate(['/login']); + } + else{ + this.errorMessage.set('Une erreur est survenue'); + } + }catch(error){ + console.error('Erreur lors de l\'inscription:', error); + this.errorMessage.set('Une erreur est survenue. Veuillez réessayer.'); + }; } - updateEmail(event: Event) { - const target = event.target as HTMLInputElement; - this.email.set(target.value); - } - - updatePassword(event: Event) { - const target = event.target as HTMLInputElement; - this.password.set(target.value); - } - - updateConfirmPassword(event: Event) { - const target = event.target as HTMLInputElement; - this.passwordConfirm.set(target.value); - } + } diff --git a/src/app/pages/search/search.ts b/src/app/pages/search/search.ts index 0caf67f..77f89a4 100644 --- a/src/app/pages/search/search.ts +++ b/src/app/pages/search/search.ts @@ -11,8 +11,8 @@ import { Router } from '@angular/router'; styleUrl: './search.css' }) export class Search { - private nasaApi = inject(NAPOD); - private router = inject(Router) + private readonly nasaApi = inject(NAPOD); + private readonly router = inject(Router) searchResults = signal(null) searchString=signal(''); diff --git a/src/app/pages/video/video.ts b/src/app/pages/video/video.ts index 6b6b504..5e9af01 100644 --- a/src/app/pages/video/video.ts +++ b/src/app/pages/video/video.ts @@ -3,6 +3,8 @@ import { ActivatedRoute } from '@angular/router'; import { Collection } from '../../interfaces/nasa-api'; import { NAPOD } from '../../services/napod'; + + @Component({ selector: 'app-video', imports: [], @@ -10,21 +12,19 @@ import { NAPOD } from '../../services/napod'; styleUrl: './video.css' }) export class Video { - private route = inject(ActivatedRoute) + private readonly route = inject(ActivatedRoute) asset=signal(null); - //TODO: nom de merde pour le service a changer - private nasaApi: NAPOD = inject(NAPOD) + //TODO: nom nul pour le service a changer + private readonly nasaApi: NAPOD = inject(NAPOD) isLoading = signal(true); ngOnInit(){ const nasaId=this.route.snapshot.params['id']; - this.nasaApi.getAssetDetail(nasaId).subscribe({ next: (data)=>{ this.asset.set(data.collection); this.isLoading.set(false); - console.log(this.asset()); - + console.log(this.asset()); }, error: error =>{ console.log(error); diff --git a/src/app/services/auth.ts b/src/app/services/auth.ts index 603f9a9..1be1803 100644 --- a/src/app/services/auth.ts +++ b/src/app/services/auth.ts @@ -1,12 +1,17 @@ -import { Injectable, signal } from '@angular/core'; -import { LoggedUser, User } from '../interfaces/user'; +import { inject, Injectable, signal } from '@angular/core'; +import { LoggedUser, User, UserToRegister } from '../interfaces/user'; +import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; +import { environment } from '../../environments/environment.development'; +import { ApiResponse } from '../interfaces/apiResponse'; +import { catchError, map, Observable, of } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class Auth { - private connectedUserSignal = signal(null); - private users = signal([]); + private readonly connectedUserSignal = signal(null); + private readonly users = signal([]); + private readonly http = inject(HttpClient); constructor(){ this.loadStoredData(); @@ -36,52 +41,70 @@ export class Auth { return this.users().find(user=>user.email==userEmail)!; } - register(user: User): boolean{ - console.log("time to save users"); - - if(this.users().find(u => u.email===user.email)){ - console.log("seem to be such a user already"+user.email); - - return false; - } + register(user: UserToRegister): Observable{ + const apiUrl = `${environment.AUTH_API_BASE}/signup`; + const requestBody = { + email: user.email, + pseudo: user.pseudo, + password: user.password, + passwordConfirm: user.passwordConfirm, + cityCode: user.cityCode, + city: user.city, + phone: user.phone }; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); - this.users.update(users=>[...users,user]) - this.saveUsers(); - return true; - } - - saveUsers() { - localStorage.setItem('users', JSON.stringify(this.users())) - } - //################################ LOGIN/LOGOUT ############################### - login(userToConnect: User): boolean { - - const userToCheck = this.getUserByEmail(userToConnect.email); - - console.log("User has been found : " + userToCheck.email); - - - if(!userToCheck){ - console.log("No such user"); - return false; - } - else if(userToCheck.password==userToConnect.password){ - console.log("password is ok"); - //ATTENTION: ici il faut stocker le isAdmin de userToCheck parce que - // l'information sur le role est récupérée lors du getUser - const userStoreData: LoggedUser = { email: userToConnect.email, - token: 'fake-jwt'+Date.now(), roles: userToCheck.roles + return this.http.post>(apiUrl, requestBody, { headers }).pipe( + map((res)=>{ + if(res.code==="200"){ + return true; + } + else { + console.error('Erreur lors du register:'); + return false; + } } - sessionStorage.setItem('connectedUser',JSON.stringify(userStoreData)) - this.connectedUserSignal.set(userStoreData); - return true; - } - else{ - console.log("password doesn't seem right"); - return false - } + ) + ) + + + + + + } + + //################################ LOGIN/LOGOUT ############################### + + login(userToConnect: User): Observable { + const apiUrl = `${environment.AUTH_API_BASE}/login`; + const requestBody = { email: userToConnect.email, password: userToConnect.password }; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + + return this.http.post>(apiUrl, requestBody, { headers }).pipe( + map((res) => { + if (res.code === '200') { + const userStoreData: LoggedUser = { + email: res.data.email, + token: res.data.token, + roles: res.data.roles || [] + }; + sessionStorage.setItem('connectedUser', JSON.stringify(userStoreData)); + this.connectedUserSignal.set(userStoreData); + return true; + } else { + console.log("Mot de passe ou email incorrect"); + return false; + } + }), + catchError((error) => { + console.error('Erreur lors du login:', error); + return of(false); + }) + ); +} + logout(){ sessionStorage.removeItem('connectedUser'); this.connectedUserSignal.set(null); diff --git a/src/environments/environment.development.ts b/src/environments/environment.development.ts index bbfccad..78234cd 100644 --- a/src/environments/environment.development.ts +++ b/src/environments/environment.development.ts @@ -1,7 +1,7 @@ export const environment = { production: false, - BASE_COLOR_API_URL: 'https://www.colourlovers.com/api/', NASA_API_BASE_URL : "https://api.nasa.gov", NASA_API_KEY: '3azuPabFKF5HNbHpZuQ1rGzIPO6i2DbOLQ6hYuGl', - NASA_API_IMAGE_BASE_URL:'https://images-api.nasa.gov' + NASA_API_IMAGE_BASE_URL:'https://images-api.nasa.gov', + AUTH_API_BASE:'http://makusu.duckdns.org:3000' };