From 80b5f9ba51a9faa2bae6024228c41d4f4e0d90bf Mon Sep 17 00:00:00 2001
From: "emre.kartal" <emre.kartal@etu.uca.fr>
Date: Mon, 27 May 2024 15:16:33 +0200
Subject: [PATCH 1/3] Fix get bets

---
 Sources/AllInApp/AllIn/Views/ProfileView.swift | 4 +++-
 Sources/Api/Sources/Api/BetApiManager.swift    | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/Sources/AllInApp/AllIn/Views/ProfileView.swift b/Sources/AllInApp/AllIn/Views/ProfileView.swift
index 6fb658f..48edfec 100644
--- a/Sources/AllInApp/AllIn/Views/ProfileView.swift
+++ b/Sources/AllInApp/AllIn/Views/ProfileView.swift
@@ -87,8 +87,10 @@ struct ProfileView: View {
                                 Spacer()
                                 
                                 Image(systemName: "chevron.right")
+                                    .resizable()
+                                    .frame(width: 8, height: 12)
                                     .foregroundColor(parameters[index].itemColor)
-                                    .padding(.trailing, 8)
+                                    .padding(.trailing, 14)
                             }
                             .padding(.vertical, 15)
                             .background(parameters[index].backgroundColor)
diff --git a/Sources/Api/Sources/Api/BetApiManager.swift b/Sources/Api/Sources/Api/BetApiManager.swift
index e094e42..d0e1f0e 100644
--- a/Sources/Api/Sources/Api/BetApiManager.swift
+++ b/Sources/Api/Sources/Api/BetApiManager.swift
@@ -20,7 +20,7 @@ public struct BetApiManager: BetDataManager {
         let url = URL(string: allInApi + "bets/gets")!
 
         var request = URLRequest(url: url)
-        request.httpMethod = "GET"
+        request.httpMethod = "POST"
         request.setValue("application/json", forHTTPHeaderField: "Content-Type")
         request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
 
-- 
2.36.3


From 431c95e84c6fb1929cb88feaec6e52bb3604adf3 Mon Sep 17 00:00:00 2001
From: ludelanier <lucas.delanier@etu.uca.fr>
Date: Mon, 27 May 2024 16:46:50 +0200
Subject: [PATCH 2/3] nice

---
 .../AllInApp/AllIn/Components/BetCard.swift   |  2 +-
 .../AllIn/Components/ChoiceCapsule.swift      | 34 ++++++++++++++-----
 .../AllInApp/AllIn/Ressources/Config.swift    |  2 +-
 .../Ressources/en.lproj/Localizable.strings   |  1 +
 .../Ressources/fr.lproj/Localizable.strings   |  1 +
 .../AllIn/ViewModels/BetViewModel.swift       | 25 ++++++++++----
 Sources/AllInApp/AllIn/Views/BetView.swift    | 11 +++---
 .../AllInApp/AllIn/Views/DetailsView.swift    | 10 +++---
 Sources/Api/Sources/Api/BetApiManager.swift   | 14 ++++++--
 Sources/Api/Sources/Api/UserApiManager.swift  |  2 +-
 .../Model/Sources/Model/BetDataManager.swift  |  2 +-
 Sources/Model/Sources/Model/Enums/File.swift  | 16 +++++++++
 Sources/Model/Sources/Model/Manager.swift     |  4 +--
 .../Sources/StubLib/BetStubManager.swift      |  2 +-
 14 files changed, 90 insertions(+), 36 deletions(-)
 create mode 100644 Sources/Model/Sources/Model/Enums/File.swift

diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift
index 2b7f637..2fb87a9 100644
--- a/Sources/AllInApp/AllIn/Components/BetCard.swift
+++ b/Sources/AllInApp/AllIn/Components/BetCard.swift
@@ -19,7 +19,7 @@ struct BetCard: View {
             VStack(alignment: .leading,spacing: 2){
                 HStack{
                     Spacer()
-                    Text("bet_proposed_by_format  \(bet.author.capitalized)")
+                    Text("bet_proposed_by_format \(bet.author.capitalized)")
                         .font(.system(size: 10))
                         .foregroundColor(AllInColors.grey800Color)
                     
diff --git a/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift b/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift
index f540b1a..da3c1c9 100644
--- a/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift
+++ b/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift
@@ -6,22 +6,39 @@
 //
 
 import SwiftUI
+import Model
 
 struct ChoiceCapsule: View {
-    
+    let filter: BetFilter
     @State var pressed = false
+    @ObservedObject var viewModel: BetViewModel
+    
+    var label: String {
+        switch filter {
+        case .isPublic:
+            return String(localized: "bet_public")
+        case .isInvitation:
+            return String(localized: "bet_invitation")
+        case .inProgress:
+            return String(localized: "bet_current")
+        case .isFinished:
+            return String(localized: "bet_finished")
+        default:
+            return "NaN"
+        }
+    }
     
     var body: some View {
         Group {
             if(pressed) {
-                Text("bet_current")
+                Text(label)
                     .textStyle(weight: .semibold, color: .white, size: 15)
                     .padding([.leading,.trailing],13.8)
                     .padding([.top,.bottom], 7)
                     .background(AllInColors.lightPurpleColor)
                     .clipShape(Capsule())
             } else {
-                Text("bet_current")
+                Text(label)
                     .textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
                     .padding([.leading,.trailing], 15)
                     .padding([.top,.bottom], 7)
@@ -34,14 +51,13 @@ struct ChoiceCapsule: View {
             }
         }
         .onTapGesture() {
+            if(!pressed) {
+                viewModel.filters.insert(filter)
+            } else {
+                viewModel.filters.remove(filter)
+            }
             pressed.toggle()
         }
         
     }
 }
-
-struct ChoiceCapsule_Previews: PreviewProvider {
-    static var previews: some View {
-        ChoiceCapsule()
-    }
-}
diff --git a/Sources/AllInApp/AllIn/Ressources/Config.swift b/Sources/AllInApp/AllIn/Ressources/Config.swift
index d734b64..ab35db0 100644
--- a/Sources/AllInApp/AllIn/Ressources/Config.swift
+++ b/Sources/AllInApp/AllIn/Ressources/Config.swift
@@ -8,5 +8,5 @@
 import Foundation
 
 struct Config {
-    static let allInApi = "https://codefirst.iut.uca.fr/containers/AllDev-api/"
+    static let allInApi = "http://localhost:8080/"
 }
diff --git a/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings b/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings
index bdfcf8f..9939b51 100644
--- a/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings
+++ b/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings
@@ -132,6 +132,7 @@
 "bet_ended" = "Ended on";
 "bet_participate" = "Participate";
 "bet_proposed_by_format  %@" = "Proposed by  %@";
+"bet_proposed_by_format" = "Proposed by";
 "bet_players_waiting_format %@" = "%@ joueurs en attente";
 "bet_players_format" = "players";
 "bet_points_at_stake_format" = "points at stake";
diff --git a/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings b/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings
index f3e9b2d..4a22e95 100644
--- a/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings
+++ b/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings
@@ -132,6 +132,7 @@
 "bet_ended" = "A pris fin le";
 "bet_participate" = "Participer";
 "bet_proposed_by_format %@" = "Proposé par %@";
+"bet_proposed_by_format" = "Proposé par";
 "bet_players_waiting_format %@" = "%@ players waiting";
 "bet_players_format" = "joueurs";
 "bet_points_at_stake_format" = "points en jeu";
diff --git a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift
index 3f7e383..6b939b9 100644
--- a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift
+++ b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift
@@ -17,13 +17,27 @@ class BetViewModel: ObservableObject {
     @Published private(set) var bets: [Bet] = []
     @Published var betsOver: [BetDetail] = []
     @Published var showingSheet: Bool  = false
-    
-    init() {
-        getItems()
-    }
+    @Published var filters: Set<BetFilter> = [] {
+           didSet {
+               getItems()
+           }
+       }
+       
+       private var cancellables = Set<AnyCancellable>()
+       
+       init() {
+           getItems()
+           
+           // Observer for changes in filters
+           $filters
+               .sink { [weak self] _ in
+                   self?.getItems()
+               }
+               .store(in: &cancellables)
+       }
     
     func getItems() {
-        manager.getBets(withIndex: 0, withCount: 20) { bets in
+        manager.getBets(withIndex: 0, withCount: 20, filters: Array(filters)) { bets in
             self.bets = bets
         }
         manager.getBetsOver() { bets in
@@ -31,7 +45,6 @@ class BetViewModel: ObservableObject {
             if !self.betsOver.isEmpty {
                 self.showingSheet = true
             }
-            print(bets)
         }
     }
 }
diff --git a/Sources/AllInApp/AllIn/Views/BetView.swift b/Sources/AllInApp/AllIn/Views/BetView.swift
index 2878d7a..80e8630 100644
--- a/Sources/AllInApp/AllIn/Views/BetView.swift
+++ b/Sources/AllInApp/AllIn/Views/BetView.swift
@@ -35,13 +35,10 @@ struct BetView: View {
                             AllInColors.fadeInGradiantCard
                             ScrollView(.horizontal,showsIndicators: false){
                                 HStack{
-                                    ChoiceCapsule()
-                                    ChoiceCapsule()
-                                    ChoiceCapsule()
-                                    ChoiceCapsule()
-                                    ChoiceCapsule()
-                                    ChoiceCapsule()
-                                    ChoiceCapsule()
+                                    ChoiceCapsule(filter: .isPublic, viewModel: viewModel)
+                                    ChoiceCapsule(filter: .isInvitation, viewModel: viewModel)
+                                    ChoiceCapsule(filter: .inProgress, viewModel: viewModel)
+                                    ChoiceCapsule(filter: .isFinished, viewModel: viewModel)
                                 }
                                 .padding(.leading,25)
                                 .padding([.top,.bottom],15)
diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift
index f354f52..f32cbdd 100644
--- a/Sources/AllInApp/AllIn/Views/DetailsView.swift
+++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift
@@ -16,16 +16,16 @@ struct DetailsView: View {
         if let betType = viewModel.betDetail?.bet.status {
             switch betType {
             case .inProgress:
-                return ("bet_status_in_progress", AllInColors.darkPurpleColor)
+                return (String(localized: "bet_status_in_progress"), AllInColors.darkPurpleColor)
             case .waiting, .closing:
-                return ("bet_status_waiting", AllInColors.pink100)
+                return (String(localized: "bet_status_waiting"), AllInColors.pink100)
             case .finished:
-                return ("bet_status_finished", AllInColors.grey100Color)
+                return (String(localized: "bet_status_finished"), AllInColors.grey100Color)
             case .cancelled:
-                return ("bet_status_cancelled", AllInColors.grey100Color)
+                return (String(localized: "bet_status_cancelled"), AllInColors.grey100Color)
             }
         } else {
-            return ("bet_status_unavailable", AllInColors.pink100)
+            return (String(localized: "bet_status_unavailable"), AllInColors.pink100)
         }
     }
     
diff --git a/Sources/Api/Sources/Api/BetApiManager.swift b/Sources/Api/Sources/Api/BetApiManager.swift
index d0e1f0e..ec7f5ee 100644
--- a/Sources/Api/Sources/Api/BetApiManager.swift
+++ b/Sources/Api/Sources/Api/BetApiManager.swift
@@ -16,7 +16,7 @@ public struct BetApiManager: BetDataManager {
         self.token = token
     }
     
-    public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
+    public func getBets(withIndex index: Int, withCount count: Int, filters: [BetFilter] = [], completion: @escaping ([Bet]) -> Void) {
         let url = URL(string: allInApi + "bets/gets")!
 
         var request = URLRequest(url: url)
@@ -24,13 +24,22 @@ public struct BetApiManager: BetDataManager {
         request.setValue("application/json", forHTTPHeaderField: "Content-Type")
         request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
 
-        var bets: [Bet] = []
+        let filterStrings = filters.map { $0.rawValue }
+        let jsonDictionary: [String: Any] = ["filters": filterStrings]
+        do {
+            let jsonData = try JSONSerialization.data(withJSONObject: jsonDictionary, options: [])
+            request.httpBody = jsonData
+        } catch {
+            print("Error creating JSON data: \(error)")
+            return
+        }
 
         URLSession.shared.dataTask(with: request) { data, response, error in
             if let data = data {
                 print ("ALLIN : get bets")
                 do {
                     if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
+                        var bets: [Bet] = []
                         for json in jsonArray {
                             if let bet = FactoryApiBet().toBet(from: json) {
                                 bets.append(bet)
@@ -45,6 +54,7 @@ public struct BetApiManager: BetDataManager {
             }
         }.resume()
     }
+
     
     public func getUsers(username: String) -> [User] {
         return []
diff --git a/Sources/Api/Sources/Api/UserApiManager.swift b/Sources/Api/Sources/Api/UserApiManager.swift
index 267bf16..ef89393 100644
--- a/Sources/Api/Sources/Api/UserApiManager.swift
+++ b/Sources/Api/Sources/Api/UserApiManager.swift
@@ -8,7 +8,7 @@
 import Foundation
 import Model
 
-let allInApi = "https://codefirst.iut.uca.fr/containers/AllDev-api/"
+let allInApi = "http://localhost:8080/"
 
 public struct UserApiManager: UserDataManager {
     
diff --git a/Sources/Model/Sources/Model/BetDataManager.swift b/Sources/Model/Sources/Model/BetDataManager.swift
index 6fede4a..200ccf4 100644
--- a/Sources/Model/Sources/Model/BetDataManager.swift
+++ b/Sources/Model/Sources/Model/BetDataManager.swift
@@ -8,7 +8,7 @@
 import Foundation
 
 public protocol BetDataManager {
-    func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void)
+    func getBets(withIndex index: Int, withCount count: Int, filters: [BetFilter], completion: @escaping ([Bet]) -> Void)
     func getUsers(username: String) -> [User]
     func getBet(withId id: String, completion: @escaping (BetDetail) -> Void)
 }
diff --git a/Sources/Model/Sources/Model/Enums/File.swift b/Sources/Model/Sources/Model/Enums/File.swift
new file mode 100644
index 0000000..f5b22f5
--- /dev/null
+++ b/Sources/Model/Sources/Model/Enums/File.swift
@@ -0,0 +1,16 @@
+//
+//  File.swift
+//  
+//
+//  Created by Lucas Delanier on 27/05/2024.
+//
+
+import Foundation
+
+public enum BetFilter: String, Codable {
+    case inProgress = "IN_PROGRESS"
+    case isPublic = "PUBLIC"
+    case isInvitation = "INVITATION"
+    case isFinished = "FINISHED"
+}
+
diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift
index 65f59aa..afed8f9 100644
--- a/Sources/Model/Sources/Model/Manager.swift
+++ b/Sources/Model/Sources/Model/Manager.swift
@@ -22,8 +22,8 @@ public struct Manager {
         }
     }
     
-    public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
-        betDataManager.getBets(withIndex: index, withCount: count) { bets in
+    public func getBets(withIndex index: Int, withCount count: Int, filters: [BetFilter], completion: @escaping ([Bet]) -> Void) {
+        betDataManager.getBets(withIndex: index, withCount: count, filters: filters) { bets in
             completion(bets)
         }
     }
diff --git a/Sources/StubLib/Sources/StubLib/BetStubManager.swift b/Sources/StubLib/Sources/StubLib/BetStubManager.swift
index fa9e5bc..acd1460 100644
--- a/Sources/StubLib/Sources/StubLib/BetStubManager.swift
+++ b/Sources/StubLib/Sources/StubLib/BetStubManager.swift
@@ -12,7 +12,7 @@ public struct BetStubManager: BetDataManager {
     
     public init() {}
     
-    public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
+    public func getBets(withIndex index: Int, withCount count: Int, filters: [BetFilter] = [], completion: @escaping ([Bet]) -> Void) {
         completion(Stub.shared.bets)
     }
     
-- 
2.36.3


From e7d89089703b2d815e38220d0a40228bdae613dc Mon Sep 17 00:00:00 2001
From: "emre.kartal" <emre.kartal@etu.uca.fr>
Date: Wed, 29 May 2024 09:32:21 +0200
Subject: [PATCH 3/3] Adding friends and displaying the ranking

---
 .../AllIn/Components/AllcoinsCounter.swift    |   6 +-
 .../AllInApp/AllIn/Components/Friend.swift    |  45 ++--
 .../AllIn/Components/ReviewCard.swift         |  13 +-
 .../AllInApp/AllIn/Ressources/Config.swift    |   2 +-
 .../Ressources/en.lproj/Localizable.strings   |   3 +-
 .../Ressources/fr.lproj/Localizable.strings   |   1 +
 .../AllIn/ViewModels/BetViewModel.swift       |  12 +-
 .../ViewModels/CurrentBetViewModel.swift      |   5 +-
 .../AllIn/ViewModels/FriendsViewModel.swift   |  60 ++++-
 .../AllIn/ViewModels/RankingViewModel.swift   |  22 +-
 .../AllInApp/AllIn/Views/FriendsView.swift    |  42 +++-
 .../AllInApp/AllIn/Views/RankingView.swift    | 208 +++++++++---------
 Sources/Api/Sources/Api/UserApiManager.swift  | 104 ++++++++-
 .../Enums/{File.swift => BetFilter.swift}     |   2 +-
 .../Sources/Model/Enums/FriendStatus.swift    |  14 ++
 Sources/Model/Sources/Model/Manager.swift     |  26 ++-
 Sources/Model/Sources/Model/MatchBet.swift    |   1 +
 Sources/Model/Sources/Model/User.swift        |  19 +-
 .../Model/Sources/Model/UserDataManager.swift |   7 +-
 19 files changed, 412 insertions(+), 180 deletions(-)
 rename Sources/Model/Sources/Model/Enums/{File.swift => BetFilter.swift} (92%)
 create mode 100644 Sources/Model/Sources/Model/Enums/FriendStatus.swift

diff --git a/Sources/AllInApp/AllIn/Components/AllcoinsCounter.swift b/Sources/AllInApp/AllIn/Components/AllcoinsCounter.swift
index efd2e6b..6fd256f 100644
--- a/Sources/AllInApp/AllIn/Components/AllcoinsCounter.swift
+++ b/Sources/AllInApp/AllIn/Components/AllcoinsCounter.swift
@@ -15,13 +15,13 @@ struct AllcoinsCounter: View {
     
     var body: some View {
         HStack(alignment: .center) {
-            Image("allcoinIcon")
-                .resizable()
-                .frame(width: 17, height: 17, alignment: .leading)
             Text(String(appStateContainer.user?.nbCoins ?? 0))
                 .contentTransition(.numericText())
                 .fontWeight(.black)
                 .foregroundColor(foregroundColor)
+            Image("allcoinIcon")
+                .resizable()
+                .frame(width: 17, height: 17, alignment: .leading)
         }
         .frame(width: 90, height: 40)
         .background(backgroundColor)
diff --git a/Sources/AllInApp/AllIn/Components/Friend.swift b/Sources/AllInApp/AllIn/Components/Friend.swift
index 2cf3ca5..3744a79 100644
--- a/Sources/AllInApp/AllIn/Components/Friend.swift
+++ b/Sources/AllInApp/AllIn/Components/Friend.swift
@@ -6,38 +6,49 @@
 //
 
 import SwiftUI
+import Model
 
 struct Friend: View {
     
-    var image: String
-    var pseudo: String
+    var user: User
+    @ObservedObject var viewModel: FriendsViewModel
+    
+    var StatusValues: (String, Color, Color) {
+        switch user.friendStatus {
+        case .friend:
+            return (String(localized: "generic_delete"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
+        case .notFriend:
+            return (String(localized: "generic_add"), .white, AllInColors.lightPurpleColor)
+        case .requested:
+            return (String(localized: "friends_request_sent"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
+        default:
+            return ("NaN", AllInColors.grey400Color, AllInColors.componentBackgroundColor)
+        }
+    }
     
     var body: some View {
         HStack{
-            AsyncImage(url: URL(string: image))
+            AsyncImage(url: URL(string: "https://picsum.photos/536/354"))
                 .frame(width: 50, height: 50)
                 .cornerRadius(180)
                 .scaledToFit()
-            Text(pseudo)
+            Text(user.username)
                 .fontWeight(.medium)
                 .padding(.leading, 5)
                 .font(.system(size: 18))
                 .lineLimit(1)
             Spacer()
-            Button("generic_delete") {}
-                .frame(width: 90, height: 30)
-                .foregroundColor(AllInColors.grey400Color)
-                .font(.system(size: 14))
-                .background(AllInColors.componentBackgroundColor)
-                .cornerRadius(5)
-            
+            Button(StatusValues.0) {
+                viewModel.toggleFriendStatus(for: user)
+            }
+            .minimumScaleFactor(0.3)
+            .lineLimit(2)
+            .frame(width: 90, height: 30)
+            .foregroundColor(StatusValues.1)
+            .font(.system(size: 14))
+            .background(StatusValues.2)
+            .cornerRadius(5)
         }
         .padding([.trailing,.leading], 25)
     }
 }
-
-struct Friend_Previews: PreviewProvider {
-    static var previews: some View {
-        Friend(image: "https://picsum.photos/536/354", pseudo: "Lucas")
-    }
-}
diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift
index 300e782..d42d73f 100644
--- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift
+++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift
@@ -23,8 +23,8 @@ struct ReviewCard: View {
                 HStack{
                     Spacer()
                     Text("bet_proposed_by_format \(betDetail.bet.author)")
-                    .font(.system(size: 10))
-                    .foregroundColor(AllInColors.grey800Color)
+                        .font(.system(size: 10))
+                        .foregroundColor(AllInColors.grey800Color)
                     
                 }
                 Text(betDetail.bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color)
@@ -50,7 +50,8 @@ struct ReviewCard: View {
                             .font(.system(size: 25))
                             .fontWeight(.bold)
                     }
-                    else{Text(amountBetted.description)
+                    else{
+                        Text(amountBetted.description)
                             .foregroundColor(.white)
                             .font(.system(size: 25))
                             .fontWeight(.bold)
@@ -63,7 +64,7 @@ struct ReviewCard: View {
                             .fontWeight(.bold)
                     }
                     Spacer()
-
+                    
                 }
                 .frame(width: .infinity)
                 .padding(.all,10)
@@ -74,9 +75,9 @@ struct ReviewCard: View {
             .background(
                 isAWin || betDetail.bet.endBetDate < Date() ?
                 AnyView(AllInColors.primaryGradient) :
-                AnyView(Color.black)
+                    AnyView(Color.black)
             )            .cornerRadius(20, corners: [.bottomLeft,.bottomRight])
-            .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
+                .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
         }
         .onTapGesture {
             showDetails.toggle()
diff --git a/Sources/AllInApp/AllIn/Ressources/Config.swift b/Sources/AllInApp/AllIn/Ressources/Config.swift
index ab35db0..d734b64 100644
--- a/Sources/AllInApp/AllIn/Ressources/Config.swift
+++ b/Sources/AllInApp/AllIn/Ressources/Config.swift
@@ -8,5 +8,5 @@
 import Foundation
 
 struct Config {
-    static let allInApi = "http://localhost:8080/"
+    static let allInApi = "https://codefirst.iut.uca.fr/containers/AllDev-api/"
 }
diff --git a/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings b/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings
index 9939b51..1a3e605 100644
--- a/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings
+++ b/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings
@@ -131,7 +131,7 @@
 "bet_ends" = "Ends on";
 "bet_ended" = "Ended on";
 "bet_participate" = "Participate";
-"bet_proposed_by_format  %@" = "Proposed by  %@";
+"bet_proposed_by_format %@" = "Proposed by %@";
 "bet_proposed_by_format" = "Proposed by";
 "bet_players_waiting_format %@" = "%@ joueurs en attente";
 "bet_players_format" = "players";
@@ -166,6 +166,7 @@
 /// Friends
 
 "friends_title" = "Friends";
+"friends_request_sent" = "Request sent";
 
 /// Daily reward
 
diff --git a/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings b/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings
index 4a22e95..c8c7cb8 100644
--- a/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings
+++ b/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings
@@ -166,6 +166,7 @@
 /// Friends
 
 "friends_title" = "Amis";
+"friends_request_sent" = "Requête envoyée";
 
 /// Daily reward
 
diff --git a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift
index 6b939b9..5d994bd 100644
--- a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift
+++ b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift
@@ -38,12 +38,16 @@ class BetViewModel: ObservableObject {
     
     func getItems() {
         manager.getBets(withIndex: 0, withCount: 20, filters: Array(filters)) { bets in
-            self.bets = bets
+            DispatchQueue.main.async {
+                self.bets = bets
+            }
         }
         manager.getBetsOver() { bets in
-            self.betsOver = bets
-            if !self.betsOver.isEmpty {
-                self.showingSheet = true
+            DispatchQueue.main.async {
+                self.betsOver = bets
+                if !self.betsOver.isEmpty {
+                    self.showingSheet = true
+                }
             }
         }
     }
diff --git a/Sources/AllInApp/AllIn/ViewModels/CurrentBetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/CurrentBetViewModel.swift
index 22a44ff..23b7428 100644
--- a/Sources/AllInApp/AllIn/ViewModels/CurrentBetViewModel.swift
+++ b/Sources/AllInApp/AllIn/ViewModels/CurrentBetViewModel.swift
@@ -21,10 +21,7 @@ class CurrentBetViewModel: ObservableObject {
     
     func getItems() {
         manager.getCurrentBets(withIndex: 0, withCount: 20) { bets in
-            for bet in bets {
-                let betDetail = BetDetail(bet: bet, answers: [AnswerDetail(response: "OUI", totalStakes: 120, totalParticipants: 2, highestStake: 200, odds: 1.2), AnswerDetail(response: "NON", totalStakes: 120, totalParticipants: 2, highestStake: 200, odds: 1.2)], participations: [])
-                self.bets.append(betDetail)
-            }
+            self.bets = bets
         }
     }
     
diff --git a/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift
index 294ab23..7e52413 100644
--- a/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift
+++ b/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift
@@ -13,23 +13,69 @@ class FriendsViewModel: ObservableObject {
     
     @Inject var manager: Manager
     
+    @Published private(set) var users: [User] = []
+    @Published var text: String = "" {
+        didSet {
+            if text.isEmpty {
+                getItems()
+            } else {
+                search()
+            }
+        }
+    }
+    
     init() {
         getItems()
     }
     
-    func getItems ( ) {
-       
+    func getItems() {
+        manager.getFriends() { friends in
+            DispatchQueue.main.async {
+                self.users = friends
+            }
+        }
     }
     
-    func deleteItem(indexSet: IndexSet) {
-
+    func search() {
+        guard text.allSatisfy({ $0.isLetter || $0.isNumber }) else {
+            return
+        }
+        
+        manager.getUsers(withName: text) { users in
+            self.users = users
+        }
     }
     
-    func moveltem(from: IndexSet, to: Int) {
+    func toggleFriendStatus(for user: User) {
+        guard let index = users.firstIndex(where: { $0.username == user.username }) else { return }
+        var updatedUser = users[index]
         
+        switch updatedUser.friendStatus {
+        case .friend:
+            updatedUser.friendStatus = .notFriend
+            deleteItem(username: user.username)
+        case .notFriend:
+            updatedUser.friendStatus = .requested
+            addItem(username: user.username)
+        case .requested:
+            updatedUser.friendStatus = .notFriend
+            deleteItem(username: user.username)
+        default:
+            break
+        }
+        
+        users[index] = updatedUser
     }
     
-    func addItem(title: String) {
-
+    func deleteItem(username: String) {
+        manager.removeFriend(withUsername: username) { statusCode in
+            
+        }
+    }
+    
+    func addItem(username: String) {
+        manager.addFriend(withUsername: username) { statusCode in
+            
+        }
     }
 }
diff --git a/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift
index e321f91..7bd1879 100644
--- a/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift
+++ b/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift
@@ -13,23 +13,17 @@ class RankingViewModel: ObservableObject {
     
     @Inject var manager: Manager
     
+    @Published private(set) var friends: [User] = []
+
     init() {
         getItems()
     }
     
-    func getItems ( ) {
-       
-    }
-    
-    func deleteItem(indexSet: IndexSet) {
-
-    }
-    
-    func moveltem(from: IndexSet, to: Int) {
-        
-    }
-    
-    func addItem(title: String) {
-
+    func getItems() {
+        manager.getFriends() { users in
+            var friends = users
+            friends.append(AppStateContainer.shared.user!)
+            self.friends = friends.sorted(by: { $0.nbCoins > $1.nbCoins })
+        }
     }
 }
diff --git a/Sources/AllInApp/AllIn/Views/FriendsView.swift b/Sources/AllInApp/AllIn/Views/FriendsView.swift
index 7b1ccc1..3166e5f 100644
--- a/Sources/AllInApp/AllIn/Views/FriendsView.swift
+++ b/Sources/AllInApp/AllIn/Views/FriendsView.swift
@@ -9,6 +9,7 @@ import SwiftUI
 
 struct FriendsView: View {
     
+    @StateObject private var viewModel = FriendsViewModel()
     @Binding var showMenu: Bool
     
     var body: some View {
@@ -18,12 +19,37 @@ struct FriendsView: View {
                 .textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25)
                 .padding([.top,.bottom],15)
             
+            HStack {
+                TextField("Search...", text: $viewModel.text)
+                    .padding(7)
+                    .padding(.horizontal, 25)
+                    .background(Color(.systemGray6))
+                    .cornerRadius(8)
+                    .overlay(
+                        HStack {
+                            Image(systemName: "magnifyingglass")
+                                .foregroundColor(.gray)
+                                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
+                                .padding(.leading, 8)
+                            
+                            if !viewModel.text.isEmpty {
+                                Button(action: {
+                                    self.viewModel.text = ""
+                                }) {
+                                    Image(systemName: "multiply.circle.fill")
+                                        .foregroundColor(.gray)
+                                        .padding(.trailing, 8)
+                                }
+                            }
+                        }
+                    )
+                    .padding(.horizontal, 10)
+            }
+            
             ScrollView(showsIndicators: false){
-                Friend(image: "https://picsum.photos/536/354", pseudo: "Lucas")
-                Friend(image: "https://picsum.photos/536/354", pseudo: "Arthur")
-                Friend(image: "https://picsum.photos/536/354", pseudo: "Lucase")
-                Friend(image: "https://picsum.photos/536/354", pseudo: "Rayhan")
-                
+                ForEach(viewModel.users, id: \.self) { friend in
+                    Friend(user: friend, viewModel: viewModel)
+                }
             }
             .padding(.top, 25)
             Spacer()
@@ -32,9 +58,3 @@ struct FriendsView: View {
         .background(AllInColors.backgroundColor)
     }
 }
-
-struct FriendsView_Previews: PreviewProvider {
-    static var previews: some View {
-        FriendsView(showMenu: .constant(false))
-    }
-}
diff --git a/Sources/AllInApp/AllIn/Views/RankingView.swift b/Sources/AllInApp/AllIn/Views/RankingView.swift
index f1e08be..ea58507 100644
--- a/Sources/AllInApp/AllIn/Views/RankingView.swift
+++ b/Sources/AllInApp/AllIn/Views/RankingView.swift
@@ -10,6 +10,7 @@ import SwiftUI
 struct RankingView: View {
     
     @Binding var showMenu: Bool
+    @StateObject var viewModel = RankingViewModel()
     
     var body: some View {
         GeometryReader { geometry in
@@ -17,121 +18,126 @@ struct RankingView: View {
                 TopBar(showMenu: self.$showMenu)
                 Text("ranking_title")
                     .textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25)
-                    .padding([.top,.bottom],15)
+                    .padding([.top,.bottom], 15)
                 
-                HStack {
-                    ZStack {
-                        VStack(spacing: 0){
-                            Spacer()
-                            Text("Pseudo")
-                                .fontWeight(.bold)
-                                .padding(.bottom, 4)
-                                .font(.system(size: 16))
-                                .lineLimit(1)
-                            Divider()
-                                .background(AllInColors.lightGrey100Color)
-                            HStack{
-                                Spacer()
-                                Image("allcoinIcon")
+                if !viewModel.friends.isEmpty {
+                    HStack {
+                        if viewModel.friends.indices.contains(0) {
+                            ZStack {
+                                VStack(spacing: 0) {
+                                    Spacer()
+                                    Text(viewModel.friends[0].username)
+                                        .fontWeight(.bold)
+                                        .padding(.bottom, 4)
+                                        .font(.system(size: 16))
+                                        .lineLimit(1)
+                                    Divider()
+                                        .background(AllInColors.lightGrey100Color)
+                                    HStack {
+                                        Spacer()
+                                        Image("allcoinIcon")
+                                            .resizable()
+                                            .frame(width: 18, height: 18, alignment: .leading)
+                                            .padding([.top, .bottom], 10)
+                                        Text(String(viewModel.friends[0].nbCoins))
+                                            .textStyle(weight: .black, color: AllInColors.lightPurpleColor, size: 16)
+                                            .padding(.trailing, 18)
+                                        Spacer()
+                                    }
+                                    .frame(width: geometry.size.width * 0.43)
+                                    .background(AllInColors.underComponentBackgroundColor)
+                                }
+                                .frame(width: geometry.size.width * 0.43, height: 120)
+                                .background(AllInColors.componentBackgroundColor)
+                                .cornerRadius(41.5, corners: .topLeft)
+                                .cornerRadius(8, corners: .topRight)
+                                .cornerRadius(15, corners: [.bottomLeft, .bottomRight])
+                                
+                                Image("defaultUserImage")
                                     .resizable()
-                                    .frame(width: 18, height: 18, alignment: .leading)
-                                    .padding([.top,.bottom],10)
-                                Text(String("570"))
-                                    .textStyle(weight: .black, color: AllInColors.lightPurpleColor, size: 16)
-                                    .padding(.trailing, 18)
-                                Spacer()
+                                    .frame(width: 70, height: 70)
+                                    .scaledToFit()
+                                    .cornerRadius(180)
+                                    .offset(x: 0, y: -55)
+                                
+                                Text("1")
+                                    .frame(width: 28, height: 28)
+                                    .foregroundColor(.white)
+                                    .background(AllInColors.lightPurpleColor)
+                                    .cornerRadius(30)
+                                    .font(.system(size: 18))
+                                    .fontWeight(.bold)
+                                    .offset(x: 0, y: -23)
                             }
-                            .frame(width: geometry.size.width * 0.43)
-                            .background(AllInColors.underComponentBackgroundColor)
                         }
-                        .frame(width: geometry.size.width * 0.43, height: 120)
-                        .background(AllInColors.componentBackgroundColor)
-                        .cornerRadius(41.5, corners: .topLeft)
-                        .cornerRadius(8, corners: .topRight)
-                        .cornerRadius(15, corners: [.bottomLeft, .bottomRight])
-                        
-                        Image("defaultUserImage")
-                            .resizable()
-                            .frame(width: 70, height: 70)
-                            .scaledToFit()
-                            .cornerRadius(180)
-                            .offset(x: 0, y: -55)
-                        
-                        Text("1")
-                            .frame(width: 28, height: 28)
-                            .foregroundColor(.white)
-                            .background(AllInColors.lightPurpleColor)
-                            .cornerRadius(30)
-                            .font(.system(size: 18))
-                            .fontWeight(.bold)
-                            .offset(x: 0, y: -23)
-                    }
-                    ZStack {
-                        VStack(spacing: 0){
-                            Spacer()
-                            Text("Pseudo")
-                                .fontWeight(.bold)
-                                .padding(.bottom, 4)
-                                .font(.system(size: 15))
-                                .lineLimit(1)
-                            Divider()
-                                .background(AllInColors.lightGrey100Color)
-                            HStack{
-                                Spacer()
-                                Image("allcoinIcon")
+                        if viewModel.friends.indices.contains(1) {
+                            ZStack {
+                                VStack(spacing: 0) {
+                                    Spacer()
+                                    Text(viewModel.friends[1].username)
+                                        .fontWeight(.bold)
+                                        .padding(.bottom, 4)
+                                        .font(.system(size: 15))
+                                        .lineLimit(1)
+                                    Divider()
+                                        .background(AllInColors.lightGrey100Color)
+                                    HStack {
+                                        Spacer()
+                                        Image("allcoinIcon")
+                                            .resizable()
+                                            .frame(width: 18, height: 18, alignment: .leading)
+                                            .padding([.top, .bottom], 10)
+                                        Text(String(viewModel.friends[1].nbCoins))
+                                            .textStyle(weight: .black, color: AllInColors.lightPurpleColor, size: 16)
+                                            .padding(.trailing, 18)
+                                        Spacer()
+                                    }
+                                    .frame(width: geometry.size.width * 0.43)
+                                    .background(AllInColors.underComponentBackgroundColor)
+                                }
+                                .frame(width: geometry.size.width * 0.43, height: 90)
+                                .background(AllInColors.componentBackgroundColor)
+                                .cornerRadius(27.5, corners: .topRight)
+                                .cornerRadius(8, corners: .topLeft)
+                                .cornerRadius(15, corners: [.bottomLeft, .bottomRight])
+                                
+                                Image("defaultUserImage")
                                     .resizable()
-                                    .frame(width: 18, height: 18, alignment: .leading)
-                                    .padding([.top,.bottom],10)
-                                Text(String("570"))
-                                    .textStyle(weight: .black, color: AllInColors.lightPurpleColor, size: 16)
-                                    .padding(.trailing, 18)
-                                Spacer()
+                                    .frame(width: 50, height: 50)
+                                    .scaledToFit()
+                                    .cornerRadius(180)
+                                    .offset(x: 0, y: -50)
+                                
+                                Text("2")
+                                    .frame(width: 20, height: 20)
+                                    .foregroundColor(.white)
+                                    .background(AllInColors.lightPurpleColor)
+                                    .cornerRadius(30)
+                                    .font(.system(size: 14))
+                                    .fontWeight(.bold)
+                                    .offset(x: 0, y: -28)
                             }
-                            .frame(width: geometry.size.width * 0.43)
-                            .background(AllInColors.underComponentBackgroundColor)
+                            .padding(.top, 28)
                         }
-                        .frame(width: geometry.size.width * 0.43, height: 90)
-                        .background(AllInColors.componentBackgroundColor)
-                        .cornerRadius(27.5, corners: .topRight)
-                        .cornerRadius(8, corners: .topLeft)
-                        .cornerRadius(15, corners: [.bottomLeft, .bottomRight])
-                        
-                        Image("defaultUserImage")
-                            .resizable()
-                            .frame(width: 60, height: 60)
-                            .scaledToFit()
-                            .cornerRadius(180)
-                            .offset(x: 0, y: -50)
-                        
-                        Text("2")
-                            .frame(width: 23, height: 23)
-                            .foregroundColor(.white)
-                            .background(AllInColors.lightPurpleColor)
-                            .cornerRadius(30)
-                            .font(.system(size: 15))
-                            .fontWeight(.bold)
-                            .offset(x: 0, y: -22)
                     }
-                    .padding(.top, 28)
-                    
+                    .padding([.leading, .trailing, .top], 20)
                 }
-                .padding([.leading,.trailing,.top],20)
                 
-                ScrollView(showsIndicators: false){
-                    VStack(spacing: 10) {
-                        RankingRow(number: 3, image: "defaultUserImage", pseudo: "Lucas", allCoins: 541)
-                        RankingRow(number: 4, image: "defaultUserImage", pseudo: "Arthur", allCoins: 542)
+                ScrollView(showsIndicators: false) {
+                    ForEach(viewModel.friends.indices.dropFirst(2), id: \.self) { index in
+                        let friend = viewModel.friends[index]
+                        RankingRow(
+                            number: index + 1,
+                            image: "defaultUserImage",
+                            pseudo: friend.username,
+                            allCoins: friend.nbCoins
+                        )
                     }
-                }.padding(.top, 10)
+                }
+                .padding(.top, 10)
                 Spacer()
             }
             .edgesIgnoringSafeArea(.bottom).background(AllInColors.backgroundColor)
         }
     }
 }
-
-struct RankingView_Previews: PreviewProvider {
-    static var previews: some View {
-        RankingView(showMenu: .constant(false))
-    }
-}
diff --git a/Sources/Api/Sources/Api/UserApiManager.swift b/Sources/Api/Sources/Api/UserApiManager.swift
index ef89393..a956ead 100644
--- a/Sources/Api/Sources/Api/UserApiManager.swift
+++ b/Sources/Api/Sources/Api/UserApiManager.swift
@@ -8,7 +8,7 @@
 import Foundation
 import Model
 
-let allInApi = "http://localhost:8080/"
+let allInApi = "https://codefirst.iut.uca.fr/containers/AllDev-api/"
 
 public struct UserApiManager: UserDataManager {
     
@@ -73,8 +73,100 @@ public struct UserApiManager: UserDataManager {
         }
     }
     
-    public func getFriends() -> [User] {
-        fatalError("Not implemented yet")
+    public func addFriend(username: String, completion : @escaping (Int)-> ()) {
+        
+        let url = URL(string: allInApi + "friends/add")!
+        var request = URLRequest(url: url)
+        request.httpMethod = "POST"
+        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
+        
+        let json: [String: Any] = ["username": username]
+        
+        if let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []){
+            URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in
+                print ("ALLIN : Add friend")
+                if let httpResponse = response as? HTTPURLResponse {
+                    print(httpResponse.statusCode)
+                    completion(httpResponse.statusCode)
+                }
+            }.resume()
+        }
+    }
+    
+    public func removeFriend(username: String, completion : @escaping (Int)-> ()) {
+        
+        let url = URL(string: allInApi + "friends/delete")!
+        var request = URLRequest(url: url)
+        request.httpMethod = "POST"
+        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
+        
+        let json: [String: Any] = ["username": username]
+        
+        if let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []){
+            URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in
+                print ("ALLIN : Remove friend")
+                if let httpResponse = response as? HTTPURLResponse {
+                    print(httpResponse.statusCode)
+                    completion(httpResponse.statusCode)
+                }
+            }.resume()
+        }
+    }
+    
+    public func getFriends(completion: @escaping ([User]) -> Void) {
+        let url = URL(string: allInApi + "friends/gets")!
+        
+        var request = URLRequest(url: url)
+        request.httpMethod = "GET"
+        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
+        
+        var users: [User] = []
+        
+        URLSession.shared.dataTask(with: request) { data, response, error in
+            if let data = data {
+                print ("ALLIN : get friends")
+                do {
+                    if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
+                        print(jsonArray)
+                        users = try JSONDecoder().decode([User].self, from: JSONSerialization.data(withJSONObject: jsonArray))
+                        print(httpResponse.statusCode)
+                        completion(users)
+                    }
+                } catch {
+                    print("Error parsing JSON: \(error)")
+                }
+            }
+        }.resume()
+    }
+    
+    public func getUsers(withName name: String, completion: @escaping ([User]) -> Void) {
+        let url = URL(string: allInApi + "friends/search/" + name)!
+        
+        var request = URLRequest(url: url)
+        request.httpMethod = "GET"
+        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
+        
+        var users: [User] = []
+        
+        URLSession.shared.dataTask(with: request) { data, response, error in
+            if let data = data {
+                print ("ALLIN : get friends by search")
+                do {
+                    if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
+                        print(jsonArray)
+                        users = try JSONDecoder().decode([User].self, from: JSONSerialization.data(withJSONObject: jsonArray))
+                        print(httpResponse.statusCode)
+                        completion(users)
+                    }
+                } catch {
+                    print("Error parsing JSON: \(error)")
+                }
+            }
+        }.resume()
     }
     
     public func getGifts(completion : @escaping (Int, Int)-> ()) {
@@ -106,7 +198,7 @@ public struct UserApiManager: UserDataManager {
         fatalError("Not implemented yet")
     }
     
-    public func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
+    public func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetDetail]) -> Void) {
         let url = URL(string: allInApi + "bets/current")!
         
         var request = URLRequest(url: url)
@@ -114,7 +206,7 @@ public struct UserApiManager: UserDataManager {
         request.setValue("application/json", forHTTPHeaderField: "Content-Type")
         request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
         
-        var bets: [Bet] = []
+        var bets: [BetDetail] = []
         
         URLSession.shared.dataTask(with: request) { data, response, error in
             if let data = data {
@@ -123,7 +215,7 @@ public struct UserApiManager: UserDataManager {
                     if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
                         for json in jsonArray {
                             print(json)
-                            if let bet = FactoryApiBet().toBet(from: json) {
+                            if let bet = FactoryApiBet().toBetDetail(from: json) {
                                 bets.append(bet)
                             }
                         }
diff --git a/Sources/Model/Sources/Model/Enums/File.swift b/Sources/Model/Sources/Model/Enums/BetFilter.swift
similarity index 92%
rename from Sources/Model/Sources/Model/Enums/File.swift
rename to Sources/Model/Sources/Model/Enums/BetFilter.swift
index f5b22f5..4891632 100644
--- a/Sources/Model/Sources/Model/Enums/File.swift
+++ b/Sources/Model/Sources/Model/Enums/BetFilter.swift
@@ -1,5 +1,5 @@
 //
-//  File.swift
+//  BetFilter.swift
 //  
 //
 //  Created by Lucas Delanier on 27/05/2024.
diff --git a/Sources/Model/Sources/Model/Enums/FriendStatus.swift b/Sources/Model/Sources/Model/Enums/FriendStatus.swift
new file mode 100644
index 0000000..b190d90
--- /dev/null
+++ b/Sources/Model/Sources/Model/Enums/FriendStatus.swift
@@ -0,0 +1,14 @@
+//
+//  FriendStatus.swift
+//  
+//
+//  Created by Emre  on 28/05/2024.
+//
+
+import Foundation
+
+public enum FriendStatus: String, Codable {
+    case friend = "FRIEND"
+    case requested = "REQUESTED"
+    case notFriend = "NOT_FRIEND"
+}
diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift
index afed8f9..33dc10b 100644
--- a/Sources/Model/Sources/Model/Manager.swift
+++ b/Sources/Model/Sources/Model/Manager.swift
@@ -21,6 +21,18 @@ public struct Manager {
             completion(status)
         }
     }
+
+    public func addFriend(withUsername username: String, completion : @escaping (Int)-> ()) {
+        userDataManager.addFriend(username: username) { status in
+            completion(status)
+        }
+    }
+    
+    public func removeFriend(withUsername username: String, completion : @escaping (Int)-> ()) {
+        userDataManager.removeFriend(username: username) { status in
+            completion(status)
+        }
+    }
     
     public func getBets(withIndex index: Int, withCount count: Int, filters: [BetFilter], completion: @escaping ([Bet]) -> Void) {
         betDataManager.getBets(withIndex: index, withCount: count, filters: filters) { bets in
@@ -40,13 +52,25 @@ public struct Manager {
         }
     }
     
+    public func getFriends(completion: @escaping ([User]) -> Void) {
+        userDataManager.getFriends() { users in
+            completion(users)
+        }
+    }
+    
+    public func getUsers(withName name: String, completion: @escaping ([User]) -> Void) {
+        userDataManager.getUsers(withName: name) { users in
+            completion(users)
+        }
+    }
+    
     public func getHistoricBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
         userDataManager.getOldBets(withIndex: index, withCount: count) { bets in
             completion(bets)
         }
     }
     
-    public func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
+    public func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetDetail]) -> Void) {
         userDataManager.getCurrentBets(withIndex: index, withCount: count) { bets in
             completion(bets)
         }
diff --git a/Sources/Model/Sources/Model/MatchBet.swift b/Sources/Model/Sources/Model/MatchBet.swift
index 8bea44a..d171562 100644
--- a/Sources/Model/Sources/Model/MatchBet.swift
+++ b/Sources/Model/Sources/Model/MatchBet.swift
@@ -9,6 +9,7 @@ import Foundation
 
 /// A subclass of Bet that represents a bet on a match between two teams.
 public class MatchBet: Bet {
+    
     /// The name of the first team involved in the match.
     public var nameTeam1: String
     
diff --git a/Sources/Model/Sources/Model/User.swift b/Sources/Model/Sources/Model/User.swift
index 9bb5e79..6dd0b5d 100644
--- a/Sources/Model/Sources/Model/User.swift
+++ b/Sources/Model/Sources/Model/User.swift
@@ -8,7 +8,7 @@
 import Foundation
 
 /// A struct representing a user with details such as username, email, number of coins, and friends.
-public struct User: Codable {
+public struct User: Codable, Hashable {
     
     /// The username of the user.
     public private(set) var username: String
@@ -19,6 +19,9 @@ public struct User: Codable {
     /// The number of coins associated with the user.
     public var nbCoins: Int
     
+    /// The friendship status with the main user.
+    public var friendStatus: FriendStatus?
+    
     /// Custom constructor to initialize a User instance.
     ///
     /// - Parameters:
@@ -30,4 +33,18 @@ public struct User: Codable {
         self.email = email
         self.nbCoins = nbCoins
     }
+    
+    /// Custom constructor to initialize a User instance.
+    ///
+    /// - Parameters:
+    ///   - username: The username of the user.
+    ///   - email: The email address of the user.
+    ///   - nbCoins: The number of coins associated with the user.
+    ///   - status: The friendship status with the main user.
+    public init(username: String, email: String, nbCoins: Int, status: FriendStatus) {
+        self.username = username
+        self.email = email
+        self.nbCoins = nbCoins
+        self.friendStatus = status
+    }
 }
diff --git a/Sources/Model/Sources/Model/UserDataManager.swift b/Sources/Model/Sources/Model/UserDataManager.swift
index 2c974a9..4b76f5f 100644
--- a/Sources/Model/Sources/Model/UserDataManager.swift
+++ b/Sources/Model/Sources/Model/UserDataManager.swift
@@ -11,10 +11,13 @@ public protocol UserDataManager {
     func getBets(withIndex index: Int, withCount count: Int) -> [Bet]
     func getBetsOver(completion: @escaping ([BetDetail]) -> Void)
     func addBet(bet: Bet, completion : @escaping (Int)-> ())
-    func getFriends() -> [User]
+    func addFriend(username: String, completion : @escaping (Int)-> ())
+    func removeFriend(username: String, completion : @escaping (Int)-> ())
+    func getFriends(completion: @escaping ([User]) -> Void)
+    func getUsers(withName name: String, completion: @escaping ([User]) -> Void)
     func getGifts(completion : @escaping (Int, Int)-> ())
     func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void)
-    func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void)
+    func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetDetail]) -> Void)
     func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ())
     func addResponse(withIdBet id: String, andResponse responseBet: String)
 }
-- 
2.36.3