From 5cf7e4c4a1654f54e13ca0c186a37bd702f432c4 Mon Sep 17 00:00:00 2001 From: DJYohann Date: Wed, 21 Jun 2023 10:27:02 +0200 Subject: [PATCH] :sparkles: Add few things --- src/App/App.xcodeproj/project.pbxproj | 57 +++++++----- .../xcschemes/xcschememanagement.plist | 2 +- src/App/App/AppApp.swift | 11 +-- src/App/App/ContentView.swift | 24 ++++-- src/App/Views/BlocListItem.swift | 26 +++--- src/App/Views/CalculatorView.swift | 21 ----- src/App/Views/Exemple.swift | 23 +++++ src/App/Views/MatiereInfo.swift | 33 +++++++ ...teSlider.swift => MatiereNoteSlider.swift} | 35 ++++---- src/App/Views/NoteInfo.swift | 28 ------ src/App/Views/UEEdit.swift | 81 ++++++++++++++++++ src/App/Views/UEEditSheet.swift | 29 ------- src/App/Views/UEInfo.swift | 28 ++++++ src/App/Views/UEListItem.swift | 62 ++++---------- src/App/Views/UENoteSlider.swift | 43 ++++++++++ src/App/Views/UEView.swift | 57 ++++++------ .../UserInterfaceState.xcuserstate | Bin 67977 -> 95321 bytes src/Model/Sources/Model/Bloc.swift | 12 +++ src/Model/Sources/Model/DataManager.swift | 7 ++ src/Model/Sources/Model/Manager.swift | 5 -- src/Model/Sources/Model/Odin.swift | 21 +++++ src/Model/Sources/Model/UE.swift | 12 +++ src/Stub/Sources/Stub/Stub.swift | 50 ++++++----- .../Sources/ViewModel/ArrayExtension.swift | 11 +++ src/ViewModel/Sources/ViewModel/BlocVM.swift | 36 +++++--- .../Sources/ViewModel/MatiereVM.swift | 38 ++++++-- src/ViewModel/Sources/ViewModel/OdinVM.swift | 15 ++++ src/ViewModel/Sources/ViewModel/UEVM.swift | 62 +++++++++++--- 28 files changed, 548 insertions(+), 281 deletions(-) delete mode 100644 src/App/Views/CalculatorView.swift create mode 100644 src/App/Views/Exemple.swift create mode 100644 src/App/Views/MatiereInfo.swift rename src/App/Views/{NoteSlider.swift => MatiereNoteSlider.swift} (59%) delete mode 100644 src/App/Views/NoteInfo.swift create mode 100644 src/App/Views/UEEdit.swift delete mode 100644 src/App/Views/UEEditSheet.swift create mode 100644 src/App/Views/UEInfo.swift create mode 100644 src/App/Views/UENoteSlider.swift create mode 100644 src/Model/Sources/Model/DataManager.swift delete mode 100644 src/Model/Sources/Model/Manager.swift create mode 100644 src/Model/Sources/Model/Odin.swift create mode 100644 src/ViewModel/Sources/ViewModel/ArrayExtension.swift create mode 100644 src/ViewModel/Sources/ViewModel/OdinVM.swift diff --git a/src/App/App.xcodeproj/project.pbxproj b/src/App/App.xcodeproj/project.pbxproj index 22cfc71..27c34a6 100644 --- a/src/App/App.xcodeproj/project.pbxproj +++ b/src/App/App.xcodeproj/project.pbxproj @@ -14,14 +14,17 @@ 1E0D88F42A1E759F00786FE3 /* AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D88F32A1E759F00786FE3 /* AppTests.swift */; }; 1E0D88FE2A1E75A000786FE3 /* AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D88FD2A1E75A000786FE3 /* AppUITests.swift */; }; 1E0D89002A1E75A000786FE3 /* AppUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D88FF2A1E75A000786FE3 /* AppUITestsLaunchTests.swift */; }; - 1E0D890F2A1E7B9C00786FE3 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = 1E0D890E2A1E7B9C00786FE3 /* Model */; }; - 1E0D89132A1E7C4500786FE3 /* CalculatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D89122A1E7C4500786FE3 /* CalculatorView.swift */; }; 1E0D89152A1E7F5800786FE3 /* BlocListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D89142A1E7F5800786FE3 /* BlocListItem.swift */; }; 1E0D89172A1E838700786FE3 /* UEListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D89162A1E838700786FE3 /* UEListItem.swift */; }; 1E0D891B2A1E9BEF00786FE3 /* UEView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0D891A2A1E9BEF00786FE3 /* UEView.swift */; }; - 1E160AB22A1FA51600ECDB3F /* NoteSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E160AB12A1FA51600ECDB3F /* NoteSlider.swift */; }; - 1E4D71792A29E50A008342F0 /* UEEditSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4D71782A29E50A008342F0 /* UEEditSheet.swift */; }; - 1EDC99232A20DDAB00C3561D /* NoteInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EDC99222A20DDAB00C3561D /* NoteInfo.swift */; }; + 1E160AB22A1FA51600ECDB3F /* UENoteSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E160AB12A1FA51600ECDB3F /* UENoteSlider.swift */; }; + 1E1FF22F2A3221BB0046EBE0 /* Stub in Frameworks */ = {isa = PBXBuildFile; productRef = 1E1FF22E2A3221BB0046EBE0 /* Stub */; }; + 1E47C4572A3605E3000B9AAA /* MatiereInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E47C4562A3605E3000B9AAA /* MatiereInfo.swift */; }; + 1E4D71792A29E50A008342F0 /* UEEdit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4D71782A29E50A008342F0 /* UEEdit.swift */; }; + 1E96424E2A3DFD0100199C75 /* Exemple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E96424D2A3DFD0000199C75 /* Exemple.swift */; }; + 1EC2337A2A35BCB9006AE897 /* ViewModel in Frameworks */ = {isa = PBXBuildFile; productRef = 1EC233792A35BCB9006AE897 /* ViewModel */; }; + 1ECAD3A12A38FB0B00B61BF8 /* MatiereNoteSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ECAD3A02A38FB0B00B61BF8 /* MatiereNoteSlider.swift */; }; + 1EDC99232A20DDAB00C3561D /* UEInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EDC99222A20DDAB00C3561D /* UEInfo.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -52,13 +55,15 @@ 1E0D88F92A1E759F00786FE3 /* AppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1E0D88FD2A1E75A000786FE3 /* AppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUITests.swift; sourceTree = ""; }; 1E0D88FF2A1E75A000786FE3 /* AppUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUITestsLaunchTests.swift; sourceTree = ""; }; - 1E0D89122A1E7C4500786FE3 /* CalculatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorView.swift; sourceTree = ""; }; 1E0D89142A1E7F5800786FE3 /* BlocListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocListItem.swift; sourceTree = ""; }; 1E0D89162A1E838700786FE3 /* UEListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UEListItem.swift; sourceTree = ""; }; 1E0D891A2A1E9BEF00786FE3 /* UEView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UEView.swift; sourceTree = ""; }; - 1E160AB12A1FA51600ECDB3F /* NoteSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteSlider.swift; sourceTree = ""; }; - 1E4D71782A29E50A008342F0 /* UEEditSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UEEditSheet.swift; sourceTree = ""; }; - 1EDC99222A20DDAB00C3561D /* NoteInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteInfo.swift; sourceTree = ""; }; + 1E160AB12A1FA51600ECDB3F /* UENoteSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UENoteSlider.swift; sourceTree = ""; }; + 1E47C4562A3605E3000B9AAA /* MatiereInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatiereInfo.swift; sourceTree = ""; }; + 1E4D71782A29E50A008342F0 /* UEEdit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UEEdit.swift; sourceTree = ""; }; + 1E96424D2A3DFD0000199C75 /* Exemple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exemple.swift; sourceTree = ""; }; + 1ECAD3A02A38FB0B00B61BF8 /* MatiereNoteSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatiereNoteSlider.swift; sourceTree = ""; }; + 1EDC99222A20DDAB00C3561D /* UEInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UEInfo.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -66,7 +71,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1E0D890F2A1E7B9C00786FE3 /* Model in Frameworks */, + 1E1FF22F2A3221BB0046EBE0 /* Stub in Frameworks */, + 1EC2337A2A35BCB9006AE897 /* ViewModel in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -155,13 +161,15 @@ 1E0D89112A1E7C0800786FE3 /* Views */ = { isa = PBXGroup; children = ( - 1E0D89122A1E7C4500786FE3 /* CalculatorView.swift */, 1E0D89142A1E7F5800786FE3 /* BlocListItem.swift */, 1E0D89162A1E838700786FE3 /* UEListItem.swift */, 1E0D891A2A1E9BEF00786FE3 /* UEView.swift */, - 1E160AB12A1FA51600ECDB3F /* NoteSlider.swift */, - 1EDC99222A20DDAB00C3561D /* NoteInfo.swift */, - 1E4D71782A29E50A008342F0 /* UEEditSheet.swift */, + 1E160AB12A1FA51600ECDB3F /* UENoteSlider.swift */, + 1EDC99222A20DDAB00C3561D /* UEInfo.swift */, + 1E4D71782A29E50A008342F0 /* UEEdit.swift */, + 1E47C4562A3605E3000B9AAA /* MatiereInfo.swift */, + 1ECAD3A02A38FB0B00B61BF8 /* MatiereNoteSlider.swift */, + 1E96424D2A3DFD0000199C75 /* Exemple.swift */, ); path = Views; sourceTree = ""; @@ -183,7 +191,8 @@ ); name = App; packageProductDependencies = ( - 1E0D890E2A1E7B9C00786FE3 /* Model */, + 1E1FF22E2A3221BB0046EBE0 /* Stub */, + 1EC233792A35BCB9006AE897 /* ViewModel */, ); productName = App; productReference = 1E0D88DF2A1E759A00786FE3 /* AverageCalculator.app */; @@ -299,14 +308,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1E160AB22A1FA51600ECDB3F /* NoteSlider.swift in Sources */, + 1ECAD3A12A38FB0B00B61BF8 /* MatiereNoteSlider.swift in Sources */, + 1E160AB22A1FA51600ECDB3F /* UENoteSlider.swift in Sources */, + 1E47C4572A3605E3000B9AAA /* MatiereInfo.swift in Sources */, 1E0D89152A1E7F5800786FE3 /* BlocListItem.swift in Sources */, 1E0D88E52A1E759A00786FE3 /* ContentView.swift in Sources */, - 1E0D89132A1E7C4500786FE3 /* CalculatorView.swift in Sources */, 1E0D88E32A1E759A00786FE3 /* AppApp.swift in Sources */, - 1EDC99232A20DDAB00C3561D /* NoteInfo.swift in Sources */, + 1EDC99232A20DDAB00C3561D /* UEInfo.swift in Sources */, 1E0D891B2A1E9BEF00786FE3 /* UEView.swift in Sources */, - 1E4D71792A29E50A008342F0 /* UEEditSheet.swift in Sources */, + 1E96424E2A3DFD0100199C75 /* Exemple.swift in Sources */, + 1E4D71792A29E50A008342F0 /* UEEdit.swift in Sources */, 1E0D89172A1E838700786FE3 /* UEListItem.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -630,9 +641,13 @@ /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ - 1E0D890E2A1E7B9C00786FE3 /* Model */ = { + 1E1FF22E2A3221BB0046EBE0 /* Stub */ = { isa = XCSwiftPackageProductDependency; - productName = Model; + productName = Stub; + }; + 1EC233792A35BCB9006AE897 /* ViewModel */ = { + isa = XCSwiftPackageProductDependency; + productName = ViewModel; }; /* End XCSwiftPackageProductDependency section */ }; diff --git a/src/App/App.xcodeproj/xcuserdata/djyohann.xcuserdatad/xcschemes/xcschememanagement.plist b/src/App/App.xcodeproj/xcuserdata/djyohann.xcuserdatad/xcschemes/xcschememanagement.plist index 74c9b79..b04f406 100644 --- a/src/App/App.xcodeproj/xcuserdata/djyohann.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/src/App/App.xcodeproj/xcuserdata/djyohann.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ App.xcscheme_^#shared#^_ orderHint - 3 + 0 diff --git a/src/App/App/AppApp.swift b/src/App/App/AppApp.swift index 448d169..efe67fd 100644 --- a/src/App/App/AppApp.swift +++ b/src/App/App/AppApp.swift @@ -1,17 +1,12 @@ -// -// AppApp.swift -// App -// -// Created by BREUIL Yohann on 24/05/2023. -// - import SwiftUI +import ViewModel +import Stub @main struct AppApp: App { var body: some Scene { WindowGroup { - ContentView() + ContentView(odin: OdinVM(blocs: Stub().loadBlocs())) } } } diff --git a/src/App/App/ContentView.swift b/src/App/App/ContentView.swift index 749c06f..058a4d5 100644 --- a/src/App/App/ContentView.swift +++ b/src/App/App/ContentView.swift @@ -1,20 +1,26 @@ -// -// ContentView.swift -// App -// -// Created by BREUIL Yohann on 24/05/2023. -// - import SwiftUI +import ViewModel +import Stub struct ContentView: View { + @StateObject var odin: OdinVM + var body: some View { - CalculatorView() + NavigationStack { + ScrollView { + BlocListItem(odin: odin) + Divider() + UEListItem(odin: odin) + } + .navigationTitle("Calculette") + } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { - ContentView() + let odinVM = OdinVM(blocs: Stub().loadBlocs()) + + ContentView(odin: odinVM) } } diff --git a/src/App/Views/BlocListItem.swift b/src/App/Views/BlocListItem.swift index c57f9f5..56d23ab 100644 --- a/src/App/Views/BlocListItem.swift +++ b/src/App/Views/BlocListItem.swift @@ -1,22 +1,22 @@ import SwiftUI +import Stub +import ViewModel struct BlocListItem: View { + @StateObject var odin: OdinVM + var body: some View { VStack(alignment: .leading) { Label("Blocs", systemImage: "doc.on.doc.fill") .font(.title) Text("Vous devez avoir la moyenne à chacun de ces blocs pour avoir votre diplôme.") - HStack { - Label("Total", systemImage: "doc.on.doc.fill") - Spacer() - Text("11.67") - Image(systemName: "graduationcap.circle.fill") - } - HStack { - Label("Total", systemImage: "doc.on.doc.fill") - Spacer() - Text("11.67") - Image(systemName: "graduationcap.circle.fill") + ForEach(odin.blocsVM) { blocVM in + HStack { + Label("\(blocVM.name)", systemImage: "doc.on.doc.fill") + Spacer() + Text("\(String(format: "%.2f", blocVM.average))") + Image(systemName: "graduationcap.circle.fill") + } } } .padding() @@ -27,6 +27,8 @@ struct BlocListItem: View { struct BlocListItem_Previews: PreviewProvider { static var previews: some View { - BlocListItem() + let odinVM = OdinVM(blocs: Stub().loadBlocs()) + + BlocListItem(odin: odinVM) } } diff --git a/src/App/Views/CalculatorView.swift b/src/App/Views/CalculatorView.swift deleted file mode 100644 index 39c9efb..0000000 --- a/src/App/Views/CalculatorView.swift +++ /dev/null @@ -1,21 +0,0 @@ -import SwiftUI - -struct CalculatorView: View { - var body: some View { - NavigationStack { - ScrollView { - BlocListItem() - Divider() - UEListItem() - } - .navigationTitle("Calculette") - } - - } -} - -struct CalculatorView_Previews: PreviewProvider { - static var previews: some View { - CalculatorView() - } -} diff --git a/src/App/Views/Exemple.swift b/src/App/Views/Exemple.swift new file mode 100644 index 0000000..5b85c17 --- /dev/null +++ b/src/App/Views/Exemple.swift @@ -0,0 +1,23 @@ +// +// Exemple.swift +// App +// +// Created by BREUIL Yohann on 17/06/2023. +// + +import SwiftUI + +struct Exemple: View { + var body: some View { + @State var number = 100 + Form{ + TextField("inputNumber",value:$number,format: .number) + } + } +} + +struct Exemple_Previews: PreviewProvider { + static var previews: some View { + Exemple() + } +} diff --git a/src/App/Views/MatiereInfo.swift b/src/App/Views/MatiereInfo.swift new file mode 100644 index 0000000..b651312 --- /dev/null +++ b/src/App/Views/MatiereInfo.swift @@ -0,0 +1,33 @@ +import Foundation + +import SwiftUI +import Stub +import ViewModel + +struct MatiereInfo: View { + @StateObject var matiereVM: MatiereVM + + var canEdit: Bool + + var body: some View { + VStack { + HStack() { + Text("\(matiereVM.name)") + Spacer() + Text("\(matiereVM.factor)") + } + MatiereNoteSlider(matiereVM: matiereVM, canEdit: canEdit) + Divider() + } + } +} + +struct MatiereInfo_Previews: PreviewProvider { + static var previews: some View { + let odin = OdinVM(blocs: Stub().loadBlocs()) + let matiereVM = odin.blocsVM[0].uesVM[0].matieresVM[0] + + MatiereInfo(matiereVM: matiereVM, canEdit: true) + //NoteInfo(canEdit: false) + } +} diff --git a/src/App/Views/NoteSlider.swift b/src/App/Views/MatiereNoteSlider.swift similarity index 59% rename from src/App/Views/NoteSlider.swift rename to src/App/Views/MatiereNoteSlider.swift index e6399d8..cadd88f 100644 --- a/src/App/Views/NoteSlider.swift +++ b/src/App/Views/MatiereNoteSlider.swift @@ -1,13 +1,10 @@ -// -// NoteSliderComponent.swift -// App -// -// Created by BREUIL Yohann on 25/05/2023. -// - import SwiftUI +import Stub +import ViewModel -struct NoteSlider: View { +struct MatiereNoteSlider: View { + @ObservedObject var matiereVM: MatiereVM + @State private var sliderProgress: CGFloat = 0 @State private var sliderWidth: CGFloat = 20 @State private var sliderMaxWidth: CGFloat = 200 @@ -22,8 +19,10 @@ struct NoteSlider: View { sliderWidth = sliderWidth > sliderMaxWidth ? sliderMaxWidth : sliderWidth sliderWidth = sliderWidth >= 0 ? sliderWidth : 20 - let progress = sliderWidth / sliderMaxWidth - sliderProgress = progress <= 1.0 ? progress : 1 + let progress = sliderWidth / sliderMaxWidth * 20 + sliderProgress = progress <= 20 ? progress : 1 + + matiereVM.note = Float(sliderProgress) } .onEnded { value in sliderWidth = sliderWidth > sliderMaxWidth ? sliderMaxWidth : sliderWidth @@ -33,22 +32,26 @@ struct NoteSlider: View { } } + var canEdit: Bool + var body: some View { HStack { Rectangle() - .fill(sliderProgress < 0.5 ? Color("BadColor") : Color("GoodColor")) + .fill(sliderProgress < 10 ? Color("BadColor") : Color("GoodColor")) .frame(width: sliderWidth, height: 25) .clipShape(Capsule()) - .gesture(drag) + .gesture(drag, including: canEdit ? .gesture : .none) Spacer() - Text("\(sliderProgress)") + Text("\(String(format: "%.2f", matiereVM.note))") } - .padding() } } -struct NoteSliderComponent_Previews: PreviewProvider { +struct MatiereNoteSlider_Previews: PreviewProvider { static var previews: some View { - NoteSlider() + let odin = OdinVM(blocs: Stub().loadBlocs()) + let matierevM = odin.blocsVM[0].uesVM[0].matieresVM[0] + + MatiereNoteSlider(matiereVM: matierevM, canEdit: true) } } diff --git a/src/App/Views/NoteInfo.swift b/src/App/Views/NoteInfo.swift deleted file mode 100644 index a7acdf4..0000000 --- a/src/App/Views/NoteInfo.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// NoteInfo.swift -// App -// -// Created by BREUIL Yohann on 26/05/2023. -// - -import SwiftUI - -struct NoteInfo: View { - var body: some View { - VStack { - HStack() { - Text("Qualité de Développement") - Spacer() - Text("6") - } - NoteSlider() - Divider() - } - } -} - -struct NoteInfo_Previews: PreviewProvider { - static var previews: some View { - NoteInfo() - } -} diff --git a/src/App/Views/UEEdit.swift b/src/App/Views/UEEdit.swift new file mode 100644 index 0000000..5521e45 --- /dev/null +++ b/src/App/Views/UEEdit.swift @@ -0,0 +1,81 @@ +import SwiftUI +import ViewModel +import Stub + +struct UEEdit: View { + @ObservedObject var ueEditVM : UEVM + + @State var newMatiereName = "" + + @State var number: Int32 = 2 + + var body: some View { + NavigationStack { + Form { + Section(header: Text("UE\(String(ueEditVM.number))")) { + VStack(alignment: .leading) { + Text("Nom").font(.headline) + TextField("Nom", text: $ueEditVM.name) + } + + VStack(alignment: .leading) { + Text("Coefficient").font(.headline) + TextField("Coefficient",value: $ueEditVM.factor, format: .number) + .keyboardType(.numberPad) + } + } + + Section(header: Text("Matières")) { + ForEach($ueEditVM.matieresVM) { $matiereVM in + VStack { + TextField("Nom", text: $matiereVM.name) + TextField("Coeeficient", value: $matiereVM.factor, format: .number) + .keyboardType(.numberPad) + } + + .swipeActions(edge:.trailing){ + Button(role: .destructive) { + + } label: { + Label("Delete", systemImage: "trash") + } + } + } + HStack { + TextField("Nouvelle matière", text: $newMatiereName) + Button(action: {}) { + Image(systemName: "plus.circle.fill") + } + } + } + } + .navigationBarTitleDisplayMode(.inline) + .navigationTitle("UE\(String(ueEditVM.number))") + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button(action: { + ueEditVM.onEdited(isCancelled: true) + }) { + Text("Cancel") + } + } + ToolbarItem(placement: .confirmationAction) { + Button(action: { + ueEditVM.onEdited() + }) { + Text("Done") + } + } + } + } + } +} + +struct UEEdit_Previews: PreviewProvider { + static var previews: some View { + let odin = OdinVM(blocs: Stub().loadBlocs()) + let ueVM = odin.blocsVM[0].uesVM[0] + + UEEdit(ueEditVM: ueVM) + } +} diff --git a/src/App/Views/UEEditSheet.swift b/src/App/Views/UEEditSheet.swift deleted file mode 100644 index 1b0ca10..0000000 --- a/src/App/Views/UEEditSheet.swift +++ /dev/null @@ -1,29 +0,0 @@ -import SwiftUI - -struct UEEditSheet: View { - var body: some View { - NavigationStack { - VStack { - Text("SALUT") - } - .toolbar { - ToolbarItem(placement: .cancellationAction) { - Button(action: {}) { - Text("Cancel") - } - } - ToolbarItem(placement: .confirmationAction) { - Button(action: {}) { - Text("Save") - } - } - } - } - } -} - -struct UEEditSheet_Previews: PreviewProvider { - static var previews: some View { - UEEditSheet() - } -} diff --git a/src/App/Views/UEInfo.swift b/src/App/Views/UEInfo.swift new file mode 100644 index 0000000..3cea761 --- /dev/null +++ b/src/App/Views/UEInfo.swift @@ -0,0 +1,28 @@ +import SwiftUI +import Stub +import ViewModel + +struct UEInfo: View { + @StateObject var ueVM: UEVM + + var body: some View { + VStack { + HStack() { + Text("UE\(ueVM.number) \(ueVM.name)") + Spacer() + Text("\(ueVM.factor)") + } + UENoteSlider(ueVM: ueVM) + Divider() + } + } +} + +struct UEInfo_Previews: PreviewProvider { + static var previews: some View { + let odin = OdinVM(blocs: Stub().loadBlocs()) + let ueVM = odin.blocsVM[0].uesVM[0] + + UEInfo(ueVM: ueVM) + } +} diff --git a/src/App/Views/UEListItem.swift b/src/App/Views/UEListItem.swift index 684574e..231101f 100644 --- a/src/App/Views/UEListItem.swift +++ b/src/App/Views/UEListItem.swift @@ -1,13 +1,10 @@ -// -// UEListItem.swift -// App -// -// Created by BREUIL Yohann on 24/05/2023. -// - import SwiftUI +import Stub +import ViewModel struct UEListItem: View { + @StateObject var odin: OdinVM + var body: some View { NavigationStack { VStack(alignment: .leading) { @@ -15,46 +12,17 @@ struct UEListItem: View { .font(.title) Text("Détails des UEs") LazyVStack { - HStack { - NoteInfo() - NavigationLink(destination: UEView()) { - Image(systemName: "square.and.pencil") - } - Divider() - } - .padding() - HStack { - NoteInfo() - NavigationLink(destination: UEView()) { - Image(systemName: "square.and.pencil") - } - Divider() - } - .padding() - HStack { - NoteInfo() - NavigationLink(destination: UEView()) { - Image(systemName: "square.and.pencil") - } - Divider() - } - .padding() - HStack { - NoteInfo() - NavigationLink(destination: UEView()) { - Image(systemName: "square.and.pencil") - } - Divider() - } - .padding() - HStack { - NoteInfo() - NavigationLink(destination: UEView()) { - Image(systemName: "square.and.pencil") + ForEach(odin.blocsVM) { blocVM in + ForEach(blocVM.uesVM) { ueVM in + HStack { + UEInfo(ueVM: ueVM) + NavigationLink(destination: UEView(ueVM: ueVM)) { + Image(systemName: "square.and.pencil") + } + Divider() + } } - Divider() } - .padding() } } .padding() @@ -66,6 +34,8 @@ struct UEListItem: View { struct UEListItem_Previews: PreviewProvider { static var previews: some View { - UEListItem() + let odinVM = OdinVM(blocs: Stub().loadBlocs()) + + UEListItem(odin: odinVM) } } diff --git a/src/App/Views/UENoteSlider.swift b/src/App/Views/UENoteSlider.swift new file mode 100644 index 0000000..260a31e --- /dev/null +++ b/src/App/Views/UENoteSlider.swift @@ -0,0 +1,43 @@ +import SwiftUI +import Stub +import ViewModel + +struct UENoteSlider: View { + @StateObject var ueVM: UEVM + + @State private var sliderProgress: CGFloat = 0 + @State private var sliderWidth: CGFloat = 20 + @State private var sliderMaxWidth: CGFloat = 220 + @State private var sliderCurrentWidth: CGFloat = 0 + + var drag: some Gesture { + DragGesture() + .onEnded { _ in + sliderWidth = sliderWidth > sliderMaxWidth ? sliderMaxWidth : sliderWidth + sliderWidth = sliderWidth >= 0 ? sliderWidth : 20 + + sliderCurrentWidth = sliderWidth + } + } + + var body: some View { + HStack { + Rectangle() + .fill(ueVM.average < 10 ? Color("BadColor") : Color("GoodColor")) + .frame(width: CGFloat(ueVM.average) * 10, height: 25) + .clipShape(Capsule()) + .gesture(drag, including: .none) + Spacer() + Text("\(String(format: "%.2f", ueVM.average))") + } + } +} + +struct UENoteSlider_Previews: PreviewProvider { + static var previews: some View { + let odin = OdinVM(blocs: Stub().loadBlocs()) + let ueVM = odin.blocsVM[0].uesVM[0] + + UENoteSlider(ueVM: ueVM) + } +} diff --git a/src/App/Views/UEView.swift b/src/App/Views/UEView.swift index 1cc57f7..02b855e 100644 --- a/src/App/Views/UEView.swift +++ b/src/App/Views/UEView.swift @@ -1,64 +1,59 @@ import SwiftUI +import Stub +import ViewModel struct UEView: View { - @State private var showingSheet = false + @StateObject var ueVM: UEVM + + @State private var canEditNote = false var body: some View { NavigationStack { ScrollView { - NoteInfo() + UEInfo(ueVM: ueVM) VStack(alignment: .leading) { - Label("Coefficcient : 6", systemImage: "xmark.circle.fill") + Label("Coefficcient : \(ueVM.factor)", systemImage: "xmark.circle.fill") Label("Détails des notes ", systemImage: "note.text") } + .padding() + LazyVStack { - HStack { - Button(action: {}) { - Image(systemName: "lock") - } - NoteInfo() - } - HStack { - Button(action: {}) { - Image(systemName: "lock") - } - NoteInfo() - } - HStack { - Button(action: {}) { - Image(systemName: "lock") - } - NoteInfo() - } - HStack { - Button(action: {}) { - Image(systemName: "lock") + ForEach(ueVM.matieresVM) { matiereVM in + HStack { + Button(action: { + canEditNote.toggle() + }) { + Image(systemName: canEditNote ? "lock.open" : "lock") + } + MatiereInfo(matiereVM: matiereVM, canEdit: canEditNote) } - NoteInfo() } } } .padding() - .navigationTitle("UE1 Génie logiciel") + .navigationTitle("UE\(ueVM.number) \(ueVM.name)") .toolbar { ToolbarItem { Button(action: { - showingSheet = true + ueVM.isEditing.toggle() }) { Text("Edit") } - .sheet(isPresented: $showingSheet) { - UEEditSheet() - } } } + .sheet(isPresented: $ueVM.isEditing) { + UEEdit(ueEditVM: ueVM) + } } } } struct UEView_Previews: PreviewProvider { static var previews: some View { - UEView() + let odin = OdinVM(blocs: Stub().loadBlocs()) + let ueVM = odin.blocsVM[0].uesVM[0] + + UEView(ueVM: ueVM) } } diff --git a/src/AverageCalculator.xcworkspace/xcuserdata/djyohann.xcuserdatad/UserInterfaceState.xcuserstate b/src/AverageCalculator.xcworkspace/xcuserdata/djyohann.xcuserdatad/UserInterfaceState.xcuserstate index 48904335846d040b0950566965358cce5947c5e5..1f5414d861418979ac75437618ef02d6cf5c7797 100644 GIT binary patch literal 95321 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

