Merge pull request 'feature/current_bets' (#21) from feature/current_bets into master

Reviewed-on: #21
fix/answer-animation
Emre KARTAL 1 year ago
commit 5a4a27df9a

@ -12,3 +12,9 @@ steps:
commands: commands:
- cd Sources/Model - cd Sources/Model
- swift build - swift build
- name: test
image: swift:latest
commands:
- cd Sources/Model
- swift test

@ -12,7 +12,7 @@ class AppStateContainer: ObservableObject {
static let shared = AppStateContainer() static let shared = AppStateContainer()
let loggedState: LoggedState = LoggedState() let loggedState: LoggedState = LoggedState()
var onlineStatus: OnlineStatus = OnlineStatus() var onlineStatus: OnlineStatus = OnlineStatus()
var user: User? @Published var user: User?
@AppStorage("authenticationRefresh") var authenticationRefresh: String? @AppStorage("authenticationRefresh") var authenticationRefresh: String?
} }

@ -8,14 +8,17 @@
import SwiftUI import SwiftUI
struct AllcoinsCounter: View { struct AllcoinsCounter: View {
var backgroundColor: Color = .white var backgroundColor: Color = .white
var foregroundColor: Color = AllInColors.primaryColor var foregroundColor: Color = AllInColors.primaryColor
@ObservedObject var appStateContainer = AppStateContainer.shared
var body: some View { var body: some View {
HStack(alignment: .center) { HStack(alignment: .center) {
Image("allcoinIcon") Image("allcoinIcon")
.resizable() .resizable()
.frame(width: 17, height: 17, alignment: .leading) .frame(width: 17, height: 17, alignment: .leading)
Text(String(AppStateContainer.shared.user?.nbCoins ?? 0)) Text(String(appStateContainer.user?.nbCoins ?? 0))
.fontWeight(.black) .fontWeight(.black)
.foregroundColor(foregroundColor) .foregroundColor(foregroundColor)
} }

@ -15,7 +15,7 @@ struct BetCard: View {
@State var showParticipate: Bool = false @State var showParticipate: Bool = false
var body: some View { var body: some View {
VStack(spacing: 0){ VStack(spacing: 0) {
VStack(alignment: .leading,spacing: 2){ VStack(alignment: .leading,spacing: 2){
HStack{ HStack{
Spacer() Spacer()
@ -31,7 +31,9 @@ struct BetCard: View {
.font(.system(size: 20)) .font(.system(size: 20))
.fontWeight(.bold) .fontWeight(.bold)
HStack{ HStack{
Text("Commence le").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) Text("Commence le")
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
TextCapsule(date: bet.endRegisterDate) TextCapsule(date: bet.endRegisterDate)
Spacer() Spacer()
} }
@ -44,13 +46,14 @@ struct BetCard: View {
HStack{ HStack{
Spacer() Spacer()
UsersPreview() UsersPreview()
Text(String(bet.registered.count) + " joueurs en attente") Text(bet.registered.count.description + " joueurs en attente")
.font(.system(size: 15)) .font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color) .foregroundColor(AllInColors.grey800Color)
.fontWeight(.medium) .fontWeight(.medium)
Spacer() Spacer()
}.padding(0) }
.padding(0)
ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate, bet: bet) ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate, bet: bet)
.padding(.top, 5) .padding(.top, 5)
} }
@ -60,6 +63,7 @@ struct BetCard: View {
.cornerRadius(20, corners: [.bottomLeft,.bottomRight]) .cornerRadius(20, corners: [.bottomLeft,.bottomRight])
.border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
} }
.onTapGesture { .onTapGesture {
showDetails.toggle() showDetails.toggle()
} }

@ -23,17 +23,14 @@ struct BetLineLoading: View {
return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0 return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0
} }
var yesParticipations: [Participation] { var yesParticipations: [Participation] {
return participations.filter { $0.response.uppercased() == "YES" } participations.filter { $0.response.uppercased() == "YES" }
} }
var noParticipations: [Participation] { var noParticipations: [Participation] {
return participations.filter { $0.response.uppercased() == "NO" } participations.filter { $0.response.uppercased() == "NO" }
} }
var body: some View { var body: some View {
GeometryReader { geometry in GeometryReader { geometry in
VStack(alignment: .leading,spacing: 0){ VStack(alignment: .leading,spacing: 0){
@ -53,16 +50,15 @@ struct BetLineLoading: View {
HStack{ HStack{
Spacer() Spacer()
Rectangle() Rectangle()
.frame(width: min(CGFloat(1-self.value)*geometry.size.width, geometry.size.width), height: 17) .frame(width: min(CGFloat(1-self.value) * geometry.size.width, geometry.size.width), height: 17)
.foregroundStyle(AllInColors.PinkBetGradiant).cornerRadius(999) .foregroundStyle(AllInColors.PinkBetGradiant).cornerRadius(999)
} }
HStack(spacing: 0){ HStack(spacing: 0){
Rectangle() Rectangle()
.frame(width: min(CGFloat(self.value)*geometry.size.width, geometry.size.width), height: 17) .frame(width: min(CGFloat(self.value) * geometry.size.width, geometry.size.width), height: 17)
.foregroundStyle(AllInColors.BlueBetGradiant) .foregroundStyle(AllInColors.BlueBetGradiant)
.cornerRadius(999) .cornerRadius(999)
.animation(.linear)
Image("loadingHeartIcon") Image("loadingHeartIcon")
.resizable() .resizable()
.frame(width: 29, height: 32) .frame(width: 29, height: 32)
@ -86,13 +82,13 @@ struct BetLineLoading: View {
.foregroundColor(AllInColors.pink100) .foregroundColor(AllInColors.pink100)
Image("pinkAllCoinIcon") Image("pinkAllCoinIcon")
.resizable() .resizable()
.frame(width:10, height: 14) .frame(width: 12, height: 12)
} }
HStack(spacing: 5){ HStack(spacing: 5){
Image("bluePersonIcon") Image("bluePersonIcon")
.resizable() .resizable()
.frame(width:14, height: 12) .frame(width: 12, height: 12)
Text(yesParticipations.count.description) Text(yesParticipations.count.description)
.font(.system(size: 15)) .font(.system(size: 15))
.fontWeight(.bold) .fontWeight(.bold)
@ -104,13 +100,13 @@ struct BetLineLoading: View {
.foregroundColor(AllInColors.pink100) .foregroundColor(AllInColors.pink100)
Image("pinkPersonIcon") Image("pinkPersonIcon")
.resizable() .resizable()
.frame(width:10, height: 14) .frame(width: 12, height: 12)
} }
HStack(spacing: 5){ HStack(spacing: 5){
Image("blueBadgeIcon") Image("blueBadgeIcon")
.resizable() .resizable()
.frame(width:10, height: 14) .frame(width: 12, height: 12)
Text(yesParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0") Text(yesParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0")
.font(.system(size: 15)) .font(.system(size: 15))
.fontWeight(.bold) .fontWeight(.bold)
@ -122,13 +118,13 @@ struct BetLineLoading: View {
.foregroundColor(AllInColors.pink100) .foregroundColor(AllInColors.pink100)
Image("pinkBadgeIcon") Image("pinkBadgeIcon")
.resizable() .resizable()
.frame(width:10, height: 14) .frame(width: 12, height: 12)
} }
HStack(spacing: 5){ HStack(spacing: 5){
Image("blueTrophyIcon") Image("blueTrophyIcon")
.resizable() .resizable()
.frame(width:14, height: 13) .frame(width: 12, height: 12)
Text("1.2") Text("1.2")
.font(.system(size: 15)) .font(.system(size: 15))
.fontWeight(.bold) .fontWeight(.bold)
@ -140,7 +136,7 @@ struct BetLineLoading: View {
.foregroundColor(AllInColors.pink100) .foregroundColor(AllInColors.pink100)
Image("pinkTrophyIcon") Image("pinkTrophyIcon")
.resizable() .resizable()
.frame(width:10, height: 14) .frame(width:12, height: 12)
} }
} }

@ -62,11 +62,10 @@ struct DropDownAnswerMenu: View {
.padding([.leading, .trailing], 15) .padding([.leading, .trailing], 15)
} }
}) })
.frame(width: .infinity)
.background(AllInColors.componentBackgroundColor) .background(AllInColors.componentBackgroundColor)
.cornerRadius(10) .cornerRadius(8)
.overlay( .overlay(
RoundedRectangle(cornerRadius: 10, style: .continuous) RoundedRectangle(cornerRadius: 8, style: .continuous)
.stroke(AllInColors.veryLightPurpleColor, lineWidth: 0.4) .stroke(AllInColors.veryLightPurpleColor, lineWidth: 0.4)
) )
} }

@ -86,6 +86,7 @@ struct Menu: View {
.padding([.leading,.trailing], 13) .padding([.leading,.trailing], 13)
} }
VStack {
NavigationLink(destination: MainView(page: "Bet").navigationBarBackButtonHidden(true)) NavigationLink(destination: MainView(page: "Bet").navigationBarBackButtonHidden(true))
{ {
ParameterMenu(image: "moneyImage", title: "BET EN COURS", description: "Gérez vos bets et récompensez les gagnants.") ParameterMenu(image: "moneyImage", title: "BET EN COURS", description: "Gérez vos bets et récompensez les gagnants.")
@ -96,6 +97,14 @@ struct Menu: View {
ParameterMenu(image: "rankingImage", title: "CLASSEMENT", description: "Consultez votre classement parmis vos amis.") ParameterMenu(image: "rankingImage", title: "CLASSEMENT", description: "Consultez votre classement parmis vos amis.")
.padding([.leading,.trailing], 13) .padding([.leading,.trailing], 13)
} }
}
NavigationLink(destination: MainView(page: "Current").navigationBarBackButtonHidden(true))
{
ParameterMenu(image: "eyesImage", title: "BETS EN COURS", description: "Consultez vos paris en cours.")
.padding([.leading,.trailing], 13)
}
HStack { HStack {
Spacer() Spacer()

@ -28,6 +28,6 @@ struct OddCapsule: View {
struct OddCapsule_Previews: PreviewProvider { struct OddCapsule_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
AllcoinsCounter() OddCapsule()
} }
} }

@ -12,17 +12,23 @@ struct ParticiationCell: View {
@State var participation: Participation? @State var participation: Participation?
var body: some View { var body: some View {
HStack(alignment: .center, spacing: 0){ HStack(alignment: .center, spacing: 0){
Circle().frame(width: 30, height: 30).foregroundColor(AllInColors.grey700Color).padding(.trailing, 5) Circle()
.frame(width: 30, height: 30)
.foregroundColor(AllInColors.grey700Color)
.padding(.trailing, 7)
Text(participation?.user.username ?? "Unknown") Text(participation?.user.username ?? "Unknown")
.font(.system(size: 15)) .font(.system(size: 15))
.foregroundStyle(AllInColors.grey100Color) .foregroundStyle(AllInColors.primaryTextColor)
.fontWeight(.semibold) .fontWeight(.semibold)
Spacer() Spacer()
Text(participation?.stake.description ?? "NaN") Text(participation?.stake.description ?? "NaN")
.font(.system(size: 18)) .font(.system(size: 18))
.foregroundStyle(AllInColors.lightPurpleColor) .foregroundStyle(AllInColors.lightPurpleColor)
.fontWeight(.bold).padding(.trailing, 5) .fontWeight(.bold)
Image("PurpleAllCoin").resizable().frame(width: 11, height: 12) .padding(.trailing, 8)
Image("PurpleAllCoin")
.resizable()
.frame(width: 11, height: 12)
} }
} }
} }

@ -66,6 +66,7 @@ struct ParticipateButton: View {
.overlay( .overlay(
RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1)
) )
}.disabled(isDisabled) }
.disabled(isDisabled)
} }
} }

@ -13,6 +13,13 @@ struct ParticipationModal: View {
@Binding private var mise: String @Binding private var mise: String
private var description: String private var description: String
var participationAddedCallback: (() -> Void)? var participationAddedCallback: (() -> Void)?
var possibleGain: Int {
if let stake = Float(mise), let selectedOption = options.first(where: { $0.0 == self.selectedOption }) {
return Int(round(stake * selectedOption.2))
} else {
return 0
}
}
init(answer: Binding<Int>, mise: Binding<String>, description: String, participationAddedCallback: (() -> Void)? = nil) { init(answer: Binding<Int>, mise: Binding<String>, description: String, participationAddedCallback: (() -> Void)? = nil) {
self._selectedOption = answer self._selectedOption = answer
@ -27,23 +34,25 @@ struct ParticipationModal: View {
] ]
var body: some View { var body: some View {
GeometryReader { geometry in
VStack(alignment: .leading){ VStack(alignment: .leading){
HStack{ HStack{
Spacer() Spacer()
Rectangle() Rectangle()
.foregroundStyle(AllInColors.grey800Color) .foregroundStyle(AllInColors.lightGrey300Color)
.frame(maxWidth: 80, maxHeight: 5) .frame(maxWidth: 80, maxHeight: 5)
.cornerRadius(999) .cornerRadius(999)
Spacer() Spacer()
}.padding(10) }
.padding(10)
HStack{ HStack{
Text("Faites vos paris") Text("Faites vos paris")
.font(.system(size: 18)) .font(.system(size: 18))
.foregroundColor(AllInColors.primaryTextColor) .foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.semibold) .fontWeight(.semibold)
Spacer() Spacer()
AllcoinsCounter(backgroundColor: AllInColors.purpleAccentColor, foregroundColor: .white) AllcoinsCounter(backgroundColor: AllInColors.lightPurpleColor, foregroundColor: .white)
} }
.padding(.leading, 15) .padding(.leading, 15)
VStack(alignment: .leading){ VStack(alignment: .leading){
@ -54,9 +63,9 @@ struct ParticipationModal: View {
DropDownAnswerMenu(selectedOption: $selectedOption, options: options) DropDownAnswerMenu(selectedOption: $selectedOption, options: options)
TextField("",text: $mise, prompt: Text("Mise") TextField("", text: $mise, prompt: Text("Mise")
.foregroundColor(AllInColors.lightGrey300Color) .foregroundColor(AllInColors.lightGrey300Color)
.font(.system(size: 14)) .font(.system(size: 16))
.fontWeight(.bold)) .fontWeight(.bold))
.padding() .padding()
.keyboardType(.numberPad) .keyboardType(.numberPad)
@ -65,10 +74,10 @@ struct ParticipationModal: View {
.fill(AllInColors.lightGrey200Color) .fill(AllInColors.lightGrey200Color)
.frame(height: 40) .frame(height: 40)
) )
.frame(width: .infinity, height: 40) .frame(height: 40)
.foregroundColor(.black) .foregroundColor(.black)
.overlay( .overlay(
RoundedRectangle(cornerRadius: 10, style: .continuous) RoundedRectangle(cornerRadius: 8, style: .continuous)
.stroke(AllInColors.delimiterGrey, lineWidth: 1) .stroke(AllInColors.delimiterGrey, lineWidth: 1)
) )
.padding(.bottom, 5) .padding(.bottom, 5)
@ -81,14 +90,19 @@ struct ParticipationModal: View {
Text("Gains possibles") Text("Gains possibles")
.font(.system(size: 13)) .font(.system(size: 13))
.foregroundColor(AllInColors.primaryTextColor) .foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.regular) .fontWeight(.medium)
Spacer() Spacer()
Text("231") Text(possibleGain.description)
.font(.system(size: 13)) .font(.system(size: 13))
.foregroundColor(AllInColors.primaryTextColor) .foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.light) .fontWeight(.bold)
Image("allcoinIcon")
.resizable()
.frame(width: 11, height: 12)
} }
.padding(.top, 10).padding(.bottom, 0) .padding(.top, 10)
.padding(.bottom, 0)
Button { Button {
participationAddedCallback?() participationAddedCallback?()
} label: { } label: {
@ -100,9 +114,9 @@ struct ParticipationModal: View {
.padding(.vertical, 3) .padding(.vertical, 3)
} }
.buttonStyle(.borderedProminent) .buttonStyle(.borderedProminent)
.tint(AllInColors.purpleAccentColor) .tint(AllInColors.lightPurpleColor)
.disabled(checkAndSetError()) .disabled(checkAndSetError())
.padding(.bottom, 5)
} }
.padding(.horizontal, 10) .padding(.horizontal, 10)
.background(AllInColors.whiteColor) .background(AllInColors.whiteColor)
@ -110,10 +124,11 @@ struct ParticipationModal: View {
} }
.background(AllInColors.underComponentBackgroundColor) .background(AllInColors.underComponentBackgroundColor)
} }
}
func checkAndSetError() -> Bool { func checkAndSetError() -> Bool {
if let stake = Int(mise) { if let stake = Int(mise) {
if stake <= AppStateContainer.shared.user?.nbCoins ?? 0 { if stake <= AppStateContainer.shared.user?.nbCoins ?? 0 && stake > 0 {
return false return false
} else { } else {
return true return true

@ -16,7 +16,7 @@ struct RankingRow: View {
var body: some View { var body: some View {
HStack(){ HStack(){
Text(String(number)) Text(number.description)
.textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 18) .textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 18)
.padding(.leading, 15) .padding(.leading, 15)
@ -34,7 +34,7 @@ struct RankingRow: View {
Image("allcoinIcon") Image("allcoinIcon")
.resizable() .resizable()
.frame(width: 17, height: 17, alignment: .leading) .frame(width: 17, height: 17, alignment: .leading)
Text(String(allCoins)) Text(allCoins.description)
.textStyle(weight: .black, color: AllInColors.lightPurpleColor, size: 16) .textStyle(weight: .black, color: AllInColors.lightPurpleColor, size: 16)
.padding(.trailing, 15) .padding(.trailing, 15)
} }

@ -13,6 +13,7 @@ struct RecapBetCard: View {
@State private var isPressed = false @State private var isPressed = false
@State var showDetails: Bool = false @State var showDetails: Bool = false
@State var showPartipated: Bool = false @State var showPartipated: Bool = false
var body: some View { var body: some View {
VStack(spacing: 0){ VStack(spacing: 0){
VStack(alignment: .leading,spacing: 2){ VStack(alignment: .leading,spacing: 2){
@ -92,18 +93,17 @@ struct RecapBetCard: View {
.padding([.top,.bottom],5) .padding([.top,.bottom],5)
.background(AllInColors.primaryGradient) .background(AllInColors.primaryGradient)
.cornerRadius(8, corners: .allCorners) .cornerRadius(8, corners: .allCorners)
}
.padding([.bottom],10)
}.padding([.bottom],10) }
.frame(width: .infinity)
}.frame(width: .infinity)
.padding([.top,.bottom],8) .padding([.top,.bottom],8)
.padding([.leading,.trailing],15) .padding([.leading,.trailing],15)
.background(AllInColors.underComponentBackgroundColor) .background(AllInColors.underComponentBackgroundColor)
.cornerRadius(20, corners: [.bottomLeft,.bottomRight]) .cornerRadius(20, corners: [.bottomLeft,.bottomRight])
.padding(.bottom,0).border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) .padding(.bottom,0).border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
}.scaleEffect(longPressTap ? 0.97 : 1.0) }
.scaleEffect(longPressTap ? 0.97 : 1.0)
.animation(.easeInOut, value: longPressTap) .animation(.easeInOut, value: longPressTap)
.onTapGesture { .onTapGesture {
showDetails.toggle() showDetails.toggle()

@ -9,17 +9,22 @@ import SwiftUI
import Model import Model
struct ReviewCard: View { struct ReviewCard: View {
@State var showDetails: Bool = false @State var showDetails: Bool = false
@State var showPartipated: Bool = false @State var showPartipated: Bool = false
@State var betDetail: BetDetail @State var betDetail: BetDetail
var amountBetted: Int var amountBetted: Int
var isAWin: Bool var isAWin: Bool
var body: some View { var body: some View {
VStack(spacing: 0){ VStack(spacing: 0){
VStack(alignment: .leading,spacing: 2){ VStack(alignment: .leading,spacing: 2){
HStack{ HStack{
Spacer() Spacer()
Text("proposé par \(betDetail.bet.author.username)").font(.system(size: 10)).foregroundColor(AllInColors.grey800Color) Text("proposé par \(betDetail.bet.author.username)")
.font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color)
} }
Text(betDetail.bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) Text(betDetail.bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color)
@ -33,7 +38,8 @@ struct ReviewCard: View {
} }
.frame(width: .infinity) .frame(width: .infinity)
.padding(.all,15) .padding(.all,15)
.background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) .background(AllInColors.componentBackgroundColor)
.cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0)
VStack(alignment: .center,spacing:0){ VStack(alignment: .center,spacing:0){
HStack(){ HStack(){
@ -62,10 +68,6 @@ struct ReviewCard: View {
.frame(width: .infinity) .frame(width: .infinity)
.padding(.all,10) .padding(.all,10)
} }
.frame(width: .infinity) .frame(width: .infinity)
.padding(.all,2) .padding(.all,2)

@ -49,6 +49,9 @@ struct TextCapsule: View {
RoundedRectangle(cornerRadius: 20) RoundedRectangle(cornerRadius: 20)
.stroke(AllInColors.delimiterGrey, lineWidth: 1) .stroke(AllInColors.delimiterGrey, lineWidth: 1)
) )
Spacer()
} }
} }
} }

@ -83,42 +83,3 @@ extension View {
} }
} }
} }
struct SlideInFromBottomTransition: ViewModifier {
var yOffset: CGFloat
func body(content: Content) -> some View {
content
.offset(y: yOffset)
.animation(.easeInOut(duration: 0.3))
}
}
extension AnyTransition {
static func slideInFromBottom(yOffset: CGFloat) -> AnyTransition {
AnyTransition.modifier(
active: SlideInFromBottomTransition(yOffset: yOffset),
identity: SlideInFromBottomTransition(yOffset: 0)
)
}
}
struct SlideOutToBottomTransition: ViewModifier {
var yOffset: CGFloat
func body(content: Content) -> some View {
content
.offset(y: yOffset)
.opacity(yOffset == 0 ? 1 : 0)
.animation(.easeInOut(duration: 0.3))
}
}
extension AnyTransition {
static func slideOutToBottom(yOffset: CGFloat) -> AnyTransition {
AnyTransition.modifier(
active: SlideOutToBottomTransition(yOffset: yOffset),
identity: SlideOutToBottomTransition(yOffset: 0)
)
}
}

@ -0,0 +1,28 @@
//
// CurrentBetViewModel.swift
// AllIn
//
// Created by Emre on 31/01/2024.
//
import Foundation
import DependencyInjection
import Model
class CurrentBetViewModel: ObservableObject {
@Inject var manager: Manager
@Published private(set) var bets: [Bet] = []
init() {
getItems()
}
func getItems() {
manager.getCurrentBets(withIndex: 0, withCount: 20) { bets in
self.bets = bets
}
}
}

@ -9,36 +9,47 @@ import Foundation
import SwiftUI import SwiftUI
import Model import Model
import StubLib import StubLib
struct BetEndingValidation: View { struct BetEndingValidation: View {
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
@State var xOffset: CGFloat = 0 @State var xOffset: CGFloat = 0
@State var selectedAnswer : String? @State var selectedAnswer : String?
var bet: BetDetail = BetStubManager().getABetDetail() var bet: BetDetail = BetStubManager().getABetDetail()
var body: some View { var body: some View {
ZStack{ ZStack{
GeometryReader { geometry in GeometryReader { geometry in
InfiniteScroller(contentWidth: geometry.size.width) { InfiniteScroller(contentWidth: geometry.size.width) {
Image("marquee")
Image("marquee").resizable().scaledToFit() .resizable()
.scaledToFit()
} }
VStack { VStack {
ZStack(alignment: .topLeading){ ZStack(alignment: .topLeading){
HStack{ HStack{
Spacer() Spacer()
Image("allinIcon").resizable().frame(width: 35, height: 35) Image("allinIcon")
.resizable()
.frame(width: 35, height: 35)
Spacer() Spacer()
} }
Image("crossIcon").resizable().frame(width: 25, height: 25).onTapGesture { Image("crossIcon")
.resizable()
.frame(width: 25, height: 25)
.onTapGesture {
dismiss() dismiss()
} }
} }
ReviewCard(betDetail: bet, amountBetted: 0, isAWin: false).padding(.top, 20).padding(.bottom, 10) ReviewCard(betDetail: bet, amountBetted: 0, isAWin: false)
.padding(.top, 20)
.padding(.bottom, 10)
Text("Ce bet est arrivé à la date de fin. Vous devez à présent distribuer les gains en validant le pari gagnant.") Text("Ce bet est arrivé à la date de fin. Vous devez à présent distribuer les gains en validant le pari gagnant.")
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 13).multilineTextAlignment(.center) .textStyle(weight: .regular, color: AllInColors.grey800Color, size: 13)
.multilineTextAlignment(.center)
Text("Veuillez choisir la réponse finale:") Text("Veuillez choisir la réponse finale:")
.font(.system(size: 17)) .font(.system(size: 17))
.foregroundStyle(AllInColors.whiteColor) .foregroundStyle(AllInColors.whiteColor)

@ -0,0 +1,44 @@
//
// CurrentBetView.swift
// AllIn
//
// Created by Emre on 31/01/2024.
//
import SwiftUI
import Model
import StubLib
struct CurrentBetView: View {
@StateObject private var viewModel = CurrentBetViewModel()
@Binding var showMenu: Bool
@State private var showingSheet = false
var betD: BetDetail = BetStubManager().getABetDetail()
var body: some View {
VStack(alignment: .center, spacing: 0) {
TopBar(showMenu: self.$showMenu)
ScrollView(showsIndicators: false) {
Text("En cours")
.textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25)
.padding([.top],15)
VStack(spacing: 20){
ForEach(viewModel.bets, id: \.id) { (bet: Bet) in
ReviewCard(betDetail: betD, amountBetted: 110, isAWin: false)
}
}
.padding([.trailing, .leading, .bottom],25)
}
.refreshable {
viewModel.getItems()
}
Spacer()
}
.edgesIgnoringSafeArea(.bottom)
.background(AllInColors.backgroundColor)
}
}

@ -25,7 +25,6 @@ struct DetailsView: View {
case .orderedSame: case .orderedSame:
return true return true
} }
} else { } else {
return true return true
} }
@ -37,15 +36,15 @@ struct DetailsView: View {
switch currentDate.compare(endRegisterDate) { switch currentDate.compare(endRegisterDate) {
case .orderedAscending: case .orderedAscending:
return ("En cours...", AllInColors.purpleAccentColor) return ("En cours...", AllInColors.darkPurpleColor)
case .orderedDescending: case .orderedDescending:
return ("En attente...",AllInColors.pink100) return ("En attente...", AllInColors.pink100)
case .orderedSame: case .orderedSame:
return ("Fin des inscriptions...",AllInColors.grey50Color) return ("Fin des inscriptions...", AllInColors.grey50Color)
} }
} else { } else {
return ("Statut indisponible", AllInColors.whiteColor) return ("Statut indisponible", AllInColors.pink100)
} }
} }
@ -62,6 +61,7 @@ struct DetailsView: View {
VStack(alignment: .center) { VStack(alignment: .center) {
HStack{ HStack{
Text(StatusValues.0) Text(StatusValues.0)
.italic()
.font(.system(size: 25)) .font(.system(size: 25))
.fontWeight(.bold).padding(.bottom, 10) .fontWeight(.bold).padding(.bottom, 10)
.foregroundStyle(Color.black) .foregroundStyle(Color.black)
@ -78,15 +78,18 @@ struct DetailsView: View {
} }
.padding(.horizontal, 15) .padding(.horizontal, 15)
.background(StatusValues.1) .background(StatusValues.1)
.transition(.slideInFromBottom(yOffset:0))
VStack(spacing: 0) { VStack(spacing: 0) {
VStack(alignment: .leading,spacing: 5){ VStack(alignment: .leading, spacing: 5) {
HStack{ HStack(spacing: 3) {
Spacer() Spacer()
Text("proposé par " + (viewModel.betDetail?.bet.author.username ?? "Unknown").capitalized) Text("proposé par")
.font(.system(size: 10)) .font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color) .foregroundColor(AllInColors.grey800Color)
Text((viewModel.betDetail?.bet.author.username ?? "Unknown").capitalized)
.font(.system(size: 10))
.fontWeight(.semibold)
.foregroundColor(AllInColors.primaryTextColor)
} }
Text(viewModel.betDetail?.bet.theme ?? "Not loaded") Text(viewModel.betDetail?.bet.theme ?? "Not loaded")
@ -96,27 +99,34 @@ struct DetailsView: View {
.font(.system(size: 20)) .font(.system(size: 20))
.fontWeight(.bold) .fontWeight(.bold)
.padding(.bottom, 10) .padding(.bottom, 10)
HStack{ HStack {
HStack {
Spacer()
Text("Commence le") Text("Commence le")
.frame(maxWidth: 100)
.font(.system(size: 15)) .font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color) .foregroundColor(AllInColors.grey800Color)
}
.frame(width: 105)
.padding(.trailing, 10)
TextCapsule(date: viewModel.betDetail?.bet.endRegisterDate ?? Date()) TextCapsule(date: viewModel.betDetail?.bet.endRegisterDate ?? Date())
Spacer() Spacer()
}.padding(.bottom, 10) }.padding(.bottom, 10)
HStack{ HStack {
Text("Fini le") HStack {
.frame(maxWidth: 100) Spacer()
Text("Prend fin le")
.font(.system(size: 15)) .font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color) .foregroundColor(AllInColors.grey800Color)
}
.frame(width: 105)
.padding(.trailing, 10)
TextCapsule(date: viewModel.betDetail?.bet.endBetDate ?? Date()) TextCapsule(date: viewModel.betDetail?.bet.endBetDate ?? Date())
Spacer() Spacer()
} }
} }
.frame(width: .infinity) .padding(.all, 15)
.padding(.all,15).padding(.vertical, 10) .padding(.vertical, 10)
.background(AllInColors.componentBackgroundColor) .background(AllInColors.componentBackgroundColor)
.cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) .cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0)
@ -136,7 +146,7 @@ struct DetailsView: View {
ParticiationCell(participation: participation).padding(.horizontal, 10) ParticiationCell(participation: participation).padding(.horizontal, 10)
} }
} }
.padding(.bottom, 28) .padding(.bottom, geometry.safeAreaInsets.bottom + 28)
Spacer() Spacer()
} }
@ -146,15 +156,14 @@ struct DetailsView: View {
.border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
Spacer() Spacer()
} }
.frame(maxWidth: .infinity, maxHeight: geometry.size.height*0.98) .frame(maxWidth: .infinity, maxHeight: (geometry.size.height + geometry.safeAreaInsets.bottom) - 50)
.background(AllInColors.componentBackgroundColor) .background(AllInColors.componentBackgroundColor)
.cornerRadius(15) .cornerRadius(15, corners: [.topLeft, .topRight])
ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated, bet: viewModel.betDetail?.bet) ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated, bet: viewModel.betDetail?.bet)
.padding(10) .padding(.bottom, geometry.safeAreaInsets.bottom + 5)
.padding(.horizontal, 10)
} }
.sheet(isPresented: $isModalParticipated) { .sheet(isPresented: $isModalParticipated) {
ParticipationModal(answer: $viewModel.answer, mise: $viewModel.mise, description: viewModel.betDetail?.bet.phrase ?? "Not loaded", participationAddedCallback: { ParticipationModal(answer: $viewModel.answer, mise: $viewModel.mise, description: viewModel.betDetail?.bet.phrase ?? "Not loaded", participationAddedCallback: {

@ -9,7 +9,6 @@ import SwiftUI
struct HistoricBetView: View { struct HistoricBetView: View {
@StateObject private var viewModel = BetViewModel()
@Binding var showMenu: Bool @Binding var showMenu: Bool
@State private var showingSheet = false @State private var showingSheet = false

@ -46,6 +46,8 @@ struct MainView: View {
FriendsView(showMenu: self.$showMenu) FriendsView(showMenu: self.$showMenu)
case "CreationBet": case "CreationBet":
CreationBetView(showMenu: self.$showMenu) CreationBetView(showMenu: self.$showMenu)
case "Current":
CurrentBetView(showMenu: self.$showMenu)
default: default:
BetView(showMenu: self.$showMenu) BetView(showMenu: self.$showMenu)
} }

@ -25,6 +25,8 @@
EC01937E2B25C52E005D81E6 /* TopBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01937D2B25C52E005D81E6 /* TopBar.swift */; }; EC01937E2B25C52E005D81E6 /* TopBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01937D2B25C52E005D81E6 /* TopBar.swift */; };
EC01FCC32B56650400BB2390 /* DetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */; }; EC01FCC32B56650400BB2390 /* DetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */; };
EC01FCC52B56791B00BB2390 /* HistoricBetViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */; }; EC01FCC52B56791B00BB2390 /* HistoricBetViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */; };
EC17A15E2B6A955E008A8679 /* CurrentBetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC17A15D2B6A955E008A8679 /* CurrentBetView.swift */; };
EC17A1602B6A9781008A8679 /* CurrentBetViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC17A15F2B6A9781008A8679 /* CurrentBetViewModel.swift */; };
EC3077072B24CB840060E34D /* SplashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3077062B24CB840060E34D /* SplashView.swift */; }; EC3077072B24CB840060E34D /* SplashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3077062B24CB840060E34D /* SplashView.swift */; };
EC3077092B24CF7F0060E34D /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3077082B24CF7F0060E34D /* Colors.swift */; }; EC3077092B24CF7F0060E34D /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3077082B24CF7F0060E34D /* Colors.swift */; };
EC30770B2B24D9160060E34D /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC30770A2B24D9160060E34D /* WelcomeView.swift */; }; EC30770B2B24D9160060E34D /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC30770A2B24D9160060E34D /* WelcomeView.swift */; };
@ -128,6 +130,8 @@
EC01937D2B25C52E005D81E6 /* TopBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBar.swift; sourceTree = "<group>"; }; EC01937D2B25C52E005D81E6 /* TopBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBar.swift; sourceTree = "<group>"; };
EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsViewModel.swift; sourceTree = "<group>"; }; EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsViewModel.swift; sourceTree = "<group>"; };
EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoricBetViewModel.swift; sourceTree = "<group>"; }; EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoricBetViewModel.swift; sourceTree = "<group>"; };
EC17A15D2B6A955E008A8679 /* CurrentBetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentBetView.swift; sourceTree = "<group>"; };
EC17A15F2B6A9781008A8679 /* CurrentBetViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentBetViewModel.swift; sourceTree = "<group>"; };
EC3077062B24CB840060E34D /* SplashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashView.swift; sourceTree = "<group>"; }; EC3077062B24CB840060E34D /* SplashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashView.swift; sourceTree = "<group>"; };
EC3077082B24CF7F0060E34D /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; }; EC3077082B24CF7F0060E34D /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
EC30770A2B24D9160060E34D /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; }; EC30770A2B24D9160060E34D /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; };
@ -315,6 +319,7 @@
1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */, 1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */,
123590B32B51792000F7AEBD /* DetailsView.swift */, 123590B32B51792000F7AEBD /* DetailsView.swift */,
123225D82B67B46100D30BB3 /* BetEndingValidationView.swift */, 123225D82B67B46100D30BB3 /* BetEndingValidationView.swift */,
EC17A15D2B6A955E008A8679 /* CurrentBetView.swift */,
ECED90B42B6D9CEC00F50937 /* DailyGiftPage.swift */, ECED90B42B6D9CEC00F50937 /* DailyGiftPage.swift */,
); );
path = Views; path = Views;
@ -376,6 +381,7 @@
ECB26A1A2B40746C00FE06B3 /* FriendsViewModel.swift */, ECB26A1A2B40746C00FE06B3 /* FriendsViewModel.swift */,
EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */, EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */,
EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */, EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */,
EC17A15F2B6A9781008A8679 /* CurrentBetViewModel.swift */,
); );
path = ViewModels; path = ViewModels;
sourceTree = "<group>"; sourceTree = "<group>";
@ -535,11 +541,13 @@
ECB26A192B40744F00FE06B3 /* RankingViewModel.swift in Sources */, ECB26A192B40744F00FE06B3 /* RankingViewModel.swift in Sources */,
EC650A502B2793D5003AFCAD /* TextCapsule.swift in Sources */, EC650A502B2793D5003AFCAD /* TextCapsule.swift in Sources */,
EC650A482B25DCFF003AFCAD /* UsersPreview.swift in Sources */, EC650A482B25DCFF003AFCAD /* UsersPreview.swift in Sources */,
EC17A15E2B6A955E008A8679 /* CurrentBetView.swift in Sources */,
EC650A462B25D686003AFCAD /* RankingRow.swift in Sources */, EC650A462B25D686003AFCAD /* RankingRow.swift in Sources */,
EC01937A2B25C12B005D81E6 /* BetCard.swift in Sources */, EC01937A2B25C12B005D81E6 /* BetCard.swift in Sources */,
EC650A422B25C817003AFCAD /* Friend.swift in Sources */, EC650A422B25C817003AFCAD /* Friend.swift in Sources */,
EC7A882F2B28E6BE004F226A /* ConfidentialityButton.swift in Sources */, EC7A882F2B28E6BE004F226A /* ConfidentialityButton.swift in Sources */,
ECB7BC702B336E28002A6654 /* RegisterViewModel.swift in Sources */, ECB7BC702B336E28002A6654 /* RegisterViewModel.swift in Sources */,
EC17A1602B6A9781008A8679 /* CurrentBetViewModel.swift in Sources */,
EC650A4C2B25E9C7003AFCAD /* RankingView.swift in Sources */, EC650A4C2B25E9C7003AFCAD /* RankingView.swift in Sources */,
EC7A882B2B28D1E0004F226A /* DropDownMenu.swift in Sources */, EC7A882B2B28D1E0004F226A /* DropDownMenu.swift in Sources */,
EC7A882D2B28D8A1004F226A /* CreationBetView.swift in Sources */, EC7A882D2B28D8A1004F226A /* CreationBetView.swift in Sources */,

