Skip to content

Commit

Permalink
5 Edit Vehicle (#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
TratonGossink authored Nov 24, 2023
1 parent d9197c2 commit a6f96fa
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 4 deletions.
8 changes: 8 additions & 0 deletions Basic-Car-Maintenance.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
FF153AFF2B07C3E000D0BA30 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = FF153AFE2B07C3E000D0BA30 /* FirebaseCrashlytics */; };
FF218EF62B00865F0025A533 /* AnalyticsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF218EF52B00865F0025A533 /* AnalyticsService.swift */; };
Expand Down Expand Up @@ -121,9 +123,11 @@
8AEE816E2ACF37F800FC0C2A /* Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = "<group>"; };
8AEE81712ACF384D00FC0C2A /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = "<group>"; };
8AEE81732ACF394E00FC0C2A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E55B630C2B079E5A006BDDDF /* EditVehicleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditVehicleView.swift; sourceTree = "<group>"; };
E58499652ACDDA8B00634660 /* ContributorsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorsListView.swift; sourceTree = "<group>"; };
E58499672ACDDA9A00634660 /* ContributorsProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorsProfileView.swift; sourceTree = "<group>"; };
E58499692ACDDAFF00634660 /* Contributor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contributor.swift; sourceTree = "<group>"; };
E5EDD11C2B0933700059C52E /* EditVehicleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditVehicleEvent.swift; sourceTree = "<group>"; };
FF0813562AD0A83000910EFA /* UITests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UITests.xcconfig; sourceTree = "<group>"; };
FF0813572AD0A92700910EFA /* Widget.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Widget.xcconfig; sourceTree = "<group>"; };
FF098EFA2AB3424E003EC0FE /* Basic-Car-Maintenance.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Basic-Car-Maintenance.xcconfig"; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -422,6 +426,7 @@
8014A4CE2AD75928005B51F6 /* AppIcon.swift */,
57CDD9A32ADC320F002EFED0 /* OdometerReading.swift */,
8A3D748B2AD9C41D0000FEEB /* AlertItem.swift */,
E5EDD11C2B0933700059C52E /* EditVehicleEvent.swift */,
);
path = Models;
sourceTree = "<group>";
Expand All @@ -435,6 +440,7 @@
E58499652ACDDA8B00634660 /* ContributorsListView.swift */,
E58499672ACDDA9A00634660 /* ContributorsProfileView.swift */,
FF09FC902AB6FF44006BE61A /* AuthenticationView.swift */,
E55B630C2B079E5A006BDDDF /* EditVehicleView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -725,13 +731,15 @@
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 */,
8AEE816F2ACF37F800FC0C2A /* Action.swift in Sources */,
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 */,
Expand Down
6 changes: 5 additions & 1 deletion Basic-Car-Maintenance/Shared/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,7 @@
}
},
"Edit" : {
"comment" : "Button label to edit this maintenance",
"comment" : "Button label to edit this vehicle\nButton label to edit this maintenance",
"localizations" : {
"be" : {
"stringUnit" : {
Expand Down Expand Up @@ -4280,6 +4280,7 @@
}
},
"Update" : {
"comment" : "Label to update vehicle information.",
"localizations" : {
"be" : {
"stringUnit" : {
Expand Down Expand Up @@ -4407,6 +4408,9 @@
}
}
}
},
"Update Vehicle Info" : {

},
"Vehicle" : {
"comment" : "Maintenance event vehicle picker header",
Expand Down
22 changes: 22 additions & 0 deletions Basic-Car-Maintenance/Shared/Models/EditVehicleEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// EditVehicleEvent.swift
// Basic-Car-Maintenance
//
// 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?
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ final class SettingsViewModel {
var contributors: [Contributor]?

var vehicles = [Vehicle]()
var errorMessage: String = ""
var showErrorAlert = false

var sortedContributors: [Contributor] {
guard let contributors = contributors, !contributors.isEmpty else {
Expand Down Expand Up @@ -77,6 +79,30 @@ final class SettingsViewModel {
}
}

///Updates users vehicle that is being edited. Fetches selected vehicle from Firestore and saves to that selected vehicle.

Check warning on line 82 in Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Prefer at least one space after slashes for comments (comment_spacing)

Check warning on line 82 in Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Line should be 110 characters or less; currently it has 126 characters (line_length)
func updateEvent(_ editVehicleEvent: EditVehicleEvent) async {

if let uid = authenticationViewModel.user?.uid {
guard let id = editVehicleEvent.id else { return }
var eventToUpdate = editVehicleEvent
eventToUpdate.userID = uid
do {
try Firestore
.firestore()
.collection(FirestoreCollection.vehicles)
.document(id)
.setData(from: eventToUpdate)
} catch {
showErrorAlert.toggle()
errorMessage = error.localizedDescription
}
}

AnalyticsService.shared.logEvent(.maintenanceUpdate)

await self.getVehicles()
}

/// Fetches the user's vehicles from Firestore based on their unique user ID.
func getVehicles() async {
if let uid = authenticationViewModel.user?.uid {
Expand All @@ -99,7 +125,7 @@ final class SettingsViewModel {
}
}
}

/// Deletes a vehicle from both Firestore and the local ``SettingsViewModel/vehicles`` array.
///
/// - Parameter vehicle: The vehicle to be deleted.
Expand Down
124 changes: 124 additions & 0 deletions Basic-Car-Maintenance/Shared/Settings/Views/EditVehicleView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//
// EditVehicleView.swift
// Basic-Car-Maintenance
//
// Created by Traton Gossink on 11/6/23.
//

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("\(Self.self)")
.onAppear {
guard let selectedEvent = selectedEvent else { return }
setEditVehicleEventValues(event: selectedEvent)
}
.navigationTitle(Text("Update Vehicle Info"))
.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: "")),

Check warning on line 120 in Basic-Car-Maintenance/Shared/Settings/Views/EditVehicleView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Line should be 110 characters or less; currently it has 125 characters (line_length)
viewModel:
SettingsViewModel(authenticationViewModel: AuthenticationViewModel())
)
}
21 changes: 19 additions & 2 deletions Basic-Car-Maintenance/Shared/Settings/Views/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ struct SettingsView: View {
@State private var errorDetails: Error?
@State private var copiedAppVersion: Bool = false

@State private var selectedVehicleEvent: EditVehicleEvent?
@State private var isEditingVehicle = false
@State var editViewModel: EditVehicleView?
@State private var vehicleToEdit: Vehicle?

private let appVersion = "Version \(Bundle.main.versionNumber) (\(Bundle.main.buildNumber))"

init(authenticationViewModel: AuthenticationViewModel) {
Expand Down Expand Up @@ -92,7 +97,7 @@ struct SettingsView: View {
Text(vehicle.make)

Text(vehicle.model)

if let year = vehicle.year, !year.isEmpty {
Text(year)
}
Expand Down Expand Up @@ -123,9 +128,21 @@ struct SettingsView: View {
} label: {
Text("Delete", comment: "Label to delete a vehicle")
}
Button {
isEditingVehicle = true
} label: {
VStack {
Text("Edit", comment: "Button label to edit this vehicle")
Image(systemName: SFSymbol.pencil)
}
}
}
.sheet(isPresented: $isEditingVehicle) {
EditVehicleView(
selectedEvent: $selectedVehicleEvent, viewModel: viewModel)
}
}

Button {
// TODO: Show Paywall

Check warning on line 147 in Basic-Car-Maintenance/Shared/Settings/Views/SettingsView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

TODOs should be resolved (Show Paywall) (todo)
// Show paywall if adding more than 1 vehicle, or show the `isShowingAddVehicle` view
Expand Down

0 comments on commit a6f96fa

Please sign in to comment.