Files
fuelboard/FuelBoard/FavouritesView.swift
T

86 lines
3.8 KiB
Swift

import SwiftUI
/// Favourites tab — starred stations, ranked cheapest-first for the selected
/// fuel, with the cheapest favourite called out at the top.
struct FavouritesView: View {
let favourites: [FuelStation]
let selectedFuel: FuelType
let location: Coordinate?
let favouriteIDs: Set<String>
var onToggleFavourite: (FuelStation) -> Void = { _ in }
/// Favourites that sell the selected fuel, cheapest first (distance tiebreak).
private var ranked: [FuelStation] {
let available = favourites.filter { $0.prices[selectedFuel] != nil }
return available.sorted { lhs, rhs in
let lPrice = lhs.prices[selectedFuel]!
let rPrice = rhs.prices[selectedFuel]!
if lPrice != rPrice { return lPrice < rPrice }
guard let location else { return false }
return lhs.distanceKM(to: location.lat, lng2: location.lng) <
rhs.distanceKM(to: location.lat, lng2: location.lng)
}
}
private var cheapest: FuelStation? { ranked.first }
private var cheapestPrice: Double? { cheapest?.prices[selectedFuel] }
var body: some View {
NavigationStack {
List {
if favourites.isEmpty {
Section {
VStack(spacing: 10) {
Image(systemName: "star")
.font(.system(size: 40))
.foregroundStyle(.secondary)
Text("No favourites yet")
.font(.headline)
Text("Tap the star on any station in the Stations tab to pin it here, ranked by which is cheapest.")
.font(.caption)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
.padding(.vertical, 24)
}
} else {
Section {
if let cheapest, let price = cheapestPrice {
HStack(spacing: 10) {
Image(systemName: "crown.fill")
.foregroundStyle(.yellow)
Text("Cheapest favourite: \(cheapest.name)\(String(format: "%.1fp", price))")
.font(.footnote)
}
}
}
Section("Favourites — cheapest first") {
ForEach(Array(ranked.enumerated()), id: \.element.id) { index, station in
StationRow(
station: station,
fuel: selectedFuel,
location: location,
cheapestPrice: cheapestPrice,
isTopResult: index == 0,
isFavourite: favouriteIDs.contains(station.id),
onToggleFavourite: { onToggleFavourite(station) }
)
}
}
if let cheapest = cheapest {
Section {
Text("\(cheapest.name) is your cheapest favourite for \(selectedFuel.displayName). Add the same stations to the Alerts tab to get pinged when you drive past a cheaper one.")
.font(.caption)
.foregroundStyle(.secondary)
}
}
}
}
.navigationTitle("Favourites")
}
}
}