This commit is contained in:
Daniel Arantes Loverde
2026-03-19 08:44:31 -03:00
parent 5fa98ce358
commit c49725a5f7
16 changed files with 1496 additions and 147 deletions

View File

@@ -12,10 +12,12 @@ private struct TrackingStep: Identifiable {
struct OrderTrackingView: View {
let orderId: String
let initialShortId: String?
@Environment(\.openURL) var openURL
@State var isLoading = true
@State var errorMessage: String? = nil
@State var order: PublicOrderResult? = nil
@State var storeContactPhone: String? = nil
@State var tracker = OrderRealtimeTracker()
@State var showCancellationReason = false
@State var reviewDraft: ReviewDraft? = nil
@@ -51,6 +53,9 @@ struct OrderTrackingView: View {
await loadInitialOrder()
tracker.onOrderUpdated = { updated in
order = updated
if let inlinePhone = updated.storePhone, inlinePhone.isEmpty == false {
storeContactPhone = inlinePhone
}
isLoading = false
errorMessage = nil
}
@@ -224,7 +229,9 @@ struct OrderTrackingView: View {
}
private var contactButton: some View {
Button("CONTATO") {}
Button("CONTATO") {
openStoreWhatsApp()
}
.font(AppTypography.heading2)
.foregroundStyle(AppColors.textPrimary)
.frame(maxWidth: .infinity, minHeight: 56)
@@ -756,8 +763,10 @@ struct OrderTrackingView: View {
logger.error("OrderTracking initial fetch API error orderId=\(orderId, privacy: .public) message=\((response.message ?? "unknown"), privacy: .public)")
} else if let result = response.result {
order = result
storeContactPhone = result.storePhone
errorMessage = nil
logger.info("OrderTracking initial fetch success orderId=\(orderId, privacy: .public) status=\((result.status ?? "nil"), privacy: .public) paymentStatus=\((result.paymentStatus ?? "nil"), privacy: .public)")
await refreshStoreContactPhone(for: result)
}
} catch {
errorMessage = "Não foi possível carregar o pedido."
@@ -766,4 +775,61 @@ struct OrderTrackingView: View {
isLoading = false
}
@MainActor
private func refreshStoreContactPhone(for order: PublicOrderResult) async {
guard let storeId = order.storeId?.trimmingCharacters(in: .whitespacesAndNewlines), storeId.isEmpty == false else {
if let inlinePhone = order.storePhone, inlinePhone.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
storeContactPhone = inlinePhone
}
return
}
do {
let response = try await ApiService().storeInfo(storeId: storeId)
if response.error == false, let result = response.result {
let phone = (result.whatsapp ?? result.phone ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
if phone.isEmpty == false {
storeContactPhone = phone
return
}
}
} catch {
// Fallback handled below.
}
if let inlinePhone = order.storePhone, inlinePhone.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
storeContactPhone = inlinePhone
}
}
private func openStoreWhatsApp() {
guard let phoneRaw = storeContactPhone,
let url = makeWhatsAppURL(from: phoneRaw) else {
SnackbarCenter.shared.show(
title: "Telefone da loja indisponível.",
style: .warning,
icon: "exclamationmark.triangle.fill",
duration: 2.8
)
return
}
openURL(url)
}
private func makeWhatsAppURL(from phoneRaw: String) -> URL? {
var digits = phoneRaw.filter(\.isNumber)
if digits.isEmpty { return nil }
if digits.hasPrefix("0") {
digits = String(digits.drop(while: { $0 == "0" }))
}
if digits.hasPrefix("55") == false && (digits.count == 10 || digits.count == 11) {
digits = "55" + digits
}
guard digits.count >= 12 else { return nil }
return URL(string: "https://wa.me/\(digits)")
}
}