login et register + chat et discussion services
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Router } from '@angular/router';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import {LoggedUser} from "../../models/user.model";
|
||||
import { LoggedUser } from "../../models/user.model";
|
||||
|
||||
interface LoginResponse {
|
||||
token: string;
|
||||
@@ -14,6 +14,11 @@ interface LoginResponse {
|
||||
description: string | null;
|
||||
}
|
||||
|
||||
interface RegisterRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthService {
|
||||
private http = inject(HttpClient);
|
||||
@@ -56,7 +61,15 @@ export class AuthService {
|
||||
localStorage.setItem(this.USER_KEY, JSON.stringify(user));
|
||||
this.currentUser.set(user);
|
||||
|
||||
await this.router.navigate(['/']); // adapte la route
|
||||
await this.router.navigate(['/main/menu']);
|
||||
}
|
||||
|
||||
async register(username: string, password: string): Promise<void> {
|
||||
await firstValueFrom(
|
||||
this.http.post<void>('/API/users/register', { username, password } as RegisterRequest)
|
||||
);
|
||||
|
||||
await this.login(username, password);
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
import { LoginService } from "../../services/api/login.service";
|
||||
import { AuthService } from "../../core/auth/auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'login-form',
|
||||
@@ -16,9 +16,8 @@ import { LoginService } from "../../services/api/login.service";
|
||||
export class LoginFormComponent {
|
||||
|
||||
private fb = inject(FormBuilder);
|
||||
private loginService = inject(LoginService);
|
||||
private authService = inject(AuthService);
|
||||
private router = inject(Router);
|
||||
private navCtrl = inject(NavController);
|
||||
|
||||
isLoading = false;
|
||||
|
||||
@@ -35,26 +34,20 @@ export class LoginFormComponent {
|
||||
if (this.loginForm.valid) {
|
||||
this.isLoading = true;
|
||||
|
||||
const request = {
|
||||
name: this.loginForm.value.name!,
|
||||
password: this.loginForm.value.password!
|
||||
};
|
||||
|
||||
this.loginService.login(request).subscribe({
|
||||
next: (response) => {
|
||||
this.isLoading = false;
|
||||
// Le discussionId vient de la réponse de l'API
|
||||
this.navCtrl.navigateRoot(['main/messages', response.discussionId]);
|
||||
},
|
||||
error: (err) => {
|
||||
this.isLoading = false;
|
||||
if (err.status === 401) {
|
||||
console.error('Identifiant ou mot de passe incorrect.');
|
||||
} else {
|
||||
console.error('Impossible de contacter le serveur.');
|
||||
}
|
||||
try {
|
||||
await this.authService.login(
|
||||
this.loginForm.value.name!,
|
||||
this.loginForm.value.password!
|
||||
);
|
||||
} catch (err: any) {
|
||||
if (err.status === 401) {
|
||||
console.error('Identifiant ou mot de passe incorrect.');
|
||||
} else {
|
||||
console.error('Impossible de contacter le serveur.');
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
Object.values(this.loginForm.controls).forEach(control => {
|
||||
|
||||
@@ -12,7 +12,7 @@ export class MessagesSend {
|
||||
|
||||
private chatService = inject(ChatService);
|
||||
|
||||
@Input() discussionId!: string; // passé par le composant parent
|
||||
@Input() discussionId!: string;
|
||||
|
||||
sendMessage = new FormControl();
|
||||
isSending = false;
|
||||
@@ -21,7 +21,7 @@ export class MessagesSend {
|
||||
const message = this.sendMessage.value;
|
||||
|
||||
if (!message || message.trim() === '') return;
|
||||
if (this.isSending) return; // évite le double envoi
|
||||
if (this.isSending) return;
|
||||
|
||||
this.isSending = true;
|
||||
|
||||
@@ -30,7 +30,6 @@ export class MessagesSend {
|
||||
this.sendMessage.reset();
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de l\'envoi :', error);
|
||||
// Afficher une notification d'erreur ici
|
||||
} finally {
|
||||
this.isSending = false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<ion-content [fullscreen]="true" class="bg">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="logo-box">
|
||||
@@ -8,34 +7,37 @@
|
||||
|
||||
<h1>Knots</h1>
|
||||
|
||||
<div class="card">
|
||||
<div class="card" [formGroup]="registerForm">
|
||||
|
||||
<h3>Inscrivez-vous à Knots !</h3>
|
||||
<p class="subtitle">Commencez à nouer des liens !</p>
|
||||
|
||||
<ion-item lines="none" class="input">
|
||||
<ion-input placeholder="Nom d'utilisateur..."></ion-input>
|
||||
<ion-input placeholder="Nom d'utilisateur..." formControlName="username"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item lines="none" class="input">
|
||||
<ion-input type="password" placeholder="Mot de passe..."></ion-input>
|
||||
<ion-input type="password" placeholder="Mot de passe..." formControlName="password"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item lines="none" class="input">
|
||||
<ion-input type="password" placeholder="Confirmez votre mot de passe..."></ion-input>
|
||||
<ion-input type="password" placeholder="Confirmez votre mot de passe..." formControlName="confirmPassword"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-button expand="block" class="btn">
|
||||
Créer son compte
|
||||
<p *ngIf="registerForm.hasError('passwordMismatch')" style="color:#d97070; font-size:13px; text-align:center; margin:0;">
|
||||
Les mots de passe ne correspondent pas.
|
||||
</p>
|
||||
|
||||
<ion-button expand="block" class="btn" (click)="submitForm()" [disabled]="isLoading">
|
||||
{{ isLoading ? 'Création...' : 'Créer son compte' }}
|
||||
</ion-button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="signup">
|
||||
Déjà un compte ?<br>
|
||||
<a (click)="goToLogin()" >Connectez-vous ici</a>
|
||||
<a (click)="goToLogin()">Connectez-vous ici</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</ion-content>
|
||||
@@ -1,30 +1,59 @@
|
||||
import {Component, inject} from '@angular/core';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import {
|
||||
IonButton,
|
||||
IonCard,
|
||||
IonCardContent,
|
||||
IonCardHeader,
|
||||
IonCardSubtitle,
|
||||
IonCardTitle, IonContent, IonInput, IonItem
|
||||
IonButton, IonContent, IonInput, IonItem
|
||||
} from "@ionic/angular/standalone";
|
||||
import {Router} from "@angular/router";
|
||||
import { Router } from "@angular/router";
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import {AuthService} from "../../core/auth/auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-register-form',
|
||||
imports: [
|
||||
IonButton,
|
||||
IonInput,
|
||||
IonContent,
|
||||
IonItem
|
||||
],
|
||||
templateUrl: './register-form.component.html',
|
||||
styleUrl: './register-form.component.css'
|
||||
selector: 'app-register-form',
|
||||
imports: [IonButton, IonInput, IonContent, IonItem, ReactiveFormsModule, CommonModule],
|
||||
templateUrl: './register-form.component.html',
|
||||
styleUrl: './register-form.component.css'
|
||||
})
|
||||
export class RegisterFormComponent {
|
||||
|
||||
private router = inject(Router)
|
||||
private router = inject(Router);
|
||||
private fb = inject(FormBuilder);
|
||||
private authService = inject(AuthService);
|
||||
|
||||
isLoading = false;
|
||||
|
||||
registerForm = this.fb.group({
|
||||
username: ['', [Validators.required, Validators.maxLength(50)]],
|
||||
password: ['', [Validators.required, Validators.minLength(12), Validators.maxLength(50)]],
|
||||
confirmPassword: ['', [Validators.required]]
|
||||
}, { validators: this.passwordMatchValidator });
|
||||
|
||||
passwordMatchValidator(form: any) {
|
||||
const password = form.get('password')?.value;
|
||||
const confirm = form.get('confirmPassword')?.value;
|
||||
return password === confirm ? null : { passwordMismatch: true };
|
||||
}
|
||||
|
||||
goToLogin() {
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
|
||||
async submitForm() {
|
||||
if (this.registerForm.valid) {
|
||||
this.isLoading = true;
|
||||
try {
|
||||
await this.authService.register(
|
||||
this.registerForm.value.username!,
|
||||
this.registerForm.value.password!
|
||||
);
|
||||
} catch (err: any) {
|
||||
if (err.status === 409) {
|
||||
console.error('Ce nom d\'utilisateur est déjà pris.');
|
||||
} else {
|
||||
console.error('Impossible de contacter le serveur.');
|
||||
}
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ChatService {
|
||||
|
||||
private hub: HubConnection;
|
||||
|
||||
constructor() {
|
||||
this.hub = new HubConnectionBuilder()
|
||||
.withUrl('https://localhost:5001/hubs/chat')
|
||||
.withAutomaticReconnect()
|
||||
.build();
|
||||
}
|
||||
|
||||
async connect() {
|
||||
if (this.hub.state === HubConnectionState.Disconnected) {
|
||||
await this.hub.start();
|
||||
}
|
||||
}
|
||||
|
||||
async sendMessage(discussionId: string, content: string) {
|
||||
await this.connect(); // s'assure que la connexion est active
|
||||
await this.hub.invoke('SendMessage', discussionId, content);
|
||||
}
|
||||
|
||||
onMessage(callback: (message: any) => void) {
|
||||
this.hub.on('ReceiveMessage', callback);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import {Observable} from "rxjs";
|
||||
import {Discussion} from "../../pages/menu/menu-users/menu-users.component";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {inject, Injectable} from "@angular/core";
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class discussionsService {
|
||||
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = 'https://localhost:5001/API';
|
||||
|
||||
getDiscussions(): Observable<Discussion[]> {
|
||||
return this.http.get<Discussion[]>(`${this.apiUrl}/discussions`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user