This commit is contained in:
Daniel Arantes Loverde
2026-03-05 11:00:17 -03:00
parent 83882538c2
commit a98089b48d
2 changed files with 107 additions and 56 deletions

View File

@@ -8,6 +8,10 @@
"comment" : "A placeholder text used to maintain vertical spacing in the UI.",
"isCommentAutoGenerated" : true
},
"- %@" : {
"comment" : "A text element displaying a negative monetary value, indicating a discount.",
"isCommentAutoGenerated" : true
},
"..." : {
},
@@ -67,6 +71,9 @@
}
}
}
},
"•" : {
},
"+ %@" : {
"comment" : "A small, secondary text label displaying the price of an item.",
@@ -96,6 +103,10 @@
},
"Acompanhamento em tempo real" : {
},
"Acompanhar" : {
"comment" : "A button label that translates to \"Track\" in English.",
"isCommentAutoGenerated" : true
},
"Add" : {
"comment" : "Button in items list that will cause a new item to be added",
@@ -204,14 +215,6 @@
"comment" : "A description below the fields in the \"Editar endereço\" form, instructing the user to update their address details.",
"isCommentAutoGenerated" : true
},
"Avaliação" : {
"comment" : "A label describing a review section.",
"isCommentAutoGenerated" : true
},
"Avaliar pedido" : {
"comment" : "A button that allows users to rate and review their orders.",
"isCommentAutoGenerated" : true
},
"Avaliar Pedido" : {
},
@@ -303,10 +306,6 @@
"comment" : "A label for the comment section in the order review view.",
"isCommentAutoGenerated" : true
},
"Comprar novamente" : {
"comment" : "A button that allows a user to purchase an order again.",
"isCommentAutoGenerated" : true
},
"Concluir" : {
"comment" : "The text for a button that confirms and closes a sheet.",
"isCommentAutoGenerated" : true
@@ -419,9 +418,16 @@
"comment" : "A label describing the delivery location section.",
"isCommentAutoGenerated" : true
},
"Desconto" : {
"comment" : "A label for a discount applied to an order.",
"isCommentAutoGenerated" : true
},
"Detalhes" : {
"comment" : "The title of the navigation bar at the top of the product detail sheet.",
"isCommentAutoGenerated" : true
},
"Detalhes do Pedido" : {
},
"Do que você gostou?" : {
"comment" : "A prompt asking users to mention what they liked about a review.",
@@ -548,9 +554,6 @@
}
}
}
},
"Histórico de Pedidos" : {
},
"Home" : {
"comment" : "Tab bar item title for the Home tab",
@@ -596,6 +599,9 @@
"Ir para o Pagamento" : {
"comment" : "A button label that translates to \"Go to Payment\" in English.",
"isCommentAutoGenerated" : true
},
"Itens do Pedido" : {
},
"Já tem uma conta?" : {
"comment" : "A question displayed below the \"Cadastrar e Receber Código\" button in the registration view. The text is a hyperlink to the login view.",
@@ -821,6 +827,10 @@
"comment" : "The name of the app.",
"isCommentAutoGenerated" : true
},
"Pedir Novamente" : {
"comment" : "A button that allows a user to order the same items again.",
"isCommentAutoGenerated" : true
},
"Perfil" : {
"comment" : "A label for the \"Profile\" tab in the main tab view.",
"isCommentAutoGenerated" : true
@@ -862,6 +872,9 @@
}
}
}
},
"Precisa de ajuda com esse pedido?" : {
},
"Preencha os dados abaixo para adicionar um endereço." : {
"comment" : "A description below the form to add a new address, instructing the user to fill in the required information.",
@@ -1020,6 +1033,9 @@
"Sua vontade, no seu tempo.\nTudo o que você precisa, em um toque." : {
"comment" : "A tagline displayed in the login view.",
"isCommentAutoGenerated" : true
},
"Subtotal" : {
},
"System" : {
"comment" : "Menu item indicating that the appearance should be in the default system mode",
@@ -1051,6 +1067,10 @@
}
}
},
"Taxa de entrega" : {
"comment" : "A label describing the delivery fee.",
"isCommentAutoGenerated" : true
},
"Tem certeza que deseja sair da sua conta?" : {
},
@@ -1099,6 +1119,9 @@
"Toque no sabor para escolher adicionais." : {
"comment" : "A description below the list of pizza flavors, explaining that tapping a flavor will open an additional options list.",
"isCommentAutoGenerated" : true
},
"Toque para avaliar" : {
},
"Total" : {
"comment" : "A label displayed above the total price in the cart.",
@@ -1123,6 +1146,13 @@
"UPLOAD" : {
"comment" : "A button label that says \"UPLOAD\".",
"isCommentAutoGenerated" : true
},
"Ver Detalhes" : {
"comment" : "A button that shows order details when pressed.",
"isCommentAutoGenerated" : true
},
"Ver loja" : {
},
"Ver motivo do cancelamento" : {
@@ -1175,12 +1205,12 @@
}
}
},
"Você ainda não avaliou nenhum pedido." : {
"comment" : "A message displayed when a user has not reviewed any orders yet.",
"isCommentAutoGenerated" : true
},
"Você gostou da entrega?" : {
},
"Você não tem avaliações nem pendências no momento." : {
"comment" : "A description displayed when a user has no reviews or pending reviews.",
"isCommentAutoGenerated" : true
},
"Welcome" : {
"comment" : "Tab bar item title for the Welcome tab",

View File

@@ -12,11 +12,6 @@ struct OrdersView: View {
var body: some View {
ScrollView(showsIndicators: false) {
VStack(alignment: .leading, spacing: 14) {
Text("Meus Pedidos")
.font(AppTypography.heading1)
.foregroundStyle(AppColors.textPrimary)
.padding(.top, 6)
if isLoading {
ProgressView()
.frame(maxWidth: .infinity)
@@ -75,39 +70,22 @@ struct OrdersView: View {
return VStack(alignment: .leading, spacing: 14) {
HStack(spacing: 12) {
AsyncStoreImage(imageURL: resolvedMediaURL(order.storeLogoURL))
.frame(width: 88, height: 88)
.clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous))
.background(AppColors.brandSoft, in: RoundedRectangle(cornerRadius: 24, style: .continuous))
.frame(width: 80, height: 80)
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
.background(AppColors.brandSoft, in: RoundedRectangle(cornerRadius: 20, style: .continuous))
VStack(alignment: .leading, spacing: 5) {
Text(order.storeName?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false ? (order.storeName ?? "Pedido") : "Pedido #\(order.shortId ?? order.id)")
.font(AppTypography.heading2)
.foregroundStyle(AppColors.textPrimary)
.lineLimit(1)
HStack(spacing: 6) {
Text(orderMetaText(order))
.font(AppTypography.body)
.foregroundStyle(AppColors.textMuted)
Text(order.storeName?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false ? (order.storeName ?? "Pedido") : "Pedido #\(order.shortId ?? order.id)")
.font(AppTypography.heading2)
.minimumScaleFactor(0.01)
.foregroundStyle(AppColors.textPrimary)
.lineLimit(1)
if let rating = storeRating(for: order) {
Text("")
.font(AppTypography.body)
.foregroundStyle(AppColors.textMuted)
Image(systemName: "star.fill")
.font(.system(size: 11, weight: .bold))
.foregroundStyle(Color(hex: "#7CF02A"))
Text(String(format: "%.1f", rating).replacingOccurrences(of: ".", with: ","))
.font(AppTypography.body)
.foregroundStyle(AppColors.textMuted)
}
}
}
Spacer(minLength: 0)
Spacer()
Text(status.badgeTitle)
.font(AppTypography.caption)
.minimumScaleFactor(0.01)
.foregroundStyle(status.badgeForeground)
.padding(.horizontal, 10)
.padding(.vertical, 6)
@@ -115,17 +93,45 @@ struct OrdersView: View {
.clipShape(Capsule())
}
HStack(spacing: 6) {
Text(orderMetaText(order))
.font(AppTypography.body)
.minimumScaleFactor(0.01)
.foregroundStyle(AppColors.textMuted)
.lineLimit(1)
if let rating = storeRating(for: order) {
Text("")
.font(AppTypography.body)
.minimumScaleFactor(0.01)
.foregroundStyle(AppColors.textMuted)
Image(systemName: "star.fill")
.font(.system(size: 11, weight: .bold))
.minimumScaleFactor(0.01)
.foregroundStyle(Color(hex: "#7CF02A"))
Text(String(format: "%.1f", rating).replacingOccurrences(of: ".", with: ","))
.font(AppTypography.body)
.minimumScaleFactor(0.01)
.foregroundStyle(AppColors.textMuted)
}
}
}
}
Divider()
HStack(spacing: 12) {
Button(status.isCanceled ? "Ajuda" : "Ver Detalhes") {
selectedOrderRoute = route
}
.font(AppTypography.heading2)
.font(AppTypography.heading3)
.foregroundStyle(AppColors.textMuted)
.lineLimit(1)
.minimumScaleFactor(0.01)
.frame(maxWidth: .infinity, alignment: .leading)
.buttonStyle(.plain)
.layoutPriority(2)
Spacer(minLength: 12)
Spacer()
Button {
if status.isInProgress {
@@ -142,11 +148,13 @@ struct OrdersView: View {
HStack(spacing: 8) {
Image(systemName: status.isInProgress ? "truck.box.fill" : "arrow.clockwise")
Text(status.isInProgress ? "Acompanhar" : "Pedir Novamente")
.font(AppTypography.heading2)
.font(AppTypography.heading3)
.lineLimit(1)
}
.lineLimit(1)
.foregroundStyle(status.actionForeground)
.padding(.horizontal, 24)
.padding(.vertical, 12)
.padding(.horizontal, 16)
.padding(.vertical, 11)
.background(status.actionBackground)
.clipShape(Capsule())
}
@@ -167,18 +175,31 @@ struct OrdersView: View {
}
private func orderVisualStatus(for order: AppOrderSummary) -> OrderRowStatusStyle {
let explicitLabel = (order.statusLabel ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
if explicitLabel.isEmpty == false {
let normalizedLabel = explicitLabel.uppercased()
if normalizedLabel.contains("CANCEL") { return .canceled }
if normalizedLabel.contains("ENTREG") || normalizedLabel.contains("COMPLET") { return .delivered }
}
let rawDetailed = (order.statusDetailed ?? "").trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
let rawStatus = (order.status ?? "").trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
let normalized = ((order.statusDetailed ?? order.status) ?? "").uppercased()
if normalized.contains("CANCEL") {
let technical = [rawDetailed, rawStatus].joined(separator: "|")
if technical.contains("CANCEL") || technical.contains("REFUND") {
return .canceled
}
if normalized.contains("COMPLETED") || normalized.contains("DELIVERED") {
if technical.contains("COMPLETED") || technical.contains("DELIVERED") {
return .delivered
}
if technical.contains("IN_DELIVERY")
|| technical.contains("DELIVERING")
|| technical.contains("OUT_FOR_DELIVERY")
|| technical.contains("PENDING")
|| technical.contains("ACCEPTED")
|| technical.contains("PREPAR")
|| technical.contains("READY") {
return .inProgress
}
let label = (order.statusLabel ?? "").trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if label.contains("CANCEL") {
return .canceled
}
if label.contains("CONCLU") || label.contains("ENTREGUE") {
return .delivered
}
return .inProgress
@@ -440,7 +461,7 @@ struct OrdersView: View {
}
}
private struct OrderRouteContext: Identifiable, Hashable {
struct OrderRouteContext: Identifiable, Hashable {
var id: String { orderId }
let orderId: String
let shortId: String?