From 87eba68e42dd56caa89fe9df655706ec6c05acaa Mon Sep 17 00:00:00 2001 From: "emre.kartal" Date: Fri, 12 Jan 2024 16:11:15 +0100 Subject: [PATCH] Retrieving and displaying bets via the API :white_check_mark: --- .../AllInApp/AllIn/Components/BetCard.swift | 25 ++++++--- .../AllIn/Components/RecapBetCard.swift | 3 +- .../AllIn/Components/ReviewCard.swift | 3 +- .../AllIn/Components/TextCapsule.swift | 52 +++++++++++++++---- .../AllInApp/AllIn/Services/AuthService.swift | 2 +- .../AllIn/ViewModels/BetViewModel.swift | 26 +++++----- Sources/AllInApp/AllIn/Views/BetView.swift | 7 +-- Sources/Api/Sources/Api/BetApiManager.swift | 49 +++++++++++++++++ .../Sources/Api/Factory/FactoryApiBet.swift | 11 ++-- Sources/Model/Sources/Model/Bet.swift | 6 ++- .../Model/Sources/Model/BetDataManager.swift | 2 +- Sources/Model/Sources/Model/Manager.swift | 6 +++ .../Sources/StubLib/BetStubManager.swift | 4 +- .../Sources/ViewModel/ManagerVM.swift | 6 ++- 14 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 Sources/Api/Sources/Api/BetApiManager.swift diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index b58bb1e..9a37c5f 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -6,22 +6,25 @@ // import SwiftUI +import Model struct BetCard: View { + + var bet: Bet + var body: some View { VStack(spacing: 0){ VStack(alignment: .leading,spacing: 2){ HStack{ Spacer() - Text("proposé par Lucas").font(.system(size: 10)).foregroundColor(AllInColors.grey800Color) + Text("proposé par " + bet.author.username.capitalized).font(.system(size: 10)).foregroundColor(AllInColors.grey800Color) } - Text("Etudes").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) - Text("Emre va réussir son TP de CI/CD mercredi?").font(.system(size: 20)).fontWeight(.bold) + Text(bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) + Text(bet.phrase).font(.system(size: 20)).fontWeight(.bold) HStack{ Text("Commence le").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) - TextCapsule() - TextCapsule() + TextCapsule(date: bet.endRegisterDate) Spacer() } @@ -34,7 +37,7 @@ struct BetCard: View { HStack{ Spacer() UsersPreview() - Text(" 4 joueurs en attente").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color).fontWeight(.medium) + Text(String(bet.registered.count) + " joueurs en attente").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color).fontWeight(.medium) Spacer() @@ -75,7 +78,15 @@ struct BetCard: View { struct BetCard_Previews: PreviewProvider { static var previews: some View { - BetCard() + BetCard(bet: BinaryBet(theme: "Football - Finale de la Ligue des Champions", + phrase: "Le gagnant de la finale sera l'équipe avec le plus de tirs au but.", + endRegisterDate: Date().addingTimeInterval(86400), + endBetDate: Date().addingTimeInterval(172800), + totalStakes: 100, + isPublic: true, + invited: [], + author: User(username: "Imri", email: "emre.kartal@etu.uca.fr", nbCoins: 75, friends: []), + registered: [])) .preferredColorScheme(.dark) } } diff --git a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift index 418804a..df1957e 100644 --- a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift +++ b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift @@ -31,8 +31,7 @@ struct RecapBetCard: View { Text("Fini le ") .font(.system(size: 15)) .foregroundColor(AllInColors.grey800Color) - TextCapsule() - TextCapsule() + TextCapsule(date: Date()) Spacer() } } diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift index 8ff8846..7b4754b 100644 --- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift +++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift @@ -23,8 +23,7 @@ struct ReviewCard: View { Text("Emre va réussir son TP de CI/CD mercredi?").font(.system(size: 20)).fontWeight(.bold) HStack{ Text("Fini le").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) - TextCapsule() - TextCapsule() + TextCapsule(date: Date()) Spacer() } diff --git a/Sources/AllInApp/AllIn/Components/TextCapsule.swift b/Sources/AllInApp/AllIn/Components/TextCapsule.swift index ad556f8..11ec010 100644 --- a/Sources/AllInApp/AllIn/Components/TextCapsule.swift +++ b/Sources/AllInApp/AllIn/Components/TextCapsule.swift @@ -8,21 +8,53 @@ import SwiftUI struct TextCapsule: View { + var date: Date + + private var formattedDate: String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "dd MMM" + return dateFormatter.string(from: date) + } + + private var formattedTime: String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm" + return dateFormatter.string(from: date) + } + var body: some View { - Text("12 sept.").font(.system(size: 15)) - .foregroundColor(AllInColors.lightPurpleColor) - .fontWeight(.bold) - .padding([.leading,.trailing],10) - .padding([.top,.bottom], 5).background(AllInColors.underComponentBackgroundColor) - .clipShape(Capsule()) - .overlay(RoundedRectangle(cornerRadius: 20) - .stroke(AllInColors.delimiterGrey, lineWidth: 1) - ) + HStack { + Text(formattedDate) + .font(.system(size: 15)) + .foregroundColor(AllInColors.lightPurpleColor) + .fontWeight(.bold) + .padding([.leading, .trailing], 10) + .padding([.top, .bottom], 5) + .background(AllInColors.underComponentBackgroundColor) + .clipShape(Capsule()) + .overlay( + RoundedRectangle(cornerRadius: 20) + .stroke(AllInColors.delimiterGrey, lineWidth: 1) + ) + + Text(formattedTime) + .font(.system(size: 15)) + .foregroundColor(AllInColors.lightPurpleColor) + .fontWeight(.bold) + .padding([.leading, .trailing], 10) + .padding([.top, .bottom], 5) + .background(AllInColors.underComponentBackgroundColor) + .clipShape(Capsule()) + .overlay( + RoundedRectangle(cornerRadius: 20) + .stroke(AllInColors.delimiterGrey, lineWidth: 1) + ) + } } } struct TextCapsule_Previews: PreviewProvider { static var previews: some View { - TextCapsule() + TextCapsule(date: Date()) } } diff --git a/Sources/AllInApp/AllIn/Services/AuthService.swift b/Sources/AllInApp/AllIn/Services/AuthService.swift index 1a7ee71..62a99ec 100644 --- a/Sources/AllInApp/AllIn/Services/AuthService.swift +++ b/Sources/AllInApp/AllIn/Services/AuthService.swift @@ -144,7 +144,7 @@ class AuthService: IAuthService { } private func initManagerVM(token: String) { - DependencyInjection.shared.addSingleton(ManagerVM.self, ManagerVM(withModel: Manager(withBetDataManager: BetStubManager(), withUserDataManager: UserApiManager(withUserToken: token)))) + DependencyInjection.shared.addSingleton(ManagerVM.self, ManagerVM(withModel: Manager(withBetDataManager: BetApiManager(), withUserDataManager: UserApiManager(withUserToken: token)))) } } diff --git a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift index 522af33..6a6dd6c 100644 --- a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift @@ -8,28 +8,30 @@ import Foundation import DependencyInjection import ViewModel +import Model +import Combine class BetViewModel: ObservableObject { @Inject var manager: ManagerVM + @Published private var internalBets: [Bet] = [] + + var bets: [Bet] { + return internalBets + } + init() { getItems() } func getItems() { - - } - - func deleteItem(indexSet: IndexSet) { - - } - - func moveltem(from: IndexSet, to: Int) { - + for bet in manager.bets { + print(bet.theme) + } + manager.$bets.assign(to: \.internalBets, on: self).store(in: &cancellables) + manager.getPublicBets() } - func addItem(title: String) { - - } + private var cancellables: Set = [] } diff --git a/Sources/AllInApp/AllIn/Views/BetView.swift b/Sources/AllInApp/AllIn/Views/BetView.swift index 1ef638f..bc21e48 100644 --- a/Sources/AllInApp/AllIn/Views/BetView.swift +++ b/Sources/AllInApp/AllIn/Views/BetView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import Model struct BetView: View { @@ -16,7 +17,6 @@ struct BetView: View { var body: some View { VStack(alignment: .center, spacing: 0) { - TopBar(showMenu: self.$showMenu) ScrollView(showsIndicators: false) { LazyVStack(alignment: .leading, spacing: 0, pinnedViews: [.sectionHeaders]) { @@ -25,8 +25,9 @@ struct BetView: View { Section { VStack(spacing: 20){ - BetCard() - BetCard() + ForEach(viewModel.bets, id: \.id) { (bet: Bet) in + BetCard(bet: bet) + } Button("Show Sheet") { showingSheet.toggle() } diff --git a/Sources/Api/Sources/Api/BetApiManager.swift b/Sources/Api/Sources/Api/BetApiManager.swift new file mode 100644 index 0000000..10225a3 --- /dev/null +++ b/Sources/Api/Sources/Api/BetApiManager.swift @@ -0,0 +1,49 @@ +// +// BetApiManager.swift +// +// +// Created by Emre on 12/01/2024. +// + +import Foundation +import Model + +public struct BetApiManager: BetDataManager { + + public init() { } + + public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { + let url = URL(string: allInApi + "bets/gets")! + + var request = URLRequest(url: url) + request.httpMethod = "GET" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + + var bets: [Bet] = [] + + 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]] { + for json in jsonArray { + if let bet = FactoryApiBet().toModel(from: json) { + bets.append(bet) + print(bet.theme) + } + } + print(httpResponse.statusCode) + completion(bets) + } + } catch { + print("Error parsing JSON: \(error)") + } + } + }.resume() + } + + public func getUsers(username: String) -> [User] { + return [] + } + +} diff --git a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift index 223f685..8c29b11 100644 --- a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift +++ b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift @@ -30,9 +30,8 @@ public class FactoryApiBet: FactoryBet { let phrase = json["sentenceBet"] as? String, let endRegisterDateString = json["endRegistration"] as? String, let endBetDateString = json["endBet"] as? String, - let isPublicString = json["isPrivate"] as? String, - let createdBy = json["createdBy"] as? User, // Assuming User object can be parsed from JSON - let type = json["type"] as? Int else { + let isPublic = json["isPrivate"] as? Bool, + let createdBy = json["createdBy"] as? String else { return nil } @@ -43,10 +42,8 @@ public class FactoryApiBet: FactoryBet { let endBetDate = dateFormatter.date(from: endBetDateString) else { return nil } - - let isPublic = (isPublicString.lowercased() == "true") - - return toModel(theme: theme, description: phrase, endRegister: endRegisterDate, endBet: endBetDate, isPublic: isPublic, creator: createdBy, type: type) + + return toModel(theme: theme, description: phrase, endRegister: endRegisterDate, endBet: endBetDate, isPublic: isPublic, creator: User(username: createdBy, email: createdBy, nbCoins: 0, friends: []), type: 0) } public func toModel(theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User, type: Int) -> Bet { diff --git a/Sources/Model/Sources/Model/Bet.swift b/Sources/Model/Sources/Model/Bet.swift index 919ebbd..fca14b5 100644 --- a/Sources/Model/Sources/Model/Bet.swift +++ b/Sources/Model/Sources/Model/Bet.swift @@ -8,7 +8,11 @@ import Foundation /// A class representing a betting entity, including details about the bet theme, participants, and deadlines. -public class Bet: ObservableObject { +public class Bet: ObservableObject, Identifiable { + + /// The id for the bet. + public var id = UUID() + /// The theme or topic of the bet. public private(set) var theme: String diff --git a/Sources/Model/Sources/Model/BetDataManager.swift b/Sources/Model/Sources/Model/BetDataManager.swift index 1a3fef2..24a769c 100644 --- a/Sources/Model/Sources/Model/BetDataManager.swift +++ b/Sources/Model/Sources/Model/BetDataManager.swift @@ -8,6 +8,6 @@ import Foundation public protocol BetDataManager { - func getBets(withIndex index: Int, withCount count: Int) -> [Bet] + func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) func getUsers(username: String) -> [User] } diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift index 7eab799..224e021 100644 --- a/Sources/Model/Sources/Model/Manager.swift +++ b/Sources/Model/Sources/Model/Manager.swift @@ -19,4 +19,10 @@ public struct Manager { public func addBet(bet: Bet) { userDataManager.addBet(bet: bet) } + + public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { + betDataManager.getBets(withIndex: index, withCount: count) { bets in + completion(bets) + } + } } diff --git a/Sources/StubLib/Sources/StubLib/BetStubManager.swift b/Sources/StubLib/Sources/StubLib/BetStubManager.swift index c9c8347..bfacf3f 100644 --- a/Sources/StubLib/Sources/StubLib/BetStubManager.swift +++ b/Sources/StubLib/Sources/StubLib/BetStubManager.swift @@ -12,8 +12,8 @@ public struct BetStubManager: BetDataManager { public init() {} - public func getBets(withIndex index: Int, withCount count: Int) -> [Bet] { - return Stub.shared.bets + public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { + completion(Stub.shared.bets) } public func getUsers(username: String) -> [User] { diff --git a/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift b/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift index 2bcb8b0..673750b 100644 --- a/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift +++ b/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift @@ -11,12 +11,16 @@ import Model public class ManagerVM: ObservableObject { @Published var model: Manager + @Published public var bets: [Bet] = [] + public init(withModel model: Manager) { self.model = model } public func getPublicBets() { - + model.getBets(withIndex: 0, withCount: 20) { bets in + self.bets = bets + } } public func addBet(theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User) { -- 2.36.3