Tip section: card design per user mockup
Three stacked rounded cards, one per tier, each with an accent-tinted fuel-pump icon and price (Splash & Dash #64D2FF blue, Half a Tank #30D158 green, Fill 'Er Up #FFD60A amber — the app's fuel palette), name + blurb on the left, bold accent price on the right. Cards sit on clear list rows with their own rounded fill + subtle accent tint. Purchase flow, per-tier live prices, disabled state and footer copy unchanged.
This commit is contained in:
@@ -298,25 +298,47 @@ struct SettingsView: View {
|
||||
}
|
||||
|
||||
Section {
|
||||
VStack(spacing: 10) {
|
||||
ForEach(TipStore.tiers) { tier in
|
||||
Button {
|
||||
Task { await tipStore.purchase(tier) }
|
||||
} label: {
|
||||
HStack {
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: "fuelpump.fill")
|
||||
.font(.title3)
|
||||
.foregroundStyle(tier.accent)
|
||||
.frame(width: 34)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(tier.name)
|
||||
.font(.headline)
|
||||
Text(tier.blurb)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
Spacer(minLength: 8)
|
||||
Text(tipStore.displayPrice(for: tier))
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.headline.weight(.bold))
|
||||
.foregroundStyle(tier.accent)
|
||||
.monospacedDigit()
|
||||
}
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 12)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color(.secondarySystemGroupedBackground))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(tier.accent.opacity(0.05))
|
||||
)
|
||||
)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.disabled(tipStore.purchaseInProgress)
|
||||
}
|
||||
}
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowInsets(EdgeInsets(top: 4, leading: 16, bottom: 4, trailing: 16))
|
||||
} header: {
|
||||
Text("Support FuelBoard")
|
||||
} footer: {
|
||||
@@ -569,15 +591,19 @@ final class TipStore: ObservableObject {
|
||||
let name: String
|
||||
let blurb: String
|
||||
let fallbackPrice: String
|
||||
let accent: Color // card/price accent (matches the fuel palette)
|
||||
}
|
||||
|
||||
static let tiers: [TipTier] = [
|
||||
TipTier(id: "com.apt.fuelboard.tip099", name: "Splash & Dash",
|
||||
blurb: "Just enough to keep things moving.", fallbackPrice: "£0.99"),
|
||||
blurb: "Just enough to keep things moving.", fallbackPrice: "£0.99",
|
||||
accent: Color(red: 0.39, green: 0.82, blue: 1.0)), // #64D2FF
|
||||
TipTier(id: "com.apt.fuelboard.tip299", name: "Half a Tank",
|
||||
blurb: "A generous top-up for development.", fallbackPrice: "£2.99"),
|
||||
blurb: "A generous top-up for development.", fallbackPrice: "£2.99",
|
||||
accent: Color(red: 0.19, green: 0.82, blue: 0.35)), // #30D158
|
||||
TipTier(id: "com.apt.fuelboard.tip499", name: "Fill 'Er Up",
|
||||
blurb: "Keeping the app on the road.", fallbackPrice: "£4.99"),
|
||||
blurb: "Keeping the app on the road.", fallbackPrice: "£4.99",
|
||||
accent: Color(red: 1.0, green: 0.84, blue: 0.04)), // #FFD60A
|
||||
]
|
||||
|
||||
@Published private(set) var products: [String: Product] = [:]
|
||||
|
||||
Reference in New Issue
Block a user