From 70914dddbaff2e6609ec2236109a3c2195a879b0 Mon Sep 17 00:00:00 2001 From: Maxence Date: Tue, 13 May 2025 15:22:20 +0200 Subject: [PATCH 1/2] friend component --- .../friend-page/friend-page.component.html | 71 ++++++++++++++++-- .../friend-page/friend-page.component.ts | 73 +++++++++++++++++-- .../login-page/login-page.component.ts | 1 + src/app/components/navbar/navbar.component.ts | 1 + src/app/services/friends/friends.service.ts | 9 +++ .../local-storage/local-storage.service.ts | 13 ++++ src/app/services/user/user.service.spec.ts | 16 ++++ src/app/services/user/user.service.ts | 26 +++++++ 8 files changed, 199 insertions(+), 11 deletions(-) create mode 100644 src/app/services/user/user.service.spec.ts create mode 100644 src/app/services/user/user.service.ts diff --git a/src/app/components/friend-page/friend-page.component.html b/src/app/components/friend-page/friend-page.component.html index 8d07e0c..5f698b9 100644 --- a/src/app/components/friend-page/friend-page.component.html +++ b/src/app/components/friend-page/friend-page.component.html @@ -51,14 +51,46 @@ id="search-friends" class="w-full p-2 border rounded-lg dark:bg-gray-700 dark:text-white" placeholder="Rechercher un ami..." + [(ngModel)]="searchTerm" + (ngModelChange)="searchUser($event)" /> + +
+
+
+ Friend 2 + {{ + user.username + }} +
+ +
+
+
-

Mes Amis

+

Amis

+
+

Aucun amis

+
-
-

Mes demandes d'amis

+
+

Demandes

+
+
@@ -141,7 +175,7 @@ class="w-4 h-4" fill="none" viewBox="0 0 24 24" - stroke="currentColor" + stroke="currentColor"private >
+
+

En attente

