diff --git a/Basic-Car-Maintenance/Shared/Localizable.xcstrings b/Basic-Car-Maintenance/Shared/Localizable.xcstrings index e262b97e..296044f3 100644 --- a/Basic-Car-Maintenance/Shared/Localizable.xcstrings +++ b/Basic-Car-Maintenance/Shared/Localizable.xcstrings @@ -786,6 +786,9 @@ } } } + }, + "All" : { + }, "All Vehicles" : { diff --git a/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift b/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift index ffc18260..994f9c89 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift @@ -22,8 +22,9 @@ class OdometerViewModel { var showEditErrorAlert = false var selectedReading: OdometerReading? var isShowingEditReadingView = false - + var filterOption: String = "No vehicles found" var vehicles = [Vehicle]() + var selectedVehicle: Vehicle? init(userUID: String?) { self.userUID = userUID diff --git a/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift b/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift index 91255c9d..5696ffdb 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift @@ -14,6 +14,8 @@ struct OdometerView: View { @State private var viewModel: OdometerViewModel @State private var selectedTimeRange: TimeRange = .all + // start of my variables + @State private var selectedVehicleID: String? init(userUID: String?) { self.init(viewModel: OdometerViewModel(userUID: userUID)) @@ -60,7 +62,7 @@ struct OdometerView: View { } List { - ForEach(viewModel.readings) { reading in + ForEach(filteredReadings()) { reading in let vehicleName = viewModel.vehicles.first { $0.id == reading.vehicleID }?.name OdometerRowView(reading: reading, vehicleName: vehicleName) .swipeActions(edge: .trailing, allowsFullSwipe: true) { @@ -99,6 +101,29 @@ struct OdometerView: View { } .toolbar { ToolbarItemGroup(placement: .primaryAction) { + Menu { + Button("All") { + selectedVehicleID = "nil" + applyFilter() + print(selectedVehicleID!) + } + ForEach(viewModel.vehicles) { value in + Button(value.name) { + selectedVehicleID = value.id + applyFilter() + print(selectedVehicleID!) + } + } + } label: { + Image(systemName: SFSymbol.filter) + } + .accessibilityShowsLargeContentViewer { + Label { + Text("Filter", comment: "Label for filtering on Dashboard view") + } icon: { + Image(systemName: SFSymbol.filter) + } + } Button { viewModel.isShowingAddOdometerReading = true } label: { @@ -128,7 +153,32 @@ struct OdometerView: View { } // swiftlint:disable:next line_length - /// Filter the readins based on the selected time range, and if there are no readings in the last 30 days, just show the last reading. + /// Filter the readings based on the selected vehicle , and if no vehicle is selected , it shows all the vehicle's readings + /// - Parameter : None + /// - Returns: The `[OdometerReading]`s for all the vehicles / only the filtered vehicle + /// + private func filteredReadings() -> [OdometerReading] { + if viewModel.selectedVehicle == nil { + return viewModel.readings + } + return viewModel.readings.filter { $0.vehicleID == viewModel.selectedVehicle?.id } + } + + /// + /// Checks if we have selected any vehicle for filtering the readings. + /// - Parameter : None + /// - Returns: None + /// + private func applyFilter() { + if let selectedID = selectedVehicleID { + viewModel.selectedVehicle = viewModel.vehicles.first(where: { $0.id == selectedID }) + } else { + viewModel.selectedVehicle = nil + } + } + + // swiftlint:disable:next line_length + /// Filter the readings based on the selected time range, and if there are no readings in the last 30 days, just show the last reading. /// - Parameter vehicle: The vehicle for these readings. /// - Returns: The `[OdometerReading]`s for this vehicle in the time range. private func filteredReadings(for vehicle: Vehicle) -> [OdometerReading] { @@ -189,8 +239,9 @@ enum TimeRange: String, CaseIterable, Identifiable { let viewModel = OdometerViewModel(userUID: nil) let firstCar = createVehicle(id: "id1", name: "My 1st car") let secondCar = createVehicle(id: "id2", name: "2nd Car") - - viewModel.vehicles.append(contentsOf: [firstCar, secondCar]) + let thirdCar = createVehicle(id: "id3", name: "3rd Car") + + viewModel.vehicles.append(contentsOf: [firstCar, secondCar, thirdCar]) let firstReading = createReading(vehicleID: firstCar.id!, date: "2024/10/18", @@ -220,8 +271,12 @@ enum TimeRange: String, CaseIterable, Identifiable { date: "2024/11/13", distance: 1542) + let ninthReading = createReading(vehicleID: thirdCar.id!, + date: "2024/11/16", + distance: 1600) + // swiftlint:disable:next line_length - viewModel.readings.append(contentsOf: [firstReading, secondReading, thirdReading, fourthReading, fifthReading, sixthReading, seventhReading, eighthReading]) + viewModel.readings.append(contentsOf: [firstReading, secondReading, thirdReading, fourthReading, fifthReading, sixthReading, seventhReading, eighthReading, ninthReading]) return OdometerView(viewModel: viewModel) .environment(ActionService.shared)