From f12e9a0407f3d082bb0cb2ffde019b3f6c889cb1 Mon Sep 17 00:00:00 2001 From: ludelanier Date: Fri, 12 Jan 2024 16:19:24 +0100 Subject: [PATCH 01/14] start detail page with animation --- .../CloseiconRounded.imageset/Contents.json | 21 ++++++++++++++++++ .../CloseiconRounded.imageset/Exclude (1).png | Bin 0 -> 1540 bytes .../Image.imageset/Contents.json | 20 +++++++++++++++++ .../AllInApp/AllIn/Views/DetailsView.swift | 18 +++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Exclude (1).png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/Image.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Views/DetailsView.swift diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Contents.json new file mode 100644 index 0000000..4250f63 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Exclude (1).png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Exclude (1).png b/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Exclude (1).png new file mode 100644 index 0000000000000000000000000000000000000000..7103253d2a0916c78ff7d38f9e6242565ca85cca GIT binary patch literal 1540 zcmV+f2K)JmP)fH!kNe#3H+O>TOhA|bXM-{UVFJPg&c!4tNh@%G9jAXFZh$JaGk{U?P8D zi$|Eg$VA23BRi%wqyq9-e2eGHEqK5wbRZ8E55O-p&Y6a_rAsKW7FvkBVXcJApaBQ5 ztztCte8eS*Oq8r`#IYM=?C6%rK64UNf|6HD)1;M=&=(jk`e?u~jA#p;MLwbd1F=nn z-a!_*3xy97`+00dt&^eXOO}x7Lg%YbIxCI}jr@u)ohzjDSfj=jU+SVFejos-X~~3>~>EXAOmrxvCe^=V&?smXI-p zLWt7UM~)V5-a*C|rK?qr*6J5#dQrOiz|q;w-Z*k~*U=SZd~oFIuA_54!ynJg(f`R8 zFOEiDDpf+p7c*>?pZ(K%;~m7KX6>i=T^2n0_)MxUr8r5Isn-ymYq1}HL0&u(njI>N z4v`l@x)k876`xsR_+xxh9as!X=z+brKs&Kl1D{!9_zJ3uwtdyIcxdXOY?m05TLS;; z>q6B<_XD5Vu*EkBOGQ7V(61moKgU)u6njwQ7NPG1pmWZP&=n+#rr5e7$6#NcaD|q2 z3Lbc)yW)u0rXp)^*AvvuTacqmh(m=2w>k8PZ6q@ClkW<`vllv+qlpKTZ&XKY8<95< zhXq}*#5fU3C?~LCB4}6s(0XkBxy}&31mh26{7a6GJtio{HgWcpL?)uf=r+b;>yU`Z z#4H6zOT3DmkjTWWpld`(3#)3)Hi?P6$J;$D9&vJZiXsy!I$F{@bUy?;9IC8}*=1Fd zqN61rO+^;G2eU*}5J>3cb_yJF7nWJSQ}djn(9Q{>1jSBHXm44##Kdk$=wFZq-cy|k ziTyhjN1rU8oQT+45<2vVLl@&L9ChIwvVJkx%0bXrtWEY74@a_TkkzQajPVAc7jg$; z%&qZgD3YpNz((u`3=C~oUa-UnA3td-{AbNQm1kNyf7U);1`bRA7@rU0H@?asViEqmZ-F`|)O?aqC-Bw2Ms zXLhwa^RCcGV}{w)&U`Ht1@?V6-Dg+Z(Lm2UOUhAj;p!X6m~vC}+%7UU0}WlkRFKhu z?#Ws9y_u)_@q^n`KjJ^;5Hik9F*5(%pra+s*YwLL`z~L(7>rCft6sM*4V00-neYHRgBWW<ff?V)>Oq1yg+y%Mdsf3jC z6IccE%6oG84#Pp>QYfn+0$zI^Hi!ei23~Vlfj=lGK^GcSe^(cgA6Fe+=q|{URwW!h qguR5}2e3;~e~aa|aF`w86#M}^k89y!32C_i0000 Date: Mon, 15 Jan 2024 16:51:31 +0100 Subject: [PATCH 02/14] new logic for open the modal --- .../BleuePersonIcon.imageset/Contents.json | 21 ++++++++++ .../BleuePersonIcon.imageset/Group 179.png | Bin 0 -> 832 bytes .../BleueTrophyIcon.imageset/Contents.json | 21 ++++++++++ .../BleueTrophyIcon.imageset/Group 210.png | Bin 0 -> 2206 bytes .../BlueAllCoinIcon.imageset/Contents.json | 21 ++++++++++ .../Group 107 (1).png | Bin 0 -> 681 bytes .../Contents.json | 38 ++++++++++++++++++ .../AllIn/Components/ParticipateButton.swift | 18 +++++++++ .../AllIn/Components/ResultBanner.swift | 18 +++++++++ 9 files changed, 137 insertions(+) create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Group 179.png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Group 210.png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BlueAllCoinIcon.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BlueAllCoinIcon.imageset/Group 107 (1).png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/WinBannerBackground.colorset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Components/ParticipateButton.swift create mode 100644 Sources/AllInApp/AllIn/Components/ResultBanner.swift diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Contents.json new file mode 100644 index 0000000..af28cdf --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 179.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Group 179.png b/Sources/AllInApp/AllIn/Assets.xcassets/BleuePersonIcon.imageset/Group 179.png new file mode 100644 index 0000000000000000000000000000000000000000..f8c171f7d2b361840e5bb554e35ef6a3221f0df7 GIT binary patch literal 832 zcmV-G1Hb%@~0drDELIAGL9O(c600d`2O+f$vv5yP{3 z+CUKP9^tAi$-=41j-0@pfG8(`8-$#|xLjESYwQBwz&SzS1XgkZ$PL&zDLWMw@g_*q z=^g|I2aQGov5DUT4X9^$)Bi?rgx|aKK|!4W8$eWvf1Uv11eMnf&R$NT0AQMc-~UzC zI&33B%O*z%1EoqrbOw6_rjes4yy0aP+%Q3}^lnKqzT7DSHuGv-*IU<7%=dCokeBj@~?^uj`rQX?=4sOH_p0_tuX zFgwBE<8imwCp2j6@$a9fl5@MDUg!r)n!lF(lfjh%^FqG~8Eby_I0?@~+L1+hS5> z$O8@p0=oWser)oar88e$DmZ_2z4fT|FDAK0;b+*TlX*gvTYDJ+riP@Rk2&HiiL#)( zPl@6NIUU_Nm~sb_x2%BD7^DYG01scCrRD{zL|q6ub1*HfV){cK39Lz9W*BiXSSMJ! z{Mjyq+#{-f??=b1N+qcrvow9SAXS<Z)7-0000< KMNUMnLSTYQ?rG}) literal 0 HcmV?d00001 diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Contents.json new file mode 100644 index 0000000..329d213 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 210.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Group 210.png b/Sources/AllInApp/AllIn/Assets.xcassets/BleueTrophyIcon.imageset/Group 210.png new file mode 100644 index 0000000000000000000000000000000000000000..97f9e727f09150c60614b72a4bb81f838161cb17 GIT binary patch literal 2206 zcmV;P2x0e$P)mh?VcA9{IbpqS~qCSMf5Dk%{vLPI3`pL#T%9LXOcbPx|&tZf!+3=PnTNGwpFvgvVPmNOs35ev1}gjES> zfX)dd;lGDH!wYDD+C^H~`}nkT0(~Y)p8dH6HB-At2=ov-3}N&XYNl3^R3z73D=O(F zzrMc*HBz@F)%xXILnMM0sRy@#tX^-?NOaeE1dgCamLdf}Jo_Q}L>sWAwGfJR8Qm?dsO2m}@Bmnf6aWIT-r4e!>cj@ejFI2~93g~t z=ysxY$oJH3RM<}Oln=KiFGKpeaOeTaR7qlPR}roTvqbqeYB zcO&R7<0=az3FrsyLHrPibo;JWB+ehLLIpZJ7aKt}bRJ4Q1ZBoSCseOega_0~mxq+S z1xJb^;oQIh3tdG10Z%|j9J^=B37!9#b|b1hd@OV;DSkT5+YeP0taL@988uf6p^D6Ne)g1gL{vwxQ;IGixG5> z3yVdp$j%boAv_+XW#ss|RAG=L zI0=e;P`Ab0)lJUzI2VaC-6{X0pO{Vldk8KNc5GY{DYzgP{^%LbCIK!~W=-lwJh9z$ z3Ls)ip-VUf4Qlxu>05yi>4FXy%ja?Y9Q5?qnzq1_BD2wrWGm9hDQGaWB35OZUidis zp@=3@-8l+t>VrL*NS9pO?jLA5mk|`KCm&S#z=9ztrfa%mvMi;h`=zVR>3*%xkg z_f)!u1lkTi^(T+NxiU7ZiE2JiG+0zpo=XZeU9*`GTQ!lXuzU&+z-BzjC%mt(bAJ|N zomZ|47-Wd8y7sLEg0ZbY`L8)3BRCl#fPKGh%5L+~tW^bIO~aF)?%Xdw$mp%;DN4Ww zB@nHdEJnSIQ#+=trSQ`wLr2>PEn%yAv%2@;MOo_L0#~a8h_V1zjy*;6me`ylcX4h4 zsb7Z*IE_)~SH=-XfrmoGFN?BA0&PRx+%N8D*<_QW(JiO_E*!?7E2n^pR1!*k0~{6Y zBj&!nIbQMiOWZdjp&>@o2UVLE7P6bMDpyR;o)Z`>Rk|hcoaq3fe+TLI_mwB@3*B;> z2i1YDQMdER03m}NP5_wY?u<^kU@E)6fRU?CflEA#?#Zfc^Y&Y1RW(@8#nab_v?`cJ zgD#I%by?4)Yt)a-iW6r0U2=g+98%VkLd`VxLJ^5tH3RGd0~V`Eab~XBJbAr|HYtSU zYJm@NX0Gjz^DzrywUySD2LuPQtm52@w2-gS5~M3+q1M^DHozySHoO{2tAY5R;UXrZ z)xT29NcP|KAp3HIZ&K2jg(+dU2uWNmZiz6nv`(bUs1-;&->PH$@;T1f(0Y+d78)7K z%yfp2+AdB>Fd|77l5$!=>7Z$X5=o+jn#Qth?WMNkgWxvGEtWq!Ew1Dzawjx_Bw_Am zoVShIMPPDq^GtB_BuTLb`wiGJ#wfnu#JkEDO^}vk+e}^1YwBI)izcwN(5D_{Q!c~1 zzp9(vik=}Z#yonTwKqWqf^0QhfZ^Sb0 z(ryd@~0drDELIAGL9O(c600d`2O+f$vv5yPra20PYFM4U!vlJWyVlJ`*N6g1G^l0C58!A+NN|;2G!>ww9He zx`}N`mXiM=oUXMCbA^BlAUgNOBf+J-K9#od1SabB^4FYHyXFN` z0Gc)lX~v(@HY{L*^5xGN0+pO?3IQU(xog~O&Zy4`PgW48H2-v$L##QdfBBU9TJ?ZF z&YZ}N&O6_M-f6Cp>jxYrD|&b48u>9~LGLtY;HD5%E8ZoKJU7aHE@SFhJz*dT#8_JQz7*Dc_xyqhm=@fggQl%!83L zZWMnC+psL2*L>UcZa5E_hafk`?WHVUxidqv-MUm6^Qp+W#uCN-#b}-T5-0AuBUY%9 zbMe2s1EEI6&2@dch5)@;-syGo(e*@gA-u@Bv2)>lyV-&p?xCO7h_r>Wpo P00000NkvXXu0mjfC#62> literal 0 HcmV?d00001 diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/WinBannerBackground.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/WinBannerBackground.colorset/Contents.json new file mode 100644 index 0000000..9e04041 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/WinBannerBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xE8", + "red" : "0xD1" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xE8", + "red" : "0xD1" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift new file mode 100644 index 0000000..5cb234e --- /dev/null +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -0,0 +1,18 @@ +// +// ParticipateButton.swift +// AllIn +// +// Created by Lucas Delanier on 15/01/2024. +// + +import SwiftUI + +struct ParticipateButton: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + ParticipateButton() +} diff --git a/Sources/AllInApp/AllIn/Components/ResultBanner.swift b/Sources/AllInApp/AllIn/Components/ResultBanner.swift new file mode 100644 index 0000000..2b9b09c --- /dev/null +++ b/Sources/AllInApp/AllIn/Components/ResultBanner.swift @@ -0,0 +1,18 @@ +// +// ResultBanner.swift +// AllIn +// +// Created by Lucas Delanier on 15/01/2024. +// + +import SwiftUI + +struct ResultBanner: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + ResultBanner() +} -- 2.36.3 From a940c747d76b8571656e0fe3eaec642f35307972 Mon Sep 17 00:00:00 2001 From: ludelanier Date: Mon, 15 Jan 2024 17:02:20 +0100 Subject: [PATCH 03/14] change logic displayng modal --- .../AllInApp/AllIn/Components/BetCard.swift | 98 ++++++++----------- .../AllIn/Components/ParticipateButton.swift | 25 ++++- .../AllIn/Components/RecapBetCard.swift | 6 ++ .../AllIn/Components/ResultBanner.swift | 24 ++++- .../AllIn/Components/ReviewCard.swift | 6 ++ .../AllIn/Extensions/Extensions.swift | 39 ++++++++ .../AllInApp/AllIn/Ressources/Colors.swift | 1 + .../AllIn/ViewModels/LoginViewModel.swift | 4 + Sources/AllInApp/AllIn/Views/BetView.swift | 82 ++++++++-------- .../AllInApp/AllIn/Views/DetailsView.swift | 82 ++++++++++++++-- Sources/AllInApp/AllIn/Views/MainView.swift | 2 + .../AllInApp.xcodeproj/project.pbxproj | 12 +++ 12 files changed, 274 insertions(+), 107 deletions(-) diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index b58bb1e..a1d3eda 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -8,68 +8,54 @@ import SwiftUI struct BetCard: View { + @State var showDetails: Bool = false 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("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) - HStack{ - Text("Commence le").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) - TextCapsule() - TextCapsule() - Spacer() - + ZStack{ + VStack(spacing: 0){ + VStack(alignment: .leading,spacing: 2){ + HStack{ + Spacer() + Text("proposé par Lucas").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) + HStack{ + Text("Commence le").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) + TextCapsule() + TextCapsule() + Spacer() + + } } - } - .frame(width: .infinity) - .padding(.all,15) - .background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) - - VStack(alignment: .leading,spacing: 2){ - HStack{ - Spacer() - UsersPreview() - Text(" 4 joueurs en attente").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color).fontWeight(.medium) - - Spacer() - - }.padding(0) - Button { + .frame(width: .infinity) + .padding(.all,15) + .background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) + + VStack(alignment: .leading,spacing: 2){ + HStack{ + Spacer() + UsersPreview() + Text(" 4 joueurs en attente").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color).fontWeight(.medium) + + Spacer() + + }.padding(0) + ParticipateButton().padding(.top, 5) - } label: { - Text("Participer") - .font(.system(size: 30)) - .fontWeight(.bold) - .frame(maxWidth: .infinity).padding(10) - .multilineTextAlignment(.center) - .overlay { - AllInColors.primaryGradient.frame(width: 170) - .mask( - Text("Participer") - .font(.system(size: 30)) - .fontWeight(.bold) - .frame(maxWidth: .infinity).padding(10) - ) - } } - .accentColor(AllInColors.componentBackgroundColor) - .buttonStyle(.borderedProminent).cornerRadius(4.0) - .overlay( - RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) - ).padding([.top],5) - + .frame(width: .infinity) + .padding(.all,8) + .background(AllInColors.underComponentBackgroundColor) + .cornerRadius(20, corners: [.bottomLeft,.bottomRight]) + .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) } - .frame(width: .infinity) - .padding(.all,8) - .background(AllInColors.underComponentBackgroundColor) - .cornerRadius(20, corners: [.bottomLeft,.bottomRight]) - .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) + }.onTapGesture { + showDetails.toggle() + }.fullScreenCover(isPresented: $showDetails) { + DetailsView(isModalPresented: $showDetails) } + } } diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift index 5cb234e..02c40c6 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -9,7 +9,30 @@ import SwiftUI struct ParticipateButton: View { var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + Button { + + } label: { + Text("Participer") + .font(.system(size: 30)) + .fontWeight(.bold) + .frame(maxWidth: .infinity).padding(10) + .multilineTextAlignment(.center) + .overlay { + AllInColors.primaryGradient.frame(width: 170) + .mask( + Text("Participer") + .font(.system(size: 30)) + .fontWeight(.bold) + .frame(maxWidth: .infinity).padding(10) + ) + } + } + .accentColor(AllInColors.componentBackgroundColor) + .buttonStyle(.borderedProminent).cornerRadius(4.0) + .overlay( + RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) + ) + } } diff --git a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift index 418804a..06c8203 100644 --- a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift +++ b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift @@ -11,6 +11,7 @@ struct RecapBetCard: View { @GestureState private var longPressTap = false @State private var isPressed = false + @State var showDetails: Bool = false var body: some View { VStack(spacing: 0){ VStack(alignment: .leading,spacing: 2){ @@ -104,6 +105,11 @@ struct RecapBetCard: View { .padding(.bottom,0).border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) }.scaleEffect(longPressTap ? 0.97 : 1.0) .animation(.easeInOut, value: longPressTap) + .onTapGesture { + showDetails.toggle() + }.fullScreenCover(isPresented: $showDetails) { + DetailsView(isModalPresented: $showDetails) + } .gesture( LongPressGesture(minimumDuration: 0.5) .updating($longPressTap) { value, state, _ in diff --git a/Sources/AllInApp/AllIn/Components/ResultBanner.swift b/Sources/AllInApp/AllIn/Components/ResultBanner.swift index 2b9b09c..91b201d 100644 --- a/Sources/AllInApp/AllIn/Components/ResultBanner.swift +++ b/Sources/AllInApp/AllIn/Components/ResultBanner.swift @@ -9,7 +9,29 @@ import SwiftUI struct ResultBanner: View { var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + VStack{ + HStack{ + Image("BleueTrophyIcon").resizable().frame(maxWidth: 70, maxHeight: 60) + Text("OUI").font(.system(size: 70)).fontWeight(.bold).foregroundStyle(AllInColors.blueGrey800Color) + }.frame(height: 80) + HStack(spacing: 20){ + HStack{ + Image("BlueAllCoinIcon").resizable().frame(maxWidth: 12, maxHeight: 12) + Text("460").font(.system(size: 16)).fontWeight(.semibold).foregroundStyle(AllInColors.blueGrey800Color) + } + HStack{ + Image("BleuePersonIcon").resizable().frame(maxWidth: 15, maxHeight: 12) + Text("ImriDu43").font(.system(size: 16)).fontWeight(.semibold).foregroundStyle(AllInColors.blueGrey800Color) + } + HStack{ + Image("BleueTrophyIcon").resizable().frame(maxWidth: 15, maxHeight: 12) + Text("x1.2").font(.system(size: 16)).fontWeight(.semibold).foregroundStyle(AllInColors.blueGrey800Color) + } + } + } + .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/) + .padding(.vertical, 20).background(AllInColors.winBannerBackground) + .border(width: 2, edges: [.top,.bottom], color: AllInColors.blueAccentColor.opacity(0.2)) } } diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift index 8ff8846..0859507 100644 --- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift +++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift @@ -8,6 +8,7 @@ import SwiftUI struct ReviewCard: View { + @State var showDetails: Bool = false var amountBetted: Int var isAWin: Bool @@ -67,5 +68,10 @@ struct ReviewCard: View { ) .cornerRadius(20, corners: [.bottomLeft,.bottomRight]) .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) } + .onTapGesture { + showDetails.toggle() + }.fullScreenCover(isPresented: $showDetails) { + DetailsView(isModalPresented: $showDetails) + } } } diff --git a/Sources/AllInApp/AllIn/Extensions/Extensions.swift b/Sources/AllInApp/AllIn/Extensions/Extensions.swift index 74732e0..a79953c 100644 --- a/Sources/AllInApp/AllIn/Extensions/Extensions.swift +++ b/Sources/AllInApp/AllIn/Extensions/Extensions.swift @@ -83,3 +83,42 @@ 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) + ) + } +} diff --git a/Sources/AllInApp/AllIn/Ressources/Colors.swift b/Sources/AllInApp/AllIn/Ressources/Colors.swift index 2f53a3e..a8eba0a 100644 --- a/Sources/AllInApp/AllIn/Ressources/Colors.swift +++ b/Sources/AllInApp/AllIn/Ressources/Colors.swift @@ -47,6 +47,7 @@ struct AllInColors { static let lightGrey300Color = Color("LightGrey300Color") static let componentBackgroundColor = Color("ComponentBackgroundColor") static let underComponentBackgroundColor = Color("UnderComponentBackgroundColor") + static let winBannerBackground = Color("WinBannerBackground") // Gradients static let primaryGradient = LinearGradient( diff --git a/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift index 2d5e698..f0e465f 100644 --- a/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift @@ -23,6 +23,10 @@ class LoginViewModel: ObservableObject { func login() { + #if DEBUG + self.onLoginSuccess() + #endif + guard checkAndSetError(forLogin: true, forPassword: true) else { return } diff --git a/Sources/AllInApp/AllIn/Views/BetView.swift b/Sources/AllInApp/AllIn/Views/BetView.swift index 1ef638f..8aac2a4 100644 --- a/Sources/AllInApp/AllIn/Views/BetView.swift +++ b/Sources/AllInApp/AllIn/Views/BetView.swift @@ -11,61 +11,65 @@ struct BetView: View { @StateObject private var viewModel = BetViewModel() @Binding var showMenu: Bool - @State private var showingSheet = false + @State var showingSheet: Bool = false var body: some View { - - VStack(alignment: .center, spacing: 0) { + ZStack(){ - TopBar(showMenu: self.$showMenu) - ScrollView(showsIndicators: false) { - LazyVStack(alignment: .leading, spacing: 0, pinnedViews: [.sectionHeaders]) { - - TrendingBetCard().padding(.top,25).padding([.leading,.trailing],25) - - Section { - VStack(spacing: 20){ - BetCard() - BetCard() - Button("Show Sheet") { - showingSheet.toggle() - } - .sheet(isPresented: $showingSheet) { - WinModal() - } - } - .padding([.leading,.trailing],25) + VStack(alignment: .center, spacing: 0) { + + + TopBar(showMenu: self.$showMenu) + ScrollView(showsIndicators: false) { + LazyVStack(alignment: .leading, spacing: 0, pinnedViews: [.sectionHeaders]) { + + TrendingBetCard().padding(.top,25).padding([.leading,.trailing],25) - } header: { - ZStack{ - AllInColors.fadeInGradiantCard - ScrollView(.horizontal,showsIndicators: false){ - HStack{ - ChoiceCapsule() - ChoiceCapsule() - ChoiceCapsule() - ChoiceCapsule() - ChoiceCapsule() - ChoiceCapsule() - ChoiceCapsule() + Section { + VStack(spacing: 20){ + BetCard() + Button("Show Sheet") { + showingSheet.toggle() + } + + } + .padding([.leading,.trailing],25) + + } header: { + ZStack{ + AllInColors.fadeInGradiantCard + ScrollView(.horizontal,showsIndicators: false){ + HStack{ + ChoiceCapsule() + ChoiceCapsule() + ChoiceCapsule() + ChoiceCapsule() + ChoiceCapsule() + ChoiceCapsule() + ChoiceCapsule() + } + .padding(.leading,25) + .padding([.top,.bottom],15) } - .padding(.leading,25) - .padding([.top,.bottom],15) } } } } + .sheet(isPresented: $showingSheet) { + WinModal() + } + Spacer() } - Spacer() + .edgesIgnoringSafeArea(.bottom) + .background(AllInColors.backgroundColor) + } - .edgesIgnoringSafeArea(.bottom) - .background(AllInColors.backgroundColor) } } struct BetView_Previews: PreviewProvider { static var previews: some View { BetView(showMenu: .constant(false)) - .preferredColorScheme(.dark) + .preferredColorScheme(.light) } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 599844c..d739ba0 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -1,18 +1,80 @@ -// -// DetailsView.swift -// AllIn -// -// Created by Lucas Delanier on 12/01/2024. -// - import SwiftUI struct DetailsView: View { + @Binding var isModalPresented: Bool var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + GeometryReader { geometry in + ZStack(alignment: .bottom) { + VStack(alignment: .trailing) { + HStack{ + Spacer() + Image("CloseiconRounded") + .resizable() + .padding(8) + .frame(maxWidth: 40, maxHeight: 40) + .onTapGesture { + isModalPresented = false + } + } + Spacer() + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.green) + .transition(.slideInFromBottom(yOffset:0)) + VStack(spacing: 0) { + VStack(alignment: .leading,spacing: 5){ + HStack{ + Spacer() + Text("proposé par Lucas").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).padding(.bottom, 10) + HStack{ + Text("Commence le").frame(maxWidth: 100).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) + TextCapsule() + TextCapsule() + Spacer() + + }.padding(.bottom, 10) + HStack{ + Text("Fini le").frame(maxWidth: 100).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) + TextCapsule() + TextCapsule() + Spacer() + + } + } + .frame(width: .infinity) + .padding(.all,15).padding(.vertical, 10) + .background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) + ResultBanner() + VStack(alignment: .leading,spacing: 2){ + + + + } + .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, maxHeight : .infinity) + .padding([.bottom,.trailing,.leading],8) + .background(AllInColors.underComponentBackgroundColor) + .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) + Spacer() + + + } + .frame(maxWidth: .infinity, maxHeight: geometry.size.height*0.98) + .background(Color.white) + .cornerRadius(15) + ParticipateButton().padding(10) + } + .transition(.slideInFromBottom(yOffset: 800)) + .edgesIgnoringSafeArea(.bottom) + } } } -#Preview { - DetailsView() +struct DetailsView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } } diff --git a/Sources/AllInApp/AllIn/Views/MainView.swift b/Sources/AllInApp/AllIn/Views/MainView.swift index 790873f..9b7900a 100644 --- a/Sources/AllInApp/AllIn/Views/MainView.swift +++ b/Sources/AllInApp/AllIn/Views/MainView.swift @@ -10,6 +10,7 @@ import SwiftUI struct MainView: View { @State var showMenu = false + var page: String var body: some View { @@ -58,6 +59,7 @@ struct MainView: View { .frame(width: geometry.size.width*0.83) .transition(.move(edge: .leading)) } + } .gesture(closeDrag) } diff --git a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj index bde5765..a86ec07 100644 --- a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj +++ b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 123590B42B51792000F7AEBD /* DetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123590B32B51792000F7AEBD /* DetailsView.swift */; }; + 123590B62B5537E200F7AEBD /* ResultBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123590B52B5537E200F7AEBD /* ResultBanner.swift */; }; + 123590B82B5541BA00F7AEBD /* ParticipateButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123590B72B5541BA00F7AEBD /* ParticipateButton.swift */; }; 1244EF602B4EC31E00374ABF /* HistoricBetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */; }; 1244EF622B4EC67000374ABF /* ReviewCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1244EF612B4EC67000374ABF /* ReviewCard.swift */; }; EC0193782B25BF16005D81E6 /* AllcoinsCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0193772B25BF16005D81E6 /* AllcoinsCapsule.swift */; }; @@ -99,6 +102,9 @@ 122278B72B4BDE1100E632AA /* DependencyInjection.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DependencyInjection.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 122278B92B4BDE9500E632AA /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Package.swift; path = ../Model/Package.swift; sourceTree = ""; }; 122278BB2B4BDEC300E632AA /* Sources */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Sources; path = ../StubLib/Sources; sourceTree = ""; }; + 123590B32B51792000F7AEBD /* DetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsView.swift; sourceTree = ""; }; + 123590B52B5537E200F7AEBD /* ResultBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultBanner.swift; sourceTree = ""; }; + 123590B72B5541BA00F7AEBD /* ParticipateButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParticipateButton.swift; sourceTree = ""; }; 1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoricBetView.swift; sourceTree = ""; }; 1244EF612B4EC67000374ABF /* ReviewCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewCard.swift; sourceTree = ""; }; EC0193772B25BF16005D81E6 /* AllcoinsCapsule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllcoinsCapsule.swift; sourceTree = ""; }; @@ -290,6 +296,7 @@ EC650A512B2794DD003AFCAD /* BetView.swift */, EC7A882C2B28D8A1004F226A /* CreationBetView.swift */, 1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */, + 123590B32B51792000F7AEBD /* DetailsView.swift */, ); path = Views; sourceTree = ""; @@ -316,6 +323,8 @@ ECA9D1C82B2D9ADA0076E0EC /* UserInfo.swift */, ECA9D1CA2B2DA2320076E0EC /* DropDownFriends.swift */, 1244EF612B4EC67000374ABF /* ReviewCard.swift */, + 123590B52B5537E200F7AEBD /* ResultBanner.swift */, + 123590B72B5541BA00F7AEBD /* ParticipateButton.swift */, ); path = Components; sourceTree = ""; @@ -496,6 +505,7 @@ EC30770F2B24FCB00060E34D /* RegisterView.swift in Sources */, EC650A522B2794DD003AFCAD /* BetView.swift in Sources */, EC6B969C2B24B4CC00FC1C58 /* AllInApp.swift in Sources */, + 123590B42B51792000F7AEBD /* DetailsView.swift in Sources */, ECB26A192B40744F00FE06B3 /* RankingViewModel.swift in Sources */, EC650A502B2793D5003AFCAD /* TextCapsule.swift in Sources */, EC650A482B25DCFF003AFCAD /* UsersPreview.swift in Sources */, @@ -518,12 +528,14 @@ EC3077072B24CB840060E34D /* SplashView.swift in Sources */, EC01937E2B25C52E005D81E6 /* TopBar.swift in Sources */, ECA9D1CB2B2DA2320076E0EC /* DropDownFriends.swift in Sources */, + 123590B82B5541BA00F7AEBD /* ParticipateButton.swift in Sources */, ECB26A1B2B40746C00FE06B3 /* FriendsViewModel.swift in Sources */, ECB7BC682B2F1ADF002A6654 /* LoginViewModel.swift in Sources */, 1244EF622B4EC67000374ABF /* ReviewCard.swift in Sources */, EC6B96D52B24BE0E00FC1C58 /* MainView.swift in Sources */, EC650A562B279D68003AFCAD /* WinModal.swift in Sources */, EC6B96D12B24BAE800FC1C58 /* AuthService.swift in Sources */, + 123590B62B5537E200F7AEBD /* ResultBanner.swift in Sources */, EC01937C2B25C2A8005D81E6 /* AllcoinsCounter.swift in Sources */, EC650A542B279545003AFCAD /* ChoiceCapsule.swift in Sources */, ECB7BC6C2B2F43EE002A6654 /* AppState.swift in Sources */, -- 2.36.3 From c381fdf0e736ff5d58af61552431b4e759709d61 Mon Sep 17 00:00:00 2001 From: "emre.kartal" Date: Fri, 19 Jan 2024 11:06:09 +0100 Subject: [PATCH 04/14] Correct AuthService --- .../contents.xcworkspacedata | 3 - .../AllInApp/AllIn/Components/BetCard.swift | 2 +- .../AllIn/Components/RecapBetCard.swift | 2 +- .../AllIn/Components/ReviewCard.swift | 2 +- .../AllInApp/AllIn/Ressources/Config.swift | 2 +- .../AllInApp/AllIn/Services/AuthService.swift | 29 +++--- .../AllIn/ViewModels/DetailsViewModel.swift | 26 ++++++ .../ViewModels/HistoricBetViewModel.swift | 24 +++++ Sources/AllInApp/AllIn/Views/BetView.swift | 3 + .../AllInApp/AllIn/Views/DetailsView.swift | 10 ++ .../AllInApp.xcodeproj/project.pbxproj | 15 +-- Sources/Api/Sources/Api/BetApiManager.swift | 4 + .../Sources/Api/Factory/FactoryApiBet.swift | 23 ++--- Sources/Api/Sources/Api/UserApiManager.swift | 9 +- Sources/Model/Sources/Model/Bet.swift | 29 +++++- .../Model/Sources/Model/BetDataManager.swift | 1 + Sources/Model/Sources/Model/BinaryBet.swift | 17 ++++ .../Sources/Model/Factory/FactoryBet.swift | 2 +- Sources/Model/Sources/Model/Manager.swift | 12 +++ Sources/Model/Sources/Model/MatchBet.swift | 21 +++++ .../Model/Sources/Model/UserDataManager.swift | 1 + Sources/StubLib/Package.swift | 29 ------ Sources/StubLib/README.md | 3 - .../Sources/StubLib/BetStubManager.swift | 26 ------ Sources/StubLib/Sources/StubLib/Stub.swift | 91 ------------------- .../Sources/StubLib/UserStubManager.swift | 38 -------- .../Sources/ViewModel/ManagerVM.swift | 16 +++- 27 files changed, 210 insertions(+), 230 deletions(-) create mode 100644 Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift create mode 100644 Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift delete mode 100644 Sources/StubLib/Package.swift delete mode 100644 Sources/StubLib/README.md delete mode 100644 Sources/StubLib/Sources/StubLib/BetStubManager.swift delete mode 100644 Sources/StubLib/Sources/StubLib/Stub.swift delete mode 100644 Sources/StubLib/Sources/StubLib/UserStubManager.swift diff --git a/Sources/AllIn.xcworkspace/contents.xcworkspacedata b/Sources/AllIn.xcworkspace/contents.xcworkspacedata index 50d956e..a92bbda 100644 --- a/Sources/AllIn.xcworkspace/contents.xcworkspacedata +++ b/Sources/AllIn.xcworkspace/contents.xcworkspacedata @@ -7,9 +7,6 @@ - - diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index c75b2b7..cf2888f 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -88,7 +88,7 @@ struct BetCard: View { }.onTapGesture { showDetails.toggle() }.fullScreenCover(isPresented: $showDetails) { - DetailsView(isModalPresented: $showDetails) + DetailsView(isModalPresented: $showDetails, id: bet.id) } } diff --git a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift index 1a47b77..440275c 100644 --- a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift +++ b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift @@ -107,7 +107,7 @@ struct RecapBetCard: View { .onTapGesture { showDetails.toggle() }.fullScreenCover(isPresented: $showDetails) { - DetailsView(isModalPresented: $showDetails) + DetailsView(isModalPresented: $showDetails, id: "1") } .gesture( LongPressGesture(minimumDuration: 0.5) diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift index 001ef16..130e085 100644 --- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift +++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift @@ -70,7 +70,7 @@ struct ReviewCard: View { .onTapGesture { showDetails.toggle() }.fullScreenCover(isPresented: $showDetails) { - DetailsView(isModalPresented: $showDetails) + DetailsView(isModalPresented: $showDetails, id: "1") } } } diff --git a/Sources/AllInApp/AllIn/Ressources/Config.swift b/Sources/AllInApp/AllIn/Ressources/Config.swift index e235a9a..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 = "https://codefirst.iut.uca.fr/containers/AllDev-api" + static let allInApi = "https://codefirst.iut.uca.fr/containers/AllDev-api/" } diff --git a/Sources/AllInApp/AllIn/Services/AuthService.swift b/Sources/AllInApp/AllIn/Services/AuthService.swift index 5c75fe3..ea344c4 100644 --- a/Sources/AllInApp/AllIn/Services/AuthService.swift +++ b/Sources/AllInApp/AllIn/Services/AuthService.swift @@ -10,46 +10,49 @@ import Model import ViewModel import DependencyInjection import Api -import StubLib class AuthService: IAuthService { - public func login(login: String, password: String, completion : @escaping (Int)-> ()) { + public func login(login: String, password: String, completion: @escaping (Int) -> ()) { let url = URL(string: Config.allInApi + "users/login")! var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") - + let json = [ "login": login.lowercased(), "password": password, ] - - if let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []){ + + if let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []) { URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in - print ("ALLIN : Process LOGIN") + print("ALLIN: Process LOGIN") if let httpResponse = response as? HTTPURLResponse { if httpResponse.statusCode == 200 { if let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let token = json["token"] as? String { - AppStateContainer.shared.authenticationRefresh = token; + AppStateContainer.shared.authenticationRefresh = token self.initializeUser(withToken: token) { status in + print(status) if status != 200 { completion(status) - AppStateContainer.shared.authenticationRefresh = nil; + AppStateContainer.shared.authenticationRefresh = nil } else { self.initManagerVM(token: token) + completion(httpResponse.statusCode) } } } + } else { + completion(httpResponse.statusCode) } - completion(httpResponse.statusCode) } }.resume() } } + func register(username: String, email: String, password: String, completion : @escaping (Int)-> ()) { let url = URL(string: Config.allInApi + "/users/register")! @@ -78,11 +81,13 @@ class AuthService: IAuthService { AppStateContainer.shared.authenticationRefresh = nil; } else { self.initManagerVM(token: token) + completion(httpResponse.statusCode) } } } + } else { + completion(httpResponse.statusCode) } - completion(httpResponse.statusCode) } }.resume() } @@ -118,12 +123,14 @@ class AuthService: IAuthService { } private func initializeUser(withToken token: String, completion: @escaping (Int) -> ()) { + let url = URL(string: Config.allInApi + "users/token")! var request = URLRequest(url: url) + request.httpMethod = "GET" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") - + URLSession.shared.dataTask(with: request) { data, response, error in if let data = data, let httpResponse = response as? HTTPURLResponse { diff --git a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift new file mode 100644 index 0000000..8f63afb --- /dev/null +++ b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift @@ -0,0 +1,26 @@ +// +// DetailsViewModel.swift +// AllIn +// +// Created by Emre on 16/01/2024. +// + +import Foundation +import SwiftUI +import ViewModel +import DependencyInjection + +class DetailsViewModel: ObservableObject { + + @Inject var manager: ManagerVM + var id: String + + init(id: String) { + self.id = id + getItem() + } + + func getItem() { + + } +} diff --git a/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift new file mode 100644 index 0000000..a5643cc --- /dev/null +++ b/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift @@ -0,0 +1,24 @@ +// +// HistoricBetViewModel.swift +// AllIn +// +// Created by Emre on 16/01/2024. +// + +import Foundation +import SwiftUI +import ViewModel +import DependencyInjection + +class HistoricBetViewModel: ObservableObject { + + @Inject var manager: ManagerVM + + init() { + getItems() + } + + func getItems() { + + } +} diff --git a/Sources/AllInApp/AllIn/Views/BetView.swift b/Sources/AllInApp/AllIn/Views/BetView.swift index 7a6ef13..9f28940 100644 --- a/Sources/AllInApp/AllIn/Views/BetView.swift +++ b/Sources/AllInApp/AllIn/Views/BetView.swift @@ -54,6 +54,9 @@ struct BetView: View { } } } + .refreshable { + viewModel.getItems() + } .sheet(isPresented: $showingSheet) { WinModal() } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 6bf0660..6c02302 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -1,7 +1,17 @@ import SwiftUI struct DetailsView: View { + @Binding var isModalPresented: Bool + var id: String + @StateObject private var viewModel: DetailsViewModel + + init(isModalPresented: Binding, id: String) { + self._isModalPresented = isModalPresented + self.id = id + self._viewModel = StateObject(wrappedValue: DetailsViewModel(id: id)) + } + var body: some View { GeometryReader { geometry in ZStack(alignment: .bottom) { diff --git a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj index a86ec07..2ba0c3a 100644 --- a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj +++ b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ EC01937A2B25C12B005D81E6 /* BetCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0193792B25C12B005D81E6 /* BetCard.swift */; }; EC01937C2B25C2A8005D81E6 /* AllcoinsCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01937B2B25C2A8005D81E6 /* AllcoinsCounter.swift */; }; EC01937E2B25C52E005D81E6 /* TopBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01937D2B25C52E005D81E6 /* TopBar.swift */; }; + EC01FCC32B56650400BB2390 /* DetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */; }; + EC01FCC52B56791B00BB2390 /* HistoricBetViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */; }; EC3077072B24CB840060E34D /* SplashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3077062B24CB840060E34D /* SplashView.swift */; }; EC3077092B24CF7F0060E34D /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3077082B24CF7F0060E34D /* Colors.swift */; }; EC30770B2B24D9160060E34D /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC30770A2B24D9160060E34D /* WelcomeView.swift */; }; @@ -23,7 +25,6 @@ EC30770F2B24FCB00060E34D /* RegisterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC30770E2B24FCB00060E34D /* RegisterView.swift */; }; EC4F0D2C2B4EBF5600853949 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = ECB357342B3E13A400045D41 /* Model */; }; EC4F0D2E2B4EC04B00853949 /* ViewModel in Frameworks */ = {isa = PBXBuildFile; productRef = EC4F0D2D2B4EC04B00853949 /* ViewModel */; }; - EC4F0D302B4EC05D00853949 /* StubLib in Frameworks */ = {isa = PBXBuildFile; productRef = EC4F0D2F2B4EC05D00853949 /* StubLib */; }; EC650A422B25C817003AFCAD /* Friend.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC650A412B25C817003AFCAD /* Friend.swift */; }; EC650A442B25CDF3003AFCAD /* ParameterMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC650A432B25CDF3003AFCAD /* ParameterMenu.swift */; }; EC650A462B25D686003AFCAD /* RankingRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC650A452B25D686003AFCAD /* RankingRow.swift */; }; @@ -111,6 +112,8 @@ EC0193792B25C12B005D81E6 /* BetCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetCard.swift; sourceTree = ""; }; EC01937B2B25C2A8005D81E6 /* AllcoinsCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllcoinsCounter.swift; sourceTree = ""; }; EC01937D2B25C52E005D81E6 /* TopBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBar.swift; sourceTree = ""; }; + EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsViewModel.swift; sourceTree = ""; }; + EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoricBetViewModel.swift; sourceTree = ""; }; EC3077062B24CB840060E34D /* SplashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashView.swift; sourceTree = ""; }; EC3077082B24CF7F0060E34D /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; EC30770A2B24D9160060E34D /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; @@ -167,7 +170,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - EC4F0D302B4EC05D00853949 /* StubLib in Frameworks */, EC4F0D2C2B4EBF5600853949 /* Model in Frameworks */, ECCD244A2B4DE8010071FA9E /* Api in Frameworks */, EC4F0D2E2B4EC04B00853949 /* ViewModel in Frameworks */, @@ -350,6 +352,8 @@ ECB26A162B4073F100FE06B3 /* CreationBetViewModel.swift */, ECB26A182B40744F00FE06B3 /* RankingViewModel.swift */, ECB26A1A2B40746C00FE06B3 /* FriendsViewModel.swift */, + EC01FCC22B56650400BB2390 /* DetailsViewModel.swift */, + EC01FCC42B56791B00BB2390 /* HistoricBetViewModel.swift */, ); path = ViewModels; sourceTree = ""; @@ -375,7 +379,6 @@ ECB357342B3E13A400045D41 /* Model */, ECCD24492B4DE8010071FA9E /* Api */, EC4F0D2D2B4EC04B00853949 /* ViewModel */, - EC4F0D2F2B4EC05D00853949 /* StubLib */, ); productName = AllIn; productReference = EC6B96982B24B4CC00FC1C58 /* AllIn.app */; @@ -529,6 +532,7 @@ EC01937E2B25C52E005D81E6 /* TopBar.swift in Sources */, ECA9D1CB2B2DA2320076E0EC /* DropDownFriends.swift in Sources */, 123590B82B5541BA00F7AEBD /* ParticipateButton.swift in Sources */, + EC01FCC32B56650400BB2390 /* DetailsViewModel.swift in Sources */, ECB26A1B2B40746C00FE06B3 /* FriendsViewModel.swift in Sources */, ECB7BC682B2F1ADF002A6654 /* LoginViewModel.swift in Sources */, 1244EF622B4EC67000374ABF /* ReviewCard.swift in Sources */, @@ -536,6 +540,7 @@ EC650A562B279D68003AFCAD /* WinModal.swift in Sources */, EC6B96D12B24BAE800FC1C58 /* AuthService.swift in Sources */, 123590B62B5537E200F7AEBD /* ResultBanner.swift in Sources */, + EC01FCC52B56791B00BB2390 /* HistoricBetViewModel.swift in Sources */, EC01937C2B25C2A8005D81E6 /* AllcoinsCounter.swift in Sources */, EC650A542B279545003AFCAD /* ChoiceCapsule.swift in Sources */, ECB7BC6C2B2F43EE002A6654 /* AppState.swift in Sources */, @@ -873,10 +878,6 @@ isa = XCSwiftPackageProductDependency; productName = ViewModel; }; - EC4F0D2F2B4EC05D00853949 /* StubLib */ = { - isa = XCSwiftPackageProductDependency; - productName = StubLib; - }; ECB357342B3E13A400045D41 /* Model */ = { isa = XCSwiftPackageProductDependency; productName = Model; diff --git a/Sources/Api/Sources/Api/BetApiManager.swift b/Sources/Api/Sources/Api/BetApiManager.swift index 10225a3..6de0b51 100644 --- a/Sources/Api/Sources/Api/BetApiManager.swift +++ b/Sources/Api/Sources/Api/BetApiManager.swift @@ -46,4 +46,8 @@ public struct BetApiManager: BetDataManager { return [] } + public func getBet(withId id: String, completion: @escaping (Bet) -> Void) { + + } + } diff --git a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift index 8c29b11..1adb92c 100644 --- a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift +++ b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift @@ -11,13 +11,13 @@ import Model public class FactoryApiBet: FactoryBet { public func toResponse(bet: Bet) -> [String: Any] { - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + let json: [String: Any] = [ + "id": "1", "theme": bet.theme, "sentenceBet": bet.phrase, - "endRegistration": dateFormatter.string(from: bet.endRegisterDate), - "endBet": dateFormatter.string(from: bet.endBetDate), + "endRegistration": bet.endRegisterDate.timeIntervalSince1970, + "endBet": bet.endBetDate.timeIntervalSince1970, "isPrivate": String(bet.isPublic), "response": [], ] @@ -26,7 +26,8 @@ public class FactoryApiBet: FactoryBet { } public func toModel(from json: [String: Any]) -> Bet? { - guard let theme = json["theme"] as? String, + guard let id = json["id"] as? String, + let theme = json["theme"] as? String, let phrase = json["sentenceBet"] as? String, let endRegisterDateString = json["endRegistration"] as? String, let endBetDateString = json["endBet"] as? String, @@ -43,19 +44,19 @@ public class FactoryApiBet: FactoryBet { return nil } - return toModel(theme: theme, description: phrase, endRegister: endRegisterDate, endBet: endBetDate, isPublic: isPublic, creator: User(username: createdBy, email: createdBy, nbCoins: 0, friends: []), type: 0) + return toModel(id: id, 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 { + public func toModel(id: String, theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User, type: Int) -> Bet { switch type { case 0: - return BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) + return BinaryBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) case 1: - return MatchBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [], nameTeam1: "", nameTeam2: "") + return MatchBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [], nameTeam1: "", nameTeam2: "") case 2: - return CustomBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) + return CustomBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) default: - return BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) + return BinaryBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) } } diff --git a/Sources/Api/Sources/Api/UserApiManager.swift b/Sources/Api/Sources/Api/UserApiManager.swift index 6330e6e..89873c8 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 = "https://codefirst.iut.uca.fr/containers/AllDev-api/" public struct UserApiManager: UserDataManager { @@ -37,9 +37,6 @@ public struct UserApiManager: UserDataManager { URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in print ("ALLIN : Add BET") if let httpResponse = response as? HTTPURLResponse { - if httpResponse.statusCode == 201 { - - } print(httpResponse.statusCode) } }.resume() @@ -49,4 +46,8 @@ public struct UserApiManager: UserDataManager { public func getFriends() -> [User] { fatalError("Not implemented yet") } + + public func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { + fatalError("Not implemented yet") + } } diff --git a/Sources/Model/Sources/Model/Bet.swift b/Sources/Model/Sources/Model/Bet.swift index fca14b5..b99b7c2 100644 --- a/Sources/Model/Sources/Model/Bet.swift +++ b/Sources/Model/Sources/Model/Bet.swift @@ -11,7 +11,7 @@ import Foundation public class Bet: ObservableObject, Identifiable { /// The id for the bet. - public var id = UUID() + public private(set) var id: String /// The theme or topic of the bet. public private(set) var theme: String @@ -43,6 +43,32 @@ public class Bet: ObservableObject, Identifiable { /// Custom Constructor /// /// - Parameters: + /// - id: The id for the bet. + /// - theme: The theme or topic of the bet. + /// - phrase: The specific phrase or question related to the bet. + /// - endRegisterDate: The deadline for users to register for the bet. + /// - endBetDate: The deadline for the actual betting to take place. + /// - totalStakes: The total stakes or amount involved in the bet. + /// - isPublic: Indicates whether the bet is public or private. + /// - invited: List of users who are invited to participate in the bet. + /// - author: The user who created the bet. + /// - registered: List of users who have registered for the bet. + public init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { + self.id = id + self.theme = theme + self.phrase = phrase + self.endRegisterDate = endRegisterDate + self.endBetDate = endBetDate + self.totalStakes = totalStakes + self.isPublic = isPublic + self.invited = invited + self.author = author + self.registered = registered + } + + /// Custom Constructor without Id + /// + /// - Parameters: /// - theme: The theme or topic of the bet. /// - phrase: The specific phrase or question related to the bet. /// - endRegisterDate: The deadline for users to register for the bet. @@ -53,6 +79,7 @@ public class Bet: ObservableObject, Identifiable { /// - author: The user who created the bet. /// - registered: List of users who have registered for the bet. public init(theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { + self.id = UUID().uuidString self.theme = theme self.phrase = phrase self.endRegisterDate = endRegisterDate diff --git a/Sources/Model/Sources/Model/BetDataManager.swift b/Sources/Model/Sources/Model/BetDataManager.swift index 24a769c..bcc0b25 100644 --- a/Sources/Model/Sources/Model/BetDataManager.swift +++ b/Sources/Model/Sources/Model/BetDataManager.swift @@ -10,4 +10,5 @@ import Foundation public protocol BetDataManager { func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) func getUsers(username: String) -> [User] + func getBet(withId id: String, completion: @escaping (Bet) -> Void) } diff --git a/Sources/Model/Sources/Model/BinaryBet.swift b/Sources/Model/Sources/Model/BinaryBet.swift index 8767849..051ccf6 100644 --- a/Sources/Model/Sources/Model/BinaryBet.swift +++ b/Sources/Model/Sources/Model/BinaryBet.swift @@ -13,6 +13,23 @@ public class BinaryBet: Bet { // Custom Constructor /// /// - Parameters: + /// - id: The id for the bet. + /// - theme: The theme or topic of the binary bet. + /// - phrase: The specific phrase or question related to the binary bet. + /// - endRegisterDate: The deadline for users to register for the binary bet. + /// - endBetDate: The deadline for the actual betting to take place for the binary bet. + /// - totalStakes: The total stakes or amount involved in the binary bet. + /// - isPublic: Indicates whether the binary bet is public or private. + /// - invited: List of users who are invited to participate in the binary bet. + /// - author: The user who created the binary bet. + /// - registered: List of users who have registered for the binary bet. + public override init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { + super.init(id: id, theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, totalStakes: totalStakes, isPublic: isPublic, invited: invited, author: author, registered: registered) + } + + // Custom Constructor without Id + /// + /// - Parameters: /// - theme: The theme or topic of the binary bet. /// - phrase: The specific phrase or question related to the binary bet. /// - endRegisterDate: The deadline for users to register for the binary bet. diff --git a/Sources/Model/Sources/Model/Factory/FactoryBet.swift b/Sources/Model/Sources/Model/Factory/FactoryBet.swift index c692035..40a7f0a 100644 --- a/Sources/Model/Sources/Model/Factory/FactoryBet.swift +++ b/Sources/Model/Sources/Model/Factory/FactoryBet.swift @@ -10,5 +10,5 @@ import Foundation public protocol FactoryBet { func toResponse(bet: Bet) -> [String: Any] func toModel(from json: [String: Any]) -> Bet? - func toModel(theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User, type: Int) -> Bet + func toModel(id: String, theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User, type: Int) -> Bet } diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift index 224e021..94e87a6 100644 --- a/Sources/Model/Sources/Model/Manager.swift +++ b/Sources/Model/Sources/Model/Manager.swift @@ -25,4 +25,16 @@ public struct Manager { completion(bets) } } + + public func getBet(withId id: String, completion: @escaping (Bet) -> Void) { + betDataManager.getBet(withId: id) { bet in + completion(bet) + } + } + + public func getHistoricBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { + userDataManager.getOldBets(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 cddcc4e..e197042 100644 --- a/Sources/Model/Sources/Model/MatchBet.swift +++ b/Sources/Model/Sources/Model/MatchBet.swift @@ -18,6 +18,27 @@ public class MatchBet: Bet { /// Custom Constructor /// /// - Parameters: + /// - id: The id for the bet. + /// - theme: The theme or topic of the match bet. + /// - phrase: The specific phrase or question related to the match bet. + /// - endRegisterDate: The deadline for users to register for the match bet. + /// - endBetDate: The deadline for the actual betting to take place for the match bet. + /// - totalStakes: The total stakes or amount involved in the match bet. + /// - isPublic: Indicates whether the match bet is public or private. + /// - invited: List of users who are invited to participate in the match bet. + /// - author: The user who created the match bet. + /// - registered: List of users who have registered for the match bet. + /// - nameTeam1: The name of the first team involved in the match. + /// - nameTeam2: The name of the second team involved in the match. + public init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User], nameTeam1: String, nameTeam2: String) { + self.nameTeam1 = nameTeam1 + self.nameTeam2 = nameTeam2 + super.init(id: id, theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, totalStakes: totalStakes, isPublic: isPublic, invited: invited, author: author, registered: registered) + } + + /// Custom Constructor without Id + /// + /// - Parameters: /// - theme: The theme or topic of the match bet. /// - phrase: The specific phrase or question related to the match bet. /// - endRegisterDate: The deadline for users to register for the match bet. diff --git a/Sources/Model/Sources/Model/UserDataManager.swift b/Sources/Model/Sources/Model/UserDataManager.swift index 584add7..487cad9 100644 --- a/Sources/Model/Sources/Model/UserDataManager.swift +++ b/Sources/Model/Sources/Model/UserDataManager.swift @@ -11,4 +11,5 @@ public protocol UserDataManager { func getBets(withIndex index: Int, withCount count: Int) -> [Bet] func addBet(bet: Bet) func getFriends() -> [User] + func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) } diff --git a/Sources/StubLib/Package.swift b/Sources/StubLib/Package.swift deleted file mode 100644 index 813f113..0000000 --- a/Sources/StubLib/Package.swift +++ /dev/null @@ -1,29 +0,0 @@ -// swift-tools-version: 5.8 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription - -let package = Package( - name: "StubLib", - platforms: [ - .iOS(.v13) - ], - products: [ - // Products define the executables and libraries a package produces, and make them visible to other packages. - .library( - name: "StubLib", - targets: ["StubLib"]), - ], - dependencies: [ - // Dependencies declare other packages that this package depends on. - // .package(url: /* package url */, from: "1.0.0"), - .package(name: "Model", path: "../Model") - ], - targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. - .target( - name: "StubLib", - dependencies: ["Model"]), - ] -) diff --git a/Sources/StubLib/README.md b/Sources/StubLib/README.md deleted file mode 100644 index 9f7060e..0000000 --- a/Sources/StubLib/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# StubLib - -A description of this package. diff --git a/Sources/StubLib/Sources/StubLib/BetStubManager.swift b/Sources/StubLib/Sources/StubLib/BetStubManager.swift deleted file mode 100644 index bfacf3f..0000000 --- a/Sources/StubLib/Sources/StubLib/BetStubManager.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// BetStubManager.swift -// -// -// Created by Emre on 31/12/2023. -// - -import Foundation -import Model - -public struct BetStubManager: BetDataManager { - - public init() {} - - public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { - completion(Stub.shared.bets) - } - - public func getUsers(username: String) -> [User] { - return Stub.shared.users - .filter { user in - user.username.contains(username) - } - } - -} diff --git a/Sources/StubLib/Sources/StubLib/Stub.swift b/Sources/StubLib/Sources/StubLib/Stub.swift deleted file mode 100644 index fe9e225..0000000 --- a/Sources/StubLib/Sources/StubLib/Stub.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// Stub.swift -// -// -// Created by Emre on 01/01/2024. -// - -import Foundation -import Model - -struct Stub { - - static var shared = Stub() - public var bets: [Bet] = [] - public var users: [User] = [] - - public init() { - loadBets() - } - - public mutating func loadBets() { - - var user1 = User(username: "Lucas", email: "lucas.delanier@etu.uca.fr", nbCoins: 100, friends: []) - users.append(user1) - - var user2 = User(username: "Imri", email: "emre.kartal@etu.uca.fr", nbCoins: 75, friends: [user1]) - users.append(user2) - user1.addFriend(user: user2) - - let user3 = User(username: "Arthur", email: "arthur.valin@etu.uca.fr", nbCoins: 30, friends: [user2]) - users.append(user3) - user2.addFriend(user: user3) - - let bet1 = 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: user1, - registered: [user2] - ) - self.bets.append(bet1) - - let bet2 = BinaryBet( - theme: "Cuisine - Concours de cuisine en direct", - phrase: "Le plat préféré du jury sera une recette végétarienne.", - endRegisterDate: Date().addingTimeInterval(172800), - endBetDate: Date().addingTimeInterval(259200), - totalStakes: 150, - isPublic: false, - invited: [user3], - author: user1, - registered: [user2] - ) - self.bets.append(bet2) - - let bet3 = BinaryBet( - theme: "Technologie - Lancement d'un nouveau smartphone", - phrase: "Le nombre total de précommandes dépassera-t-il 1 million dans la première semaine ?", - endRegisterDate: Date().addingTimeInterval(259200), - endBetDate: Date().addingTimeInterval(345600), - totalStakes: 75, - isPublic: true, - invited: [], - author: user1, - registered: [user2, user1, user3] - ) - self.bets.append(bet3) - - let bet4 = BinaryBet( - theme: "Cinéma - Oscars 2024", - phrase: "Le film favori des critiques remportera-t-il le prix du meilleur film ?", - endRegisterDate: Date().addingTimeInterval(345600), - endBetDate: Date().addingTimeInterval(432000), - totalStakes: 120, - isPublic: false, - invited: [user1], - author: user2, - registered: [user3] - ) - self.bets.append(bet4) - - } - - public mutating func add(bet: Bet) { - self.bets.append(bet) - } -} diff --git a/Sources/StubLib/Sources/StubLib/UserStubManager.swift b/Sources/StubLib/Sources/StubLib/UserStubManager.swift deleted file mode 100644 index a2f8b07..0000000 --- a/Sources/StubLib/Sources/StubLib/UserStubManager.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// UserStubManager.swift -// -// -// Created by Emre on 31/12/2023. -// - -import Foundation -import Model - -public struct UserStubManager: UserDataManager { - - private var username: String - - public init(username: String) { - self.username = username - } - - public func getBets(withIndex index: Int, withCount count: Int) -> [Bet] { - return Stub.shared.bets.filter { bet in - bet.registered.contains { user in - user.username == self.username - } - } - } - - public func addBet(bet: Bet) { - Stub.shared.add(bet: bet) - } - - public func getFriends() -> [User] { - return Stub.shared.users.filter { user in - user.friends.contains { friend in - friend.username == self.username - } - } - } -} diff --git a/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift b/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift index 673750b..f6dd67f 100644 --- a/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift +++ b/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift @@ -9,9 +9,10 @@ import Foundation import Model public class ManagerVM: ObservableObject { - @Published var model: Manager + @Published var model: Manager @Published public var bets: [Bet] = [] + @Published public var bet: Bet? public init(withModel model: Manager) { self.model = model @@ -26,4 +27,17 @@ public class ManagerVM: ObservableObject { public func addBet(theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User) { model.addBet(bet: BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [])) } + + public func getBet(withId id: String) { + model.getBet(withId: id) { bet in + self.bet = bet + } + } + + public func getHistoricBets() { + model.getHistoricBets(withIndex: 0, withCount: 20) { bets in + self.bets = bets + } + } + } -- 2.36.3 From 6eb3b2e8cd2971f1b07a44fb9291ebc74aeeb2ac Mon Sep 17 00:00:00 2001 From: "emre.kartal" Date: Fri, 19 Jan 2024 17:54:59 +0100 Subject: [PATCH 05/14] Delete ManagerVM, re add the StubLib and improvement of the model :art: --- .../contents.xcworkspacedata | 6 +- Sources/AllInApp/AllIn/AllInApp.swift | 1 - .../AllInApp/AllIn/Components/BetCard.swift | 49 ++++------ .../AllInApp/AllIn/Services/AuthService.swift | 4 +- .../AllIn/ViewModels/BetViewModel.swift | 15 +-- .../ViewModels/CreationBetViewModel.swift | 4 +- .../AllIn/ViewModels/DetailsViewModel.swift | 14 ++- .../AllIn/ViewModels/FriendsViewModel.swift | 4 +- .../ViewModels/HistoricBetViewModel.swift | 4 +- .../AllIn/ViewModels/RankingViewModel.swift | 4 +- .../AllInApp/AllIn/Views/DetailsView.swift | 2 - .../AllInApp.xcodeproj/project.pbxproj | 12 +-- Sources/Api/Sources/Api/BetApiManager.swift | 2 +- .../Model/Sources/Model/BetAnswerDetail.swift | 43 ++++++++ .../Model/Sources/Model/BetDataManager.swift | 2 +- Sources/Model/Sources/Model/BetDetail.swift | 38 ++++++++ .../Sources/Model/BinaryParticipation.swift | 33 ------- .../Sources/Model/CustomParticipation.swift | 27 ------ Sources/Model/Sources/Model/Manager.swift | 6 +- .../Sources/Model/MatchParticipation.swift | 32 ------ .../Model/Sources/Model/Participation.swift | 32 +++--- Sources/{ViewModel => StubLib}/.gitignore | 0 Sources/{ViewModel => StubLib}/Package.swift | 8 +- Sources/{ViewModel => StubLib}/README.md | 2 +- .../Sources/StubLib/BetStubManager.swift | 32 ++++++ Sources/StubLib/Sources/StubLib/Stub.swift | 97 +++++++++++++++++++ .../Sources/ViewModel/ManagerVM.swift | 43 -------- 27 files changed, 289 insertions(+), 227 deletions(-) create mode 100644 Sources/Model/Sources/Model/BetAnswerDetail.swift create mode 100644 Sources/Model/Sources/Model/BetDetail.swift delete mode 100644 Sources/Model/Sources/Model/BinaryParticipation.swift delete mode 100644 Sources/Model/Sources/Model/CustomParticipation.swift delete mode 100644 Sources/Model/Sources/Model/MatchParticipation.swift rename Sources/{ViewModel => StubLib}/.gitignore (100%) rename Sources/{ViewModel => StubLib}/Package.swift (88%) rename Sources/{ViewModel => StubLib}/README.md (72%) create mode 100644 Sources/StubLib/Sources/StubLib/BetStubManager.swift create mode 100644 Sources/StubLib/Sources/StubLib/Stub.swift delete mode 100644 Sources/ViewModel/Sources/ViewModel/ManagerVM.swift diff --git a/Sources/AllIn.xcworkspace/contents.xcworkspacedata b/Sources/AllIn.xcworkspace/contents.xcworkspacedata index a92bbda..74c136d 100644 --- a/Sources/AllIn.xcworkspace/contents.xcworkspacedata +++ b/Sources/AllIn.xcworkspace/contents.xcworkspacedata @@ -2,13 +2,13 @@ + location = "group:StubLib"> + location = "group:Api"> + location = "group:AllInApp/AllInApp.xcodeproj"> diff --git a/Sources/AllInApp/AllIn/AllInApp.swift b/Sources/AllInApp/AllIn/AllInApp.swift index f79fa97..374a309 100644 --- a/Sources/AllInApp/AllIn/AllInApp.swift +++ b/Sources/AllInApp/AllIn/AllInApp.swift @@ -8,7 +8,6 @@ import SwiftUI import DependencyInjection import Model -import ViewModel @main struct AllInApp: App { diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index cf2888f..8f29bcf 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -12,7 +12,7 @@ struct BetCard: View { var bet: Bet @State var showDetails: Bool = false - + var body: some View { VStack(spacing: 0){ VStack(alignment: .leading,spacing: 2){ @@ -67,44 +67,33 @@ struct BetCard: View { RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) ).padding([.top],5) - VStack(alignment: .leading,spacing: 2){ - HStack{ - Spacer() - UsersPreview() - Text(" 4 joueurs en attente").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color).fontWeight(.medium) - - Spacer() - - }.padding(0) - ParticipateButton().padding(.top, 5) - - } - .frame(width: .infinity) - .padding(.all,8) - .background(AllInColors.underComponentBackgroundColor) - .cornerRadius(20, corners: [.bottomLeft,.bottomRight]) - .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) } - }.onTapGesture { + .frame(width: .infinity) + .padding(.all,8) + .background(AllInColors.underComponentBackgroundColor) + .cornerRadius(20, corners: [.bottomLeft,.bottomRight]) + .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) + } + .onTapGesture { showDetails.toggle() - }.fullScreenCover(isPresented: $showDetails) { + } + .fullScreenCover(isPresented: $showDetails) { DetailsView(isModalPresented: $showDetails, id: bet.id) } - } } struct BetCard_Previews: PreviewProvider { static var previews: some View { 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) + 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/Services/AuthService.swift b/Sources/AllInApp/AllIn/Services/AuthService.swift index ea344c4..df4b7e6 100644 --- a/Sources/AllInApp/AllIn/Services/AuthService.swift +++ b/Sources/AllInApp/AllIn/Services/AuthService.swift @@ -7,9 +7,9 @@ import Foundation import Model -import ViewModel import DependencyInjection import Api +import StubLib class AuthService: IAuthService { @@ -150,7 +150,7 @@ class AuthService: IAuthService { } private func initManagerVM(token: String) { - DependencyInjection.shared.addSingleton(ManagerVM.self, ManagerVM(withModel: Manager(withBetDataManager: BetApiManager(), withUserDataManager: UserApiManager(withUserToken: token)))) + DependencyInjection.shared.addSingleton(Manager.self, Manager(withBetDataManager: BetStubManager(), withUserDataManager: UserApiManager(withUserToken: token))) } } diff --git a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift index 6a6dd6c..e378534 100644 --- a/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/BetViewModel.swift @@ -7,30 +7,23 @@ import Foundation import DependencyInjection -import ViewModel import Model import Combine class BetViewModel: ObservableObject { - @Inject var manager: ManagerVM + @Inject var manager: Manager - @Published private var internalBets: [Bet] = [] - - var bets: [Bet] { - return internalBets - } + @Published private(set) var bets: [Bet] = [] init() { getItems() } func getItems() { - for bet in manager.bets { - print(bet.theme) + manager.getBets(withIndex: 0, withCount: 20) { bets in + self.bets = bets } - manager.$bets.assign(to: \.internalBets, on: self).store(in: &cancellables) - manager.getPublicBets() } private var cancellables: Set = [] diff --git a/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift index 4adb521..bc7b7b0 100644 --- a/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift @@ -8,11 +8,11 @@ import Foundation import SwiftUI import DependencyInjection -import ViewModel +import Model class CreationBetViewModel: ObservableObject { - @Inject var manager: ManagerVM + @Inject var manager: Manager @Published var theme: String = "" @Published var description: String = "" @Published var isPublic = true diff --git a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift index 8f63afb..d8db75d 100644 --- a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift @@ -7,20 +7,24 @@ import Foundation import SwiftUI -import ViewModel import DependencyInjection +import Model class DetailsViewModel: ObservableObject { - @Inject var manager: ManagerVM + @Inject var manager: Manager var id: String + @Published var bet: BetDetail? + init(id: String) { self.id = id - getItem() + getItem(withId: id) } - func getItem() { - + func getItem(withId id: String) { + manager.getBet(withId: id) { bet in + self.bet = bet + } } } diff --git a/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift index a98dfbf..294ab23 100644 --- a/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/FriendsViewModel.swift @@ -7,11 +7,11 @@ import Foundation import DependencyInjection -import ViewModel +import Model class FriendsViewModel: ObservableObject { - @Inject var manager: ManagerVM + @Inject var manager: Manager init() { getItems() diff --git a/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift index a5643cc..480c7a1 100644 --- a/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/HistoricBetViewModel.swift @@ -7,12 +7,12 @@ import Foundation import SwiftUI -import ViewModel import DependencyInjection +import Model class HistoricBetViewModel: ObservableObject { - @Inject var manager: ManagerVM + @Inject var manager: Manager init() { getItems() diff --git a/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift index d9bfcbd..e321f91 100644 --- a/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/RankingViewModel.swift @@ -7,11 +7,11 @@ import Foundation import DependencyInjection -import ViewModel +import Model class RankingViewModel: ObservableObject { - @Inject var manager: ManagerVM + @Inject var manager: Manager init() { getItems() diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 6c02302..f317d0e 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -43,14 +43,12 @@ struct DetailsView: View { HStack{ Text("Commence le").frame(maxWidth: 100).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) TextCapsule(date: Date()) - TextCapsule(date: Date()) Spacer() }.padding(.bottom, 10) HStack{ Text("Fini le").frame(maxWidth: 100).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) TextCapsule(date: Date()) - TextCapsule(date: Date()) Spacer() } diff --git a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj index 2ba0c3a..3199431 100644 --- a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj +++ b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj @@ -24,7 +24,7 @@ EC30770D2B24DB7A0060E34D /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC30770C2B24DB7A0060E34D /* Extensions.swift */; }; EC30770F2B24FCB00060E34D /* RegisterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC30770E2B24FCB00060E34D /* RegisterView.swift */; }; EC4F0D2C2B4EBF5600853949 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = ECB357342B3E13A400045D41 /* Model */; }; - EC4F0D2E2B4EC04B00853949 /* ViewModel in Frameworks */ = {isa = PBXBuildFile; productRef = EC4F0D2D2B4EC04B00853949 /* ViewModel */; }; + EC60C5682B5A83FB00FFD6EF /* StubLib in Frameworks */ = {isa = PBXBuildFile; productRef = EC60C5672B5A83FB00FFD6EF /* StubLib */; }; EC650A422B25C817003AFCAD /* Friend.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC650A412B25C817003AFCAD /* Friend.swift */; }; EC650A442B25CDF3003AFCAD /* ParameterMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC650A432B25CDF3003AFCAD /* ParameterMenu.swift */; }; EC650A462B25D686003AFCAD /* RankingRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC650A452B25D686003AFCAD /* RankingRow.swift */; }; @@ -102,7 +102,6 @@ /* Begin PBXFileReference section */ 122278B72B4BDE1100E632AA /* DependencyInjection.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DependencyInjection.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 122278B92B4BDE9500E632AA /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Package.swift; path = ../Model/Package.swift; sourceTree = ""; }; - 122278BB2B4BDEC300E632AA /* Sources */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Sources; path = ../StubLib/Sources; sourceTree = ""; }; 123590B32B51792000F7AEBD /* DetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsView.swift; sourceTree = ""; }; 123590B52B5537E200F7AEBD /* ResultBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultBanner.swift; sourceTree = ""; }; 123590B72B5541BA00F7AEBD /* ParticipateButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParticipateButton.swift; sourceTree = ""; }; @@ -170,9 +169,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + EC60C5682B5A83FB00FFD6EF /* StubLib in Frameworks */, EC4F0D2C2B4EBF5600853949 /* Model in Frameworks */, ECCD244A2B4DE8010071FA9E /* Api in Frameworks */, - EC4F0D2E2B4EC04B00853949 /* ViewModel in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -334,7 +333,6 @@ ECB3572D2B3CA3BD00045D41 /* Frameworks */ = { isa = PBXGroup; children = ( - 122278BB2B4BDEC300E632AA /* Sources */, 122278B92B4BDE9500E632AA /* Package.swift */, 122278B72B4BDE1100E632AA /* DependencyInjection.framework */, ECB357302B3CA69300045D41 /* DependencyInjection.framework */, @@ -378,7 +376,7 @@ packageProductDependencies = ( ECB357342B3E13A400045D41 /* Model */, ECCD24492B4DE8010071FA9E /* Api */, - EC4F0D2D2B4EC04B00853949 /* ViewModel */, + EC60C5672B5A83FB00FFD6EF /* StubLib */, ); productName = AllIn; productReference = EC6B96982B24B4CC00FC1C58 /* AllIn.app */; @@ -874,9 +872,9 @@ /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ - EC4F0D2D2B4EC04B00853949 /* ViewModel */ = { + EC60C5672B5A83FB00FFD6EF /* StubLib */ = { isa = XCSwiftPackageProductDependency; - productName = ViewModel; + productName = StubLib; }; ECB357342B3E13A400045D41 /* Model */ = { isa = XCSwiftPackageProductDependency; diff --git a/Sources/Api/Sources/Api/BetApiManager.swift b/Sources/Api/Sources/Api/BetApiManager.swift index 6de0b51..4141547 100644 --- a/Sources/Api/Sources/Api/BetApiManager.swift +++ b/Sources/Api/Sources/Api/BetApiManager.swift @@ -46,7 +46,7 @@ public struct BetApiManager: BetDataManager { return [] } - public func getBet(withId id: String, completion: @escaping (Bet) -> Void) { + public func getBet(withId id: String, completion: @escaping (BetDetail) -> Void) { } diff --git a/Sources/Model/Sources/Model/BetAnswerDetail.swift b/Sources/Model/Sources/Model/BetAnswerDetail.swift new file mode 100644 index 0000000..77ab2d8 --- /dev/null +++ b/Sources/Model/Sources/Model/BetAnswerDetail.swift @@ -0,0 +1,43 @@ +// +// BetAnswerDetail.swift +// +// +// Created by Emre on 19/01/2024. +// + +import Foundation + +/// A class representing detailed information about a specific answer option for a bet. +public class BetAnswerDetail: ObservableObject { + + /// The response or outcome associated with this answer. + public private(set) var response: String + + /// The total amount of stakes placed on this answer. + public private(set) var totalStakes: Int + + /// The total number of participants who selected this answer. + public private(set) var totalParticipants: Int + + /// The highest stake placed on this answer. + public private(set) var highestStake: Int + + /// The odds associated with this answer. + public private(set) var odds: Float + + /// Custom Constructor + /// + /// - Parameters: + /// - response: The response or outcome associated with this answer. + /// - totalStakes: The total amount of stakes placed on this answer. + /// - totalParticipants: The total number of participants who selected this answer. + /// - highestStake: The highest stake placed on this answer. + /// - odds: The odds associated with this answer. + public init(response: String, totalStakes: Int, totalParticipants: Int, highestStake: Int, odds: Float) { + self.response = response + self.totalStakes = totalStakes + self.totalParticipants = totalParticipants + self.highestStake = highestStake + self.odds = odds + } +} diff --git a/Sources/Model/Sources/Model/BetDataManager.swift b/Sources/Model/Sources/Model/BetDataManager.swift index bcc0b25..6fede4a 100644 --- a/Sources/Model/Sources/Model/BetDataManager.swift +++ b/Sources/Model/Sources/Model/BetDataManager.swift @@ -10,5 +10,5 @@ import Foundation public protocol BetDataManager { func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) func getUsers(username: String) -> [User] - func getBet(withId id: String, completion: @escaping (Bet) -> Void) + func getBet(withId id: String, completion: @escaping (BetDetail) -> Void) } diff --git a/Sources/Model/Sources/Model/BetDetail.swift b/Sources/Model/Sources/Model/BetDetail.swift new file mode 100644 index 0000000..e9d7804 --- /dev/null +++ b/Sources/Model/Sources/Model/BetDetail.swift @@ -0,0 +1,38 @@ +// +// BetDetail.swift +// +// +// Created by Emre on 19/01/2024. +// + +import Foundation + +/// A class representing detailed information about a specific bet, including answers and user participations. +public class BetDetail: ObservableObject { + + /// The main bet information. + public private(set) var bet: Bet + + /// Details about the answers available for the bet. + public private(set) var answers: [BetAnswerDetail] + + /// List of user participations in the bet. + public private(set) var participations: [Participation] + + /// The user's own participation in the bet. + public private(set) var userParticipation: Participation + + /// Custom Constructor + /// + /// - Parameters: + /// - bet: The main bet information. + /// - answers: Details about the answers available for the bet. + /// - participations: List of user participations in the bet. + /// - userParticipation: The user's own participation in the bet. + public init(bet: Bet, answers: [BetAnswerDetail], participations: [Participation], userParticipation: Participation) { + self.bet = bet + self.answers = answers + self.participations = participations + self.userParticipation = userParticipation + } +} diff --git a/Sources/Model/Sources/Model/BinaryParticipation.swift b/Sources/Model/Sources/Model/BinaryParticipation.swift deleted file mode 100644 index 5a02622..0000000 --- a/Sources/Model/Sources/Model/BinaryParticipation.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// BinaryParticipation.swift -// -// -// Created by Emre on 28/12/2023. -// - -import Foundation - -/// Enum to represent the possible answers for a binary participation. -public enum YesNo { - case yes - case no -} - -/// A subclass of Participation that represents a binary participation (yes/no) in a bet. -public class BinaryParticipation: Participation { - /// The answer for the binary participation (yes or no). - public var answer: YesNo - - /// Custom Constructor - /// - /// - Parameters: - /// - coinAmount: The amount of coins involved in the binary participation. - /// - date: The date and time when the binary participation occurred. - /// - user: The user who participated in the binary bet. - /// - bet: The binary bet in which the user participated. - /// - answer: The answer for the binary participation (yes or no). - public init(coinAmount: Int, date: Date, user: User, bet: Bet, answer: YesNo) { - self.answer = answer - super.init(coinAmount: coinAmount, date: date, user: user, bet: bet) - } -} diff --git a/Sources/Model/Sources/Model/CustomParticipation.swift b/Sources/Model/Sources/Model/CustomParticipation.swift deleted file mode 100644 index 9956aa9..0000000 --- a/Sources/Model/Sources/Model/CustomParticipation.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// CustomParticipation.swift -// -// -// Created by Emre on 28/12/2023. -// - -import Foundation - -/// A subclass of Participation that represents a custom participation in a bet. -public class CustomParticipation: Participation { - /// The user's response to the custom bet. - public var answer: CustomBetResponse - - /// Custom Constructor - /// - /// - Parameters: - /// - coinAmount: The amount of coins involved in the custom participation. - /// - date: The date and time when the custom participation occurred. - /// - user: The user who participated in the custom bet. - /// - bet: The custom bet in which the user participated. - /// - answer: The user's response to the custom bet. - public init(coinAmount: Int, date: Date, user: User, bet: Bet, answer: CustomBetResponse) { - self.answer = answer - super.init(coinAmount: coinAmount, date: date, user: user, bet: bet) - } -} diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift index 94e87a6..3ff086a 100644 --- a/Sources/Model/Sources/Model/Manager.swift +++ b/Sources/Model/Sources/Model/Manager.swift @@ -16,8 +16,8 @@ public struct Manager { self.userDataManager = userDataManager } - public func addBet(bet: Bet) { - userDataManager.addBet(bet: bet) + public func addBet(theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User) { + userDataManager.addBet(bet: BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [])) } public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { @@ -26,7 +26,7 @@ public struct Manager { } } - public func getBet(withId id: String, completion: @escaping (Bet) -> Void) { + public func getBet(withId id: String, completion: @escaping (BetDetail) -> Void) { betDataManager.getBet(withId: id) { bet in completion(bet) } diff --git a/Sources/Model/Sources/Model/MatchParticipation.swift b/Sources/Model/Sources/Model/MatchParticipation.swift deleted file mode 100644 index 68b47ba..0000000 --- a/Sources/Model/Sources/Model/MatchParticipation.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// MatchParticipation.swift -// -// -// Created by Emre on 28/12/2023. -// - -import Foundation - -/// A subclass of Participation that represents a user's participation in a match bet. -public class MatchParticipation: Participation { - /// The points earned by the user for the first team in the match. - public var pointsTeam1: Int - - /// The points earned by the user for the second team in the match. - public var pointsTeam2: Int - - /// Custom Constructor - /// - /// - Parameters: - /// - coinAmount: The amount of coins involved in the match participation. - /// - date: The date and time when the match participation occurred. - /// - user: The user who participated in the match bet. - /// - bet: The match bet in which the user participated. - /// - pointsTeam1: The points earned by the user for the first team in the match. - /// - pointsTeam2: The points earned by the user for the second team in the match. - public init(coinAmount: Int, date: Date, user: User, bet: Bet, pointsTeam1: Int, pointsTeam2: Int) { - self.pointsTeam1 = pointsTeam1 - self.pointsTeam2 = pointsTeam2 - super.init(coinAmount: coinAmount, date: date, user: user, bet: bet) - } -} diff --git a/Sources/Model/Sources/Model/Participation.swift b/Sources/Model/Sources/Model/Participation.swift index 6ccd9be..4040e22 100644 --- a/Sources/Model/Sources/Model/Participation.swift +++ b/Sources/Model/Sources/Model/Participation.swift @@ -1,37 +1,43 @@ // // Participation.swift -// +// // // Created by Emre on 28/12/2023. // import Foundation -/// A class representing a user's participation in a bet, including the amount of coins, date, user, and the associated bet. +/// A class representing a user's participation in a bet. public class Participation: ObservableObject { - /// The amount of coins involved in the participation. - var coinAmount: Int + + /// The amount of stake in the bet. + public private(set) var stake: Int /// The date and time when the participation occurred. - var date: Date + public private(set) var date: Date + + /// The response or outcome of the participation. + public private(set) var response: String /// The user who participated in the bet. - var user: User + public private(set) var user: User - /// The bet in which the user participated. - var bet: Bet + /// The unique identifier of the bet. + let betId: String /// Custom Constructor /// /// - Parameters: - /// - coinAmount: The amount of coins involved in the participation. + /// - stake: The amount of stake in the bet. /// - date: The date and time when the participation occurred. + /// - response: The response or outcome of the participation. /// - user: The user who participated in the bet. - /// - bet: The bet in which the user participated. - init(coinAmount: Int, date: Date, user: User, bet: Bet) { - self.coinAmount = coinAmount + /// - betId: The unique identifier of the bet. + public init(stake: Int, date: Date, response: String, user: User, betId: String) { + self.stake = stake self.date = date + self.response = response self.user = user - self.bet = bet + self.betId = betId } } diff --git a/Sources/ViewModel/.gitignore b/Sources/StubLib/.gitignore similarity index 100% rename from Sources/ViewModel/.gitignore rename to Sources/StubLib/.gitignore diff --git a/Sources/ViewModel/Package.swift b/Sources/StubLib/Package.swift similarity index 88% rename from Sources/ViewModel/Package.swift rename to Sources/StubLib/Package.swift index 67fd2cf..813f113 100644 --- a/Sources/ViewModel/Package.swift +++ b/Sources/StubLib/Package.swift @@ -4,15 +4,15 @@ import PackageDescription let package = Package( - name: "ViewModel", + name: "StubLib", platforms: [ .iOS(.v13) ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( - name: "ViewModel", - targets: ["ViewModel"]), + name: "StubLib", + targets: ["StubLib"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -23,7 +23,7 @@ let package = Package( // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( - name: "ViewModel", + name: "StubLib", dependencies: ["Model"]), ] ) diff --git a/Sources/ViewModel/README.md b/Sources/StubLib/README.md similarity index 72% rename from Sources/ViewModel/README.md rename to Sources/StubLib/README.md index 74e3704..9f7060e 100644 --- a/Sources/ViewModel/README.md +++ b/Sources/StubLib/README.md @@ -1,3 +1,3 @@ -# ViewModel +# StubLib A description of this package. diff --git a/Sources/StubLib/Sources/StubLib/BetStubManager.swift b/Sources/StubLib/Sources/StubLib/BetStubManager.swift new file mode 100644 index 0000000..7bb801f --- /dev/null +++ b/Sources/StubLib/Sources/StubLib/BetStubManager.swift @@ -0,0 +1,32 @@ +// +// BetStubManager.swift +// +// +// Created by Emre on 31/12/2023. +// + +import Foundation +import Model + +public struct BetStubManager: BetDataManager { + + public init() {} + + public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { + completion(Stub.shared.bets) + } + + public func getUsers(username: String) -> [User] { + return [] + } + + public func getBet(withId id: String, completion: @escaping (BetDetail) -> Void) { + + if let betDetail = Stub.shared.betsDetail.first(where: { $0.bet.id == id }) { + completion(betDetail) + } else { + print("BetDetail with ID \(id) not found.") + } + } + +} diff --git a/Sources/StubLib/Sources/StubLib/Stub.swift b/Sources/StubLib/Sources/StubLib/Stub.swift new file mode 100644 index 0000000..5e70aa0 --- /dev/null +++ b/Sources/StubLib/Sources/StubLib/Stub.swift @@ -0,0 +1,97 @@ +// +// Stub.swift +// +// +// Created by Emre on 01/01/2024. +// + +import Foundation +import Model + +struct Stub { + + static var shared = Stub() + public var bets: [Bet] = [] + public var betsDetail: [BetDetail] = [] + public var users: [User] = [] + + public init() { + loadBets() + } + + public mutating func loadBets() { + + var user1 = User(username: "Lucas", email: "lucas.delanier@etu.uca.fr", nbCoins: 100, friends: []) + users.append(user1) + + var user2 = User(username: "Imri", email: "emre.kartal@etu.uca.fr", nbCoins: 75, friends: [user1]) + users.append(user2) + user1.addFriend(user: user2) + + let user3 = User(username: "Arthur", email: "arthur.valin@etu.uca.fr", nbCoins: 30, friends: [user2]) + users.append(user3) + user2.addFriend(user: user3) + + let bet1 = 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: user1, + registered: [user2] + ) + self.bets.append(bet1) + + let bet2 = BinaryBet( + theme: "Cuisine - Concours de cuisine en direct", + phrase: "Le plat préféré du jury sera une recette végétarienne.", + endRegisterDate: Date().addingTimeInterval(172800), + endBetDate: Date().addingTimeInterval(259200), + totalStakes: 150, + isPublic: false, + invited: [user3], + author: user1, + registered: [user2] + ) + self.bets.append(bet2) + + let bet3 = BinaryBet( + theme: "Technologie - Lancement d'un nouveau smartphone", + phrase: "Le nombre total de précommandes dépassera-t-il 1 million dans la première semaine ?", + endRegisterDate: Date().addingTimeInterval(259200), + endBetDate: Date().addingTimeInterval(345600), + totalStakes: 75, + isPublic: true, + invited: [], + author: user1, + registered: [user2, user1, user3] + ) + self.bets.append(bet3) + + let bet4 = BinaryBet( + theme: "Cinéma - Oscars 2024", + phrase: "Le film favori des critiques remportera-t-il le prix du meilleur film ?", + endRegisterDate: Date().addingTimeInterval(345600), + endBetDate: Date().addingTimeInterval(432000), + totalStakes: 120, + isPublic: false, + invited: [user1], + author: user2, + registered: [user3] + ) + self.bets.append(bet4) + + for bet in bets { + let betDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: user1, betId: "")) + self.betsDetail.append(betDetail) + } + } + + public mutating func add(bet: Bet) { + let newBetDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: users[1], betId: "")) + self.betsDetail.append(newBetDetail) + } +} diff --git a/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift b/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift deleted file mode 100644 index f6dd67f..0000000 --- a/Sources/ViewModel/Sources/ViewModel/ManagerVM.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// ManagerVM.swift -// -// -// Created by Emre on 30/12/2023. -// - -import Foundation -import Model - -public class ManagerVM: ObservableObject { - - @Published var model: Manager - @Published public var bets: [Bet] = [] - @Published public var bet: 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) { - model.addBet(bet: BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [])) - } - - public func getBet(withId id: String) { - model.getBet(withId: id) { bet in - self.bet = bet - } - } - - public func getHistoricBets() { - model.getHistoricBets(withIndex: 0, withCount: 20) { bets in - self.bets = bets - } - } - -} -- 2.36.3 From fefbd7030e91de787a2c33327ac0e4b5763227e0 Mon Sep 17 00:00:00 2001 From: ludelanier Date: Fri, 19 Jan 2024 19:25:24 +0100 Subject: [PATCH 06/14] Add bet loading component participation modal and status text on top left --- .../BlackTitleColor.colorset/Contents.json | 38 ++++++++ .../Bleue200.colorset/Contents.json | 38 ++++++++ .../BleueBadge.imageset/Contents.json | 21 +++++ .../BleueBadge.imageset/Vector.png | Bin 0 -> 986 bytes .../LoadingHeart.imageset/Contents.json | 21 +++++ .../LoadingHeart.imageset/Group 280.png | Bin 0 -> 3590 bytes .../Pink100.colorset/Contents.json | 38 ++++++++ .../Pink200.colorset/Contents.json | 38 ++++++++ .../PinkBadge.imageset/Contents.json | 21 +++++ .../PinkBadge.imageset/Vector (1).png | Bin 0 -> 1008 bytes .../Purple200.colorset/Contents.json | 38 ++++++++ .../AllIn/Components/AllcoinsCounter.swift | 6 +- .../AllInApp/AllIn/Components/BetCard.swift | 73 ++++++++-------- .../AllIn/Components/BetLineLoading.swift | 77 +++++++++++++++++ .../AllIn/Components/DropDownAnswerMenu.swift | 81 ++++++++++++++++++ .../AllIn/Components/ParticipateButton.swift | 7 +- .../AllIn/Components/ParticipationModal.swift | 77 +++++++++++++++++ .../AllInApp/AllIn/Ressources/Colors.swift | 18 +++- .../AllInApp/AllIn/Views/DetailsView.swift | 29 ++++--- .../AllInApp.xcodeproj/project.pbxproj | 12 +++ 20 files changed, 579 insertions(+), 54 deletions(-) create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BlackTitleColor.colorset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/Bleue200.colorset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Vector.png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Group 280.png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/Pink100.colorset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/Pink200.colorset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Vector (1).png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/Purple200.colorset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Components/BetLineLoading.swift create mode 100644 Sources/AllInApp/AllIn/Components/DropDownAnswerMenu.swift create mode 100644 Sources/AllInApp/AllIn/Components/ParticipationModal.swift diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BlackTitleColor.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/BlackTitleColor.colorset/Contents.json new file mode 100644 index 0000000..0e54db2 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/BlackTitleColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x49", + "green" : "0x49", + "red" : "0x49" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x49", + "green" : "0x49", + "red" : "0x49" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/Bleue200.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/Bleue200.colorset/Contents.json new file mode 100644 index 0000000..0286b3d --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/Bleue200.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0x99", + "red" : "0x23" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0x99", + "red" : "0x23" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Contents.json new file mode 100644 index 0000000..446d6be --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Vector.png b/Sources/AllInApp/AllIn/Assets.xcassets/BleueBadge.imageset/Vector.png new file mode 100644 index 0000000000000000000000000000000000000000..2114e9dcc254289d6bea9b24e25ce216e5d7aec1 GIT binary patch literal 986 zcmV<0110>4P)@~0drDELIAGL9O(c600d`2O+f$vv5yPL`rIK4pV3F^PhB$=r{lAmI) zDlM28@S3HmW(>AhtGBC_o@9hQB)s}v(>m=SU{{_AX!N6hJlMwuRv8DKwn0M;6eJ4( z>;O@)ZUJKi8k>8gOL5eHH`yDodHHz9e<$#765XC1x5@@o*~@VF(0&7$F%f=y49f<# zb||hSo!xD@ZeI~sE3Xyx4&ze5wSXY1!T%6*zIp)aV9LPB3Xs79-qp>UcU1+fyoP`- z&QQ<8eZWu*@a3v+Y^NOYunHQrdlEu|1OxP*52OB3T`u&}IwG9{QoM7%LgP{&T!amx z%34wXLtK0v_001myt@t;at!W42oe5ZP9c&X=boe&0+R<5H%q;`v&KjAB zliU8$DL4q{-UT6iwG1cd`3;}4^qL>6X@Hu(gR3CUga9p46D)CQ2vw4%F}R91pY6~H z1u&{qIXG~qxYQ4-hB@gY#i1?dV?S)l+yNDS0Xtd(jHOJ35sa;Ps5%l@utQAn0erIB z;q(zKwOm5^b3eECX zF=U&j<=h06s?YxJ=J_UVo}8&U1B9MjrROWITaK@Ey_Z(L31XX&{^=HWz7P)eUncS_ z-BvE91S#m4$(k9;e;$>&Zlh01cmszkKU81 zk(!*d?IIa)H~2X^JDM6m$1a;gJR3yk??(loeOgP?jiYqPT%~WoQRG}-17gcF)pH42 zs7kE)201TMAUYjfLf2Y*I+MgB@+6E&WO)X8e8IP&TWG42c>TIX}bN+ zA2Fdz)Ydi@(pm+Pf|CXRO6zZ1%H`9DKR7$D7VO>IrmlQ1MrZH3WxDp3+w(4piH>S+ z|I($x&Sj4Ga$!@o0-6dUoGMHrE3RsUnF={I#;;9t-5N-L0r3ylK08P&P5=M^07*qo IM6N<$f`UT5w*UYD literal 0 HcmV?d00001 diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Contents.json new file mode 100644 index 0000000..063d4f3 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 280.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Group 280.png b/Sources/AllInApp/AllIn/Assets.xcassets/LoadingHeart.imageset/Group 280.png new file mode 100644 index 0000000000000000000000000000000000000000..956a97aeb104dc7809adf5f6291c34343929b0ce GIT binary patch literal 3590 zcmV+h4*BtkP)@~0drDELIAGL9O(c600d`2O+f$vv5yPqQ(B1EtzDCfVpzH{El?L|w^BwEc)^&ENM6DAf+o}0AVq3iq)DvnnyzHL z7$~VkyGckRl_rgMNu`Z#+Mk+9P-vUgY@G&_t)>wLrL;=QpC(Rx&z|4em)eQ{+@0^9 z=WORArMB-bvFq>s{ye|uA43Ju-*+lhpPbtX=-nI$i$jxOEY3I%?>@A77)#8<;B%gN z>{vKeS2qIABl*rVX#KknZQ6$=416spiK%Pa(Tr6VhOwca9NZkm68;r*p!Zc_k%5tt zVrF2B4evgXyYVm6yFKzSWJ@|7gd9g*#E?d z_OiqzMDi4vojv+Y-?1=i5Z_qn&v%^MuJhC|TtfWE5?X`a@zl_k1ZoIh2K|YChls8N8?a{5D?d-2*$0zX%6d6my=G$lPU%DpgSGHBl+1 zi6Lt5iM@7yCml1bi)lilUJ=O?Bq2@EfnH%11-iggz@hhB6?OL3!Mz0%AWLY%{U#%W zQvUB!k|O%z=nI4o(O6ygj}P8)xX^hLQ)j#%w$bY*jpu?2%iJmM?jiUXuIU|n zp5GE%czh=EY^OLm0{2J=Q9Ha8)l)$;ZOv2gKa+J0`o`>Pl8Ad@;VS8~yV_1>VDWl} z4i=Ak(i`Mi45f^gI;c?@g!H5~-$RoT)03iy@K%vo4#!QWQg|XL4eClqIH*|@hDT6>MX?zk;EAB3KXPv+iD~j#AQ1WU4L67zk+;KRDADqwIpeyZMpJH#I>9)SMyr4i|A%P>P#=ZJyX+k>|>4 zA(SO(y69d#aWfy1trU#2z2&%G$AVT%6U7Q-r4k91<9ZznTJ5ej8?sVa#fCJz(`nZ0 zNYGkvwF^1(`IV4~)2!FFpta;`vzfSNIV2NKLbshD*%q{xTx~WJ%cToS6^EU6YrVDv zO&1Vq%hj4t9G#L=-_6GC%Cn4RLDL=9mD`Kr2A6}4kPUU^*-4Nr3tDZpS|=#5Py=D5 zmOH~O37RSIbz=!7kd-DQ&vje5){>y9I;~R1230LwRFJG(S5nY{-ecY37V*shX_Yih z&p;tzD|KEA7OHtNm}v?7SgG?C6_l*A))S#@R(<*@6cd_(-d*g15*E5-ohHG#IW&qN z)d(xyS?qj4L6@vEm(`ysw@#CAv5dEfg)UiVHmlXU+pBP`;GEOEf-YI-V%A^01iw(M zdQ`wdm#i}zil5g{O~FqTsva#8G`&3Al67X|H!%sa(tJ&rMWdfIop0yxC)a;z1=iov zgy6C|jKBK{#{c^XrY`3O~Br zEJ6#DqXjY4f6375waai%*V=;TO;O1Wd%>OK=ip~Fj+{cnyr2WU$0L4AhD@F3Z-Lz8XkJjgM2%1dcHC*(=9NaAbrZi^XNJ%$^iK1IcJ&E+5I%w|jx5g( z6lbq*T>&?!4C~C0RXH*QO^-tR$(TtTRn$Iilt7Hq^;xQm1dm=oU?88s8MqTvR0KY0+sd3akcrNzem}xRj4X-+xhdT zOww^w(={H3Vkq9-|J`-)0z29Ao#)Q^VpM`tD2{5P0jhjNpPR0BA#}4?Y0pw3L_e0f zHV8br3Ha%~z^=Q1mTRFJ20aqcpluK_6sn*v+G!KT&U=ukho5~r|9RnRZ6!j@LcHHR zlor)w+fBgZBf$BOp$gJc(vY5uz*8tJGN?%A#lZQ9J77u(Cs!$?m zYg<#<^;%bW;O4Yog&<3NbTe#2$&;dXsm8z)kc_I>nHLf)pQt3}u5ZFIw<*bX6S5Yu z%i)VQJFY#4L?t)*&IRD(q$m>HSbkz-C4q7sHW}bdONa(c7!tY8!%=#UAvf9VqMKYJ z-{mrfNm0w???Ez6eiYPgzT#~;Gaowm6qWuw*$}4YSt0+X)o6Qa4P41iv{jFS;)1Zy zgy;{|mMpYN;Lze)D$o#vWMoV*szn-sxR%+ETB?=KTuGto`9OBRC`-@=c}As(L5o2m zUd|Tt4If;FOhj_~COxJ{{qfW*kVs7kdRg|!K^~)j(}LE?&2%Tu*MOk^cpoyMgoqvu zK~sT7dLb>2l7&uJdmKG;5fYhP7LUg0i6N+w7%?WzN+~J2P|a?a5~4AA7RnjsL*~`) zGhIIdiJbYDuV+S=$CzAqtAUMPeV$=17#xN~PM^3`y>9pSZ$T#FTa1~{=LOBU-54Z6 zZg=dJ3#d9IyIUqS6Y(=)zRn%7AldEyyBe+Zh2xOS;p`VVf@a*Vv}~73fK_FsWSzg0 z>TV|+;?d#k137|{+vVVgA(64aU%=&RsqOykuaJpwx1$S>EgmGM@li;GV(H7jt-J}g zi+Jgu(z9C;toAKDwn)%D&u@vzOpXXz=Izx#eTa&MT&?8TxiA?r$vcdbv(!FF=Cwb5 zh||aYvxKQ-NKBe__OaaBZ9eNH@(QZLN{PRXzF%2|dlFH>6vB*k#`2vjIM7;!l~O!? z>EOGSQAIK=b5zNE&_dQpuwuXX^p4|4Mc-OG6hP}ExVjC`Jxs|JpK3^!{Vy#P=qn<@4hukXR8@d z|KJ$LoFK_85dBa#oe5=?XL##f|wV#qfbeW+O7&o`q$;yw|}ZDib7H z1L6KNXBMBJ>3}rL>$aBCQ{}BdBF6qFy1(9*-mWZ$5OY|F*<bVNPP4s8R1%l0n5@^BfV4np66%wg^ei*VR%yl=4Hu#3J`(XNEK#hP zvgm5qVE+?ubTS>%_Y&P6kNaz9BZI5VZtl-5Iox>7Auzonek)YHO zuIYLQB(zUw0!mg5PzX!t3>`F21rBh$3d&Qz+LBUfjdMXJ2V9We=47M}82)YGe0W4dZ%se57)uB{|S zqSop9MlZ5oN{q%@no)hYD<6&)b&ArtsQB-oVqSvIyZ5O-feISYby{`{3u$^#;$`O@Ka;EQVj6Yd&w1F${ z28pG5sawa-NfuVUkn^7e zKEh2`Ov2uN{=BE79VkYM&w3yjk4l|_SqxtZYO?={W9=-Zbu)%-<%&zi2-_Rg6(wzr z;>L@qh>@l6rJ&ikB`%G8Sbymfz9xiSH)V4&6r(}T{0Ijd^`nT{_+HR#26|tO2+N?K z2SxcT4DM{JOv;SOatn$p1QcHkH92TOrMAH%0p@l_H!v@Y+ zNK{Khj3ZRQq9<9Vn@?PuSdmO7ww^uvUfV|>(fHT6=t@thPHf8I|9E1Er>k;+LjV8( M07*qoM6N<$f(uFC00000 literal 0 HcmV?d00001 diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/Pink100.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/Pink100.colorset/Contents.json new file mode 100644 index 0000000..3492dff --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/Pink100.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x8A", + "green" : "0x2B", + "red" : "0xFE" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x8A", + "green" : "0x2B", + "red" : "0xFE" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/Pink200.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/Pink200.colorset/Contents.json new file mode 100644 index 0000000..c0ba743 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/Pink200.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xA8", + "green" : "0x49", + "red" : "0xC2" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xA8", + "green" : "0x49", + "red" : "0xC2" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Contents.json new file mode 100644 index 0000000..b0b4a62 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector (1).png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Vector (1).png b/Sources/AllInApp/AllIn/Assets.xcassets/PinkBadge.imageset/Vector (1).png new file mode 100644 index 0000000000000000000000000000000000000000..c6c1d71a0e15b2a8d3174f5daa4ae87a1a553212 GIT binary patch literal 1008 zcmV@~0drDELIAGL9O(c600d`2O+f$vv5yP zXkN^Yv!v46+efKuYn*D8WdoeQD;fc}2tm|^|6vSD;LfwGGiBg%4ai_Q@9O5CcNGEV z-R=vhe}>jp2d%(7Gx?Wl9NSgQcvzDrd-^8C(gB<+eg7i6JAElXrOiuz4USU4NhzOF z4JqbRQVp{C$6{-Ec|D>2=b5veq(|a+h(NC*V5NZJ4%jZR`0!~N^dXZkk4wVb2APRC z;q)Crg4y21kPn{%)1}gSUy-rbvDd&6eT76L#Cc@8OU7I)0y>B|fi|XqM9Z>j9$gSC zkV3#&%n3T3bcr)Mk4<}xMP14B2|jE`HW`pr>TPh6$%on;shWM`a2Rzg#DXWR_IVwQ z0yOb#_Rgq^a3~NlzlnivNMn$E7SuO6`WGLa>xL^METxG9a@i6go~`w*UlKQdzXa_@p)d)B?Pek-=|b{^rWpAw-x&=v$HjzFB@DwQiZq$&{FWTU;8U* zY^eC3^Hd>z0<2g94YyvoM?H`%iHv&;*08jvf2bQ`NWw&KlyT4FQx|EyZqsU z1-h-3ar-w^$iUz$$yn?AQB&%6`lK>joV{2B);qc0@Glv7s#c{5vCE}k9$JJ~AclFX(u=maA?Yi92L|S8gED*w(WK&QNfB#rUny?Oi8ZgP z=0@vWHKbW}-1O0y)+46Auy*SiO8SUNgiIo(pzj>z5^9%V~wy#p#vO0 eG|j^xk^TZT`S#|-t!?B00000 Date: Fri, 19 Jan 2024 19:27:30 +0100 Subject: [PATCH 07/14] start of binding DetailsView --- .../Contents.json | 0 .../Exclude (1).png | Bin .../AllIn/Components/ReviewCard.swift | 4 +- .../AllIn/ViewModels/DetailsViewModel.swift | 4 +- .../AllInApp/AllIn/Views/DetailsView.swift | 49 ++++++++++-------- 5 files changed, 32 insertions(+), 25 deletions(-) rename Sources/AllInApp/AllIn/Assets.xcassets/{CloseiconRounded.imageset => closeIcon.imageset}/Contents.json (100%) rename Sources/AllInApp/AllIn/Assets.xcassets/{CloseiconRounded.imageset => closeIcon.imageset}/Exclude (1).png (100%) diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/closeIcon.imageset/Contents.json similarity index 100% rename from Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Contents.json rename to Sources/AllInApp/AllIn/Assets.xcassets/closeIcon.imageset/Contents.json diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Exclude (1).png b/Sources/AllInApp/AllIn/Assets.xcassets/closeIcon.imageset/Exclude (1).png similarity index 100% rename from Sources/AllInApp/AllIn/Assets.xcassets/CloseiconRounded.imageset/Exclude (1).png rename to Sources/AllInApp/AllIn/Assets.xcassets/closeIcon.imageset/Exclude (1).png diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift index 130e085..2798c36 100644 --- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift +++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift @@ -37,14 +37,14 @@ struct ReviewCard: View { HStack(){ Spacer() Text(amountBetted.description) - .foregroundColor(AllInColors.whiteColor) + .foregroundColor(.white) .font(.system(size: 25)) .fontWeight(.bold) Image("allcoinWhiteIcon") .resizable() .frame(width: 20, height: 20, alignment: .bottom) Text(isAWin ? "Gagnés!" : "Perdus!") - .foregroundColor(AllInColors.whiteColor) + .foregroundColor(.white) .font(.system(size: 25)) .fontWeight(.bold) Spacer() diff --git a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift index d8db75d..e6980e6 100644 --- a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift @@ -15,7 +15,7 @@ class DetailsViewModel: ObservableObject { @Inject var manager: Manager var id: String - @Published var bet: BetDetail? + @Published var betDetail: BetDetail? init(id: String) { self.id = id @@ -24,7 +24,7 @@ class DetailsViewModel: ObservableObject { func getItem(withId id: String) { manager.getBet(withId: id) { bet in - self.bet = bet + self.betDetail = bet } } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index f317d0e..2dd996f 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -18,7 +18,7 @@ struct DetailsView: View { VStack(alignment: .trailing) { HStack{ Spacer() - Image("CloseiconRounded") + Image("closeIcon") .resizable() .padding(8) .frame(maxWidth: 40, maxHeight: 40) @@ -35,34 +35,45 @@ struct DetailsView: View { VStack(alignment: .leading,spacing: 5){ HStack{ Spacer() - Text("proposé par Lucas").font(.system(size: 10)).foregroundColor(AllInColors.grey800Color) + Text("proposé par " + (viewModel.betDetail?.bet.author.username ?? "Unknown").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).padding(.bottom, 10) + Text(viewModel.betDetail?.bet.theme ?? "Not loaded") + .font(.system(size: 15)) + .foregroundColor(AllInColors.grey800Color) + Text(viewModel.betDetail?.bet.phrase ?? "Not loaded") + .font(.system(size: 20)) + .fontWeight(.bold) + .padding(.bottom, 10) HStack{ - Text("Commence le").frame(maxWidth: 100).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) - TextCapsule(date: Date()) + Text("Commence le") + .frame(maxWidth: 100) + .font(.system(size: 15)) + .foregroundColor(AllInColors.grey800Color) + TextCapsule(date: viewModel.betDetail?.bet.endRegisterDate ?? Date()) Spacer() }.padding(.bottom, 10) HStack{ - Text("Fini le").frame(maxWidth: 100).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) - TextCapsule(date: Date()) + Text("Fini le") + .frame(maxWidth: 100) + .font(.system(size: 15)) + .foregroundColor(AllInColors.grey800Color) + TextCapsule(date: viewModel.betDetail?.bet.endBetDate ?? Date()) Spacer() } } .frame(width: .infinity) .padding(.all,15).padding(.vertical, 10) - .background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) + .background(AllInColors.componentBackgroundColor) + .cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) ResultBanner() - VStack(alignment: .leading,spacing: 2){ - - - + VStack(alignment: .leading, spacing: 2){ } - .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, maxHeight : .infinity) + .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, maxHeight: .infinity) .padding([.bottom,.trailing,.leading],8) .background(AllInColors.underComponentBackgroundColor) .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) @@ -71,18 +82,14 @@ struct DetailsView: View { } .frame(maxWidth: .infinity, maxHeight: geometry.size.height*0.98) - .background(Color.white) + .background(AllInColors.componentBackgroundColor) .cornerRadius(15) ParticipateButton().padding(10) } .transition(.slideInFromBottom(yOffset: 800)) + .background(Color.white) + .edgesIgnoringSafeArea(.bottom) } } } - -struct DetailsView_Previews: PreviewProvider { - static var previews: some View { - ContentView() - } -} -- 2.36.3 From f3f2d9af61df33351da01671c3d0b7f484d088b4 Mon Sep 17 00:00:00 2001 From: "emre.kartal" Date: Fri, 19 Jan 2024 19:39:39 +0100 Subject: [PATCH 08/14] Delete Previews --- Sources/AllInApp/AllIn/Components/ParticipationModal.swift | 4 ---- Sources/AllInApp/AllIn/Components/ResultBanner.swift | 4 ---- 2 files changed, 8 deletions(-) diff --git a/Sources/AllInApp/AllIn/Components/ParticipationModal.swift b/Sources/AllInApp/AllIn/Components/ParticipationModal.swift index 3ce675f..48b4f6d 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipationModal.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipationModal.swift @@ -71,7 +71,3 @@ struct ParticipationModal: View { }.background(AllInColors.underComponentBackgroundColor) } } - -#Preview { - ParticipationModal() -} diff --git a/Sources/AllInApp/AllIn/Components/ResultBanner.swift b/Sources/AllInApp/AllIn/Components/ResultBanner.swift index 91b201d..441542f 100644 --- a/Sources/AllInApp/AllIn/Components/ResultBanner.swift +++ b/Sources/AllInApp/AllIn/Components/ResultBanner.swift @@ -34,7 +34,3 @@ struct ResultBanner: View { .border(width: 2, edges: [.top,.bottom], color: AllInColors.blueAccentColor.opacity(0.2)) } } - -#Preview { - ResultBanner() -} -- 2.36.3 From f9e45ce97911774e8a9f918d96d4856dc45624a5 Mon Sep 17 00:00:00 2001 From: ludelanier Date: Fri, 19 Jan 2024 21:58:09 +0100 Subject: [PATCH 09/14] make the page accurate style for the status of the bet --- .../AllIn/Components/ParticipateButton.swift | 45 +++++++++++------ .../AllInApp/AllIn/Views/DetailsView.swift | 49 +++++++++++++++++-- Sources/Model/Sources/Model/BetDetail.swift | 9 +++- Sources/StubLib/Sources/StubLib/Stub.swift | 4 +- 4 files changed, 85 insertions(+), 22 deletions(-) diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift index 72a020b..96648ec 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -9,30 +9,45 @@ import SwiftUI struct ParticipateButton: View { @Binding var isOpen : Bool + @State var isDisabled: Bool = false var body: some View { Button { isOpen.toggle() } label: { Text("Participer") - .font(.system(size: 30)) - .fontWeight(.bold) + .font(.system(size: 27)) + .fontWeight(.semibold) .frame(maxWidth: .infinity).padding(10) .multilineTextAlignment(.center) .overlay { - AllInColors.primaryGradient.frame(width: 170) - .mask( - Text("Participer") - .font(.system(size: 30)) - .fontWeight(.bold) - .frame(maxWidth: .infinity).padding(10) - ) + switch isDisabled{ + case true: + AllInColors.grey700Color.frame(width: 170) + .mask( + Text("Participer") + .font(.system(size: 27)) + .fontWeight(.semibold) + .frame(maxWidth: .infinity).padding(10) + ) + case false: + AllInColors.primaryGradient.frame(width: 170) + .mask( + Text("Participer") + .font(.system(size: 27)) + .fontWeight(.semibold) + .frame(maxWidth: .infinity).padding(10) + ) + + } } + .accentColor(AllInColors.componentBackgroundColor) + .background(isDisabled ? AllInColors.delimiterGrey.opacity(0.5):AllInColors.whiteColor) + .buttonStyle(.borderedProminent).cornerRadius(4.0) + .overlay( + RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) + ) + + } - .accentColor(AllInColors.componentBackgroundColor) - .buttonStyle(.borderedProminent).cornerRadius(4.0) - .overlay( - RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) - ) - } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index b17fa02..938487f 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -5,6 +5,45 @@ struct DetailsView: View { @Binding var isModalPresented: Bool @State var isModalParticipated: Bool = false @State var progressValue: Float = 0.2 + var isFinished: Bool { + viewModel.betDetail?.finalAnswer == nil ? false : true + } + + var isDisabled: Bool { + if let endRegisterDate = viewModel.betDetail?.bet.endRegisterDate { + let currentDate = Date() + + switch currentDate.compare(endRegisterDate) { + case .orderedAscending: + return false + case .orderedDescending: + return true + case .orderedSame: + return true + } + + } else { + return true + } + } + + var StatusValues: (String, Color) { + if let endRegisterDate = viewModel.betDetail?.bet.endRegisterDate { + let currentDate = Date() + + switch currentDate.compare(endRegisterDate) { + case .orderedAscending: + return ("En cours...", AllInColors.purpleAccentColor) + case .orderedDescending: + return ("En attente...",AllInColors.pink100) + case .orderedSame: + return ("Fin des inscriptions...",AllInColors.grey50Color) + } + + } else { + return ("Statut indisponible", AllInColors.whiteColor) + } + } var id: String @StateObject private var viewModel: DetailsViewModel @@ -20,7 +59,7 @@ struct DetailsView: View { ZStack(alignment: .bottom) { VStack(alignment: .center) { HStack{ - Text("Terminé!").font(.system(size: 25)).fontWeight(.bold).padding(.bottom, 10).foregroundStyle(AllInColors.blackTitleColor).opacity(0.7) + Text(StatusValues.0).font(.system(size: 25)).fontWeight(.bold).padding(.bottom, 10).foregroundStyle(Color.black).opacity(0.4) Spacer() Image("closeIcon") .resizable() @@ -32,7 +71,7 @@ struct DetailsView: View { Spacer() } .padding(.horizontal, 15) - .background(Color.green) + .background(StatusValues.1) .transition(.slideInFromBottom(yOffset:0)) VStack(spacing: 0) { VStack(alignment: .leading,spacing: 5){ @@ -73,7 +112,9 @@ struct DetailsView: View { .padding(.all,15).padding(.vertical, 10) .background(AllInColors.componentBackgroundColor) .cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) - ResultBanner() + if isFinished { + ResultBanner() + } VStack(alignment: .leading, spacing: 15) { BetLineLoading(value: $progressValue).padding(.vertical, 15) Spacer() @@ -91,7 +132,7 @@ struct DetailsView: View { .background(AllInColors.componentBackgroundColor) .cornerRadius(15) - ParticipateButton(isOpen: $isModalParticipated).padding(10) + ParticipateButton(isOpen: $isModalParticipated, isDisabled: isDisabled).padding(10).disabled(isDisabled) } diff --git a/Sources/Model/Sources/Model/BetDetail.swift b/Sources/Model/Sources/Model/BetDetail.swift index e9d7804..8e55642 100644 --- a/Sources/Model/Sources/Model/BetDetail.swift +++ b/Sources/Model/Sources/Model/BetDetail.swift @@ -22,6 +22,8 @@ public class BetDetail: ObservableObject { /// The user's own participation in the bet. public private(set) var userParticipation: Participation + public private(set) var finalAnswer: String? + /// Custom Constructor /// /// - Parameters: @@ -29,10 +31,15 @@ public class BetDetail: ObservableObject { /// - answers: Details about the answers available for the bet. /// - participations: List of user participations in the bet. /// - userParticipation: The user's own participation in the bet. - public init(bet: Bet, answers: [BetAnswerDetail], participations: [Participation], userParticipation: Participation) { + public init(bet: Bet, answers: [BetAnswerDetail], participations: [Participation], userParticipation: Participation, finalAnswer: String? = nil) { self.bet = bet self.answers = answers self.participations = participations self.userParticipation = userParticipation + self.finalAnswer = finalAnswer } + + public func updateFinalAnswer(newFinalAnswer: String) { + self.finalAnswer = newFinalAnswer + } } diff --git a/Sources/StubLib/Sources/StubLib/Stub.swift b/Sources/StubLib/Sources/StubLib/Stub.swift index 5e70aa0..646abe3 100644 --- a/Sources/StubLib/Sources/StubLib/Stub.swift +++ b/Sources/StubLib/Sources/StubLib/Stub.swift @@ -35,7 +35,7 @@ struct Stub { let bet1 = 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), + endRegisterDate: Date().addingTimeInterval(-86400), endBetDate: Date().addingTimeInterval(172800), totalStakes: 100, isPublic: true, @@ -91,7 +91,7 @@ struct Stub { } public mutating func add(bet: Bet) { - let newBetDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: users[1], betId: "")) + let newBetDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: users[1], betId: ""), finalAnswer: "test") self.betsDetail.append(newBetDetail) } } -- 2.36.3 From f64f03a1cee99a39e60255e6a65080bc8a3d28ff Mon Sep 17 00:00:00 2001 From: ludelanier Date: Fri, 19 Jan 2024 23:35:51 +0100 Subject: [PATCH 10/14] Auto open particapte modal when clicking on Participate button --- Sources/AllInApp/AllIn/Components/BetCard.swift | 4 ++-- Sources/AllInApp/AllIn/Components/ParticipateButton.swift | 5 ++++- Sources/AllInApp/AllIn/Components/RecapBetCard.swift | 3 ++- Sources/AllInApp/AllIn/Components/ReviewCard.swift | 3 ++- Sources/AllInApp/AllIn/Views/DetailsView.swift | 7 ++++--- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index eac1299..f03f234 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -51,7 +51,7 @@ struct BetCard: View { Spacer() }.padding(0) - ParticipateButton(isOpen: $showParticipate).padding(.top, 5) + ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate).padding(.top, 5) } .frame(width: .infinity) .padding(.all,8) @@ -63,7 +63,7 @@ struct BetCard: View { showDetails.toggle() } .fullScreenCover(isPresented: $showDetails) { - DetailsView(isModalPresented: $showDetails, id: bet.id) + DetailsView(isModalPresented: $showDetails, isModalParticipated: $showParticipate,id: bet.id) } } } diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift index 96648ec..126fa74 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -9,10 +9,13 @@ import SwiftUI struct ParticipateButton: View { @Binding var isOpen : Bool + @Binding var isParticapatedOpen: Bool @State var isDisabled: Bool = false + var body: some View { Button { - isOpen.toggle() + isOpen = true + isParticapatedOpen = true } label: { Text("Participer") .font(.system(size: 27)) diff --git a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift index 440275c..b788b52 100644 --- a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift +++ b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift @@ -12,6 +12,7 @@ struct RecapBetCard: View { @GestureState private var longPressTap = false @State private var isPressed = false @State var showDetails: Bool = false + @State var showPartipated: Bool = false var body: some View { VStack(spacing: 0){ VStack(alignment: .leading,spacing: 2){ @@ -107,7 +108,7 @@ struct RecapBetCard: View { .onTapGesture { showDetails.toggle() }.fullScreenCover(isPresented: $showDetails) { - DetailsView(isModalPresented: $showDetails, id: "1") + DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated,id: "1") } .gesture( LongPressGesture(minimumDuration: 0.5) diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift index 2798c36..1730ff8 100644 --- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift +++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift @@ -9,6 +9,7 @@ import SwiftUI struct ReviewCard: View { @State var showDetails: Bool = false + @State var showPartipated: Bool = false var amountBetted: Int var isAWin: Bool @@ -70,7 +71,7 @@ struct ReviewCard: View { .onTapGesture { showDetails.toggle() }.fullScreenCover(isPresented: $showDetails) { - DetailsView(isModalPresented: $showDetails, id: "1") + DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated, id: "1") } } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 938487f..8701c81 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -3,7 +3,7 @@ import SwiftUI struct DetailsView: View { @Binding var isModalPresented: Bool - @State var isModalParticipated: Bool = false + @Binding var isModalParticipated: Bool @State var progressValue: Float = 0.2 var isFinished: Bool { viewModel.betDetail?.finalAnswer == nil ? false : true @@ -48,8 +48,9 @@ struct DetailsView: View { var id: String @StateObject private var viewModel: DetailsViewModel - init(isModalPresented: Binding, id: String) { + init(isModalPresented: Binding, isModalParticipated: Binding,id: String) { self._isModalPresented = isModalPresented + self._isModalParticipated = isModalParticipated self.id = id self._viewModel = StateObject(wrappedValue: DetailsViewModel(id: id)) } @@ -132,7 +133,7 @@ struct DetailsView: View { .background(AllInColors.componentBackgroundColor) .cornerRadius(15) - ParticipateButton(isOpen: $isModalParticipated, isDisabled: isDisabled).padding(10).disabled(isDisabled) + ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated,isDisabled: isDisabled ).padding(10).disabled(isDisabled) } -- 2.36.3 From 7390f5767bc54dd684fe9a3383981754626cae99 Mon Sep 17 00:00:00 2001 From: ludelanier Date: Sun, 21 Jan 2024 16:02:36 +0100 Subject: [PATCH 11/14] add list of user in detailview --- .../BleueCoin.imageset/Contents.json | 21 ++++++++ .../BleueCoin.imageset/Group 107 (1).png | Bin 0 -> 681 bytes .../PurpleAllCoin.imageset/Contents.json | 21 ++++++++ .../PurpleAllCoin.imageset/Vector (3).png | Bin 0 -> 1131 bytes .../AllIn/Components/BetLineLoading.swift | 48 +++++++++++++----- .../AllIn/Components/ParticiationCell.swift | 29 +++++++++++ .../AllInApp/AllIn/Views/DetailsView.swift | 16 ++++-- .../AllInApp.xcodeproj/project.pbxproj | 4 ++ Sources/Model/Sources/Model/Bet.swift | 4 ++ Sources/Model/Sources/Model/BetDetail.swift | 10 ++++ .../Model/Sources/Model/Participation.swift | 6 ++- Sources/StubLib/Sources/StubLib/Stub.swift | 6 +++ 12 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Group 107 (1).png create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Contents.json create mode 100644 Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Vector (3).png create mode 100644 Sources/AllInApp/AllIn/Components/ParticiationCell.swift diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Contents.json new file mode 100644 index 0000000..67a98bf --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 107 (1).png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Group 107 (1).png b/Sources/AllInApp/AllIn/Assets.xcassets/BleueCoin.imageset/Group 107 (1).png new file mode 100644 index 0000000000000000000000000000000000000000..d982a56c3fa043a8c4b0c7e109628eead0745cfb GIT binary patch literal 681 zcmV;a0#^NrP)@~0drDELIAGL9O(c600d`2O+f$vv5yPra20PYFM4U!vlJWyVlJ`*N6g1G^l0C58!A+NN|;2G!>ww9He zx`}N`mXiM=oUXMCbA^BlAUgNOBf+J-K9#od1SabB^4FYHyXFN` z0Gc)lX~v(@HY{L*^5xGN0+pO?3IQU(xog~O&Zy4`PgW48H2-v$L##QdfBBU9TJ?ZF z&YZ}N&O6_M-f6Cp>jxYrD|&b48u>9~LGLtY;HD5%E8ZoKJU7aHE@SFhJz*dT#8_JQz7*Dc_xyqhm=@fggQl%!83L zZWMnC+psL2*L>UcZa5E_hafk`?WHVUxidqv-MUm6^Qp+W#uCN-#b}-T5-0AuBUY%9 zbMe2s1EEI6&2@dch5)@;-syGo(e*@gA-u@Bv2)>lyV-&p?xCO7h_r>Wpo P00000NkvXXu0mjfC#62> literal 0 HcmV?d00001 diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Contents.json new file mode 100644 index 0000000..1904c47 --- /dev/null +++ b/Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector (3).png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Vector (3).png b/Sources/AllInApp/AllIn/Assets.xcassets/PurpleAllCoin.imageset/Vector (3).png new file mode 100644 index 0000000000000000000000000000000000000000..2ae155ae0e4345897b9fa73f1db22db9f217316a GIT binary patch literal 1131 zcmV-x1eE)UP)@~0drDELIAGL9O(c600d`2O+f$vv5yPrw6366k7Q>zLp^{*R|LoKriG__N7(dzMe?ZT0eXlfOZJiLPA z(&G-TYw`hcK&>aAQl}luA)+uGnCvgFVCWyO?QMYspG@`_2P7g|^&q|yqJSsVbHkY))K}TjINt&y-G?rj-LWP0tNc1pT7-D+g?v zo*NLM@VE>VZJeGP3N@`1(6ydig%_}(NYhFIo$I;6XPz9IfRG|ht0{`q2ba8SP53na z0XeyvmIhSUVP8J&UIBzjJX00~W3V7k)6#%saBCs~BYM{Vbx0SQmMiL7&nTF@{T94} zoP(Mc22?*51Lt}^;B0Hl1Z+6a85RcQX+gJo(r(A1Zn>HW#t&FF5Kvz~C)wVX8!+CH zz^$INUomcn&mgA*VYoAunP0)h(rq|?u$l8v)9Rw1)igJtdp)D!q3v~RdN5!zYkj=l zGefp*8q$H)Dn0hY6^tLMxB~&lncg$AgJ-2FMU-lKI3T(nd$xv!@B1w)O+im9CYtUA z)Ou3IDLDzH)q`YILm*mJk&tS-UqPpOa7 zrJk{x_w8}j{cQ)|kX-b4E9gv5u3FIg2Bz2zzO{{AFSEgco;br*>s+#khbu4!OVWT& z^yIESUT0Rd-DOY@?`Pay%)o-T3f8Ts4j0k6bP-+pHHh-wlxUU)taZgiP2m!xqnf!M z*Twb8b3jH`C*EF71?pBiX7{dFItYj}K-o;n!7 zh=2G=bbT{K|AzXxoL0DuO>yO4Zg23(p!8g=3Fw%x9lRVp)HeM4JhFM*nZ{h3G~rjHy!MakJGVjK=lM^X^M~i) xd2_zu)Ls1iq=62Q9&5y-8;?5?ZkuJt_#bX(sxlpmL9_q>002ovPDHLkV1huR2zUSh literal 0 HcmV?d00001 diff --git a/Sources/AllInApp/AllIn/Components/BetLineLoading.swift b/Sources/AllInApp/AllIn/Components/BetLineLoading.swift index ba9dc95..8bf0d58 100644 --- a/Sources/AllInApp/AllIn/Components/BetLineLoading.swift +++ b/Sources/AllInApp/AllIn/Components/BetLineLoading.swift @@ -6,13 +6,37 @@ // import SwiftUI +import Model struct BetLineLoading: View { - @Binding var value: Float + @State var participations: [Participation] + + var value: CGFloat { + let totalParticipations = participations.count + let numberOfYes = participations.filter { $0.response == "OUI" }.count + let numberOfNo = participations.filter { $0.response == "NON" }.count + if(numberOfNo == 0 && numberOfYes == 0){ + return 0.5 + } + + return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0 + } + + + + var yesParticipations: [Participation] { + return participations.filter { $0.response == "OUI" } + } + + var noParticipations: [Participation] { + return participations.filter { $0.response == "NON" } + } + + var body: some View { GeometryReader { geometry in - VStack(spacing: 0){ + VStack(alignment: .leading,spacing: 0){ HStack(spacing: 5){ Text("OUI").font(.system(size: 25)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) Spacer() @@ -36,31 +60,31 @@ struct BetLineLoading: View { } VStack(spacing: 1){ HStack(spacing: 5){ - Image("BleueBadge").resizable().frame(width:10, height: 14) - Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) + Image("BlueAllCoinIcon").resizable().frame(width:12, height: 12) + Text(yesParticipations.reduce(0, {x,y in x + y.stake}).description).font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) Spacer() - Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) + Text(noParticipations.reduce(0, {x,y in x + y.stake}).description).font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) } HStack(spacing: 5){ - Image("BleueBadge").resizable().frame(width:10, height: 14) - Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) + Image("BleuePersonIcon").resizable().frame(width:14, height: 12) + Text(yesParticipations.count.description).font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) Spacer() - Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) + Text(noParticipations.count.description).font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) } HStack(spacing: 5){ Image("BleueBadge").resizable().frame(width:10, height: 14) - Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) + Text(yesParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) Spacer() - Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) + Text(noParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) } HStack(spacing: 5){ - Image("BleueBadge").resizable().frame(width:10, height: 14) + Image("BleueTrophyIcon").resizable().frame(width:14, height: 13) Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) Spacer() Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) @@ -70,7 +94,7 @@ struct BetLineLoading: View { } } - } + }.frame(height: 140) } } diff --git a/Sources/AllInApp/AllIn/Components/ParticiationCell.swift b/Sources/AllInApp/AllIn/Components/ParticiationCell.swift new file mode 100644 index 0000000..735f808 --- /dev/null +++ b/Sources/AllInApp/AllIn/Components/ParticiationCell.swift @@ -0,0 +1,29 @@ +// +// ParticiationCell.swift +// AllIn +// +// Created by Lucas Delanier on 21/01/2024. +// + +import SwiftUI +import Model + +struct ParticiationCell: View { + @State var participation: Participation? + var body: some View { + HStack(alignment: .center, spacing: 0){ + Circle().frame(width: 30, height: 30).foregroundColor(AllInColors.grey700Color).padding(.trailing, 5) + Text(participation?.user.username ?? "Unknown") + .font(.system(size: 15)) + .foregroundStyle(AllInColors.grey100Color) + .fontWeight(.semibold) + Spacer() + Text(participation?.stake.description ?? "NaN") + .font(.system(size: 18)) + .foregroundStyle(AllInColors.lightPurpleColor) + .fontWeight(.bold).padding(.trailing, 5) + Image("PurpleAllCoin").resizable().frame(width: 11, height: 12) + } + } +} + diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 8701c81..fdf23ca 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -1,4 +1,5 @@ import SwiftUI +import Model struct DetailsView: View { @@ -106,7 +107,7 @@ struct DetailsView: View { .foregroundColor(AllInColors.grey800Color) TextCapsule(date: viewModel.betDetail?.bet.endBetDate ?? Date()) Spacer() - + } } .frame(width: .infinity) @@ -116,8 +117,17 @@ struct DetailsView: View { if isFinished { ResultBanner() } - VStack(alignment: .leading, spacing: 15) { - BetLineLoading(value: $progressValue).padding(.vertical, 15) + VStack(alignment: .leading, spacing: 5) { + BetLineLoading(participations: viewModel.betDetail!.participations).padding(.vertical,15) + Text("Liste des participants") + .font(.system(size: 18)) + .foregroundStyle(AllInColors.grey100Color) + .fontWeight(.bold) + .padding(.bottom, 10) + ForEach(viewModel.betDetail?.participations ?? []) { (participation: Participation) in + ParticiationCell(participation: participation).padding(.horizontal, 10) + } + Spacer() } .frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, maxHeight: .infinity) diff --git a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj index f394329..3fbc216 100644 --- a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj +++ b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 1244EF602B4EC31E00374ABF /* HistoricBetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */; }; 1244EF622B4EC67000374ABF /* ReviewCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1244EF612B4EC67000374ABF /* ReviewCard.swift */; }; 12C370482B5A5EE500CD9F0F /* BetLineLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C370472B5A5EE500CD9F0F /* BetLineLoading.swift */; }; + 12C3704A2B5D5BD000CD9F0F /* ParticiationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C370492B5D5BD000CD9F0F /* ParticiationCell.swift */; }; EC0193782B25BF16005D81E6 /* AllcoinsCapsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0193772B25BF16005D81E6 /* AllcoinsCapsule.swift */; }; EC01937A2B25C12B005D81E6 /* BetCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0193792B25C12B005D81E6 /* BetCard.swift */; }; EC01937C2B25C2A8005D81E6 /* AllcoinsCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC01937B2B25C2A8005D81E6 /* AllcoinsCounter.swift */; }; @@ -113,6 +114,7 @@ 1244EF5F2B4EC31E00374ABF /* HistoricBetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoricBetView.swift; sourceTree = ""; }; 1244EF612B4EC67000374ABF /* ReviewCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewCard.swift; sourceTree = ""; }; 12C370472B5A5EE500CD9F0F /* BetLineLoading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetLineLoading.swift; sourceTree = ""; }; + 12C370492B5D5BD000CD9F0F /* ParticiationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParticiationCell.swift; sourceTree = ""; }; EC0193772B25BF16005D81E6 /* AllcoinsCapsule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllcoinsCapsule.swift; sourceTree = ""; }; EC0193792B25C12B005D81E6 /* BetCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetCard.swift; sourceTree = ""; }; EC01937B2B25C2A8005D81E6 /* AllcoinsCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllcoinsCounter.swift; sourceTree = ""; }; @@ -335,6 +337,7 @@ 120919172B56D0AE00D0FA29 /* ParticipationModal.swift */, 120919192B56DC6C00D0FA29 /* DropDownAnswerMenu.swift */, 12C370472B5A5EE500CD9F0F /* BetLineLoading.swift */, + 12C370492B5D5BD000CD9F0F /* ParticiationCell.swift */, ); path = Components; sourceTree = ""; @@ -539,6 +542,7 @@ EC3077072B24CB840060E34D /* SplashView.swift in Sources */, EC01937E2B25C52E005D81E6 /* TopBar.swift in Sources */, ECA9D1CB2B2DA2320076E0EC /* DropDownFriends.swift in Sources */, + 12C3704A2B5D5BD000CD9F0F /* ParticiationCell.swift in Sources */, 123590B82B5541BA00F7AEBD /* ParticipateButton.swift in Sources */, EC01FCC32B56650400BB2390 /* DetailsViewModel.swift in Sources */, ECB26A1B2B40746C00FE06B3 /* FriendsViewModel.swift in Sources */, diff --git a/Sources/Model/Sources/Model/Bet.swift b/Sources/Model/Sources/Model/Bet.swift index b99b7c2..4ad6268 100644 --- a/Sources/Model/Sources/Model/Bet.swift +++ b/Sources/Model/Sources/Model/Bet.swift @@ -90,4 +90,8 @@ public class Bet: ObservableObject, Identifiable { self.author = author self.registered = registered } + + public func addRegistered(newUser: User){ + self.registered.append(newUser) + } } diff --git a/Sources/Model/Sources/Model/BetDetail.swift b/Sources/Model/Sources/Model/BetDetail.swift index 8e55642..d492e8f 100644 --- a/Sources/Model/Sources/Model/BetDetail.swift +++ b/Sources/Model/Sources/Model/BetDetail.swift @@ -42,4 +42,14 @@ public class BetDetail: ObservableObject { public func updateFinalAnswer(newFinalAnswer: String) { self.finalAnswer = newFinalAnswer } + + public func addParticipation(newParticipation: Participation){ + if !self.bet.registered.contains(where: { existingUser in + return existingUser.email == newParticipation.user.email + }) { + self.bet.addRegistered(newUser: newParticipation.user) + } + + self.participations.append(newParticipation) + } } diff --git a/Sources/Model/Sources/Model/Participation.swift b/Sources/Model/Sources/Model/Participation.swift index 4040e22..9b5d088 100644 --- a/Sources/Model/Sources/Model/Participation.swift +++ b/Sources/Model/Sources/Model/Participation.swift @@ -8,8 +8,9 @@ import Foundation /// A class representing a user's participation in a bet. -public class Participation: ObservableObject { - +public class Participation: ObservableObject, Identifiable{ + + public let id: UUID /// The amount of stake in the bet. public private(set) var stake: Int @@ -39,5 +40,6 @@ public class Participation: ObservableObject { self.response = response self.user = user self.betId = betId + self.id = UUID() } } diff --git a/Sources/StubLib/Sources/StubLib/Stub.swift b/Sources/StubLib/Sources/StubLib/Stub.swift index 646abe3..2692c33 100644 --- a/Sources/StubLib/Sources/StubLib/Stub.swift +++ b/Sources/StubLib/Sources/StubLib/Stub.swift @@ -88,6 +88,12 @@ struct Stub { let betDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: user1, betId: "")) self.betsDetail.append(betDetail) } + + self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 120, date: Date(), response: "OUI", user: user1, betId: "1")) + self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 20, date: Date(), response: "NON", user: user2, betId: "2")) + self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 320, date: Date(), response: "OUI", user: user3, betId: "3")) + self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 320, date: Date(), response: "OUI", user: user3, betId: "3")) + } public mutating func add(bet: Bet) { -- 2.36.3 From 0cafea89196996cbd4889536d6029e196cd00d11 Mon Sep 17 00:00:00 2001 From: ludelanier Date: Sun, 21 Jan 2024 21:56:39 +0100 Subject: [PATCH 12/14] fix dark mod and participate button disabled --- .../Grey100Color.colorset/Contents.json | 8 +++---- .../AllInApp/AllIn/Components/BetCard.swift | 2 +- .../AllIn/Components/ParticipateButton.swift | 24 +++++++++++++++++-- .../AllInApp/AllIn/Views/DetailsView.swift | 2 +- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json index cf9f629..806eef5 100644 --- a/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json +++ b/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json @@ -20,12 +20,12 @@ } ], "color" : { - "color-space" : "srgb", + "color-space" : "display-p3", "components" : { "alpha" : "1.000", - "blue" : "0x45", - "green" : "0x45", - "red" : "0x45" + "blue" : "0xCF", + "green" : "0xCF", + "red" : "0xCF" } }, "idiom" : "universal" diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index f03f234..b8ca216 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -51,7 +51,7 @@ struct BetCard: View { Spacer() }.padding(0) - ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate).padding(.top, 5) + ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate, bet: bet).padding(.top, 5) } .frame(width: .infinity) .padding(.all,8) diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift index 126fa74..cdb3ea8 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -6,11 +6,31 @@ // import SwiftUI +import Model struct ParticipateButton: View { @Binding var isOpen : Bool @Binding var isParticapatedOpen: Bool - @State var isDisabled: Bool = false + @State var bet: Bet? + + var isDisabled: Bool { + let endRegisterDate: Date? = bet?.endRegisterDate + if endRegisterDate != nil{ + let currentDate = Date() + + switch currentDate.compare(endRegisterDate!) { + case .orderedAscending: + return false + case .orderedDescending: + return true + case .orderedSame: + return true + } + + } else { + return true + } + } var body: some View { Button { @@ -51,6 +71,6 @@ struct ParticipateButton: View { ) - } + }.disabled(isDisabled) } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index fdf23ca..8266de9 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -143,7 +143,7 @@ struct DetailsView: View { .background(AllInColors.componentBackgroundColor) .cornerRadius(15) - ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated,isDisabled: isDisabled ).padding(10).disabled(isDisabled) + ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated,bet: viewModel.betDetail?.bet ).padding(10) } -- 2.36.3 From 6fb1146ab68e907b91c0b71d75c7b5f20632694f Mon Sep 17 00:00:00 2001 From: "emre.kartal" Date: Tue, 23 Jan 2024 21:23:14 +0100 Subject: [PATCH 13/14] Update Factory and add a new Method toBetDetail, also improve the Model :art: --- .../Grey100Color.colorset/Contents.json | 6 +-- .../AllInApp/AllIn/Components/BetCard.swift | 2 +- .../AllInApp/AllIn/Services/AuthService.swift | 2 +- .../AllInApp/AllIn/Views/DetailsView.swift | 2 +- Sources/Api/Sources/Api/BetApiManager.swift | 34 ++++++++++-- .../Sources/Api/Factory/FactoryApiBet.swift | 52 +++++++++++++------ Sources/Api/Sources/Api/UserApiManager.swift | 7 ++- ...tAnswerDetail.swift => AnswerDetail.swift} | 4 +- Sources/Model/Sources/Model/Bet.swift | 16 +++--- Sources/Model/Sources/Model/BetDetail.swift | 8 +-- Sources/Model/Sources/Model/BinaryBet.swift | 32 ------------ .../Sources/Model/Factory/FactoryBet.swift | 5 +- Sources/Model/Sources/Model/File.swift | 12 +++++ Sources/Model/Sources/Model/Manager.swift | 2 +- Sources/Model/Sources/Model/MatchBet.swift | 8 +-- .../Model/Sources/Model/Participation.swift | 4 +- Sources/Model/Sources/Model/User.swift | 8 +-- Sources/StubLib/Sources/StubLib/Stub.swift | 12 ++--- 18 files changed, 117 insertions(+), 99 deletions(-) rename Sources/Model/Sources/Model/{BetAnswerDetail.swift => AnswerDetail.swift} (94%) create mode 100644 Sources/Model/Sources/Model/File.swift diff --git a/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json b/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json index 806eef5..c165084 100644 --- a/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json +++ b/Sources/AllInApp/AllIn/Assets.xcassets/Grey100Color.colorset/Contents.json @@ -23,9 +23,9 @@ "color-space" : "display-p3", "components" : { "alpha" : "1.000", - "blue" : "0xCF", - "green" : "0xCF", - "red" : "0xCF" + "blue" : "0x45", + "green" : "0x45", + "red" : "0x45" } }, "idiom" : "universal" diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index b8ca216..68058b2 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -74,8 +74,8 @@ struct BetCard_Previews: PreviewProvider { 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, + status: .FINISHED, invited: [], author: User(username: "Imri", email: "emre.kartal@etu.uca.fr", nbCoins: 75, friends: []), registered: [])) diff --git a/Sources/AllInApp/AllIn/Services/AuthService.swift b/Sources/AllInApp/AllIn/Services/AuthService.swift index df4b7e6..3d2ab62 100644 --- a/Sources/AllInApp/AllIn/Services/AuthService.swift +++ b/Sources/AllInApp/AllIn/Services/AuthService.swift @@ -150,7 +150,7 @@ class AuthService: IAuthService { } private func initManagerVM(token: String) { - DependencyInjection.shared.addSingleton(Manager.self, Manager(withBetDataManager: BetStubManager(), withUserDataManager: UserApiManager(withUserToken: token))) + DependencyInjection.shared.addSingleton(Manager.self, Manager(withBetDataManager: BetApiManager(withUserToken: token), withUserDataManager: UserApiManager(withUserToken: token))) } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 8266de9..2afda06 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -118,7 +118,7 @@ struct DetailsView: View { ResultBanner() } VStack(alignment: .leading, spacing: 5) { - BetLineLoading(participations: viewModel.betDetail!.participations).padding(.vertical,15) + BetLineLoading(participations: viewModel.betDetail?.participations ?? []).padding(.vertical,15) Text("Liste des participants") .font(.system(size: 18)) .foregroundStyle(AllInColors.grey100Color) diff --git a/Sources/Api/Sources/Api/BetApiManager.swift b/Sources/Api/Sources/Api/BetApiManager.swift index 4141547..380d832 100644 --- a/Sources/Api/Sources/Api/BetApiManager.swift +++ b/Sources/Api/Sources/Api/BetApiManager.swift @@ -10,7 +10,11 @@ import Model public struct BetApiManager: BetDataManager { - public init() { } + public let token: String + + public init(withUserToken token: String) { + self.token = token + } public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { let url = URL(string: allInApi + "bets/gets")! @@ -27,9 +31,8 @@ public struct BetApiManager: BetDataManager { 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) { + if let bet = FactoryApiBet().toBet(from: json) { bets.append(bet) - print(bet.theme) } } print(httpResponse.statusCode) @@ -47,7 +50,30 @@ public struct BetApiManager: BetDataManager { } public func getBet(withId id: String, completion: @escaping (BetDetail) -> Void) { - + let url = URL(string: allInApi + "betdetail/get/" + id)! + + var request = URLRequest(url: url) + request.httpMethod = "GET" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") + + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + print ("ALLIN : get bet with id :" + id) + do { + if let httpResponse = response as? HTTPURLResponse, let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { + + if let betDetail = FactoryApiBet().toBetDetail(from: json) { + completion(betDetail) + } + print(httpResponse.statusCode) + } + } catch { + print("Error parsing JSON: \(error)") + } + } + }.resume() + } } diff --git a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift index 1adb92c..0a4931c 100644 --- a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift +++ b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift @@ -10,14 +10,19 @@ import Model public class FactoryApiBet: FactoryBet { + func formatZonedDateTime(dateTime: Date) -> String { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z" + formatter.timeZone = TimeZone.current + return formatter.string(from: dateTime) + } + public func toResponse(bet: Bet) -> [String: Any] { - let json: [String: Any] = [ - "id": "1", "theme": bet.theme, "sentenceBet": bet.phrase, - "endRegistration": bet.endRegisterDate.timeIntervalSince1970, - "endBet": bet.endBetDate.timeIntervalSince1970, + "endRegistration": formatZonedDateTime(dateTime: bet.endRegisterDate), + "endBet": formatZonedDateTime(dateTime: bet.endBetDate), "isPrivate": String(bet.isPublic), "response": [], ] @@ -25,7 +30,15 @@ public class FactoryApiBet: FactoryBet { return json } - public func toModel(from json: [String: Any]) -> Bet? { + public func fromJsonDateString(_ dateString: String) -> Date? { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z" + let date = formatter.date(from: dateString) + return date + } + + public func toBet(from json: [String: Any]) -> Bet? { guard let id = json["id"] as? String, let theme = json["theme"] as? String, let phrase = json["sentenceBet"] as? String, @@ -36,28 +49,33 @@ public class FactoryApiBet: FactoryBet { return nil } - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" - - guard let endRegisterDate = dateFormatter.date(from: endRegisterDateString), - let endBetDate = dateFormatter.date(from: endBetDateString) else { + guard let endRegisterDate = fromJsonDateString(endRegisterDateString), + let endBetDate = fromJsonDateString(endBetDateString) else { return nil } - - return toModel(id: id, theme: theme, description: phrase, endRegister: endRegisterDate, endBet: endBetDate, isPublic: isPublic, creator: User(username: createdBy, email: createdBy, nbCoins: 0, friends: []), type: 0) + + return toBet(id: id, theme: theme, description: phrase, endRegister: endRegisterDate, endBet: endBetDate, isPublic: isPublic, status: .FINISHED, creator: User(username: createdBy, email: createdBy, nbCoins: 0, friends: []), type: 0) } - public func toModel(id: String, theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User, type: Int) -> Bet { + public func toBet(id: String, theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, status: BetStatus, creator: User, type: Int) -> Bet { switch type { case 0: - return BinaryBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) + return BinaryBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, isPublic: isPublic, status: status, invited: [], author: creator, registered: []) case 1: - return MatchBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [], nameTeam1: "", nameTeam2: "") + return MatchBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, isPublic: isPublic, status: status, invited: [], author: creator, registered: [], nameTeam1: "", nameTeam2: "") case 2: - return CustomBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) + return CustomBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, isPublic: isPublic, status: status, invited: [], author: creator, registered: []) default: - return BinaryBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: []) + return BinaryBet(id: id, theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, isPublic: isPublic, status: status, invited: [], author: creator, registered: []) + } + } + + public func toBetDetail(from json: [String: Any]) -> BetDetail? { + guard let betJson = json["bet"] as? [String: Any], + let bet = self.toBet(from: betJson) else { + return nil } + return BetDetail(bet: bet, answers: [], participations: []) } } diff --git a/Sources/Api/Sources/Api/UserApiManager.swift b/Sources/Api/Sources/Api/UserApiManager.swift index 89873c8..eecc76b 100644 --- a/Sources/Api/Sources/Api/UserApiManager.swift +++ b/Sources/Api/Sources/Api/UserApiManager.swift @@ -24,15 +24,14 @@ public struct UserApiManager: UserDataManager { public func addBet(bet: Bet) { - print(token) let url = URL(string: allInApi + "bets/add")! var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") + + let json = FactoryApiBet().toResponse(bet: bet) - var json = FactoryApiBet().toResponse(bet: bet) - json["createdBy"] = token - if let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []){ URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in print ("ALLIN : Add BET") diff --git a/Sources/Model/Sources/Model/BetAnswerDetail.swift b/Sources/Model/Sources/Model/AnswerDetail.swift similarity index 94% rename from Sources/Model/Sources/Model/BetAnswerDetail.swift rename to Sources/Model/Sources/Model/AnswerDetail.swift index 77ab2d8..6474788 100644 --- a/Sources/Model/Sources/Model/BetAnswerDetail.swift +++ b/Sources/Model/Sources/Model/AnswerDetail.swift @@ -1,5 +1,5 @@ // -// BetAnswerDetail.swift +// AnswerDetail.swift // // // Created by Emre on 19/01/2024. @@ -8,7 +8,7 @@ import Foundation /// A class representing detailed information about a specific answer option for a bet. -public class BetAnswerDetail: ObservableObject { +public class AnswerDetail: ObservableObject { /// The response or outcome associated with this answer. public private(set) var response: String diff --git a/Sources/Model/Sources/Model/Bet.swift b/Sources/Model/Sources/Model/Bet.swift index 4ad6268..f733cd4 100644 --- a/Sources/Model/Sources/Model/Bet.swift +++ b/Sources/Model/Sources/Model/Bet.swift @@ -25,12 +25,11 @@ public class Bet: ObservableObject, Identifiable { /// The deadline for the actual betting to take place. public private(set) var endBetDate: Date - /// The total stakes or amount involved in the bet. - public private(set) var totalStakes: Int - /// Indicates whether the bet is public or private. public private(set) var isPublic: Bool + public private(set) var status: BetStatus + /// List of users who are invited to participate in the bet. public private(set) var invited: [User] @@ -39,6 +38,7 @@ public class Bet: ObservableObject, Identifiable { /// List of users who have registered for the bet. public private(set) var registered: [User] + /// Custom Constructor /// @@ -48,19 +48,18 @@ public class Bet: ObservableObject, Identifiable { /// - phrase: The specific phrase or question related to the bet. /// - endRegisterDate: The deadline for users to register for the bet. /// - endBetDate: The deadline for the actual betting to take place. - /// - totalStakes: The total stakes or amount involved in the bet. /// - isPublic: Indicates whether the bet is public or private. /// - invited: List of users who are invited to participate in the bet. /// - author: The user who created the bet. /// - registered: List of users who have registered for the bet. - public init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { + public init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, isPublic: Bool, status: BetStatus, invited: [User], author: User, registered: [User]) { self.id = id self.theme = theme self.phrase = phrase self.endRegisterDate = endRegisterDate self.endBetDate = endBetDate - self.totalStakes = totalStakes self.isPublic = isPublic + self.status = status self.invited = invited self.author = author self.registered = registered @@ -73,19 +72,18 @@ public class Bet: ObservableObject, Identifiable { /// - phrase: The specific phrase or question related to the bet. /// - endRegisterDate: The deadline for users to register for the bet. /// - endBetDate: The deadline for the actual betting to take place. - /// - totalStakes: The total stakes or amount involved in the bet. /// - isPublic: Indicates whether the bet is public or private. /// - invited: List of users who are invited to participate in the bet. /// - author: The user who created the bet. /// - registered: List of users who have registered for the bet. - public init(theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { + public init(theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, isPublic: Bool, status: BetStatus, invited: [User], author: User, registered: [User]) { self.id = UUID().uuidString self.theme = theme self.phrase = phrase self.endRegisterDate = endRegisterDate self.endBetDate = endBetDate - self.totalStakes = totalStakes self.isPublic = isPublic + self.status = status self.invited = invited self.author = author self.registered = registered diff --git a/Sources/Model/Sources/Model/BetDetail.swift b/Sources/Model/Sources/Model/BetDetail.swift index d492e8f..2f647f5 100644 --- a/Sources/Model/Sources/Model/BetDetail.swift +++ b/Sources/Model/Sources/Model/BetDetail.swift @@ -14,14 +14,11 @@ public class BetDetail: ObservableObject { public private(set) var bet: Bet /// Details about the answers available for the bet. - public private(set) var answers: [BetAnswerDetail] + public private(set) var answers: [AnswerDetail] /// List of user participations in the bet. public private(set) var participations: [Participation] - /// The user's own participation in the bet. - public private(set) var userParticipation: Participation - public private(set) var finalAnswer: String? /// Custom Constructor @@ -31,11 +28,10 @@ public class BetDetail: ObservableObject { /// - answers: Details about the answers available for the bet. /// - participations: List of user participations in the bet. /// - userParticipation: The user's own participation in the bet. - public init(bet: Bet, answers: [BetAnswerDetail], participations: [Participation], userParticipation: Participation, finalAnswer: String? = nil) { + public init(bet: Bet, answers: [AnswerDetail], participations: [Participation], finalAnswer: String? = nil) { self.bet = bet self.answers = answers self.participations = participations - self.userParticipation = userParticipation self.finalAnswer = finalAnswer } diff --git a/Sources/Model/Sources/Model/BinaryBet.swift b/Sources/Model/Sources/Model/BinaryBet.swift index 051ccf6..fafd7be 100644 --- a/Sources/Model/Sources/Model/BinaryBet.swift +++ b/Sources/Model/Sources/Model/BinaryBet.swift @@ -10,36 +10,4 @@ import Foundation /// A subclass of Bet that represents a binary bet, where participants make a choice between two possible outcomes. public class BinaryBet: Bet { - // Custom Constructor - /// - /// - Parameters: - /// - id: The id for the bet. - /// - theme: The theme or topic of the binary bet. - /// - phrase: The specific phrase or question related to the binary bet. - /// - endRegisterDate: The deadline for users to register for the binary bet. - /// - endBetDate: The deadline for the actual betting to take place for the binary bet. - /// - totalStakes: The total stakes or amount involved in the binary bet. - /// - isPublic: Indicates whether the binary bet is public or private. - /// - invited: List of users who are invited to participate in the binary bet. - /// - author: The user who created the binary bet. - /// - registered: List of users who have registered for the binary bet. - public override init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { - super.init(id: id, theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, totalStakes: totalStakes, isPublic: isPublic, invited: invited, author: author, registered: registered) - } - - // Custom Constructor without Id - /// - /// - Parameters: - /// - theme: The theme or topic of the binary bet. - /// - phrase: The specific phrase or question related to the binary bet. - /// - endRegisterDate: The deadline for users to register for the binary bet. - /// - endBetDate: The deadline for the actual betting to take place for the binary bet. - /// - totalStakes: The total stakes or amount involved in the binary bet. - /// - isPublic: Indicates whether the binary bet is public or private. - /// - invited: List of users who are invited to participate in the binary bet. - /// - author: The user who created the binary bet. - /// - registered: List of users who have registered for the binary bet. - public override init(theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User]) { - super.init(theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, totalStakes: totalStakes, isPublic: isPublic, invited: invited, author: author, registered: registered) - } } diff --git a/Sources/Model/Sources/Model/Factory/FactoryBet.swift b/Sources/Model/Sources/Model/Factory/FactoryBet.swift index 40a7f0a..be18215 100644 --- a/Sources/Model/Sources/Model/Factory/FactoryBet.swift +++ b/Sources/Model/Sources/Model/Factory/FactoryBet.swift @@ -9,6 +9,7 @@ import Foundation public protocol FactoryBet { func toResponse(bet: Bet) -> [String: Any] - func toModel(from json: [String: Any]) -> Bet? - func toModel(id: String, theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User, type: Int) -> Bet + func toBet(from json: [String: Any]) -> Bet? + func toBetDetail(from json: [String: Any]) -> BetDetail? + func toBet(id: String, theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, status: BetStatus, creator: User, type: Int) -> Bet } diff --git a/Sources/Model/Sources/Model/File.swift b/Sources/Model/Sources/Model/File.swift new file mode 100644 index 0000000..a44b593 --- /dev/null +++ b/Sources/Model/Sources/Model/File.swift @@ -0,0 +1,12 @@ +// +// File.swift +// +// +// Created by étudiant on 23/01/2024. +// + +import Foundation + +public enum BetStatus { + case WAITING, IN_PROGRESS, FINISHED +} diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift index 3ff086a..06392df 100644 --- a/Sources/Model/Sources/Model/Manager.swift +++ b/Sources/Model/Sources/Model/Manager.swift @@ -17,7 +17,7 @@ public struct Manager { } public func addBet(theme: String, description: String, endRegister: Date, endBet: Date, isPublic: Bool, creator: User) { - userDataManager.addBet(bet: BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, totalStakes: 0, isPublic: isPublic, invited: [], author: creator, registered: [])) + userDataManager.addBet(bet: BinaryBet(theme: theme, phrase: description, endRegisterDate: endRegister, endBetDate: endBet, isPublic: isPublic, status: .IN_PROGRESS, invited: [], author: creator, registered: [])) } public func getBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { diff --git a/Sources/Model/Sources/Model/MatchBet.swift b/Sources/Model/Sources/Model/MatchBet.swift index e197042..a6100c1 100644 --- a/Sources/Model/Sources/Model/MatchBet.swift +++ b/Sources/Model/Sources/Model/MatchBet.swift @@ -30,10 +30,10 @@ public class MatchBet: Bet { /// - registered: List of users who have registered for the match bet. /// - nameTeam1: The name of the first team involved in the match. /// - nameTeam2: The name of the second team involved in the match. - public init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User], nameTeam1: String, nameTeam2: String) { + public init(id: String, theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, isPublic: Bool, status: BetStatus, invited: [User], author: User, registered: [User], nameTeam1: String, nameTeam2: String) { self.nameTeam1 = nameTeam1 self.nameTeam2 = nameTeam2 - super.init(id: id, theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, totalStakes: totalStakes, isPublic: isPublic, invited: invited, author: author, registered: registered) + super.init(id: id, theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, isPublic: isPublic, status: status, invited: invited, author: author, registered: registered) } /// Custom Constructor without Id @@ -50,9 +50,9 @@ public class MatchBet: Bet { /// - registered: List of users who have registered for the match bet. /// - nameTeam1: The name of the first team involved in the match. /// - nameTeam2: The name of the second team involved in the match. - public init(theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, totalStakes: Int, isPublic: Bool, invited: [User], author: User, registered: [User], nameTeam1: String, nameTeam2: String) { + public init(theme: String, phrase: String, endRegisterDate: Date, endBetDate: Date, isPublic: Bool, status: BetStatus, invited: [User], author: User, registered: [User], nameTeam1: String, nameTeam2: String) { self.nameTeam1 = nameTeam1 self.nameTeam2 = nameTeam2 - super.init(theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, totalStakes: totalStakes, isPublic: isPublic, invited: invited, author: author, registered: registered) + super.init(theme: theme, phrase: phrase, endRegisterDate: endRegisterDate, endBetDate: endBetDate, isPublic: isPublic, status: status, invited: invited, author: author, registered: registered) } } diff --git a/Sources/Model/Sources/Model/Participation.swift b/Sources/Model/Sources/Model/Participation.swift index 9b5d088..f8e7058 100644 --- a/Sources/Model/Sources/Model/Participation.swift +++ b/Sources/Model/Sources/Model/Participation.swift @@ -8,7 +8,7 @@ import Foundation /// A class representing a user's participation in a bet. -public class Participation: ObservableObject, Identifiable{ +public class Participation: ObservableObject, Identifiable { public let id: UUID /// The amount of stake in the bet. @@ -24,7 +24,7 @@ public class Participation: ObservableObject, Identifiable{ public private(set) var user: User /// The unique identifier of the bet. - let betId: String + public private(set) var betId: String /// Custom Constructor /// diff --git a/Sources/Model/Sources/Model/User.swift b/Sources/Model/Sources/Model/User.swift index 784902f..385d6ee 100644 --- a/Sources/Model/Sources/Model/User.swift +++ b/Sources/Model/Sources/Model/User.swift @@ -8,10 +8,10 @@ import Foundation public struct User { - public var username: String - public var email: String - public var nbCoins: Int - public var friends: [User] + public private(set) var username: String + public private(set) var email: String + public private(set) var nbCoins: Int + public private(set) var friends: [User] public init(username: String, email: String, nbCoins: Int, friends: [User]) { self.username = username diff --git a/Sources/StubLib/Sources/StubLib/Stub.swift b/Sources/StubLib/Sources/StubLib/Stub.swift index 2692c33..09618bf 100644 --- a/Sources/StubLib/Sources/StubLib/Stub.swift +++ b/Sources/StubLib/Sources/StubLib/Stub.swift @@ -37,8 +37,8 @@ struct Stub { 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, + status: .IN_PROGRESS, invited: [], author: user1, registered: [user2] @@ -50,8 +50,8 @@ struct Stub { phrase: "Le plat préféré du jury sera une recette végétarienne.", endRegisterDate: Date().addingTimeInterval(172800), endBetDate: Date().addingTimeInterval(259200), - totalStakes: 150, isPublic: false, + status: .IN_PROGRESS, invited: [user3], author: user1, registered: [user2] @@ -63,8 +63,8 @@ struct Stub { phrase: "Le nombre total de précommandes dépassera-t-il 1 million dans la première semaine ?", endRegisterDate: Date().addingTimeInterval(259200), endBetDate: Date().addingTimeInterval(345600), - totalStakes: 75, isPublic: true, + status: .FINISHED, invited: [], author: user1, registered: [user2, user1, user3] @@ -76,8 +76,8 @@ struct Stub { phrase: "Le film favori des critiques remportera-t-il le prix du meilleur film ?", endRegisterDate: Date().addingTimeInterval(345600), endBetDate: Date().addingTimeInterval(432000), - totalStakes: 120, isPublic: false, + status: .FINISHED, invited: [user1], author: user2, registered: [user3] @@ -85,7 +85,7 @@ struct Stub { self.bets.append(bet4) for bet in bets { - let betDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: user1, betId: "")) + let betDetail = BetDetail(bet: bet, answers: [], participations: []) self.betsDetail.append(betDetail) } @@ -97,7 +97,7 @@ struct Stub { } public mutating func add(bet: Bet) { - let newBetDetail = BetDetail(bet: bet, answers: [], participations: [], userParticipation: Participation(stake: 0, date: Date(), response: "", user: users[1], betId: ""), finalAnswer: "test") + let newBetDetail = BetDetail(bet: bet, answers: [], participations: [], finalAnswer: "test") self.betsDetail.append(newBetDetail) } } -- 2.36.3 From 0b4f5a0f537c1ba0b1a5f96d37207722b2511cbd Mon Sep 17 00:00:00 2001 From: "emre.kartal" Date: Wed, 24 Jan 2024 13:35:18 +0100 Subject: [PATCH 14/14] Add Participation functions --- .../AllInApp/AllIn/Components/BetCard.swift | 3 +- .../AllIn/Components/BetLineLoading.swift | 38 +++++----- Sources/AllInApp/AllIn/Components/Menu.swift | 15 ++++ .../AllIn/Components/ParticipateButton.swift | 29 +++----- .../AllIn/Components/ParticipationModal.swift | 73 ++++++++++++++----- .../AllInApp/AllIn/Services/AuthService.swift | 5 ++ .../AllIn/Services/IAuthService.swift | 1 + .../AllIn/ViewModels/DetailsViewModel.swift | 16 +++- .../AllInApp/AllIn/Views/DetailsView.swift | 50 ++++++++----- .../Sources/Api/Factory/FactoryApiBet.swift | 28 ++++++- Sources/Api/Sources/Api/UserApiManager.swift | 23 ++++++ Sources/Model/Sources/Model/Manager.swift | 4 + .../Model/Sources/Model/Participation.swift | 6 +- .../Model/Sources/Model/UserDataManager.swift | 1 + Sources/StubLib/Sources/StubLib/Stub.swift | 8 +- 15 files changed, 215 insertions(+), 85 deletions(-) diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index 68058b2..4e4073d 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -51,7 +51,8 @@ struct BetCard: View { Spacer() }.padding(0) - ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate, bet: bet).padding(.top, 5) + ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate, bet: bet) + .padding(.top, 5) } .frame(width: .infinity) .padding(.all,8) diff --git a/Sources/AllInApp/AllIn/Components/BetLineLoading.swift b/Sources/AllInApp/AllIn/Components/BetLineLoading.swift index 8bf0d58..5d841af 100644 --- a/Sources/AllInApp/AllIn/Components/BetLineLoading.swift +++ b/Sources/AllInApp/AllIn/Components/BetLineLoading.swift @@ -10,28 +10,28 @@ import Model struct BetLineLoading: View { - @State var participations: [Participation] + var participations: [Participation] var value: CGFloat { let totalParticipations = participations.count - let numberOfYes = participations.filter { $0.response == "OUI" }.count - let numberOfNo = participations.filter { $0.response == "NON" }.count + let numberOfYes = participations.filter { $0.response.uppercased() == "YES" }.count + let numberOfNo = participations.filter { $0.response.uppercased() == "NO" }.count if(numberOfNo == 0 && numberOfYes == 0){ return 0.5 } - - return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0 - } + + return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0 + } + - var yesParticipations: [Participation] { - return participations.filter { $0.response == "OUI" } - } - - var noParticipations: [Participation] { - return participations.filter { $0.response == "NON" } - } + return participations.filter { $0.response.uppercased() == "YES" } + } + + var noParticipations: [Participation] { + return participations.filter { $0.response.uppercased() == "NO" } + } var body: some View { @@ -41,7 +41,7 @@ struct BetLineLoading: View { Text("OUI").font(.system(size: 25)).fontWeight(.bold).foregroundColor(AllInColors.bleue200) Spacer() Text("NON").font(.system(size: 25)).fontWeight(.bold).foregroundColor(AllInColors.pink100) - + } ZStack(alignment: .leading) { HStack{ @@ -65,7 +65,7 @@ struct BetLineLoading: View { Spacer() Text(noParticipations.reduce(0, {x,y in x + y.stake}).description).font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) - + } HStack(spacing: 5){ Image("BleuePersonIcon").resizable().frame(width:14, height: 12) @@ -73,7 +73,7 @@ struct BetLineLoading: View { Spacer() Text(noParticipations.count.description).font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) - + } HStack(spacing: 5){ Image("BleueBadge").resizable().frame(width:10, height: 14) @@ -81,7 +81,7 @@ struct BetLineLoading: View { Spacer() Text(noParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) - + } HStack(spacing: 5){ Image("BleueTrophyIcon").resizable().frame(width:14, height: 13) @@ -89,11 +89,11 @@ struct BetLineLoading: View { Spacer() Text("1.2").font(.system(size: 15)).fontWeight(.bold).foregroundColor(AllInColors.pink100) Image("PinkBadge").resizable().frame(width:10, height: 14) - + } } } - + }.frame(height: 140) } } diff --git a/Sources/AllInApp/AllIn/Components/Menu.swift b/Sources/AllInApp/AllIn/Components/Menu.swift index 29804cf..3bfd971 100644 --- a/Sources/AllInApp/AllIn/Components/Menu.swift +++ b/Sources/AllInApp/AllIn/Components/Menu.swift @@ -6,8 +6,12 @@ // import SwiftUI +import DependencyInjection struct Menu: View { + + @Inject var authService: IAuthService + var body: some View { VStack(alignment: .leading, spacing: 10) { @@ -93,6 +97,17 @@ struct Menu: View { .padding([.leading,.trailing], 13) } + HStack { + Spacer() + Button { + authService.logout() + } label: { + Text("Deconnexion") + .foregroundColor(.white) + } + Spacer() + } + Spacer() Image("gearIcon") .resizable() diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift index cdb3ea8..44c1511 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -9,25 +9,22 @@ import SwiftUI import Model struct ParticipateButton: View { + @Binding var isOpen : Bool @Binding var isParticapatedOpen: Bool - @State var bet: Bet? + var bet: Bet? var isDisabled: Bool { - let endRegisterDate: Date? = bet?.endRegisterDate - if endRegisterDate != nil{ - let currentDate = Date() + guard let endRegisterDate = bet?.endRegisterDate else { + return true + } + + let currentDate = Date() - switch currentDate.compare(endRegisterDate!) { - case .orderedAscending: - return false - case .orderedDescending: - return true - case .orderedSame: - return true - } - - } else { + switch currentDate.compare(endRegisterDate) { + case .orderedAscending: + return false + case .orderedDescending, .orderedSame: return true } } @@ -43,7 +40,7 @@ struct ParticipateButton: View { .frame(maxWidth: .infinity).padding(10) .multilineTextAlignment(.center) .overlay { - switch isDisabled{ + switch isDisabled { case true: AllInColors.grey700Color.frame(width: 170) .mask( @@ -69,8 +66,6 @@ struct ParticipateButton: View { .overlay( RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1) ) - - }.disabled(isDisabled) } } diff --git a/Sources/AllInApp/AllIn/Components/ParticipationModal.swift b/Sources/AllInApp/AllIn/Components/ParticipationModal.swift index da30d02..04f33a3 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipationModal.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipationModal.swift @@ -8,29 +8,52 @@ import SwiftUI struct ParticipationModal: View { - @State private var selectedOption = 0 - @State private var mise: String = "" + + @Binding private var selectedOption: Int + @Binding private var mise: String + private var description: String + var participationAddedCallback: (() -> Void)? + + init(answer: Binding, mise: Binding, description: String, participationAddedCallback: (() -> Void)? = nil) { + self._selectedOption = answer + self._mise = mise + self.description = description + self.participationAddedCallback = participationAddedCallback + } + let options: [(Int, String, Float)] = [ (0, "OUI", 1.2), (1, "NON", 3.3), ] + var body: some View { VStack(alignment: .leading){ HStack{ Spacer() - Rectangle().foregroundStyle(AllInColors.grey800Color).frame(maxWidth: 80, maxHeight: 5).cornerRadius(999) + Rectangle() + .foregroundStyle(AllInColors.grey800Color) + .frame(maxWidth: 80, maxHeight: 5) + .cornerRadius(999) Spacer() - + }.padding(10) HStack{ - Text("Faites vos paris").font(.system(size: 18)).foregroundColor(AllInColors.blackTitleColor).fontWeight(.semibold) + Text("Faites vos paris") + .font(.system(size: 18)) + .foregroundColor(AllInColors.blackTitleColor) + .fontWeight(.semibold) Spacer() AllcoinsCounter(backgroundColor: AllInColors.purpleAccentColor, foregroundColor: AllInColors.whiteColor) } .padding(.leading, 15) VStack(alignment: .leading){ - Text("Emre va réussir son TP de CI/CD mercredi?").font(.system(size: 13)).foregroundColor(AllInColors.grey100Color).fontWeight(.light) + Text(description) + .font(.system(size: 13)) + .foregroundColor(AllInColors.grey100Color) + .fontWeight(.light) + DropDownAnswerMenu(selectedOption: $selectedOption, options: options) + TextField("",text: $mise, prompt: Text("Mise") .foregroundColor(AllInColors.lightGrey300Color) .font(.system(size: 14)) @@ -49,25 +72,41 @@ struct ParticipationModal: View { .stroke(AllInColors.delimiterGrey, lineWidth: 1) ) .padding(.bottom, 5) - + } .padding(15) Spacer() VStack{ HStack{ - Text("Gains possibles").font(.system(size: 13)).foregroundColor(AllInColors.blackTitleColor).fontWeight(.regular) + Text("Gains possibles") + .font(.system(size: 13)) + .foregroundColor(AllInColors.blackTitleColor) + .fontWeight(.regular) Spacer() - Text("231").font(.system(size: 13)).foregroundColor(AllInColors.blackTitleColor).fontWeight(.light) - }.padding(.top, 10).padding(.bottom, 0) + Text("231") + .font(.system(size: 13)) + .foregroundColor(AllInColors.blackTitleColor) + .fontWeight(.light) + } + .padding(.top, 10).padding(.bottom, 0) Button { - + participationAddedCallback?() } label: { - Text("Miser").font(.system(size: 23)).foregroundColor(AllInColors.whiteColor).fontWeight(.bold) - .frame(maxWidth: .infinity).padding(.vertical, 3) + Text("Miser") + .font(.system(size: 23)) + .foregroundColor(AllInColors.whiteColor) + .fontWeight(.bold) + .frame(maxWidth: .infinity) + .padding(.vertical, 3) } - .buttonStyle(.borderedProminent).tint(AllInColors.purpleAccentColor) - - }.padding(.horizontal, 10).background(AllInColors.whiteColor).border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) - }.background(AllInColors.underComponentBackgroundColor) + .buttonStyle(.borderedProminent) + .tint(AllInColors.purpleAccentColor) + + } + .padding(.horizontal, 10) + .background(AllInColors.whiteColor) + .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) + } + .background(AllInColors.underComponentBackgroundColor) } } diff --git a/Sources/AllInApp/AllIn/Services/AuthService.swift b/Sources/AllInApp/AllIn/Services/AuthService.swift index 3d2ab62..700fd21 100644 --- a/Sources/AllInApp/AllIn/Services/AuthService.swift +++ b/Sources/AllInApp/AllIn/Services/AuthService.swift @@ -153,4 +153,9 @@ class AuthService: IAuthService { DependencyInjection.shared.addSingleton(Manager.self, Manager(withBetDataManager: BetApiManager(withUserToken: token), withUserDataManager: UserApiManager(withUserToken: token))) } + public func logout() { + AppStateContainer.shared.authenticationRefresh = nil + AppStateContainer.shared.loggedState.connectedUser = false + } + } diff --git a/Sources/AllInApp/AllIn/Services/IAuthService.swift b/Sources/AllInApp/AllIn/Services/IAuthService.swift index cafd070..57c7050 100644 --- a/Sources/AllInApp/AllIn/Services/IAuthService.swift +++ b/Sources/AllInApp/AllIn/Services/IAuthService.swift @@ -11,4 +11,5 @@ protocol IAuthService { func login(login: String, password: String, completion : @escaping (Int)-> ()) func register(username: String, email: String, password: String, completion : @escaping (Int)-> ()) func refreshAuthentication() + func logout() } diff --git a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift index e6980e6..3615836 100644 --- a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift @@ -14,7 +14,9 @@ class DetailsViewModel: ObservableObject { @Inject var manager: Manager var id: String - + @Published var answer = 0 + @Published var mise: String = "" + @Published var betDetail: BetDetail? init(id: String) { @@ -27,4 +29,16 @@ class DetailsViewModel: ObservableObject { self.betDetail = bet } } + + func addParticipate() { + if let stake = Int(mise) { + var rep: String = "" + if answer == 0 { + rep = "Yes" + } else { + rep = "No" + } + manager.addParticipation(withId: id, withAnswer: rep, andStake: stake) + } + } } diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index 2afda06..2bd3322 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -6,6 +6,9 @@ struct DetailsView: View { @Binding var isModalPresented: Bool @Binding var isModalParticipated: Bool @State var progressValue: Float = 0.2 + var id: String + @StateObject private var viewModel: DetailsViewModel + var isFinished: Bool { viewModel.betDetail?.finalAnswer == nil ? false : true } @@ -13,13 +16,13 @@ struct DetailsView: View { var isDisabled: Bool { if let endRegisterDate = viewModel.betDetail?.bet.endRegisterDate { let currentDate = Date() - + switch currentDate.compare(endRegisterDate) { - case .orderedAscending: + case .orderedAscending: return false - case .orderedDescending: + case .orderedDescending: return true - case .orderedSame: + case .orderedSame: return true } @@ -31,13 +34,13 @@ struct DetailsView: View { var StatusValues: (String, Color) { if let endRegisterDate = viewModel.betDetail?.bet.endRegisterDate { let currentDate = Date() - + switch currentDate.compare(endRegisterDate) { - case .orderedAscending: + case .orderedAscending: return ("En cours...", AllInColors.purpleAccentColor) - case .orderedDescending: + case .orderedDescending: return ("En attente...",AllInColors.pink100) - case .orderedSame: + case .orderedSame: return ("Fin des inscriptions...",AllInColors.grey50Color) } @@ -45,11 +48,8 @@ struct DetailsView: View { return ("Statut indisponible", AllInColors.whiteColor) } } - - var id: String - @StateObject private var viewModel: DetailsViewModel - init(isModalPresented: Binding, isModalParticipated: Binding,id: String) { + init(isModalPresented: Binding, isModalParticipated: Binding, id: String) { self._isModalPresented = isModalPresented self._isModalParticipated = isModalParticipated self.id = id @@ -61,7 +61,11 @@ struct DetailsView: View { ZStack(alignment: .bottom) { VStack(alignment: .center) { HStack{ - Text(StatusValues.0).font(.system(size: 25)).fontWeight(.bold).padding(.bottom, 10).foregroundStyle(Color.black).opacity(0.4) + Text(StatusValues.0) + .font(.system(size: 25)) + .fontWeight(.bold).padding(.bottom, 10) + .foregroundStyle(Color.black) + .opacity(0.4) Spacer() Image("closeIcon") .resizable() @@ -75,6 +79,7 @@ struct DetailsView: View { .padding(.horizontal, 15) .background(StatusValues.1) .transition(.slideInFromBottom(yOffset:0)) + VStack(spacing: 0) { VStack(alignment: .leading,spacing: 5){ HStack{ @@ -107,18 +112,20 @@ struct DetailsView: View { .foregroundColor(AllInColors.grey800Color) TextCapsule(date: viewModel.betDetail?.bet.endBetDate ?? Date()) Spacer() - + } } .frame(width: .infinity) .padding(.all,15).padding(.vertical, 10) .background(AllInColors.componentBackgroundColor) .cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0) + if isFinished { ResultBanner() } VStack(alignment: .leading, spacing: 5) { - BetLineLoading(participations: viewModel.betDetail?.participations ?? []).padding(.vertical,15) + BetLineLoading(participations: viewModel.betDetail?.participations ?? []) + .padding(.vertical,15) Text("Liste des participants") .font(.system(size: 18)) .foregroundStyle(AllInColors.grey100Color) @@ -135,7 +142,7 @@ struct DetailsView: View { .background(AllInColors.underComponentBackgroundColor) .border(width: 1, edges: [.top], color: AllInColors.delimiterGrey) Spacer() - + } @@ -143,12 +150,15 @@ struct DetailsView: View { .background(AllInColors.componentBackgroundColor) .cornerRadius(15) - ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated,bet: viewModel.betDetail?.bet ).padding(10) - - + ParticipateButton(isOpen: $isModalPresented, isParticapatedOpen: $isModalParticipated, bet: viewModel.betDetail?.bet) + .padding(10) } .sheet(isPresented: $isModalParticipated) { - ParticipationModal().presentationDetents([.fraction(0.55)]) + ParticipationModal(answer: $viewModel.answer, mise: $viewModel.mise, description: viewModel.betDetail?.bet.phrase ?? "Not loaded", participationAddedCallback: { + viewModel.addParticipate() + isModalParticipated.toggle() + }) + .presentationDetents([.fraction(0.55)]) } .edgesIgnoringSafeArea(.bottom) } diff --git a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift index 0a4931c..555d852 100644 --- a/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift +++ b/Sources/Api/Sources/Api/Factory/FactoryApiBet.swift @@ -24,7 +24,7 @@ public class FactoryApiBet: FactoryBet { "endRegistration": formatZonedDateTime(dateTime: bet.endRegisterDate), "endBet": formatZonedDateTime(dateTime: bet.endBetDate), "isPrivate": String(bet.isPublic), - "response": [], + "response": ["Yes","No"], ] return json @@ -37,7 +37,7 @@ public class FactoryApiBet: FactoryBet { let date = formatter.date(from: dateString) return date } - + public func toBet(from json: [String: Any]) -> Bet? { guard let id = json["id"] as? String, let theme = json["theme"] as? String, @@ -76,6 +76,28 @@ public class FactoryApiBet: FactoryBet { return nil } - return BetDetail(bet: bet, answers: [], participations: []) + var participations: [Participation] = [] + + if let participationsJson = json["participations"] as? [[String: Any]], !participationsJson.isEmpty { + for participationJson in participationsJson { + if let participation = self.toParticipate(from: participationJson) { + participations.append(participation) + } + } + } + + return BetDetail(bet: bet, answers: [], participations: participations) + } + + public func toParticipate(from json: [String: Any]) -> Participation? { + guard let id = json["id"] as? String, + let betId = json["betId"] as? String, + let username = json["username"] as? String, + let answer = json["answer"] as? String, + let stake = json["stake"] as? Int else { + return nil + } + + return Participation(id: id, stake: stake, date: Date(), response: answer, user: User(username: username, email: "Email", nbCoins: 0, friends: []), betId: betId) } } diff --git a/Sources/Api/Sources/Api/UserApiManager.swift b/Sources/Api/Sources/Api/UserApiManager.swift index eecc76b..cea22c2 100644 --- a/Sources/Api/Sources/Api/UserApiManager.swift +++ b/Sources/Api/Sources/Api/UserApiManager.swift @@ -49,4 +49,27 @@ public struct UserApiManager: UserDataManager { public func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) { fatalError("Not implemented yet") } + + public func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int) { + let url = URL(string: allInApi + "participations/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] = [ + "betId": id, + "answer": answer, + "stake": stake + ] + + if let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []){ + URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in + print ("ALLIN : Add Participation") + if let httpResponse = response as? HTTPURLResponse { + print(httpResponse.statusCode) + } + }.resume() + } + } } diff --git a/Sources/Model/Sources/Model/Manager.swift b/Sources/Model/Sources/Model/Manager.swift index 06392df..cc4e25e 100644 --- a/Sources/Model/Sources/Model/Manager.swift +++ b/Sources/Model/Sources/Model/Manager.swift @@ -37,4 +37,8 @@ public struct Manager { completion(bets) } } + + public func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int) { + userDataManager.addParticipation(withId: id, withAnswer: answer, andStake: stake) + } } diff --git a/Sources/Model/Sources/Model/Participation.swift b/Sources/Model/Sources/Model/Participation.swift index f8e7058..c435ff9 100644 --- a/Sources/Model/Sources/Model/Participation.swift +++ b/Sources/Model/Sources/Model/Participation.swift @@ -10,7 +10,7 @@ import Foundation /// A class representing a user's participation in a bet. public class Participation: ObservableObject, Identifiable { - public let id: UUID + public let id: String /// The amount of stake in the bet. public private(set) var stake: Int @@ -34,12 +34,12 @@ public class Participation: ObservableObject, Identifiable { /// - response: The response or outcome of the participation. /// - user: The user who participated in the bet. /// - betId: The unique identifier of the bet. - public init(stake: Int, date: Date, response: String, user: User, betId: String) { + public init(id: String, stake: Int, date: Date, response: String, user: User, betId: String) { + self.id = id self.stake = stake self.date = date self.response = response self.user = user self.betId = betId - self.id = UUID() } } diff --git a/Sources/Model/Sources/Model/UserDataManager.swift b/Sources/Model/Sources/Model/UserDataManager.swift index 487cad9..87eb2a6 100644 --- a/Sources/Model/Sources/Model/UserDataManager.swift +++ b/Sources/Model/Sources/Model/UserDataManager.swift @@ -12,4 +12,5 @@ public protocol UserDataManager { func addBet(bet: Bet) func getFriends() -> [User] func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void) + func addParticipation(withId id: String, withAnswer answer: String, andStake stake: Int) } diff --git a/Sources/StubLib/Sources/StubLib/Stub.swift b/Sources/StubLib/Sources/StubLib/Stub.swift index 09618bf..5371b6c 100644 --- a/Sources/StubLib/Sources/StubLib/Stub.swift +++ b/Sources/StubLib/Sources/StubLib/Stub.swift @@ -89,10 +89,10 @@ struct Stub { self.betsDetail.append(betDetail) } - self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 120, date: Date(), response: "OUI", user: user1, betId: "1")) - self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 20, date: Date(), response: "NON", user: user2, betId: "2")) - self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 320, date: Date(), response: "OUI", user: user3, betId: "3")) - self.betsDetail[0].addParticipation(newParticipation: Participation(stake: 320, date: Date(), response: "OUI", user: user3, betId: "3")) + self.betsDetail[0].addParticipation(newParticipation: Participation(id: UUID().uuidString, stake: 120, date: Date(), response: "OUI", user: user1, betId: "1")) + self.betsDetail[0].addParticipation(newParticipation: Participation(id: UUID().uuidString, stake: 20, date: Date(), response: "NON", user: user2, betId: "2")) + self.betsDetail[0].addParticipation(newParticipation: Participation(id: UUID().uuidString, stake: 320, date: Date(), response: "OUI", user: user3, betId: "3")) + self.betsDetail[0].addParticipation(newParticipation: Participation(id: UUID().uuidString, stake: 320, date: Date(), response: "OUI", user: user3, betId: "3")) } -- 2.36.3