@ -51,6 +51,36 @@ public struct UserApiManager: UserDataManager {
fatalError("Not implemented yet") fatalError("Not implemented yet")
} }
public func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
let url = URL(string: allInApi + "bets/current")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
var bets: [Bet] = []
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print ("ALLIN : get current 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().toBet(from: json) {
bets.append(bet)
}
}
print(httpResponse.statusCode)
completion(bets)
}
} catch {
print("Error parsing JSON: \(error)")
}
}
}.resume()
}
public func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ()) { public func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ()) {
let url = URL(string: allInApi + "participations/add")! let url = URL(string: allInApi + "participations/add")!
var request = URLRequest(url: url) var request = URLRequest(url: url)

@ -40,6 +40,12 @@ public struct Manager {
} }
} }
public func getCurrentBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) {
userDataManager.getCurrentBets(withIndex: index, withCount: count) { bets in
completion(bets)
}
}
public func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ()) { public func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ()) {
userDataManager.addParticipation(withId: id, withAnswer: answer, andStake: stake) { status in userDataManager.addParticipation(withId: id, withAnswer: answer, andStake: stake) { status in
completion(status) completion(status)

@ -12,5 +12,6 @@ public protocol UserDataManager {
func addBet(bet: Bet, completion : @escaping (Int)-> ()) func addBet(bet: Bet, completion : @escaping (Int)-> ())
func getFriends() -> [User] func getFriends() -> [User]
func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) 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 addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ()) func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int, completion : @escaping (Int)-> ())
} }

Loading…
Cancel
Save