Début du login + parametres
This commit is contained in:
@@ -3,9 +3,10 @@ import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
import { provideIonicAngular } from '@ionic/angular/standalone';
|
||||
import {provideHttpClient} from "@angular/common/http";
|
||||
import {provideHttpClient, withInterceptors} from "@angular/common/http";
|
||||
import {authInterceptor} from "./core/auth/auth.interceptor";
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideIonicAngular({}), provideHttpClient()],
|
||||
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideIonicAngular({}),provideHttpClient(withInterceptors([authInterceptor])), provideHttpClient()],
|
||||
};
|
||||
|
||||
|
||||
+6
-11
@@ -1,4 +1,5 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import {authGuard} from "./core/auth/auth.guard";
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
@@ -8,35 +9,29 @@ export const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'main',
|
||||
canActivate: [authGuard],
|
||||
loadComponent: () => import('./pages/main/main.component').then(x => x.Main),
|
||||
children: [
|
||||
/*{
|
||||
path:'groupmessages',
|
||||
loadComponent: () => import('./pages/groupmessages/groupmessages.component').then(x => x.Groupmessages)
|
||||
},*/
|
||||
|
||||
{
|
||||
path: 'messages/:discussionId',
|
||||
loadComponent: () => import('./pages/messages/messages-main/messages-main.component').then(x => x.MessagesMain)
|
||||
},
|
||||
{
|
||||
path:'menu',
|
||||
path: 'menu',
|
||||
loadComponent: () => import('./pages/menu/menu/menu.component').then(x => x.Menu)
|
||||
},
|
||||
|
||||
{
|
||||
path:'parameters',
|
||||
path: 'parameters',
|
||||
loadComponent: () => import('./pages/parameters/parameters-main/parameters-main.component').then(x => x.ParametersMain)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path:'login',
|
||||
path: 'login',
|
||||
loadComponent: () => import('./pages/login-form/login-form.component').then(x => x.LoginFormComponent)
|
||||
},
|
||||
|
||||
{
|
||||
path:'register',
|
||||
path: 'register',
|
||||
loadComponent: () => import('./pages/register-form/register-form.component').then(x => x.RegisterFormComponent)
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,13 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { CanActivateFn, Router } from '@angular/router';
|
||||
import {AuthService} from "./auth.service";
|
||||
|
||||
export const authGuard: CanActivateFn = () => {
|
||||
const authService = inject(AuthService);
|
||||
const router = inject(Router);
|
||||
|
||||
if (authService.isLoggedIn()) return true;
|
||||
|
||||
router.navigate(['/login']);
|
||||
return false;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { HttpInterceptorFn } from '@angular/common/http';
|
||||
import { inject } from '@angular/core';
|
||||
import {AuthService} from "./auth.service";
|
||||
|
||||
export const authInterceptor: HttpInterceptorFn = (req, next) => {
|
||||
const token = inject(AuthService).getToken();
|
||||
|
||||
if (token) {
|
||||
req = req.clone({
|
||||
setHeaders: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
}
|
||||
|
||||
return next(req);
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
import { inject, Injectable, signal } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Router } from '@angular/router';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import {LoggedUser} from "../../models/user.model";
|
||||
|
||||
interface LoginResponse {
|
||||
token: string;
|
||||
id: number;
|
||||
username: string;
|
||||
email: string | null;
|
||||
tel: string | null;
|
||||
profilePicture: string | null;
|
||||
description: string | null;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthService {
|
||||
private http = inject(HttpClient);
|
||||
private router = inject(Router);
|
||||
|
||||
private readonly TOKEN_KEY = 'knots_token';
|
||||
private readonly USER_KEY = 'knots_user';
|
||||
|
||||
currentUser = signal<LoggedUser | null>(this.loadUser());
|
||||
|
||||
private loadUser(): LoggedUser | null {
|
||||
const raw = localStorage.getItem(this.USER_KEY);
|
||||
return raw ? JSON.parse(raw) : null;
|
||||
}
|
||||
|
||||
isLoggedIn(): boolean {
|
||||
return !!localStorage.getItem(this.TOKEN_KEY);
|
||||
}
|
||||
|
||||
getToken(): string | null {
|
||||
return localStorage.getItem(this.TOKEN_KEY);
|
||||
}
|
||||
|
||||
async login(username: string, password: string): Promise<void> {
|
||||
const response = await firstValueFrom(
|
||||
this.http.post<LoginResponse>('/API/users/login', { username, password })
|
||||
);
|
||||
|
||||
localStorage.setItem(this.TOKEN_KEY, response.token);
|
||||
|
||||
const user: LoggedUser = {
|
||||
id: response.id,
|
||||
username: response.username,
|
||||
email: response.email,
|
||||
tel: response.tel,
|
||||
profilePicture: response.profilePicture,
|
||||
description: response.description,
|
||||
};
|
||||
|
||||
localStorage.setItem(this.USER_KEY, JSON.stringify(user));
|
||||
this.currentUser.set(user);
|
||||
|
||||
await this.router.navigate(['/']); // adapte la route
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
localStorage.removeItem(this.TOKEN_KEY);
|
||||
localStorage.removeItem(this.USER_KEY);
|
||||
this.currentUser.set(null);
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface LoggedUser {
|
||||
id: number;
|
||||
username: string;
|
||||
email: string | null;
|
||||
tel: string | null;
|
||||
profilePicture: string | null;
|
||||
description: string | null;
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Modifier les coordonnées</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="close.emit()">
|
||||
<ion-icon name="close-outline" />
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<form [formGroup]="form" (ngSubmit)="submit()">
|
||||
|
||||
<ion-item [class.invalid]="email.invalid && email.touched">
|
||||
<ion-input
|
||||
label="Email"
|
||||
labelPlacement="floating"
|
||||
type="email"
|
||||
formControlName="email"
|
||||
placeholder="exemple@email.com"
|
||||
/>
|
||||
</ion-item>
|
||||
<ion-note *ngIf="email.invalid && email.touched" color="danger">
|
||||
Adresse email invalide
|
||||
</ion-note>
|
||||
|
||||
<ion-item [class.invalid]="tel.invalid && tel.touched" class="ion-margin-top">
|
||||
<ion-input
|
||||
label="Téléphone"
|
||||
labelPlacement="floating"
|
||||
type="tel"
|
||||
formControlName="tel"
|
||||
placeholder="0612345678"
|
||||
/>
|
||||
</ion-item>
|
||||
<ion-note *ngIf="tel.invalid && tel.touched" color="danger">
|
||||
Numéro à 10 chiffres requis
|
||||
</ion-note>
|
||||
|
||||
<ion-button
|
||||
expand="block"
|
||||
class="ion-margin-top"
|
||||
type="submit"
|
||||
[disabled]="form.invalid"
|
||||
>
|
||||
Valider
|
||||
</ion-button>
|
||||
|
||||
</form>
|
||||
</ion-content>
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
import {Component, EventEmitter, inject, Output, signal} from '@angular/core';
|
||||
import { addIcons } from 'ionicons';
|
||||
import { closeOutline } from 'ionicons/icons';
|
||||
import {
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonIcon, IonInput,
|
||||
IonItem, IonNote,
|
||||
IonTitle,
|
||||
IonToolbar
|
||||
} from "@ionic/angular/standalone";
|
||||
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
|
||||
import {firstValueFrom} from "rxjs";
|
||||
import {KnotsDTOUserUpdateUserContactDto, UsersService} from "../../../services/api";
|
||||
|
||||
@Component({
|
||||
selector: 'app-parameters-coordinates-form',
|
||||
imports: [
|
||||
IonHeader,
|
||||
IonToolbar,
|
||||
IonTitle,
|
||||
IonButtons,
|
||||
IonButton,
|
||||
IonIcon,
|
||||
IonContent,
|
||||
ReactiveFormsModule,
|
||||
IonItem,
|
||||
IonInput,
|
||||
IonNote
|
||||
],
|
||||
templateUrl: './parameters-coordinates-form.component.html',
|
||||
styleUrl: './parameters-coordinates-form.component.css'
|
||||
})
|
||||
export class ParametersCoordinatesFormComponent {
|
||||
@Output() close = new EventEmitter<void>();
|
||||
|
||||
private userService = inject(UsersService);
|
||||
//private authService = inject(AuthService);
|
||||
|
||||
loading = signal(false);
|
||||
|
||||
coordinatesForm = new FormGroup({
|
||||
email: new FormControl<string>(null, [Validators.required, Validators.email]),
|
||||
tel: new FormControl<string>(null, [Validators.required, Validators.pattern(/^\d{10}$/)]),
|
||||
});
|
||||
|
||||
constructor() {
|
||||
addIcons({ closeOutline });
|
||||
}
|
||||
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
//const user = this.userService.currentUser();
|
||||
|
||||
//this.coordinatesForm.patchValue({
|
||||
//email: user?.email ?? null,
|
||||
//tel: user?.tel ?? null,
|
||||
//});
|
||||
}
|
||||
|
||||
get email() { return this.coordinatesForm.get('email')!; }
|
||||
get tel() { return this.coordinatesForm.get('tel')!; }
|
||||
|
||||
async submitForm() {
|
||||
if (this.coordinatesForm.invalid) return;
|
||||
this.loading.set(true);
|
||||
|
||||
//const user = this.authService.currentUser();
|
||||
|
||||
const userValue: KnotsDTOUserUpdateUserContactDto = {
|
||||
email: this.coordinatesForm.value.email,
|
||||
tel: this.coordinatesForm.value.tel,
|
||||
};
|
||||
|
||||
try {
|
||||
//await firstValueFrom(this.userService.patchUserContactEndpoint(user.id, userValue));
|
||||
this.coordinatesForm.reset();
|
||||
this.close.emit();
|
||||
} catch (e) {
|
||||
console.error('Erreur lors de la mise à jour des coordonnées', e);
|
||||
}
|
||||
|
||||
this.loading.set(false);
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -1,4 +1,4 @@
|
||||
<button class="coordinates-btn">
|
||||
<button class="coordinates-btn" (click)="openModal()">
|
||||
<svg width="35" height="35" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M256 48c-114.9 0-208 93.1-208 208s93.1 208 208 208c42.6 0 81.8-12.8 114.4-34.7 6.6-4.5 8.3-13.5 3.8-20.1-4.5-6.6-13.5-8.3-20.1-3.8C325.9 420.6 292.2 432 256 432c-97 0-176-79-176-176S159 80 256 80s176 79 176 176v40c0 22.1-17.9 40-40 40s-40-17.9-40-40v-40c0-53-43-96-96-96s-96 43-96 96 43 96 96 96c22.1 0 42.4-7.5 58.6-20.1C328.7 354.2 358.1 368 392 368c39.7 0 72-32.3 72-72v-40c0-114.9-93.1-208-208-208zm0 272c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z" fill="#BD5A5A" fill-opacity="0.8"
|
||||
stroke="#BD5A5A"
|
||||
@@ -8,4 +8,10 @@
|
||||
/>
|
||||
</svg>
|
||||
<span class="username">Modifier les coordonnées</span>
|
||||
</button>
|
||||
</button>
|
||||
|
||||
<ion-modal [isOpen]="isModalOpen" (didDismiss)="closeModal()">
|
||||
<ng-template>
|
||||
<app-parameters-coordinates-form (close)="closeModal()" />
|
||||
</ng-template>
|
||||
</ion-modal>
|
||||
+7
-32
@@ -1,43 +1,18 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {Component} from '@angular/core';
|
||||
import { IonModal, IonButton } from '@ionic/angular/standalone';
|
||||
import {FormsModule} from "@angular/forms";
|
||||
|
||||
export interface Coordonnees {
|
||||
phone: string;
|
||||
email: string;
|
||||
}
|
||||
import {ParametersCoordinatesFormComponent} from "../parameters-coordinates-form/parameters-coordinates-form.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-parameters-coordinates',
|
||||
imports: [
|
||||
FormsModule
|
||||
],
|
||||
imports: [IonModal, FormsModule, ParametersCoordinatesFormComponent],
|
||||
templateUrl: './parameters-coordinates.component.html',
|
||||
styleUrl: './parameters-coordinates.component.css'
|
||||
})
|
||||
export class ParametersCoordinatesComponent {
|
||||
@Input() isOpen: boolean = false;
|
||||
@Output() closed = new EventEmitter<void>();
|
||||
@Output() saved = new EventEmitter<Coordonnees>();
|
||||
isModalOpen = false;
|
||||
|
||||
form: Coordonnees = { phone: '', email: '' };
|
||||
phoneFocused = false;
|
||||
emailFocused = false;
|
||||
|
||||
close(): void {
|
||||
this.closed.emit();
|
||||
}
|
||||
|
||||
save(): void {
|
||||
if (this.form.phone || this.form.email) {
|
||||
this.saved.emit({ ...this.form });
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
onOverlayClick(event: MouseEvent): void {
|
||||
if ((event.target as HTMLElement).classList.contains('modal-overlay')) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
openModal() { this.isModalOpen = true; }
|
||||
closeModal() { this.isModalOpen = false; }
|
||||
|
||||
}
|
||||
|
||||
@@ -247,4 +247,10 @@
|
||||
opacity: 1;
|
||||
transform: scale(1.15);
|
||||
}
|
||||
|
||||
.field-error {
|
||||
color: var(--ion-color-danger, #eb445a);
|
||||
font-size: 0.75rem;
|
||||
padding: 2px 0 0 4px;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,9 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Sous la div.field du username -->
|
||||
<span class="field-error" *ngIf="usernameError()">{{ usernameError() }}</span>
|
||||
|
||||
<!-- Bio field -->
|
||||
<div class="field bio-field">
|
||||
<ng-container *ngIf="!editingBio(); else editBioBlock">
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import {Component, signal} from '@angular/core';
|
||||
import {Component, inject, signal} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import {firstValueFrom} from "rxjs";
|
||||
import {UsersService} from "../../../services/api";
|
||||
import {AuthService} from "../../../core/auth/auth.service";
|
||||
|
||||
|
||||
@Component({
|
||||
@@ -10,36 +13,118 @@ import { FormsModule } from '@angular/forms';
|
||||
styleUrl: './parameters-profile.component.css'
|
||||
})
|
||||
export class ParametersProfileComponent {
|
||||
username = signal('Doggeybag');
|
||||
bio = signal('Joueur Valorant');
|
||||
private usersService = inject(UsersService);
|
||||
private authService = inject(AuthService);
|
||||
|
||||
profileImage = signal<string>(null);
|
||||
username = signal<string>(null);
|
||||
bio = signal<string>(null);
|
||||
|
||||
editingUsername = signal(false);
|
||||
editingBio = signal(false);
|
||||
|
||||
profileImage = signal<string | null>(null);
|
||||
usernameError = signal<string>(null);
|
||||
loading = signal(false);
|
||||
|
||||
onPhotoChange(event: Event): void {
|
||||
const input = event.target as HTMLInputElement;
|
||||
if (input.files && input.files[0]) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
this.profileImage.set(e.target?.result as string);
|
||||
};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
ngOnInit() {
|
||||
const user = this.authService.currentUser();
|
||||
this.profileImage.set(user?.profilePicture ?? null);
|
||||
this.username.set(user?.username ?? null);
|
||||
this.bio.set(user?.description ?? null);
|
||||
}
|
||||
|
||||
// --- Username ---
|
||||
|
||||
toggleEditUsername() {
|
||||
if (this.editingUsername()) {
|
||||
this.submitUsername();
|
||||
} else {
|
||||
this.usernameError.set(null);
|
||||
this.editingUsername.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
triggerFileInput(): void {
|
||||
const input = document.getElementById('photoInput') as HTMLInputElement;
|
||||
input?.click();
|
||||
async submitUsername() {
|
||||
const value = this.username()?.trim();
|
||||
|
||||
if (!value) {
|
||||
this.usernameError.set('Le pseudo ne peut pas être vide.');
|
||||
return;
|
||||
}
|
||||
if (value === this.authService.currentUser()?.username) {
|
||||
this.editingUsername.set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading.set(true);
|
||||
const user = this.authService.currentUser();
|
||||
|
||||
try {
|
||||
await firstValueFrom(this.usersService.patchUsernameEndpoint(user.id, { username: value }));
|
||||
this.usernameError.set(null);
|
||||
this.editingUsername.set(false);
|
||||
} catch (e: any) {
|
||||
if (e?.status === 400) {
|
||||
this.usernameError.set('Ce nom d\'utilisateur est déjà pris.');
|
||||
} else {
|
||||
this.usernameError.set('Erreur lors de la mise à jour.');
|
||||
}
|
||||
}
|
||||
|
||||
this.loading.set(false);
|
||||
}
|
||||
|
||||
toggleEditUsername(): void {
|
||||
this.editingUsername.update((v) => !v);
|
||||
// --- Bio ---
|
||||
|
||||
toggleEditBio() {
|
||||
if (this.editingBio()) {
|
||||
this.submitBio();
|
||||
} else {
|
||||
this.editingBio.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
toggleEditBio(): void {
|
||||
this.editingBio.update((v) => !v);
|
||||
async submitBio() {
|
||||
this.loading.set(true);
|
||||
const user = this.authService.currentUser();
|
||||
|
||||
try {
|
||||
await firstValueFrom(this.usersService.patchUserDescriptionEndpoint(user.id, { description: this.bio() }));
|
||||
this.editingBio.set(false);
|
||||
} catch (e) {
|
||||
console.error('Erreur lors de la mise à jour de la bio', e);
|
||||
}
|
||||
|
||||
this.loading.set(false);
|
||||
}
|
||||
|
||||
// --- Photo ---
|
||||
|
||||
triggerFileInput() {
|
||||
document.getElementById('photoInput')?.click();
|
||||
}
|
||||
|
||||
async onPhotoChange(event: Event) {
|
||||
const file = (event.target as HTMLInputElement).files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = async () => {
|
||||
const base64 = reader.result as string;
|
||||
this.profileImage.set(base64);
|
||||
|
||||
this.loading.set(true);
|
||||
const user = this.authService.currentUser();
|
||||
|
||||
try {
|
||||
await firstValueFrom(this.usersService.patchUserProfilePictureEndpoint(user.id, { profilePicture: base64 }));
|
||||
} catch (e) {
|
||||
console.error('Erreur lors de la mise à jour de la photo', e);
|
||||
}
|
||||
|
||||
this.loading.set(false);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -172,17 +172,29 @@ export class DiscussionsService extends BaseService {
|
||||
/**
|
||||
* @endpoint get /API/discussions
|
||||
* @param id
|
||||
* @param name
|
||||
* @param isGroup
|
||||
* @param membersCount
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
* @param options additional options
|
||||
*/
|
||||
public getDiscussionEndpoint(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<any>;
|
||||
public getDiscussionEndpoint(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<any>>;
|
||||
public getDiscussionEndpoint(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<any>>;
|
||||
public getDiscussionEndpoint(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<any> {
|
||||
public getDiscussionEndpoint(id: number, name: string, isGroup: boolean, membersCount: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<any>;
|
||||
public getDiscussionEndpoint(id: number, name: string, isGroup: boolean, membersCount: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<any>>;
|
||||
public getDiscussionEndpoint(id: number, name: string, isGroup: boolean, membersCount: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<any>>;
|
||||
public getDiscussionEndpoint(id: number, name: string, isGroup: boolean, membersCount: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable<any> {
|
||||
if (id === null || id === undefined) {
|
||||
throw new Error('Required parameter id was null or undefined when calling getDiscussionEndpoint.');
|
||||
}
|
||||
if (name === null || name === undefined) {
|
||||
throw new Error('Required parameter name was null or undefined when calling getDiscussionEndpoint.');
|
||||
}
|
||||
if (isGroup === null || isGroup === undefined) {
|
||||
throw new Error('Required parameter isGroup was null or undefined when calling getDiscussionEndpoint.');
|
||||
}
|
||||
if (membersCount === null || membersCount === undefined) {
|
||||
throw new Error('Required parameter membersCount was null or undefined when calling getDiscussionEndpoint.');
|
||||
}
|
||||
|
||||
let localVarQueryParameters = new OpenApiHttpParams(this.encoder);
|
||||
|
||||
@@ -195,6 +207,33 @@ export class DiscussionsService extends BaseService {
|
||||
);
|
||||
|
||||
|
||||
localVarQueryParameters = this.addToHttpParams(
|
||||
localVarQueryParameters,
|
||||
'Name',
|
||||
<any>name,
|
||||
QueryParamStyle.Form,
|
||||
true,
|
||||
);
|
||||
|
||||
|
||||
localVarQueryParameters = this.addToHttpParams(
|
||||
localVarQueryParameters,
|
||||
'IsGroup',
|
||||
<any>isGroup,
|
||||
QueryParamStyle.Form,
|
||||
true,
|
||||
);
|
||||
|
||||
|
||||
localVarQueryParameters = this.addToHttpParams(
|
||||
localVarQueryParameters,
|
||||
'MembersCount',
|
||||
<any>membersCount,
|
||||
QueryParamStyle.Form,
|
||||
true,
|
||||
);
|
||||
|
||||
|
||||
let localVarHeaders = this.defaultHeaders;
|
||||
|
||||
const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
|
||||
|
||||
@@ -58,10 +58,10 @@ export class UsersService extends BaseService {
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
* @param options additional options
|
||||
*/
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable<KnotsDTOUserGetUserDto>;
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<KnotsDTOUserGetUserDto>>;
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<KnotsDTOUserGetUserDto>>;
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable<any> {
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<KnotsDTOUserGetUserDto>;
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<KnotsDTOUserGetUserDto>>;
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<KnotsDTOUserGetUserDto>>;
|
||||
public createUserEndpoint(knotsDTOUserCreateUserDto: KnotsDTOUserCreateUserDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> {
|
||||
if (knotsDTOUserCreateUserDto === null || knotsDTOUserCreateUserDto === undefined) {
|
||||
throw new Error('Required parameter knotsDTOUserCreateUserDto was null or undefined when calling createUserEndpoint.');
|
||||
}
|
||||
@@ -69,8 +69,7 @@ export class UsersService extends BaseService {
|
||||
let localVarHeaders = this.defaultHeaders;
|
||||
|
||||
const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
|
||||
'application/json',
|
||||
'application/problem+json'
|
||||
'application/json'
|
||||
]);
|
||||
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
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`);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Observable, tap, finalize } from "rxjs";
|
||||
|
||||
export interface LoginRequest {
|
||||
name: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface LoginResponse {
|
||||
token: string;
|
||||
discussionId: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LoginService {
|
||||
|
||||
private http = inject(HttpClient);
|
||||
private apiUrl = 'https://localhost:5001/API';
|
||||
private isRefreshing = false;
|
||||
|
||||
login(credentials: LoginRequest): Observable<LoginResponse> {
|
||||
return this.http.post<LoginResponse>(`${this.apiUrl}/auth/login`, credentials).pipe(
|
||||
tap(response => localStorage.setItem('token', response.token))
|
||||
);
|
||||
}
|
||||
|
||||
refreshToken(): Observable<{ token: string }> {
|
||||
this.isRefreshing = true;
|
||||
|
||||
return this.http.post<{ token: string }>(`${this.apiUrl}/auth/refresh`, {}).pipe(
|
||||
tap(response => localStorage.setItem('token', response.token)),
|
||||
finalize(() => { this.isRefreshing = false; })
|
||||
);
|
||||
}
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem('token');
|
||||
}
|
||||
}
|
||||
@@ -19,4 +19,4 @@ export * from './knots-dto-user-update-user-contact-dto';
|
||||
export * from './knots-dto-user-update-user-description-dto';
|
||||
export * from './knots-dto-user-update-user-password-dto';
|
||||
export * from './knots-dto-user-update-user-profile-picture-dto';
|
||||
export * from './knots-dto-user-update-username-dto';
|
||||
export * from './knots-dto-user-update-username-dto';
|
||||
Reference in New Issue
Block a user