4 changed files with 75 additions and 12 deletions
+23 -10
View File
@@ -981,6 +981,21 @@ struct StationRow: View {
return String(format: "%+.1fp", delta) return String(format: "%+.1fp", delta)
} }
private func handleTap() {
switch tapAction {
case .openMap:
if let url = station.mapsDirectionsURL {
UIApplication.shared.open(url)
}
case .showDetails:
showDetails()
}
}
private func showDetails() {
onShowDetails(station)
}
var body: some View { var body: some View {
HStack(spacing: 12) { HStack(spacing: 12) {
// LEFT round brand logo (or generic fuel pump fallback) // LEFT round brand logo (or generic fuel pump fallback)
@@ -1017,6 +1032,12 @@ struct StationRow: View {
.background(Capsule().fill(.blue.opacity(0.15))) .background(Capsule().fill(.blue.opacity(0.15)))
.foregroundStyle(.blue) .foregroundStyle(.blue)
} }
ForEach(StationNotice.notices(for: station)) { notice in
Image(systemName: notice.symbolName)
.font(.caption2.weight(.semibold))
.foregroundStyle(.secondary)
.accessibilityLabel(notice.title)
}
} }
Text("\(station.address), \(station.postcode)") Text("\(station.address), \(station.postcode)")
.font(.caption) .font(.caption)
@@ -1059,16 +1080,8 @@ struct StationRow: View {
.buttonStyle(.borderless) .buttonStyle(.borderless)
} }
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture(perform: handleTap)
switch tapAction { .onLongPressGesture(perform: showDetails)
case .openMap:
if let url = station.mapsDirectionsURL {
UIApplication.shared.open(url)
}
case .showDetails:
onShowDetails(station)
}
}
} }
} }
+9 -1
View File
@@ -45,6 +45,14 @@ struct StationDetailView: View {
LabeledContent("Distance", value: distanceUnit.format(km)) LabeledContent("Distance", value: distanceUnit.format(km))
.monospacedDigit() .monospacedDigit()
} }
ForEach(StationNotice.notices(for: station)) { notice in
Label(notice.title, systemImage: notice.symbolName)
.font(.subheadline.weight(.semibold))
.foregroundStyle(.orange)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(Capsule().fill(Color.orange.opacity(0.14)))
}
} }
Section { Section {
Button { Button {
@@ -65,7 +73,7 @@ struct StationDetailView: View {
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.alert("Report an error?", isPresented: $showingReportIssueConfirmation) { .alert("Report an error?", isPresented: $showingReportIssueConfirmation) {
Button("Cancel", role: .cancel) { } Button("Cancel", role: .cancel) { }
Button("Open GOV.UK") { Button("Report") {
UIApplication.shared.open(reportIssueURL) UIApplication.shared.open(reportIssueURL)
} }
} message: { } message: {
+41
View File
@@ -0,0 +1,41 @@
import Foundation
/// Presentation-only notices derived from existing station metadata.
///
/// These do not alter `FuelStation`, persistence, filtering, sorting, or
/// navigation. They are intentionally small and reusable so additional
/// informational station notices can be added later from the UI layer.
enum StationNotice: Identifiable, Equatable {
case membershipRequired
var id: String {
switch self {
case .membershipRequired: return "membershipRequired"
}
}
var title: String {
switch self {
case .membershipRequired: return "Membership required"
}
}
var symbolName: String {
switch self {
case .membershipRequired: return "creditcard.fill"
}
}
static func notices(for station: FuelStation) -> [StationNotice] {
isCostco(station) ? [.membershipRequired] : []
}
static func isCostco(_ station: FuelStation) -> Bool {
containsCostcoToken(station.brand) || containsCostcoToken(station.name)
}
private static func containsCostcoToken(_ value: String) -> Bool {
let tokens = value.uppercased().split { !$0.isLetter && !$0.isNumber }
return tokens.contains("COSTCO")
}
}
+2 -1
View File
@@ -148,9 +148,10 @@
"Done" = "Done"; "Done" = "Done";
"Directions" = "Directions"; "Directions" = "Directions";
"Report issue" = "Report issue"; "Report issue" = "Report issue";
"Membership required" = "Membership required";
"Report an error?" = "Report an error?"; "Report an error?" = "Report an error?";
"Cancel" = "Cancel"; "Cancel" = "Cancel";
"Open GOV.UK" = "Open GOV.UK"; "Report" = "Report";
"Are you sure you want to report an error in fuel prices or forecourt details? This will open in your chosen browser." = "Are you sure you want to report an error in fuel prices or forecourt details? This will open in your chosen browser."; "Are you sure you want to report an error in fuel prices or forecourt details? This will open in your chosen browser." = "Are you sure you want to report an error in fuel prices or forecourt details? This will open in your chosen browser.";
/* Station row */ /* Station row */