payment and list
This commit is contained in:
@@ -7,7 +7,9 @@ struct CartView: View {
|
||||
@State var couponCode = ""
|
||||
@State var appliedCouponCode: String? = nil
|
||||
@State var discountValue: Double = 0
|
||||
@State var deliveryFee: Double = 5
|
||||
@State var deliveryFee: Double? = nil
|
||||
@State var selectedCustomerAddress: CustomerAddress? = nil
|
||||
@State var isLoadingDeliveryFee = false
|
||||
|
||||
var body: some View {
|
||||
ScrollView(showsIndicators: false) {
|
||||
@@ -50,6 +52,9 @@ struct CartView: View {
|
||||
.navigationDestination(isPresented: $openCheckout) {
|
||||
CheckoutView(appState: $appState)
|
||||
}
|
||||
.task(id: deliveryFeeWatchKey) {
|
||||
await refreshDeliveryFee()
|
||||
}
|
||||
}
|
||||
|
||||
private var subtotalValue: Double {
|
||||
@@ -57,7 +62,16 @@ struct CartView: View {
|
||||
}
|
||||
|
||||
private var totalValue: Double {
|
||||
max(0, subtotalValue + deliveryFee - discountValue)
|
||||
max(0, subtotalValue + (deliveryFee ?? 0) - discountValue)
|
||||
}
|
||||
|
||||
private var deliveryFeeWatchKey: String {
|
||||
let storeId = appState.cart.storeId ?? "nil"
|
||||
let selectedId = appState.address.selectedId ?? "nil"
|
||||
let display = appState.address.display.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
|
||||
let lat = appState.address.latitude.map { String(format: "%.5f", $0) } ?? "nil"
|
||||
let lng = appState.address.longitude.map { String(format: "%.5f", $0) } ?? "nil"
|
||||
return "\(storeId)|\(selectedId)|\(display)|\(lat)|\(lng)"
|
||||
}
|
||||
|
||||
private var couponSection: some View {
|
||||
@@ -108,7 +122,7 @@ struct CartView: View {
|
||||
.foregroundStyle(AppColors.textPrimary)
|
||||
|
||||
summaryRow(title: "Subtotal", value: formatCurrency(subtotalValue))
|
||||
summaryRow(title: "Taxa de Entrega", value: formatCurrency(deliveryFee))
|
||||
summaryRow(title: "Taxa de Entrega", value: deliveryFeeLabel)
|
||||
summaryRow(title: "Desconto", value: "-\(formatCurrency(discountValue))", valueColor: Color.red)
|
||||
|
||||
Divider()
|
||||
@@ -136,6 +150,16 @@ struct CartView: View {
|
||||
.clipShape(RoundedRectangle(cornerRadius: AppLayout.radiusXL, style: .continuous))
|
||||
}
|
||||
|
||||
private var deliveryFeeLabel: String {
|
||||
if isLoadingDeliveryFee {
|
||||
return "Calculando..."
|
||||
}
|
||||
if let deliveryFee {
|
||||
return formatCurrency(deliveryFee)
|
||||
}
|
||||
return "Indisponível"
|
||||
}
|
||||
|
||||
private func summaryRow(title: String, value: String, valueColor: Color? = nil, highlighted: Bool = false) -> some View {
|
||||
HStack {
|
||||
Text(title)
|
||||
@@ -230,4 +254,88 @@ struct CartView: View {
|
||||
private func formatCurrency(_ value: Double) -> String {
|
||||
String(format: "R$ %.2f", value).replacingOccurrences(of: ".", with: ",")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func refreshDeliveryFee() async {
|
||||
guard appState.cart.items.isEmpty == false else {
|
||||
deliveryFee = nil
|
||||
selectedCustomerAddress = nil
|
||||
return
|
||||
}
|
||||
guard let storeId = appState.cart.storeId, storeId.isEmpty == false else {
|
||||
deliveryFee = nil
|
||||
selectedCustomerAddress = nil
|
||||
return
|
||||
}
|
||||
|
||||
isLoadingDeliveryFee = true
|
||||
defer { isLoadingDeliveryFee = false }
|
||||
|
||||
do {
|
||||
let profileResponse = try await ApiService().profile()
|
||||
let addresses = profileResponse.result?.addressBook ?? []
|
||||
|
||||
if let selectedId = appState.address.selectedId, selectedId.isEmpty == false {
|
||||
selectedCustomerAddress = addresses.first(where: { $0.id == selectedId })
|
||||
} else {
|
||||
selectedCustomerAddress = nil
|
||||
}
|
||||
|
||||
if selectedCustomerAddress == nil {
|
||||
let display = appState.address.display
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
.lowercased()
|
||||
if display.isEmpty == false, display != "defina seu endereco" {
|
||||
selectedCustomerAddress = addresses.first {
|
||||
($0.label ?? "").trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == display
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if selectedCustomerAddress == nil {
|
||||
selectedCustomerAddress = addresses.first
|
||||
}
|
||||
|
||||
if let selected = selectedCustomerAddress {
|
||||
appState.address.selectedId = selected.id
|
||||
let label = (selected.label ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if label.isEmpty == false {
|
||||
appState.address.display = label
|
||||
}
|
||||
if let lat = selected.latLong?.first, let lng = selected.latLong?.dropFirst().first {
|
||||
appState.address.latitude = lat
|
||||
appState.address.longitude = lng
|
||||
}
|
||||
SessionStateStore.saveAddress(appState.address)
|
||||
}
|
||||
|
||||
let payloadLat = selectedCustomerAddress?.latLong?.first ?? appState.address.latitude
|
||||
let payloadLng = selectedCustomerAddress?.latLong?.dropFirst().first ?? appState.address.longitude
|
||||
|
||||
let payload = ValidateDeliveryAddressPayload(
|
||||
address: ValidateDeliveryAddressDataPayload(
|
||||
street: selectedCustomerAddress?.address,
|
||||
number: selectedCustomerAddress?.number,
|
||||
neighborhood: selectedCustomerAddress?.neighborhood,
|
||||
city: selectedCustomerAddress?.city,
|
||||
state: selectedCustomerAddress?.state,
|
||||
zip: selectedCustomerAddress?.zipCode,
|
||||
lat: payloadLat,
|
||||
lng: payloadLng
|
||||
)
|
||||
)
|
||||
|
||||
let validationResponse = try await ApiService().validateDeliveryAddress(storeId: storeId, payload: payload)
|
||||
guard validationResponse.error == false,
|
||||
validationResponse.result?.deliveryAllowed == true,
|
||||
let fee = validationResponse.result?.deliveryFee else {
|
||||
deliveryFee = nil
|
||||
return
|
||||
}
|
||||
|
||||
deliveryFee = fee
|
||||
} catch {
|
||||
deliveryFee = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user