diff --git a/Basic-Car-Maintenance/Shared/Dashboard/Views/AddMaintenanceView.swift b/Basic-Car-Maintenance/Shared/Dashboard/Views/AddMaintenanceView.swift index 098b6f69..81a8ce6e 100644 --- a/Basic-Car-Maintenance/Shared/Dashboard/Views/AddMaintenanceView.swift +++ b/Basic-Car-Maintenance/Shared/Dashboard/Views/AddMaintenanceView.swift @@ -99,10 +99,10 @@ struct AddMaintenanceView: View { } #Preview { + let sampleVehicles = [ + Vehicle(name: "Lexus", make: "Lexus", model: "White"), + Vehicle(name: "Test", make: "Lexus", model: "White") + ] + AddMaintenanceView(vehicles: sampleVehicles) { _ in } } - -let sampleVehicles = [ - Vehicle(name: "Lexus", make: "Lexus", model: "White"), - Vehicle(name: "Test", make: "Lexus", model: "White") -] diff --git a/Basic-Car-Maintenance/Shared/Localizable.xcstrings b/Basic-Car-Maintenance/Shared/Localizable.xcstrings index 91f0f2ce..7bf8901c 100644 --- a/Basic-Car-Maintenance/Shared/Localizable.xcstrings +++ b/Basic-Car-Maintenance/Shared/Localizable.xcstrings @@ -78,6 +78,18 @@ } } }, + "%lld %@" : { + "comment" : "A text label followed by a value, indicating the distance traveled by a vehicle. The value is formatted as a number followed by a unit of distance (either kilometers or miles).", + "isCommentAutoGenerated" : true, + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$lld %2$@" + } + } + } + }, "^[%lld contributions](inflect: true)" : { "comment" : "the number of contributions by a contributor", "localizations" : { @@ -614,7 +626,8 @@ } }, "Add your first odometer" : { - "comment" : "Placeholder text for empty odometer reading list", + "comment" : "Placeholder description for empty odometer reading list", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -666,6 +679,9 @@ } } }, + "Add your first odometer reading" : { + "comment" : "Placeholder text for empty odometer reading list" + }, "AddEvent" : { "comment" : "Label for adding maintenance event on Dashboard view", "localizations" : { @@ -2931,6 +2947,7 @@ } }, "Kilometers" : { + "comment" : "Label for kilometers unit", "localizations" : { "de" : { "stringUnit" : { @@ -3276,23 +3293,8 @@ } } }, - "Mileage: %lld %@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Mileage: %1$lld %2$@" - } - }, - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verbruik: %1$lld %2$@" - } - } - } - }, "Miles" : { + "comment" : "Label for miles unit", "localizations" : { "de" : { "stringUnit" : { @@ -4285,16 +4287,6 @@ "Rate this app" : { "comment" : "Link to rate the app." }, - "Recorded On: %@" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Opgenomen op: %@" - } - } - } - }, "Report a Bug" : { "comment" : "Link to report a bug", "localizations" : { @@ -4863,7 +4855,11 @@ } } }, + "Tap the + tadd your firsst odometer reading" : { + "comment" : "Placeholder description for empty odometer reading list" + }, "Tap the + to begin" : { + "comment" : "Empty odometer list prompt", "localizations" : { "fa" : { "stringUnit" : { @@ -6753,5 +6749,5 @@ } } }, - "version" : "1.0" + "version" : "1.1" } \ No newline at end of file diff --git a/Basic-Car-Maintenance/Shared/Odometer/Views/AddOdometerReadingView.swift b/Basic-Car-Maintenance/Shared/Odometer/Views/AddOdometerReadingView.swift index 2515c8aa..b36ec03b 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/Views/AddOdometerReadingView.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/Views/AddOdometerReadingView.swift @@ -37,11 +37,15 @@ struct AddOdometerReadingView: View { Form { Section { HStack { + Image(systemName: SFSymbol.gaugeWithNeedle) + .foregroundStyle(.secondary) TextField("Distance", value: $distance, format: .number) Picker(selection: $isMetric) { - Text("Miles").tag(false) - Text("Kilometers").tag(true) + Text("Miles", comment: "Label for miles unit") + .tag(false) + Text("Kilometers", comment: "Label for kilometers unit") + .tag(true) } label: { Text("Preferred units", comment: "Label for units selected when adding an odometer reading") @@ -51,25 +55,35 @@ struct AddOdometerReadingView: View { } Section { - Picker(selection: $selectedVehicleID) { - ForEach(vehicles) { vehicle in - Text(vehicle.name) - .tag(vehicle.id) + HStack { + Image(systemName: SFSymbol.carFill) + .foregroundStyle(.secondary) + + Picker(selection: $selectedVehicleID) { + ForEach(vehicles) { vehicle in + Text(vehicle.name) + .tag(vehicle.id) + } + } label: { + Text("Select a vehicle", + comment: "Picker for selecting a vehicle") } - } label: { - Text("Select a vehicle", - comment: "Picker for selecting a vehicle") + .pickerStyle(.menu) } - .pickerStyle(.menu) } header: { Text("VehicleSectionHeader", comment: "Label for Picker for selecting a vehicle") } - DatePicker(selection: $date, displayedComponents: .date) { - Text("Date", comment: "Date picker label") + HStack { + Image(systemName: SFSymbol.calendar) + .foregroundStyle(.secondary) + + DatePicker(selection: $date, displayedComponents: .date) { + Text("Date", comment: "Date picker label") + } + .dynamicTypeSize(...DynamicTypeSize.accessibility2) } - .dynamicTypeSize(...DynamicTypeSize.accessibility2) } .onAppear { if !vehicles.isEmpty { @@ -80,7 +94,7 @@ struct AddOdometerReadingView: View { comment: "Title for form when adding an odometer reading")) .toolbar { ToolbarItem { - Button { + Button(role: .confirm) { if let selectedVehicleID { let reading = OdometerReading(date: date, distance: distance, @@ -89,8 +103,8 @@ struct AddOdometerReadingView: View { addTapped(reading) } } label: { - Text("Add", - comment: "Label for submit button on form to add an entry") + Label("Add", systemImage: "checkmark") + .labelStyle(.iconOnly) } .disabled(distance < 0) } @@ -101,10 +115,10 @@ struct AddOdometerReadingView: View { } #Preview { + let sampleVehicles = [ + Vehicle(name: "Nate Forester", make: "Subaru", model: "Forester"), + Vehicle(name: "Dani Impreza", make: "Subaru", model: "Impreza") + ] + AddOdometerReadingView(vehicles: sampleVehicles) { _ in } } - -let sampleVehicle = [ - Vehicle(name: "Nate Forester", make: "Subaru", model: "Forester"), - Vehicle(name: "Dani Impreza", make: "Subaru", model: "Impreza") -] diff --git a/Basic-Car-Maintenance/Shared/Odometer/Views/EditOdometerReadingView.swift b/Basic-Car-Maintenance/Shared/Odometer/Views/EditOdometerReadingView.swift index 69249e17..cdc5c3a9 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/Views/EditOdometerReadingView.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/Views/EditOdometerReadingView.swift @@ -25,11 +25,15 @@ struct EditOdometerReadingView: View { Form { Section { HStack { + Image(systemName: SFSymbol.gaugeWithNeedle) + .foregroundStyle(.secondary) TextField("Distance", value: $distance, format: .number) Picker(selection: $isMetric) { - Text("Miles").tag(false) - Text("Kilometers").tag(true) + Text("Miles", comment: "Label for miles unit") + .tag(false) + Text("Kilometers", comment: "Label for kilometers unit") + .tag(true) } label: { Text("Preferred units", comment: "Label for units selected when adding an odometer reading") @@ -39,19 +43,29 @@ struct EditOdometerReadingView: View { } Section { - if let vehicleName = vehicles - .filter({ $0.id == selectedReading.vehicleID }).first?.name { - Text(vehicleName) - .opacity(0.3) + HStack { + Image(systemName: SFSymbol.carFill) + .foregroundStyle(.secondary) + + if let vehicleName = vehicles + .filter({ $0.id == selectedReading.vehicleID }).first?.name { + Text(vehicleName) + .opacity(0.3) + } } } header: { Text("Vehicle") } - DatePicker(selection: $date, displayedComponents: .date) { - Text("Date", comment: "Date picker label") + HStack { + Image(systemName: SFSymbol.calendar) + .foregroundStyle(.secondary) + + DatePicker(selection: $date, displayedComponents: .date) { + Text("Date", comment: "Date picker label") + } + .dynamicTypeSize(...DynamicTypeSize.accessibility2) } - .dynamicTypeSize(...DynamicTypeSize.accessibility2) } .onAppear { setEditReadingValues(selectedReading) @@ -60,15 +74,13 @@ struct EditOdometerReadingView: View { comment: "Title for form when editing an odometer reading")) .toolbar { ToolbarItem(placement: .topBarLeading) { - Button { + Button(role: .cancel) { dismiss() - } label: { - Text("Cancel") } } ToolbarItem { - Button { + Button(role: .confirm) { let reading = OdometerReading(id: selectedReading.id, date: date, distance: distance, @@ -76,8 +88,8 @@ struct EditOdometerReadingView: View { vehicleID: selectedReading.vehicleID) updateTapped(reading) } label: { - Text("Update", - comment: "Label for submit button on form to update an existing entry") + Label("Update", systemImage: "checkmark") + .labelStyle(.iconOnly) } .disabled(distance < 0) } @@ -94,10 +106,15 @@ struct EditOdometerReadingView: View { } #Preview { + let sampleVehicles = [ + Vehicle(id: UUID().uuidString, name: "Nate Forester", make: "Subaru", model: "Forester"), + Vehicle(id: UUID().uuidString, name: "Dani Impreza", make: "Subaru", model: "Impreza") + ] + EditOdometerReadingView( selectedReading: OdometerReading(date: Date(), distance: 0, isMetric: false, - vehicleID: ""), - vehicles: []) { _ in } + vehicleID: sampleVehicles[0].id!), + vehicles: sampleVehicles) { _ in } } diff --git a/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerRowView.swift b/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerRowView.swift index 046721a3..1f1ca645 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerRowView.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerRowView.swift @@ -14,15 +14,25 @@ struct OdometerRowView: View { var body: some View { VStack(alignment: .leading, spacing: 8) { - Text("\(vehicleName ?? "No Name")") - .font(.title3) - + HStack { + Image(systemName: SFSymbol.carFill) + + Text(vehicleName ?? "No Name") + .font(.title3) + } + VStack(alignment: .leading, spacing: 4) { - Text("Mileage: \(reading.distance) \(reading.isMetric ? "km" : "mi")") - .foregroundStyle(.gray) + Label { + Text("\(reading.distance) \(reading.isMetric ? "km" : "mi")") + } icon: { + Image(systemName: SFSymbol.gaugeWithNeedle) + } - Text("Recorded On: \(reading.date.formatted(date: .abbreviated, time: .omitted))") - .foregroundStyle(.gray) + Label { + Text(reading.date.formatted(date: .abbreviated, time: .omitted)) + } icon: { + Image(systemName: SFSymbol.calendar) + } } } } @@ -30,5 +40,5 @@ struct OdometerRowView: View { #Preview { OdometerRowView(reading: .init(date: .now, distance: 1000, isMetric: true, vehicleID: "1234"), - vehicleName: "Sample Vehicle Name") + vehicleName: "Sample Vehicle Name") } diff --git a/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift b/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift index 7b54fd6a..b22d39ae 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/Views/OdometerView.swift @@ -73,6 +73,7 @@ struct OdometerView: View { ForEach(filteredReadings) { reading in let vehicleName = viewModel.vehicles.first { $0.id == reading.vehicleID }?.name OdometerRowView(reading: reading, vehicleName: vehicleName) + .foregroundStyle(.primary) .swipeActions(edge: .trailing, allowsFullSwipe: true) { Button(role: .destructive) { Task { @@ -99,8 +100,17 @@ struct OdometerView: View { } .overlay { if viewModel.readings.isEmpty { - Text("Add your first odometer", - comment: "Placeholder text for empty odometer reading list") + ContentUnavailableView { + Label { + Text("Add your first odometer reading", + comment: "Placeholder text for empty odometer reading list") + } icon: { + Image(systemName: SFSymbol.gaugeWithNeedle) + } + } description: { + Text("Tap the + tadd your firsst odometer reading", + comment: "Placeholder description for empty odometer reading list") + } } } .navigationTitle(Text("Odometer")) diff --git a/Basic-Car-Maintenance/Shared/Utilities/Constants.swift b/Basic-Car-Maintenance/Shared/Utilities/Constants.swift index 2a9e17ab..73353b51 100644 --- a/Basic-Car-Maintenance/Shared/Utilities/Constants.swift +++ b/Basic-Car-Maintenance/Shared/Utilities/Constants.swift @@ -65,11 +65,14 @@ enum SFSymbol { static let filter = "line.3.horizontal.decrease" static let plus = "plus" static let share = "square.and.arrow.up" + static let carFill = "car.fill" // Dashboard static let trash = "trash" static let pencil = "pencil" static let magnifyingGlass = "magnifyingglass" + static let gaugeWithNeedle = "gauge.with.needle" + static let calendar = "calendar" // Settings static let document = "doc.badge.plus"