feature/winnings #37

Merged
emre.kartal merged 4 commits from feature/winnings into master 10 months ago

@ -8,11 +8,12 @@
import SwiftUI
struct AllcoinsCapsule: View {
var gains: Int
var body: some View {
Text("Vous remportez")
.foregroundColor(.white)
HStack{
Text("2340")
Text(gains.description)
.textStyle(weight: .bold, color: .white, size: 60)
Image("allcoinWhiteIcon")
.resizable()
@ -30,6 +31,6 @@ struct AllcoinsCapsule: View {
struct AllcoinsCapsule_Previews: PreviewProvider {
static var previews: some View {
AllcoinsCapsule()
AllcoinsCapsule(gains: 100)
}
}

@ -6,9 +6,11 @@
//
import SwiftUI
import Model
struct RecapBetCard: View {
var betResult: BetResultDetail
@GestureState private var longPressTap = false
@State private var isPressed = false
@State var showDetails: Bool = false
@ -19,22 +21,22 @@ struct RecapBetCard: View {
VStack(alignment: .leading,spacing: 2){
HStack{
Spacer()
Text("bet_proposed_by_format \("Lucas")")
Text("bet_proposed_by_format \(betResult.bet.author)")
.font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color)
}
Text("Etudes")
Text(betResult.bet.theme)
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
Text("Emre va réussir son TP de CI/CD mercredi?")
Text(betResult.bet.phrase)
.font(.system(size: 20))
.fontWeight(.bold)
HStack{
Text("bet_ends")
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
TextCapsule(date: Date())
TextCapsule(date: betResult.bet.endBetDate)
Spacer()
}
}
@ -48,7 +50,7 @@ struct RecapBetCard: View {
Text("Mise")
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
Spacer()
Text("1630")
Text(betResult.participation.stake.description)
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
Image("Allcoins")
.resizable()
@ -65,7 +67,7 @@ struct RecapBetCard: View {
Text("Gains")
.textStyle(weight: .medium, color: AllInColors.lightPurpleColor, size: 15)
Spacer()
Text("1630")
Text(betResult.amount.description)
.font(.system(size: 15))
.fontWeight(.medium)
.overlay {
@ -108,7 +110,7 @@ struct RecapBetCard: View {
.onTapGesture {
showDetails.toggle()
}.fullScreenCover(isPresented: $showDetails) {
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated,id: "1")
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated, id: betResult.bet.id)
}
.gesture(
LongPressGesture(minimumDuration: 0.5)
@ -118,10 +120,3 @@ struct RecapBetCard: View {
)
}
}
struct RecapBetCard_Previews: PreviewProvider {
static var previews: some View {
RecapBetCard()
.preferredColorScheme(.dark)
}
}

@ -12,26 +12,25 @@ struct ReviewCard: View {
@State var showDetails: Bool = false
@State var showPartipated: Bool = false
@State var betDetail: BetDetail
var amountBetted: Int
var isAWin: Bool
var bet: Bet
var amount: Int
var isWin: Bool
var body: some View {
VStack(spacing: 0){
VStack(alignment: .leading,spacing: 2){
HStack{
Spacer()
Text("bet_proposed_by_format \(betDetail.bet.author)")
Text("bet_proposed_by_format \(bet.author)")
.font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color)
}
Text(betDetail.bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color)
Text(betDetail.bet.phrase).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("bet_ends").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color)
TextCapsule(date: betDetail.bet.endBetDate)
TextCapsule(date: bet.endBetDate)
Spacer()
}
@ -40,20 +39,18 @@ struct ReviewCard: View {
.padding(.all,15)
.background(AllInColors.componentBackgroundColor)
.cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0)
VStack(alignment: .center,spacing:0){
HStack(){
Spacer()
if(betDetail.userParticipation != nil){
Text((betDetail.userParticipation?.stake.description ?? ""))
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
Image("allcoinWhiteIcon")
.resizable()
.frame(width: 18, height: 20)
}
switch betDetail.bet.status {
Text(amount.description)
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
Image("allcoinWhiteIcon")
.resizable()
.frame(width: 18, height: 20)
switch bet.status {
case .waiting, .inProgress:
Text("bet_status_stake")
.foregroundColor(.white)
@ -65,14 +62,7 @@ struct ReviewCard: View {
.font(.system(size: 25))
.fontWeight(.bold)
case .finished:
Text(amountBetted.description)
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
Image("allcoinWhiteIcon")
.resizable()
.frame(width: 20, height: 20, alignment: .bottom)
Text(isAWin ? "Gagnés!" : "Perdus!")
Text(isWin ? "Gagnés!" : "Perdus!")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
@ -91,24 +81,26 @@ struct ReviewCard: View {
}
.frame(width: .infinity)
.padding(.all,2)
.background({
switch betDetail.bet.status {
case .inProgress, .waiting, .closing:
return AllInColors.grey50Color
case .finished:
return Color.black
case .cancelled:
return Color.red
}
}())
.background(backgroundColor())
.cornerRadius(20, corners: [.bottomLeft,.bottomRight])
.border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
}
.onTapGesture {
showDetails.toggle()
}.fullScreenCover(isPresented: $showDetails) {
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated, id: betDetail.bet.id)
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated, id: bet.id)
}
}
private func backgroundColor() -> Color {
switch bet.status {
case .inProgress, .waiting, .closing:
return AllInColors.grey50Color
case .finished:
return Color.black
case .cancelled:
return Color.red
}
}
}

@ -6,9 +6,11 @@
//
import SwiftUI
import Model
struct WinModal: View {
@Environment(\.dismiss) var dismiss
var betResult: BetResultDetail
@State var xOffset: CGFloat = 0
var body: some View {
@ -35,15 +37,15 @@ struct WinModal: View {
}
HStack{
Text("FÉLICITATIONS").font(.system(size: 20)).foregroundColor(.white).fontWeight(.semibold).italic()
Text("PSEUDO!").padding(.top,9).font(.system(size: 33)).fontWeight(.heavy).foregroundColor(.white)
Text(AppStateContainer.shared.user?.username ?? "").padding(.top,9).font(.system(size: 33)).fontWeight(.heavy).foregroundColor(.white)
}
.rotationEffect(.degrees(-4))
.padding(.top,40)
Spacer()
AllcoinsCapsule()
AllcoinsCapsule(gains: betResult.amount)
Spacer()
RecapBetCard()
RecapBetCard(betResult: betResult)
Spacer()
}
.padding([.all],20)
@ -58,12 +60,6 @@ struct WinModal: View {
}
}
struct WinModal_Previews: PreviewProvider {
static var previews: some View {
WinModal()
}
}
struct InfiniteScroller<Content: View>: View {
var contentWidth: CGFloat
var content: (() -> Content)

@ -17,7 +17,9 @@ class BetViewModel: ObservableObject {
@Published var popularBet: Bet?
@Published private(set) var bets: [Bet] = []
@Published var betsOver: [BetDetail] = []
@Published var showingSheet: Bool = false
@Published var betsWon: [BetResultDetail] = []
@Published var showingSheetOver: Bool = false
@Published var showingSheetWon: Bool = false
@Published var filters: Set<BetFilter> = [] {
didSet {
getItems()
@ -28,6 +30,7 @@ class BetViewModel: ObservableObject {
getItems()
getPopularBet()
getBetsOver()
getBetsWon()
}
func getItems() {
@ -43,7 +46,18 @@ class BetViewModel: ObservableObject {
DispatchQueue.main.async {
self.betsOver = bets
if !self.betsOver.isEmpty {
self.showingSheet = true
self.showingSheetOver = true
}
}
}
}
func getBetsWon() {
manager.getBetsWon() { bets in
DispatchQueue.main.async {
self.betsWon = bets
if !self.betsWon.isEmpty {
self.showingSheetWon = true
}
}
}

@ -13,7 +13,7 @@ class HistoricBetViewModel: ObservableObject {
@Inject var manager: Manager
@Published private(set) var bets: [BetDetail] = []
@Published private(set) var bets: [BetResultDetail] = []
init() {
getItems()

@ -15,10 +15,10 @@ struct BetEndingValidationView: View {
@Environment(\.dismiss) var dismiss
@StateObject private var viewModel: BetEndingValidationViewModel
var bet: BetDetail
var betDetail: BetDetail
init(bet: BetDetail) {
self.bet = bet
self.betDetail = bet
self._viewModel = StateObject(wrappedValue: BetEndingValidationViewModel(id: bet.bet.id))
}
@ -48,7 +48,7 @@ struct BetEndingValidationView: View {
dismiss()
}
}
ReviewCard(betDetail: bet, amountBetted: 0, isAWin: false)
ReviewCard(bet: betDetail.bet, amount: 0, isWin: false)
.padding(.top, 20)
.padding(.bottom, 10)
Text("bet_confirmation_text")
@ -64,7 +64,7 @@ struct BetEndingValidationView: View {
.frame(maxWidth: .infinity, alignment: .leading)
VStack(spacing: 14){
ForEach(bet.answers) { answer in
ForEach(betDetail.answers) { answer in
ChoiceFinalAnswerCell(selected : answer.response == viewModel.selectedAnswer, answer: answer).onTapGesture {
if(viewModel.selectedAnswer == answer.response){
viewModel.selectedAnswer = nil

@ -59,14 +59,22 @@ struct BetView: View {
.refreshable {
viewModel.getItems()
}
.sheet(isPresented: $viewModel.showingSheet, onDismiss: {
.sheet(isPresented: $viewModel.showingSheetOver, onDismiss: {
viewModel.betsOver.removeFirst()
viewModel.showingSheet = !viewModel.betsOver.isEmpty
viewModel.showingSheetOver = !viewModel.betsOver.isEmpty
}) {
if let firstBetDetail = viewModel.betsOver.first {
BetEndingValidationView(bet: firstBetDetail)
}
}
.sheet(isPresented: $viewModel.showingSheetWon, onDismiss: {
viewModel.betsWon.removeFirst()
viewModel.showingSheetWon = !viewModel.betsWon.isEmpty
}) {
if let firstBetResultDetail = viewModel.betsWon.first {
WinModal(betResult: firstBetResultDetail)
}
}
Spacer()
}
.edgesIgnoringSafeArea(.bottom)

@ -23,8 +23,8 @@ struct CurrentBetView: View {
.textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25)
.padding([.top],15)
VStack(spacing: 20){
ForEach(viewModel.bets, id: \.bet.id) { (bet: BetDetail) in
ReviewCard(betDetail: bet, amountBetted: 110, isAWin: false)
ForEach(viewModel.bets, id: \.bet.id) { (betDetail: BetDetail) in
ReviewCard(bet: betDetail.bet, amount: betDetail.userParticipation?.stake ?? 0, isWin: false)
}
}
.padding([.trailing, .leading, .bottom],25)

@ -24,8 +24,8 @@ struct HistoricBetView: View {
.textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25)
.padding([.top],15)
VStack(spacing: 20){
ForEach(viewModel.bets, id: \.bet.id) { (bet: BetDetail) in
ReviewCard(betDetail: bet, amountBetted: 110, isAWin: false)
ForEach(viewModel.bets, id: \.bet.id) { (betDetail: BetResultDetail) in
ReviewCard(bet: betDetail.bet, amount: betDetail.participation.stake, isWin: betDetail.won)
}
}
.padding([.trailing, .leading, .bottom],25)

@ -77,6 +77,7 @@ public struct BetApiManager: BetDataManager {
do {
if let httpResponse = response as? HTTPURLResponse, let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
print(httpResponse.statusCode)
print(json)
if let betDetail = FactoryApiBet().toBetDetail(from: json) {
completion(betDetail)
}

@ -88,20 +88,51 @@ public class FactoryApiBet: FactoryBet {
do {
wonParticipation = try JSONDecoder().decode(Participation.self, from: JSONSerialization.data(withJSONObject: participationJson))
} catch {
print("Error decoding participations: \(error)")
print("Error decoding participation: \(error)")
}
}
if let participationUserJson = json["userParticipation"] as? [String: Any] {
do {
userParticipation = try JSONDecoder().decode(Participation.self, from: JSONSerialization.data(withJSONObject: participationUserJson))
} catch {
print("Error decoding participations: \(error)")
print("Error decoding participation: \(error)")
}
}
return BetDetail(bet: bet, answers: answers, participations: participations, wonParticipation: wonParticipation, userParticipation: userParticipation)
}
public func toBetResultDetail(from json: [String: Any]) -> BetResultDetail? {
guard let amount = json["amount"] as? Int,
let won = json["won"] as? Bool else {
return nil
}
guard let betJson = json["bet"] as? [String: Any],
let bet = self.toBet(from: betJson) else {
return nil
}
let decoder = JSONDecoder()
guard let betResultJson = json["betResult"] as? [String: Any],
let betResultData = try? JSONSerialization.data(withJSONObject: betResultJson),
let betResult = try? decoder.decode(BetResult.self, from: betResultData) else {
print("Error decoding bet result")
return nil
}
guard let participationJson = json["participation"] as? [String: Any],
let participationData = try? JSONSerialization.data(withJSONObject: participationJson),
let participation = try? decoder.decode(Participation.self, from: participationData) else {
print("Error decoding participation")
return nil
}
return BetResultDetail(betResult: betResult, bet: bet, participation: participation, amount: amount, won: won)
}
public func betTypeString(fromType type: String) -> String {
switch type {
case "BinaryBet":

@ -52,6 +52,39 @@ public struct UserApiManager: UserDataManager {
}.resume()
}
public func getBetsWon(completion : @escaping ([BetResultDetail])-> ()) {
let url = URL(string: url + "bets/getWon")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
var bets: [BetResultDetail] = []
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print ("ALLIN : get bets won")
do {
if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
print(jsonArray)
for json in jsonArray {
if let bet = FactoryApiBet().toBetResultDetail(from: json) {
print(bet)
bets.append(bet)
}
}
print(httpResponse.statusCode)
completion(bets)
}
} catch {
print("Error parsing JSON: \(error)")
}
}
}.resume()
}
public func addBet(bet: Bet, completion : @escaping (Int)-> ()) {
let url = URL(string: url + "bets/add")!
@ -218,7 +251,7 @@ public struct UserApiManager: UserDataManager {
}.resume()
}
public func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetDetail]) -> Void) {
public func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetResultDetail]) -> Void) {
let url = URL(string: url + "bets/history")!
var request = URLRequest(url: url)
@ -226,15 +259,16 @@ public struct UserApiManager: UserDataManager {
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
var bets: [BetDetail] = []
var bets: [BetResultDetail] = []
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print ("ALLIN : get old bets")
do {
if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
print(jsonArray)
for json in jsonArray {
if let bet = FactoryApiBet().toBetDetail(from: json) {
if let bet = FactoryApiBet().toBetResultDetail(from: json) {
bets.append(bet)
}
}

@ -0,0 +1,21 @@
//
// BetResult.swift
//
//
// Created by Emre on 06/06/2024.
//
import Foundation
public class BetResult: Codable {
public private(set) var betId: String
public private(set) var result: String
public init(betId: String, result: String) {
self.betId = betId
self.result = result
}
}

@ -0,0 +1,30 @@
//
// BetResultDetail.swift
//
//
// Created by Emre on 06/06/2024.
//
import Foundation
public class BetResultDetail: Codable {
public private(set) var betResult: BetResult
public private(set) var bet: Bet
public private(set) var participation: Participation
public private(set) var amount: Int
public private(set) var won: Bool
public init(betResult: BetResult, bet: Bet, participation: Participation, amount: Int, won: Bool) {
self.betResult = betResult
self.bet = bet
self.participation = participation
self.amount = amount
self.won = won
}
}

@ -11,4 +11,5 @@ public protocol FactoryBet {
func toResponse(bet: Bet) -> [String: Any]
func toBet(from json: [String: Any]) -> Bet?
func toBetDetail(from json: [String: Any]) -> BetDetail?
func toBetResultDetail(from json: [String: Any]) -> BetResultDetail?
}

@ -46,6 +46,12 @@ public struct Manager {
}
}
public func getBetsWon(completion: @escaping ([BetResultDetail]) -> Void) {
userDataManager.getBetsWon() { bets in
completion(bets)
}
}
public func getBet(withId id: String, completion: @escaping (BetDetail) -> Void) {
betDataManager.getBet(withId: id) { bet in
completion(bet)
@ -70,7 +76,7 @@ public struct Manager {
}
}
public func getHistoricBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetDetail]) -> Void) {
public func getHistoricBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetResultDetail]) -> Void) {
userDataManager.getOldBets(withIndex: index, withCount: count) { bets in
completion(bets)
}

@ -10,6 +10,7 @@ import Foundation
public protocol UserDataManager {
func getBets(withIndex index: Int, withCount count: Int) -> [Bet]
func getBetsOver(completion: @escaping ([BetDetail]) -> Void)
func getBetsWon(completion : @escaping ([BetResultDetail])-> ())
func addBet(bet: Bet, completion : @escaping (Int)-> ())
func addFriend(username: String, completion : @escaping (Int)-> ())
func removeFriend(username: String, completion : @escaping (Int)-> ())
@ -17,7 +18,7 @@ public protocol UserDataManager {
func getRequests(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 ([BetDetail]) -> Void)
func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([BetResultDetail]) -> 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)

Loading…
Cancel
Save