+
+
+
+
+ +
+ Friend 2 + {{ + friend.username + }} +
+ + +
diff --git a/src/app/components/friend-page/friend-page.component.ts b/src/app/components/friend-page/friend-page.component.ts index e758ec3..0680691 100644 --- a/src/app/components/friend-page/friend-page.component.ts +++ b/src/app/components/friend-page/friend-page.component.ts @@ -1,10 +1,13 @@ import { CommonModule } from '@angular/common'; import { Component, OnInit } from '@angular/core'; import { FriendsService } from '../../services/friends/friends.service'; +import { FormsModule, NgModel } from '@angular/forms'; +import { UserService } from '../../services/user/user.service'; +import { LocalStorageService } from '../../services/local-storage/local-storage.service'; @Component({ selector: 'app-friend-page', - imports: [CommonModule], + imports: [CommonModule, FormsModule], templateUrl: './friend-page.component.html', }) export class FriendPageComponent implements OnInit { @@ -14,23 +17,62 @@ export class FriendPageComponent implements OnInit { friend_user_id: string; id: string; }[] = []; + + protected listUser: { + uid: string, + username: string + }[] = []; + userId: string = ''; status: string = ''; isFriendModalOpen: boolean = false; hasAcceptedFriends: boolean = false; - hasPendingFriends: boolean = false; + hasPendingFriends: boolean = false;; + searchTerm: string = ''; - constructor(private friendService: FriendsService) {} + constructor(private friendService: FriendsService, private userService:UserService, private localStorage: LocalStorageService) {} ngOnInit(): void { this.getFriendData(); } + + protected searchUser(username: string) { + this.searchTerm = username + if (this.searchTerm) { + this.getUserData(this.searchTerm.trim()) + } + else { + this.listUser = [] + } + } + + protected addUser(user_id:string): void { + this.friendService.addFriend(user_id).subscribe((data:any) => { + if(data.id){ + const add_user = this.listUser.find(x => x.uid == user_id) + if (add_user){ + this.listFriend.push({username:add_user.username, status:"pending", friend_user_id:add_user.uid, id:data.id}) + this.searchTerm = ''; + this.listUser = []; + } + } + }) + } + + private getUserData(search:string): void{ + const username = this.localStorage.getUsername() + this.userService.getUser('^(?!'+username+')'+search).subscribe((data:any[]) => { + if (data.length > 0) { + const existingFriendIds = this.listFriend.map(friend => friend.friend_user_id); + this.listUser = data.filter(user => !existingFriendIds.includes(user.uid)); + } + }) + } private getFriendData(): void { this.friendService.getFriend().subscribe((data: any[]) => { if (data.length > 0) { data.forEach((friend) => { - console.log(friend); let status = friend['status']; let userId = friend['friend_user_id']; let id = friend['id']; @@ -84,6 +126,27 @@ export class FriendPageComponent implements OnInit { } deleteFriend(id: string) { - this.friendService.deleteFriend(id).subscribe(); + this.friendService.deleteFriend(id).subscribe((data :any) => { + if (data.message == 'Friend deleted') { + this.listFriend.forEach((friend, index) => { + if(friend.id == id) { + this.listFriend.splice(index, 1) + } + }) + } + }); + } + + hasNoAcceptedFriends(): boolean { + return this.listFriend.filter(friend => friend.status === 'accepted').length === 0; + } + + hasPendingApprovalFriend(): boolean { + return this.listFriend.filter(friend => friend.status === 'pending_approval').length !== 0; + } + + hasPendingFriend(): boolean { + return this.listFriend.filter(friend => friend.status === 'pending').length !== 0; } + } diff --git a/src/app/components/login-page/login-page.component.ts b/src/app/components/login-page/login-page.component.ts index 93778af..ae85187 100644 --- a/src/app/components/login-page/login-page.component.ts +++ b/src/app/components/login-page/login-page.component.ts @@ -69,6 +69,7 @@ export class LoginPageComponent { this.loginService.login(this.user.login, this.user.password).subscribe({ next: (response) => { this.localStorageService.setToken(response.access_token); + this.localStorageService.setUsername(this.user.login) this.closeLoginModal(); setTimeout(() => { this.router.navigate(['/map']); diff --git a/src/app/components/navbar/navbar.component.ts b/src/app/components/navbar/navbar.component.ts index 0eea527..f53de85 100644 --- a/src/app/components/navbar/navbar.component.ts +++ b/src/app/components/navbar/navbar.component.ts @@ -150,6 +150,7 @@ export class NavbarComponent implements OnInit { public logout() { this.localStorageService.removeToken(); + this.localStorageService.removeUsername(); this.router.navigate(['/']); } } diff --git a/src/app/services/friends/friends.service.ts b/src/app/services/friends/friends.service.ts index 8bd49a1..c9710c9 100644 --- a/src/app/services/friends/friends.service.ts +++ b/src/app/services/friends/friends.service.ts @@ -30,6 +30,15 @@ export class FriendsService { return this.http.get(url, { headers }); } + addFriend(user_id: string){ + const url = `${this.apiURL}/friend/add`; + const headers = new HttpHeaders({ + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + localStorage.getItem('auth_token'), + }); + return this.http.post(url, { friend_user_id:user_id } , { headers }) + } + acceptFriendById(id: string){ const url = `${this.apiURL}/friend/${id}/accept`; const headers = new HttpHeaders({ diff --git a/src/app/services/local-storage/local-storage.service.ts b/src/app/services/local-storage/local-storage.service.ts index 16ee8ad..b2f66b2 100644 --- a/src/app/services/local-storage/local-storage.service.ts +++ b/src/app/services/local-storage/local-storage.service.ts @@ -7,6 +7,7 @@ import { ModalService } from '../modal/modal.service'; }) export class LocalStorageService { private readonly AUTH_TOKEN_KEY = 'auth_token'; + private readonly USERNAME_KEY = 'username'; constructor(private router: Router, private modalService: ModalService) {} @@ -14,6 +15,18 @@ export class LocalStorageService { localStorage.setItem(this.AUTH_TOKEN_KEY, token); } + setUsername(username: string): void { + localStorage.setItem(this.USERNAME_KEY, username); + } + + getUsername(): string | null{ + return localStorage.getItem(this.USERNAME_KEY); + } + + removeUsername(): void { + localStorage.removeItem(this.USERNAME_KEY); + } + getToken(): string | null { // Check if token is expired const token = localStorage.getItem(this.AUTH_TOKEN_KEY); diff --git a/src/app/services/user/user.service.spec.ts b/src/app/services/user/user.service.spec.ts new file mode 100644 index 0000000..3f804c9 --- /dev/null +++ b/src/app/services/user/user.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { UserService } from './user.service'; + +describe('UserService', () => { + let service: UserService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(UserService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/user/user.service.ts b/src/app/services/user/user.service.ts new file mode 100644 index 0000000..b977765 --- /dev/null +++ b/src/app/services/user/user.service.ts @@ -0,0 +1,26 @@ +import { Injectable, OnInit } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { environment } from '../../../environments/environment'; + +@Injectable({ + providedIn: 'root' +}) +export class UserService { + + private apiURL = environment.apiURL; + constructor(private http: HttpClient) { + } + + getUser(username:string) { + const url = `${this.apiURL}/users`; + const headers = new HttpHeaders({ + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + localStorage.getItem('auth_token'), + }); + const params = { name : username }; + + return this.http.get(url,{ headers:headers, params:params }) + } + + +} \ No newline at end of file From 8d08868560136e70f092a81e1c815188949d58e8 Mon Sep 17 00:00:00 2001 From: Maxence Date: Thu, 15 May 2025 08:36:11 +0200 Subject: [PATCH 2/2] end friend component --- .../friend-page/friend-page.component.html | 2 +- .../friend-page/friend-page.component.ts | 39 +++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/app/components/friend-page/friend-page.component.html b/src/app/components/friend-page/friend-page.component.html index 5f698b9..8cccf93 100644 --- a/src/app/components/friend-page/friend-page.component.html +++ b/src/app/components/friend-page/friend-page.component.html @@ -52,7 +52,7 @@ class="w-full p-2 border rounded-lg dark:bg-gray-700 dark:text-white" placeholder="Rechercher un ami..." [(ngModel)]="searchTerm" - (ngModelChange)="searchUser($event)" + (ngModelChange)="onSearchTermChange($event)" />
diff --git a/src/app/components/friend-page/friend-page.component.ts b/src/app/components/friend-page/friend-page.component.ts index 0680691..0cbf0a0 100644 --- a/src/app/components/friend-page/friend-page.component.ts +++ b/src/app/components/friend-page/friend-page.component.ts @@ -4,6 +4,7 @@ import { FriendsService } from '../../services/friends/friends.service'; import { FormsModule, NgModel } from '@angular/forms'; import { UserService } from '../../services/user/user.service'; import { LocalStorageService } from '../../services/local-storage/local-storage.service'; +import { debounceTime, distinctUntilChanged, Subject } from 'rxjs'; @Component({ selector: 'app-friend-page', @@ -29,11 +30,23 @@ export class FriendPageComponent implements OnInit { hasAcceptedFriends: boolean = false; hasPendingFriends: boolean = false;; searchTerm: string = ''; + searchTermChanged = new Subject(); - constructor(private friendService: FriendsService, private userService:UserService, private localStorage: LocalStorageService) {} + + constructor(private friendService: FriendsService, private userService:UserService, private localStorage: LocalStorageService) { + + } ngOnInit(): void { this.getFriendData(); + this.searchTermChanged + .pipe( + debounceTime(200), + distinctUntilChanged() + ) + .subscribe((username: string) => { + this.searchUser(username); + }); } protected searchUser(username: string) { @@ -46,6 +59,20 @@ export class FriendPageComponent implements OnInit { } } + onSearchTermChange(username: string) { + this.searchTermChanged.next(username); + } + + private getUserData(search:string): void{ + const username = this.localStorage.getUsername() + this.userService.getUser('^(?!'+username+')'+search).subscribe((data:any[]) => { + if (data.length > 0) { + const existingFriendIds = this.listFriend.map(friend => friend.friend_user_id); + this.listUser = data.filter(user => !existingFriendIds.includes(user.uid)); + } + }) + } + protected addUser(user_id:string): void { this.friendService.addFriend(user_id).subscribe((data:any) => { if(data.id){ @@ -59,16 +86,6 @@ export class FriendPageComponent implements OnInit { }) } - private getUserData(search:string): void{ - const username = this.localStorage.getUsername() - this.userService.getUser('^(?!'+username+')'+search).subscribe((data:any[]) => { - if (data.length > 0) { - const existingFriendIds = this.listFriend.map(friend => friend.friend_user_id); - this.listUser = data.filter(user => !existingFriendIds.includes(user.uid)); - } - }) - } - private getFriendData(): void { this.friendService.getFriend().subscribe((data: any[]) => { if (data.length > 0) {