add average mpg to fuel log list
This commit is contained in:
parent
75af0a4ebf
commit
16d65536d0
|
@ -20,7 +20,7 @@ struct FuelLogListView: View {
|
||||||
@State private var selectedVehicleID: UUID? = nil
|
@State private var selectedVehicleID: UUID? = nil
|
||||||
@State private var showAddVehicleSheet = false
|
@State private var showAddVehicleSheet = false
|
||||||
|
|
||||||
// For tracking the previous odometer reading
|
// For tracking the previous odometer reading (used for validation)
|
||||||
@State private var previousOdometer: Double? = nil
|
@State private var previousOdometer: Double? = nil
|
||||||
@State private var showOdometerAlert = false
|
@State private var showOdometerAlert = false
|
||||||
@State private var isUpdatingCalculation = false
|
@State private var isUpdatingCalculation = false
|
||||||
|
@ -44,9 +44,32 @@ struct FuelLogListView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Computed property to calculate average MPG for full-tank logs.
|
||||||
|
// MPG for an individual log is computed as:
|
||||||
|
// (current.odometer - next.odometer) / current.fuelVolume
|
||||||
|
private var averageMPG: Double? {
|
||||||
|
let logs = filteredFuelLogs
|
||||||
|
guard logs.count > 1 else { return nil }
|
||||||
|
var mpgValues: [Double] = []
|
||||||
|
// Iterate over logs except the oldest.
|
||||||
|
for i in 0..<logs.count - 1 {
|
||||||
|
let current = logs[i]
|
||||||
|
let next = logs[i + 1]
|
||||||
|
// Only include if fullTank is true, fuelVolume is positive, and odometer difference is positive.
|
||||||
|
if current.fullTank, current.fuelVolume > 0, current.odometer > next.odometer {
|
||||||
|
let mpg = (current.odometer - next.odometer) / current.fuelVolume
|
||||||
|
mpgValues.append(mpg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guard !mpgValues.isEmpty else { return nil }
|
||||||
|
let total = mpgValues.reduce(0, +)
|
||||||
|
return total / Double(mpgValues.count)
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
if vehicles.isEmpty {
|
if vehicles.isEmpty {
|
||||||
|
// Empty state: no vehicles exist.
|
||||||
VStack(spacing: 20) {
|
VStack(spacing: 20) {
|
||||||
Text("No vehicles found.")
|
Text("No vehicles found.")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
|
@ -67,6 +90,7 @@ struct FuelLogListView: View {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List {
|
List {
|
||||||
|
// Vehicle Picker Section
|
||||||
Section {
|
Section {
|
||||||
Picker("Vehicle", selection: $selectedVehicleID) {
|
Picker("Vehicle", selection: $selectedVehicleID) {
|
||||||
ForEach(vehicles, id: \.id) { vehicle in
|
ForEach(vehicles, id: \.id) { vehicle in
|
||||||
|
@ -77,6 +101,22 @@ struct FuelLogListView: View {
|
||||||
.pickerStyle(MenuPickerStyle())
|
.pickerStyle(MenuPickerStyle())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Average MPG Section
|
||||||
|
Section {
|
||||||
|
HStack {
|
||||||
|
Text("Average MPG:")
|
||||||
|
Spacer()
|
||||||
|
if let avg = averageMPG {
|
||||||
|
Text("\(avg, specifier: "%.1f")")
|
||||||
|
.bold()
|
||||||
|
} else {
|
||||||
|
Text("N/A")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fuel Logs Section (filtered by selected vehicle)
|
||||||
ForEach(filteredFuelLogs.indices, id: \.self) { index in
|
ForEach(filteredFuelLogs.indices, id: \.self) { index in
|
||||||
let log = filteredFuelLogs[index]
|
let log = filteredFuelLogs[index]
|
||||||
let distance: Double? = {
|
let distance: Double? = {
|
||||||
|
@ -131,6 +171,7 @@ struct FuelLogListView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default vehicle selection on appear.
|
||||||
private func setDefaultVehicle() {
|
private func setDefaultVehicle() {
|
||||||
if selectedVehicleID == nil {
|
if selectedVehicleID == nil {
|
||||||
if let lastFuelLog = fuelLogs.first, let vehicle = lastFuelLog.vehicle {
|
if let lastFuelLog = fuelLogs.first, let vehicle = lastFuelLog.vehicle {
|
||||||
|
|
Loading…
Reference in New Issue