Add debug logging for orderTotal

This commit is contained in:
John Pinkyfloyd 2026-02-17 09:35:19 -08:00
parent 4a2f984c94
commit 40b1ee5d60
3 changed files with 160 additions and 85 deletions

View file

@ -441,7 +441,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = U83YL8VRF3;
GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = PayfritWorks/Info.plist;
@ -456,8 +456,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.payfrit.works;
MARKETING_VERSION = 1.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
PRODUCT_NAME = "Payfrit Works";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
@ -473,7 +473,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = U83YL8VRF3;
GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = PayfritWorks/Info.plist;
@ -488,8 +488,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.payfrit.works;
MARKETING_VERSION = 1.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
PRODUCT_NAME = "Payfrit Works";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;

View file

@ -3,6 +3,28 @@ import SwiftUI
struct AboutScreen: View {
@Environment(\.dismiss) private var dismiss
@State private var appearAnimation = false
@State private var aboutInfo: AboutInfo?
@State private var isLoading = true
@State private var error: String?
// Fallback content if API fails
private let fallbackInfo = AboutInfo(
description: "Payfrit Works helps you manage tasks, accept cash payments, and earn money. Get notified of new tasks, complete them efficiently, and track your earnings.",
features: [
AboutFeature(icon: "checkmark.circle", title: "Claim Tasks", description: "View available tasks from businesses you work for and claim them with one tap."),
AboutFeature(icon: "dollarsign.circle", title: "Accept Cash", description: "Collect cash payments from customers with automatic change calculation."),
AboutFeature(icon: "antenna.radiowaves.left.and.right", title: "Beacon Auto-Complete", description: "Tasks complete automatically when you're near the customer's table beacon."),
AboutFeature(icon: "creditcard", title: "Earn & Get Paid", description: "Track your earnings in real-time and receive payouts to your bank account.")
],
contacts: [
AboutContact(icon: "globe", label: "Website", url: "https://www.payfrit.com")
],
copyright: "© 2026 Payfrit. All rights reserved."
)
private var displayInfo: AboutInfo {
aboutInfo ?? fallbackInfo
}
var body: some View {
ScrollView {
@ -19,7 +41,7 @@ struct AboutScreen: View {
.fontWeight(.bold)
.foregroundColor(.primary)
Text("Version 1.0.0")
Text("Version \(appVersion)")
.font(.caption)
.foregroundColor(.secondary)
}
@ -28,88 +50,57 @@ struct AboutScreen: View {
.scaleEffect(appearAnimation ? 1 : 0.9)
.opacity(appearAnimation ? 1 : 0)
// Intro
Text("Payfrit Works helps you manage tasks, accept cash payments, and earn money. Get notified of new tasks, complete them efficiently, and track your earnings.")
.font(.caption)
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(.horizontal, 16)
.opacity(appearAnimation ? 1 : 0)
.offset(y: appearAnimation ? 0 : 15)
if isLoading {
ProgressView()
.padding(.vertical, 20)
} else {
// Description
if !displayInfo.description.isEmpty {
Text(displayInfo.description)
.font(.caption)
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(.horizontal, 16)
.opacity(appearAnimation ? 1 : 0)
.offset(y: appearAnimation ? 0 : 15)
}
// Feature cards
VStack(spacing: 12) {
featureCard(
icon: "checkmark.circle",
title: "Claim Tasks",
description: "View available tasks from businesses you work for and claim them with one tap."
)
.staggeredAppear(index: 0, appeared: appearAnimation)
featureCard(
icon: "dollarsign.circle",
title: "Accept Cash",
description: "Collect cash payments from customers with automatic change calculation."
)
.staggeredAppear(index: 1, appeared: appearAnimation)
featureCard(
icon: "antenna.radiowaves.left.and.right",
title: "Beacon Auto-Complete",
description: "Tasks complete automatically when you're near the customer's table beacon."
)
.staggeredAppear(index: 2, appeared: appearAnimation)
featureCard(
icon: "creditcard",
title: "Earn & Get Paid",
description: "Track your earnings in real-time and receive payouts to your bank account."
)
.staggeredAppear(index: 3, appeared: appearAnimation)
}
.padding(.horizontal, 16)
// Links
VStack(spacing: 8) {
Link(destination: URL(string: "https://www.payfrit.com")!) {
HStack(spacing: 10) {
Image(systemName: "globe")
.font(.subheadline)
.foregroundColor(.payfritGreen)
.frame(width: 28, height: 28)
.background(Color.payfritGreen.opacity(0.1))
.clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
VStack(alignment: .leading, spacing: 2) {
Text("Website")
.font(.caption)
.fontWeight(.medium)
.foregroundColor(.primary)
Text("www.payfrit.com")
.font(.caption2)
.foregroundColor(.secondary)
}
Spacer()
Image(systemName: "arrow.up.right")
.font(.caption2)
.foregroundColor(.secondary)
// Feature cards
VStack(spacing: 12) {
ForEach(Array(displayInfo.features.enumerated()), id: \.offset) { index, feature in
featureCard(
icon: mapIconName(feature.icon),
title: feature.title,
description: feature.description
)
.staggeredAppear(index: index, appeared: appearAnimation)
}
.padding(12)
.background(Color(.secondarySystemGroupedBackground))
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
.contentShape(Rectangle())
}
.padding(.horizontal, 16)
// Contact links
if !displayInfo.contacts.isEmpty {
VStack(spacing: 8) {
ForEach(Array(displayInfo.contacts.enumerated()), id: \.offset) { index, contact in
if let url = URL(string: contact.url) {
Link(destination: url) {
contactRow(contact: contact)
}
}
}
}
.padding(.horizontal, 16)
.staggeredAppear(index: displayInfo.features.count, appeared: appearAnimation)
}
// Copyright
if !displayInfo.copyright.isEmpty {
Text(displayInfo.copyright)
.font(.caption2)
.foregroundColor(.secondary)
.padding(.top, 4)
}
}
.padding(.horizontal, 16)
.staggeredAppear(index: 4, appeared: appearAnimation)
// Copyright
Text("\u{00A9} 2026 Payfrit. All rights reserved.")
.font(.caption2)
.foregroundColor(.secondary)
.padding(.top, 4)
Spacer()
.frame(height: 20)
@ -118,6 +109,9 @@ struct AboutScreen: View {
.background(Color(.systemGroupedBackground).ignoresSafeArea())
.navigationTitle("About Payfrit")
.navigationBarTitleDisplayMode(.inline)
.task {
await loadAboutInfo()
}
.onAppear {
withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) {
appearAnimation = true
@ -125,6 +119,55 @@ struct AboutScreen: View {
}
}
private var appVersion: String {
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0"
}
private func loadAboutInfo() async {
do {
aboutInfo = try await APIService.shared.getAboutInfo()
} catch {
// Use fallback on error
print("Failed to load about info: \(error)")
}
isLoading = false
}
/// Map icon names from API to SF Symbols
private func mapIconName(_ apiIcon: String) -> String {
// If it's already an SF Symbol name, use it
if UIImage(systemName: apiIcon) != nil {
return apiIcon
}
// Map common icon names
switch apiIcon.lowercased() {
case "beacon", "radar", "walkup":
return "wave.3.right"
case "group", "friends", "people":
return "person.3"
case "delivery", "bag", "takeaway":
return "bag"
case "payment", "card", "credit":
return "creditcard"
case "globe", "web", "website":
return "globe"
case "email", "mail":
return "envelope"
case "phone", "call":
return "phone"
case "chat", "message":
return "message"
case "task", "tasks", "check":
return "checkmark.circle"
case "cash", "money", "dollar":
return "dollarsign.circle"
case "earn", "payout":
return "creditcard"
default:
return "star"
}
}
private func featureCard(icon: String, title: String, description: String) -> some View {
HStack(spacing: 10) {
Image(systemName: icon)
@ -151,6 +194,37 @@ struct AboutScreen: View {
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
.contentShape(Rectangle())
}
private func contactRow(contact: AboutContact) -> some View {
HStack(spacing: 10) {
Image(systemName: mapIconName(contact.icon))
.font(.subheadline)
.foregroundColor(.payfritGreen)
.frame(width: 28, height: 28)
.background(Color.payfritGreen.opacity(0.1))
.clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
VStack(alignment: .leading, spacing: 2) {
Text(contact.label)
.font(.caption)
.fontWeight(.medium)
.foregroundColor(.primary)
Text(contact.url.replacingOccurrences(of: "https://", with: "").replacingOccurrences(of: "http://", with: ""))
.font(.caption2)
.foregroundColor(.secondary)
}
Spacer()
Image(systemName: "arrow.up.right")
.font(.caption2)
.foregroundColor(.secondary)
}
.padding(12)
.background(Color(.secondarySystemGroupedBackground))
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
.contentShape(Rectangle())
}
}
// MARK: - Staggered Appear Modifier

View file

@ -183,6 +183,7 @@ struct TaskDetailScreen: View {
let fromDetails = details?.orderTotal ?? 0
let fromTask = task.orderTotal
let cents = fromDetails > 0 ? fromDetails : fromTask
NSLog("[Cash] orderTotal fromDetails=%.2f, fromTask=%.2f, using=%.2f, asInt=%d", fromDetails, fromTask, cents, Int(cents))
return Int(cents)
}