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

+
{{
+ 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..0cbf0a0 100644
--- a/src/app/components/friend-page/friend-page.component.ts
+++ b/src/app/components/friend-page/friend-page.component.ts
@@ -1,10 +1,14 @@
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';
+import { debounceTime, distinctUntilChanged, Subject } from 'rxjs';
@Component({
selector: 'app-friend-page',
- imports: [CommonModule],
+ imports: [CommonModule, FormsModule],
templateUrl: './friend-page.component.html',
})
export class FriendPageComponent implements OnInit {
@@ -14,23 +18,78 @@ 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 = '';
+ searchTermChanged = new Subject
();
+
- constructor(private friendService: FriendsService) {}
+ 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) {
+ this.searchTerm = username
+ if (this.searchTerm) {
+ this.getUserData(this.searchTerm.trim())
+ }
+ else {
+ this.listUser = []
+ }
+ }
+
+ 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){
+ 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 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 +143,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