Add debug logging for orderTotal
This commit is contained in:
parent
4a2f984c94
commit
40b1ee5d60
3 changed files with 160 additions and 85 deletions
|
|
@ -441,7 +441,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 3;
|
CURRENT_PROJECT_VERSION = 5;
|
||||||
DEVELOPMENT_TEAM = U83YL8VRF3;
|
DEVELOPMENT_TEAM = U83YL8VRF3;
|
||||||
GENERATE_INFOPLIST_FILE = NO;
|
GENERATE_INFOPLIST_FILE = NO;
|
||||||
INFOPLIST_FILE = PayfritWorks/Info.plist;
|
INFOPLIST_FILE = PayfritWorks/Info.plist;
|
||||||
|
|
@ -456,8 +456,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.payfrit.works;
|
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
|
||||||
PRODUCT_NAME = "Payfrit Works";
|
PRODUCT_NAME = "Payfrit Works";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
|
@ -473,7 +473,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 3;
|
CURRENT_PROJECT_VERSION = 5;
|
||||||
DEVELOPMENT_TEAM = U83YL8VRF3;
|
DEVELOPMENT_TEAM = U83YL8VRF3;
|
||||||
GENERATE_INFOPLIST_FILE = NO;
|
GENERATE_INFOPLIST_FILE = NO;
|
||||||
INFOPLIST_FILE = PayfritWorks/Info.plist;
|
INFOPLIST_FILE = PayfritWorks/Info.plist;
|
||||||
|
|
@ -488,8 +488,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.payfrit.works;
|
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
|
||||||
PRODUCT_NAME = "Payfrit Works";
|
PRODUCT_NAME = "Payfrit Works";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,28 @@ import SwiftUI
|
||||||
struct AboutScreen: View {
|
struct AboutScreen: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
@State private var appearAnimation = false
|
@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 {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
|
@ -19,7 +41,7 @@ struct AboutScreen: View {
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
Text("Version 1.0.0")
|
Text("Version \(appVersion)")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
|
|
@ -28,88 +50,57 @@ struct AboutScreen: View {
|
||||||
.scaleEffect(appearAnimation ? 1 : 0.9)
|
.scaleEffect(appearAnimation ? 1 : 0.9)
|
||||||
.opacity(appearAnimation ? 1 : 0)
|
.opacity(appearAnimation ? 1 : 0)
|
||||||
|
|
||||||
// Intro
|
if isLoading {
|
||||||
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.")
|
ProgressView()
|
||||||
|
.padding(.vertical, 20)
|
||||||
|
} else {
|
||||||
|
// Description
|
||||||
|
if !displayInfo.description.isEmpty {
|
||||||
|
Text(displayInfo.description)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.multilineTextAlignment(.leading)
|
.multilineTextAlignment(.leading)
|
||||||
.padding(.horizontal, 16)
|
.padding(.horizontal, 16)
|
||||||
.opacity(appearAnimation ? 1 : 0)
|
.opacity(appearAnimation ? 1 : 0)
|
||||||
.offset(y: appearAnimation ? 0 : 15)
|
.offset(y: appearAnimation ? 0 : 15)
|
||||||
|
}
|
||||||
|
|
||||||
// Feature cards
|
// Feature cards
|
||||||
VStack(spacing: 12) {
|
VStack(spacing: 12) {
|
||||||
|
ForEach(Array(displayInfo.features.enumerated()), id: \.offset) { index, feature in
|
||||||
featureCard(
|
featureCard(
|
||||||
icon: "checkmark.circle",
|
icon: mapIconName(feature.icon),
|
||||||
title: "Claim Tasks",
|
title: feature.title,
|
||||||
description: "View available tasks from businesses you work for and claim them with one tap."
|
description: feature.description
|
||||||
)
|
)
|
||||||
.staggeredAppear(index: 0, appeared: appearAnimation)
|
.staggeredAppear(index: index, 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)
|
.padding(.horizontal, 16)
|
||||||
|
|
||||||
// Links
|
// Contact links
|
||||||
|
if !displayInfo.contacts.isEmpty {
|
||||||
VStack(spacing: 8) {
|
VStack(spacing: 8) {
|
||||||
Link(destination: URL(string: "https://www.payfrit.com")!) {
|
ForEach(Array(displayInfo.contacts.enumerated()), id: \.offset) { index, contact in
|
||||||
HStack(spacing: 10) {
|
if let url = URL(string: contact.url) {
|
||||||
Image(systemName: "globe")
|
Link(destination: url) {
|
||||||
.font(.subheadline)
|
contactRow(contact: contact)
|
||||||
.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)
|
|
||||||
}
|
}
|
||||||
.padding(12)
|
|
||||||
.background(Color(.secondarySystemGroupedBackground))
|
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
|
|
||||||
.contentShape(Rectangle())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 16)
|
.padding(.horizontal, 16)
|
||||||
.staggeredAppear(index: 4, appeared: appearAnimation)
|
.staggeredAppear(index: displayInfo.features.count, appeared: appearAnimation)
|
||||||
|
}
|
||||||
|
|
||||||
// Copyright
|
// Copyright
|
||||||
Text("\u{00A9} 2026 Payfrit. All rights reserved.")
|
if !displayInfo.copyright.isEmpty {
|
||||||
|
Text(displayInfo.copyright)
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.padding(.top, 4)
|
.padding(.top, 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
.frame(height: 20)
|
.frame(height: 20)
|
||||||
|
|
@ -118,6 +109,9 @@ struct AboutScreen: View {
|
||||||
.background(Color(.systemGroupedBackground).ignoresSafeArea())
|
.background(Color(.systemGroupedBackground).ignoresSafeArea())
|
||||||
.navigationTitle("About Payfrit")
|
.navigationTitle("About Payfrit")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.task {
|
||||||
|
await loadAboutInfo()
|
||||||
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) {
|
withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) {
|
||||||
appearAnimation = true
|
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 {
|
private func featureCard(icon: String, title: String, description: String) -> some View {
|
||||||
HStack(spacing: 10) {
|
HStack(spacing: 10) {
|
||||||
Image(systemName: icon)
|
Image(systemName: icon)
|
||||||
|
|
@ -151,6 +194,37 @@ struct AboutScreen: View {
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
|
||||||
.contentShape(Rectangle())
|
.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
|
// MARK: - Staggered Appear Modifier
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,7 @@ struct TaskDetailScreen: View {
|
||||||
let fromDetails = details?.orderTotal ?? 0
|
let fromDetails = details?.orderTotal ?? 0
|
||||||
let fromTask = task.orderTotal
|
let fromTask = task.orderTotal
|
||||||
let cents = fromDetails > 0 ? fromDetails : fromTask
|
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)
|
return Int(cents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue