diff --git a/pedi-foods/Sources/PediFoods/Resources/Localizable.xcstrings b/pedi-foods/Sources/PediFoods/Resources/Localizable.xcstrings index 41be62f..59d8729 100644 --- a/pedi-foods/Sources/PediFoods/Resources/Localizable.xcstrings +++ b/pedi-foods/Sources/PediFoods/Resources/Localizable.xcstrings @@ -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", diff --git a/pedi-foods/Sources/PediFoods/Views/Main/OrdersView.swift b/pedi-foods/Sources/PediFoods/Views/Main/OrdersView.swift index b606bbc..94baa83 100644 --- a/pedi-foods/Sources/PediFoods/Views/Main/OrdersView.swift +++ b/pedi-foods/Sources/PediFoods/Views/Main/OrdersView.swift @@ -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,44 +70,51 @@ 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(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) + Spacer() + Text(status.badgeTitle) + .font(AppTypography.caption) + .minimumScaleFactor(0.01) + .foregroundStyle(status.badgeForeground) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(status.badgeBackground) + .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) } } } - - Spacer(minLength: 0) - - Text(status.badgeTitle) - .font(AppTypography.caption) - .foregroundStyle(status.badgeForeground) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(status.badgeBackground) - .clipShape(Capsule()) } Divider() @@ -121,11 +123,15 @@ struct OrdersView: View { 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?