From 5594ab54ca93798de44fa59810e1641d5a53e7ca Mon Sep 17 00:00:00 2001 From: Traton Gossink <79613749+TratonGossink@users.noreply.github.com> Date: Tue, 21 Nov 2023 10:11:20 -0600 Subject: [PATCH] - change button for vehicle edit. - add Observable to EditVehicleView. --- .../project.pbxproj | 8 ++ .../Shared/Localizable.xcstrings | 4 + .../Shared/Models/EditVehicleEvent.swift | 14 ++ .../ViewModels/SettingsViewModel.swift | 2 +- .../Settings/Views/EditVehicleView.swift | 120 +++++++++++++++++- .../Shared/Settings/Views/SettingsView.swift | 34 +++-- 6 files changed, 167 insertions(+), 15 deletions(-) diff --git a/Basic-Car-Maintenance.xcodeproj/project.pbxproj b/Basic-Car-Maintenance.xcodeproj/project.pbxproj index 2bcd6003..711d340e 100644 --- a/Basic-Car-Maintenance.xcodeproj/project.pbxproj +++ b/Basic-Car-Maintenance.xcodeproj/project.pbxproj @@ -23,9 +23,11 @@ 8A3D748C2AD9C41D0000FEEB /* AlertItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A3D748B2AD9C41D0000FEEB /* AlertItem.swift */; }; 8AEE816F2ACF37F800FC0C2A /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AEE816E2ACF37F800FC0C2A /* Action.swift */; }; 8AEE81722ACF384D00FC0C2A /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AEE81712ACF384D00FC0C2A /* MainTabView.swift */; }; + E55B630D2B079E5A006BDDDF /* EditVehicleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55B630C2B079E5A006BDDDF /* EditVehicleView.swift */; }; E58499662ACDDA8B00634660 /* ContributorsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58499652ACDDA8B00634660 /* ContributorsListView.swift */; }; E58499682ACDDA9A00634660 /* ContributorsProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58499672ACDDA9A00634660 /* ContributorsProfileView.swift */; }; E584996A2ACDDAFF00634660 /* Contributor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58499692ACDDAFF00634660 /* Contributor.swift */; }; + E5EDD11D2B0933700059C52E /* EditVehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5EDD11C2B0933700059C52E /* EditVehicleEvent.swift */; }; FF09FC912AB6FF44006BE61A /* AuthenticationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF09FC902AB6FF44006BE61A /* AuthenticationView.swift */; }; FF218EF62B00865F0025A533 /* AnalyticsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF218EF52B00865F0025A533 /* AnalyticsService.swift */; }; FF3DDF522AA4D28F009D91C4 /* DashboardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3DDF512AA4D28F009D91C4 /* DashboardViewModel.swift */; }; @@ -120,9 +122,11 @@ 8AEE816E2ACF37F800FC0C2A /* Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; 8AEE81712ACF384D00FC0C2A /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; 8AEE81732ACF394E00FC0C2A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E55B630C2B079E5A006BDDDF /* EditVehicleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditVehicleView.swift; sourceTree = ""; }; E58499652ACDDA8B00634660 /* ContributorsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorsListView.swift; sourceTree = ""; }; E58499672ACDDA9A00634660 /* ContributorsProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorsProfileView.swift; sourceTree = ""; }; E58499692ACDDAFF00634660 /* Contributor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contributor.swift; sourceTree = ""; }; + E5EDD11C2B0933700059C52E /* EditVehicleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditVehicleEvent.swift; sourceTree = ""; }; FF0813562AD0A83000910EFA /* UITests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UITests.xcconfig; sourceTree = ""; }; FF0813572AD0A92700910EFA /* Widget.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Widget.xcconfig; sourceTree = ""; }; FF098EFA2AB3424E003EC0FE /* Basic-Car-Maintenance.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Basic-Car-Maintenance.xcconfig"; sourceTree = SOURCE_ROOT; }; @@ -420,6 +424,7 @@ 8014A4CE2AD75928005B51F6 /* AppIcon.swift */, 57CDD9A32ADC320F002EFED0 /* OdometerReading.swift */, 8A3D748B2AD9C41D0000FEEB /* AlertItem.swift */, + E5EDD11C2B0933700059C52E /* EditVehicleEvent.swift */, ); path = Models; sourceTree = ""; @@ -433,6 +438,7 @@ E58499652ACDDA8B00634660 /* ContributorsListView.swift */, E58499672ACDDA9A00634660 /* ContributorsProfileView.swift */, FF09FC902AB6FF44006BE61A /* AuthenticationView.swift */, + E55B630C2B079E5A006BDDDF /* EditVehicleView.swift */, ); path = Views; sourceTree = ""; @@ -698,6 +704,7 @@ 8A3D74862AD6D9A10000FEEB /* AlertView.swift in Sources */, 57CDD9A02ADC31A8002EFED0 /* AddOdometerReadingView.swift in Sources */, 57CDD99E2ADC3173002EFED0 /* OdometerViewModel.swift in Sources */, + E55B630D2B079E5A006BDDDF /* EditVehicleView.swift in Sources */, FF755B3E2A908E7A00F49A13 /* SettingsView.swift in Sources */, FF3DDF522AA4D28F009D91C4 /* DashboardViewModel.swift in Sources */, FFE0AF562AD66C3500AB46F8 /* OdometerView.swift in Sources */, @@ -705,6 +712,7 @@ 0CA7ED092AE82BF100609019 /* ContributionTip.swift in Sources */, FFBFE0972A98F7CB000A9BEB /* AddVehicleView.swift in Sources */, 8A3D748C2AD9C41D0000FEEB /* AlertItem.swift in Sources */, + E5EDD11D2B0933700059C52E /* EditVehicleEvent.swift in Sources */, 8A3D748A2AD9C3E00000FEEB /* MainTabViewModel.swift in Sources */, E584996A2ACDDAFF00634660 /* Contributor.swift in Sources */, 8014A4D32AD77C92005B51F6 /* ChooseAppIconViewModel.swift in Sources */, diff --git a/Basic-Car-Maintenance/Shared/Localizable.xcstrings b/Basic-Car-Maintenance/Shared/Localizable.xcstrings index 0a687355..3887d1a4 100644 --- a/Basic-Car-Maintenance/Shared/Localizable.xcstrings +++ b/Basic-Car-Maintenance/Shared/Localizable.xcstrings @@ -4280,6 +4280,7 @@ } }, "Update" : { + "comment" : "Label to update vehicle information.", "localizations" : { "be" : { "stringUnit" : { @@ -4407,6 +4408,9 @@ } } } + }, + "Update Vehicle" : { + }, "Vehicle" : { "comment" : "Maintenance event vehicle picker header", diff --git a/Basic-Car-Maintenance/Shared/Models/EditVehicleEvent.swift b/Basic-Car-Maintenance/Shared/Models/EditVehicleEvent.swift index 026d6b64..535f116d 100644 --- a/Basic-Car-Maintenance/Shared/Models/EditVehicleEvent.swift +++ b/Basic-Car-Maintenance/Shared/Models/EditVehicleEvent.swift @@ -5,4 +5,18 @@ // Created by Traton Gossink on 11/18/23. // +import FirebaseFirestoreSwift import Foundation + +struct EditVehicleEvent: Codable, Identifiable, Hashable { + @DocumentID var id: String? + var userID: String? + let name: String + let make: String + let model: String + let year: String + let color: String + let VIN: String + let licenseplatenumber: String + var vehicle: Vehicle +} diff --git a/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift b/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift index 46ed2ae5..f59ff58d 100644 --- a/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift +++ b/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift @@ -110,7 +110,7 @@ final class SettingsViewModel { } } } - + /// Deletes a vehicle from both Firestore and the local ``SettingsViewModel/vehicles`` array. /// /// - Parameter vehicle: The vehicle to be deleted. diff --git a/Basic-Car-Maintenance/Shared/Settings/Views/EditVehicleView.swift b/Basic-Car-Maintenance/Shared/Settings/Views/EditVehicleView.swift index 115b5fe9..4038c04f 100644 --- a/Basic-Car-Maintenance/Shared/Settings/Views/EditVehicleView.swift +++ b/Basic-Car-Maintenance/Shared/Settings/Views/EditVehicleView.swift @@ -2,7 +2,123 @@ // EditVehicleView.swift // Basic-Car-Maintenance // -// Created by Traton Gossink on 11/17/23. +// Created by Traton Gossink on 11/6/23. // -import Foundation +import SwiftUI + +struct EditVehicleView: View, Observable { + @Binding var selectedEvent: EditVehicleEvent? + var viewModel: SettingsViewModel + @State private var selectedVehicle: Vehicle? + @State private var name = "" + @State private var make = "" + @State private var model = "" + @State private var year = "" + @State private var color = "" + @State private var VIN = "" + @State private var licensePlateNumber = "" + @Environment(\.dismiss) var dismiss + + var body: some View { + NavigationStack { + Form { + Section { + TextField("Name", text: $name) + } header: { + Text("Name") + } + Section { + TextField("Make", text: $make) + } header: { + Text("Make") + } + + Section { + TextField("Model", text: $model) + } header: { + Text("Model") + } + + Section { + TextField("Year", text: $year) + } header: { + Text("Year") + } + + Section { + TextField("Color", text: $color) + } header: { + Text("Color") + } + Section { + TextField("VIN", text: $VIN) + } header: { + Text("VIN") + } + Section { + TextField("License Plate Number", text: $licensePlateNumber) + } header: { + Text("License Plate Number") + } + } + .analyticsView() + .onAppear { + guard let selectedEvent = selectedEvent else { return } + setEditVehicleEventValues(event: selectedEvent) + } + .navigationTitle(Text("Update Vehicle")) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button { + dismiss() + } label: { + Text("Cancel") + } + } + + ToolbarItem(placement: .topBarTrailing) { + Button { + if let selectedVehicle, let selectedEvent { + var event = EditVehicleEvent(name: name, + make: make, + model: model, + year: year, + color: color, + VIN: VIN, + licenseplatenumber: licensePlateNumber, + vehicle: selectedVehicle) + event.id = selectedEvent.id + Task { +// await viewModel.updateEvent(event) + dismiss() + } + } + } label: { + Text("Update") + } + .disabled(name.isEmpty) + } + } + } + } + + func setEditVehicleEventValues(event: EditVehicleEvent) { + self.name = event.name + self.make = event.make + self.model = event.model + self.year = event.year + self.color = event.color + self.VIN = event.VIN + self.licensePlateNumber = event.licenseplatenumber + self.selectedVehicle = event.vehicle + } +} + +//#Preview { +// EditVehicleView(selectedEvent: +// .constant(EditVehicleEvent(name: "", make: "", model: "", year: "", color: "", VIN: "", licenseplatenumber: "", vehicle: vehicle)), +// viewModel: +// SettingsViewModel(authenticationViewModel: AuthenticationViewModel()) +// ) +//} diff --git a/Basic-Car-Maintenance/Shared/Settings/Views/SettingsView.swift b/Basic-Car-Maintenance/Shared/Settings/Views/SettingsView.swift index 8e1d53f9..f743f63f 100644 --- a/Basic-Car-Maintenance/Shared/Settings/Views/SettingsView.swift +++ b/Basic-Car-Maintenance/Shared/Settings/Views/SettingsView.swift @@ -23,6 +23,11 @@ struct SettingsView: View { @State private var errorDetails: Error? @State private var copiedAppVersion: Bool = false + @State private var selectedVehicleEvent: EditVehicleEvent? + @Binding private var isEditingVehicle: Bool + @State var editViewModel: EditVehicleView? + @State private var vehicleToEdit: Vehicle? + private let appVersion = "Version \(Bundle.main.versionNumber) (\(Bundle.main.buildNumber))" init(authenticationViewModel: AuthenticationViewModel) { @@ -93,7 +98,7 @@ struct SettingsView: View { Text(vehicle.make) Text(vehicle.model) - + if let year = vehicle.year, !year.isEmpty { Text(year) } @@ -106,7 +111,8 @@ struct SettingsView: View { Text(vin) } - if let licensePlateNumber = vehicle.licensePlateNumber, !licensePlateNumber.isEmpty { + if let licensePlateNumber = vehicle.licensePlateNumber, + !licensePlateNumber.isEmpty { Text(licensePlateNumber) } } @@ -123,21 +129,24 @@ struct SettingsView: View { } label: { Text("Delete", comment: "Label to delete a vehicle") } - Button(role: .edit) { + Button { Task { - do { - try await viewModel.getVehicles(vehicle) - } catch { - errorDetails = error - showDeleteVehicleError = true - } + selectedVehicleEvent = vehicle + isEditingVehicle = true } - } label: { - Text("Edit", comment: "Edit current vehicle") + } + } label: { + VStack { + Text("Edit", comment: "Button label to edit this vehicle") + Image(systemName: SFSymbol.pencil) + } + .sheet(isPresented: $isEditingVehicle) { + EditVehicleView( + selectedEvent: $selectedVehicleEvent, viewModel: viewModel) } } } - + Button { isShowingAddVehicle = true } label: { @@ -218,6 +227,7 @@ struct SettingsView: View { } } } + // swiftlint:disable:next line_length .alert(Text("Failed To Delete Vehicle", comment: "Label to dsplay title of the delete vehicle alert"), isPresented: $showDeleteVehicleError) {