#XP 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

>Nk@XZ=Pf_nv`*9Yxz>J(?Moy9c6tzB0 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 C`|VZ$ literal 67977 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

ed?5n$Vikn$fze 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 R [Bloc] + + func saveBlocs(blocs: [Bloc]) -> Void +} diff --git a/src/Model/Sources/Model/Manager.swift b/src/Model/Sources/Model/Manager.swift deleted file mode 100644 index 249f60f..0000000 --- a/src/Model/Sources/Model/Manager.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Foundation - -struct Manager { - -} diff --git a/src/Model/Sources/Model/Odin.swift b/src/Model/Sources/Model/Odin.swift new file mode 100644 index 0000000..6d72258 --- /dev/null +++ b/src/Model/Sources/Model/Odin.swift @@ -0,0 +1,21 @@ +import Foundation + +public struct Odin { + let dataManager: DataManager + public var blocs: [Bloc] = [] + + public init(dataManager: DataManager) { + self.dataManager = dataManager + } + + public mutating func loadBlocs(){ + self.blocs.removeAll() + for bloc in self.dataManager.loadBlocs() { + self.blocs.append(bloc) + } + } + + public func saveBlocs() { + self.dataManager.saveBlocs(blocs: self.blocs) + } +} diff --git a/src/Model/Sources/Model/UE.swift b/src/Model/Sources/Model/UE.swift index 03585e2..93bce18 100644 --- a/src/Model/Sources/Model/UE.swift +++ b/src/Model/Sources/Model/UE.swift @@ -8,6 +8,18 @@ public struct UE: Identifiable, Equatable { public var factor: Int32 public var matieres: [Matiere] + public var average: Float { + var averages : Float = 0 + var factors: Float = 0 + + for matiere in matieres { + averages = averages + (matiere.note * Float(matiere.factor)) + factors = factors + Float(matiere.factor) + } + + return averages / factors + } + public init(id: UUID, number: Int32, name: String, factor: Int32, matieres: [Matiere]) { self.id = id self.number = number diff --git a/src/Stub/Sources/Stub/Stub.swift b/src/Stub/Sources/Stub/Stub.swift index 156688c..70b9e0a 100644 --- a/src/Stub/Sources/Stub/Stub.swift +++ b/src/Stub/Sources/Stub/Stub.swift @@ -1,11 +1,13 @@ import Model import Foundation -public struct Stub { +public struct Stub : DataManager { + public init() {} + public func loadBlocs() -> [Bloc] { var blocs: [Bloc] = [] - var bloc1 = Bloc(name: "Total", ues: [ + let bloc1 = Bloc(name: "Total", ues: [ UE(number: 1, name: "Génie logiciel", factor: 6, matieres: [ Matiere(name: "Processus de développement", factor: 4, note: 19.04), Matiere(name: "Programmation objets", factor: 9, note: 9.08), @@ -13,39 +15,39 @@ public struct Stub { Matiere(name: "Remise à niveau Objets", factor: 4, note: 12), ]), UE(number: 2, name: "Systèmes et réseaux", factor: 6, matieres: [ - Matiere(name: "Internet des Objets", factor: 4, note: 10), - Matiere(name: "Réseaux", factor: 4, note: 10), - Matiere(name: "Services Mobiles", factor: 4, note: 10), - Matiere(name: "Système", factor: 5, note: 10) + Matiere(name: "Internet des Objets", factor: 4, note: 9), + Matiere(name: "Réseaux", factor: 4, note: 8), + Matiere(name: "Services Mobiles", factor: 4, note: 7), + Matiere(name: "Système", factor: 5, note: 12) ]), UE(number: 3, name: "Insertion Professionnellle", factor: 6, matieres: [ - Matiere(name: "Anglais", factor: 5, note: 10), - Matiere(name: "Économie", factor: 4, note: 10), - Matiere(name: "Gestion", factor: 3, note: 10), - Matiere(name: "Communication", factor: 4, note: 10) + Matiere(name: "Anglais", factor: 5, note: 4), + Matiere(name: "Économie", factor: 4, note: 1), + Matiere(name: "Gestion", factor: 3, note: 1), + Matiere(name: "Communication", factor: 4, note: 14) ]), UE(number: 4, name: "Technologies Mobiles 1", factor: 9, matieres: [ - Matiere(name: "Android", factor: 6, note: 10), - Matiere(name: "Architecture de projets .NET (1)", factor: 5, note: 10), - Matiere(name: "C++", factor: 4, note: 10), - Matiere(name: "Swift", factor: 5, note: 10) + Matiere(name: "Android", factor: 6, note: 2), + Matiere(name: "Architecture de projets .NET (1)", factor: 5, note: 13), + Matiere(name: "C++", factor: 4, note: 8), + Matiere(name: "Swift", factor: 5, note: 8.5) ]), UE(number: 5, name: "Technologies Mobiles 2", factor: 9, matieres: [ - Matiere(name: "Architecture de projets .NET (2)", factor: 4, note: 10), - Matiere(name: "Client / Serveur", factor: 4, note: 10), - Matiere(name: "iOS", factor: 5, note: 10), - Matiere(name: "Multiplateformes", factor: 3, note: 10), - Matiere(name: "QT Quick", factor: 5, note: 10), + Matiere(name: "Architecture de projets .NET (2)", factor: 4, note: 12), + Matiere(name: "Client / Serveur", factor: 4, note: 17), + Matiere(name: "iOS", factor: 5, note: 20), + Matiere(name: "Multiplateformes", factor: 3, note: 15), + Matiere(name: "QT Quick", factor: 5, note: 1), Matiere(name: "Xamarin", factor: 5, note: 10) ]), ]) - var bloc2 = Bloc(name: "Projet / Stage", ues: [ + let bloc2 = Bloc(name: "Projet / Stage", ues: [ UE(number: 6, name: "Projet", factor: 9, matieres: [ - Matiere(name: "Projet", factor: 1, note: 10) + Matiere(name: "Projet", factor: 1, note: 12) ]), UE(number: 7, name: "Stage", factor: 15, matieres: [ - Matiere(name: "Stage", factor: 1, note: 10) + Matiere(name: "Stage", factor: 1, note: 15) ]) ]) @@ -54,5 +56,7 @@ public struct Stub { return blocs } - + public func saveBlocs(blocs: [Model.Bloc]) { + + } } diff --git a/src/ViewModel/Sources/ViewModel/ArrayExtension.swift b/src/ViewModel/Sources/ViewModel/ArrayExtension.swift new file mode 100644 index 0000000..d63d2fc --- /dev/null +++ b/src/ViewModel/Sources/ViewModel/ArrayExtension.swift @@ -0,0 +1,11 @@ +import Foundation + +extension Array where Element: Equatable { + func compare(to other: [Element]) -> Bool { + self.count == other.count && self.allSatisfy({ elt in + other.contains { otherElt in + otherElt == elt + } + }) + } +} diff --git a/src/ViewModel/Sources/ViewModel/BlocVM.swift b/src/ViewModel/Sources/ViewModel/BlocVM.swift index eeae83d..5c47f39 100644 --- a/src/ViewModel/Sources/ViewModel/BlocVM.swift +++ b/src/ViewModel/Sources/ViewModel/BlocVM.swift @@ -2,28 +2,30 @@ import Foundation import Model @available(iOS 13.0, *) -public class BlocVM : ObservableObject, Identifiable { +public class BlocVM : ObservableObject, Identifiable, Equatable { public init(model: Bloc) { self.model = model } public var id: UUID { model.id } - @Published - var model: Bloc = Bloc(id: UUID(), name: "", ues: []) { + @Published var model: Bloc = Bloc(id: UUID(), name: "", ues: []) { didSet { if self.name != model.name { self.name = self.model.name } - if self.ues != model.ues { - self.ues = self.model.ues + if !self.model.ues.compare(to: self.uesVM.map({$0.model})) { + self.uesVM = self.model.ues.map({UEVM(model: $0)}) + } + + if self.average != self.model.average { + self.average = self.model.average } } } - @Published - var name: String = "" { + @Published public var name: String = "" { didSet { if self.name != self.model.name { self.name = self.model.name @@ -31,12 +33,24 @@ public class BlocVM : ObservableObject, Identifiable { } } - @Published - var ues: [UE] = [] { + @Published public var uesVM: [UEVM] = [] { didSet { - if self.ues != self.model.ues { - self.ues = self.model.ues + let ues = self.uesVM.map({$0.model}) + if !self.model.ues.compare(to: ues) { + self.model.ues = uesVM.map({$0.model}) } } } + + @Published public var average: Float = 0 { + didSet { + if self.average != self.model.average { + self.average = self.model.average + } + } + } + + public static func == (lhs: BlocVM, rhs: BlocVM) -> Bool { + lhs.id == rhs.id + } } diff --git a/src/ViewModel/Sources/ViewModel/MatiereVM.swift b/src/ViewModel/Sources/ViewModel/MatiereVM.swift index b6d09d4..a1a1c84 100644 --- a/src/ViewModel/Sources/ViewModel/MatiereVM.swift +++ b/src/ViewModel/Sources/ViewModel/MatiereVM.swift @@ -2,11 +2,17 @@ import Foundation import Model @available(iOS 13.0, *) -class MatiereVM : ObservableObject, Identifiable { +public class MatiereVM : ObservableObject, Identifiable, Equatable { public init(model: Matiere) { self.model = model } + private var copy: MatiereVM { + MatiereVM(model: self.model) + } + + public var editedCopy: MatiereVM? + public var id: UUID { model.id } @Published @@ -26,8 +32,7 @@ class MatiereVM : ObservableObject, Identifiable { } } - @Published - var name: String = "" { + @Published public var name: String = "" { didSet { if model.name != self.model.name { self.name = self.model.name @@ -35,8 +40,7 @@ class MatiereVM : ObservableObject, Identifiable { } } - @Published - var factor: Int = 0 { + @Published public var factor: Int = 0 { didSet { if model.factor != self.model.factor { self.factor = self.model.factor @@ -44,12 +48,32 @@ class MatiereVM : ObservableObject, Identifiable { } } - @Published - var note: Float = 0 { + @Published public var note: Float = 0 { didSet { if model.note != self.model.note { self.note = self.model.note } } } + + @Published + public var isEditing: Bool = false + + func onEditing(){ + editedCopy = self.copy + isEditing = true + } + + func onEdited(isCancelled: Bool = false){ + if(!isCancelled){ + if let edit = editedCopy { + self.model = edit.model + } + } + isEditing = false + } + + public static func == (lhs: MatiereVM, rhs: MatiereVM) -> Bool { + lhs.id == rhs.id + } } diff --git a/src/ViewModel/Sources/ViewModel/OdinVM.swift b/src/ViewModel/Sources/ViewModel/OdinVM.swift new file mode 100644 index 0000000..76ef306 --- /dev/null +++ b/src/ViewModel/Sources/ViewModel/OdinVM.swift @@ -0,0 +1,15 @@ +import Foundation +import Model + +@available(iOS 13.0, *) +public class OdinVM: ObservableObject { + @Published public var blocsVM: [BlocVM] = [] + + public init(blocs: [Bloc]) { + self.blocsVM = blocs.map({BlocVM(model: $0)}) + } + + public init(blocsVM: [BlocVM]) { + self.blocsVM = blocsVM + } +} diff --git a/src/ViewModel/Sources/ViewModel/UEVM.swift b/src/ViewModel/Sources/ViewModel/UEVM.swift index 2ad4b6b..90988b8 100644 --- a/src/ViewModel/Sources/ViewModel/UEVM.swift +++ b/src/ViewModel/Sources/ViewModel/UEVM.swift @@ -2,11 +2,17 @@ import Foundation import Model @available(iOS 13.0, *) -public class UEVM : ObservableObject, Identifiable { +public class UEVM : ObservableObject, Identifiable, Equatable { public init(model: UE) { self.model = model } + private var copy: UEVM { + UEVM(model: self.model) + } + + public var editedCopy: UEVM? + public var id: UUID { model.id } @Published @@ -24,14 +30,17 @@ public class UEVM : ObservableObject, Identifiable { self.factor = self.model.factor } - if self.matieres != self.model.matieres { - self.matieres = self.model.matieres + if !self.model.matieres.compare(to: self.matieresVM.map({$0.model})) { + self.matieresVM = self.model.matieres.map({MatiereVM(model: $0)}) + } + + if self.average != self.model.average { + self.average = self.model.average } } } - @Published - var number: Int32 = 0 { + @Published public var number: Int32 = 0 { didSet { if model.number != self.model.number { self.number = self.model.number @@ -39,8 +48,7 @@ public class UEVM : ObservableObject, Identifiable { } } - @Published - var name: String = "" { + @Published public var name: String = "" { didSet { if model.name != self.model.name { self.name = self.model.name @@ -48,8 +56,7 @@ public class UEVM : ObservableObject, Identifiable { } } - @Published - var factor: Int32 = 0 { + @Published public var factor: Int32 = 0 { didSet { if model.factor != self.model.factor { self.factor = self.model.factor @@ -57,12 +64,41 @@ public class UEVM : ObservableObject, Identifiable { } } - @Published - var matieres: [Matiere] = [] { + @Published public var matieresVM: [MatiereVM] = [] { + didSet { + let matieres = self.matieresVM.map({$0.model}) + if !self.model.matieres.compare(to: matieres) { + self.model.matieres = matieresVM.map({$0.model}) + } + } + } + + @Published public var average: Float = 0 { didSet { - if model.matieres != self.model.matieres { - self.matieres = self.model.matieres + if self.average != self.model.average { + self.average = self.model.average + } + } + } + + @Published + public var isEditing: Bool = false + + public func onEditing(){ + editedCopy = self.copy + isEditing = true + } + + public func onEdited(isCancelled: Bool = false){ + if(!isCancelled) { + if let edit = editedCopy { + self.model = edit.model } } + isEditing = false + } + + public static func == (lhs: UEVM, rhs: UEVM) -> Bool { + lhs.id == rhs.id } }