taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

PaidTransactionDetailV.swift (5336B)


      1 /*
      2  * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
      3  * See LICENSE.md
      4  */
      5 /**
      6  * Overview when there's more than 1 currency/exchange
      7  *
      8  * @author Marc Stibane
      9  */
     10 import SwiftUI
     11 
     12 struct PaidTransactionDetailV: View {
     13     let stack: CallStack
     14     let paymentTx: PaymentTransaction
     15 
     16 #if DEBUG
     17     @AppStorage("developerMode") var developerMode: Bool = true
     18 #else
     19     @AppStorage("developerMode") var developerMode: Bool = false
     20 #endif
     21 
     22     var body: some View {
     23         let common = paymentTx.common
     24         let details = paymentTx.details
     25         let terms = details.contractTerms
     26         let info = details.info
     27         Section {
     28             if let posConfirmation = details.posConfirmation {
     29                 Text("Confirmation:", comment: "purchase may have a pos validation / confirmation")
     30                     .talerFont(.title3)
     31                     .listRowSeparator(.hidden)
     32                 let totp = Text(posConfirmation)
     33                     .talerFont(.title1)
     34                 let posConfirmationViaNfc = details.posConfirmationViaNfc
     35                 let isPaying = common.isDialog   // We are ALWAYS already finished with the tx
     36                 if #available(iOS 17.7, *) {
     37                     BorderWithNFC(totpString: posConfirmation, nfcHint: true,
     38                                 automaticNfc: isPaying ? posConfirmationViaNfc : false,
     39                                         size: 250, scanHints: nil
     40                     ) { totp }
     41                 } else {
     42                     totp
     43                 }
     44             }
     45             if let info {
     46 //              Text(info.merchant.name)        TODO: show name & logo here?
     47                 if common.isDone {
     48                     VStack(alignment: .leading) {
     49                         Text("Order-ID:")
     50                             .talerFont(.title3)
     51                         HStack {
     52                             Spacer()
     53                             Text(info.orderId)
     54                                 .talerFont(.body)
     55                         }
     56                     }
     57                 }
     58             }
     59             VStack(alignment: .leading) {
     60                 if let info {
     61                     Text(info.summary)
     62                         .talerFont(.title3)
     63                 }
     64                 if let choiceIndex = details.choiceIndex {
     65                     if let contractTerms = details.contractTerms {
     66                         if let choices = contractTerms.choices,
     67                            choices.indices.contains(choiceIndex) {
     68                             let choice = choices[choiceIndex]
     69                             HStack {
     70                                 if let info {
     71                                     Spacer()
     72                                 }
     73                                 Text(choice.locDescription ?? "Index: \(choiceIndex)")   // fallback should never happen
     74                                     .talerFont(.body)
     75                             }
     76                         }
     77                     }
     78                 }
     79             }
     80             if let info {
     81                 if let fulfillmentUrl = info.fulfillmentUrl, common.isDone {
     82                     // per api-common.rst's WebURL definition, fulfillment_url must be http(s) -
     83                     // reject any other scheme (tel:, sms:, a third-party app's custom scheme, ...)
     84                     if let destination = URL(string: fulfillmentUrl),
     85                        let scheme = destination.scheme?.lowercased(), scheme == "http" || scheme == "https" {
     86                         let buttonTitle = info.fulfillmentMessage ?? String(localized: "Open merchant website")
     87                         Link(buttonTitle, destination: destination)
     88                             .buttonStyle(TalerButtonStyle(type: .prominent))
     89                             .accessibilityHint(String(localized: "Will go to the merchant website.", comment: "a11y"))
     90                     }
     91                 } else if let fulfillmentMessage = info.fulfillmentMessage {
     92                     Text(fulfillmentMessage)
     93                         .talerFont(.body)
     94                 }
     95             }
     96             if let failReason = common.failReason {
     97                 if let hint = failReason.hint {
     98                     Text(hint)
     99                         .talerFont(.title3)
    100                 }
    101             }
    102             if let abortReason = details.abortReason {
    103                 if let exchangeResponse = abortReason.exchangeResponse,
    104                    let hint2 = exchangeResponse.hint {
    105                     Text(hint2)
    106                         .talerFont(.body)
    107                 }
    108                 if developerMode {
    109                     if let hint3 = abortReason.hint {
    110                         Text(hint3)
    111                             .talerFont(.body)
    112                     }
    113                 }
    114             }
    115         }
    116         if let products = terms?.products {
    117             if !products.isEmpty {
    118                 Section {
    119                     ForEach(products) { product in
    120 //                        if let productId = product.productId {
    121                         if let productName = product.productName {
    122                             Text(productName)
    123                                 .talerFont(.body)
    124                         }
    125                     }
    126                 }
    127             }
    128         }
    129     }
    130 }
    131 
    132 // MARK: -
    133 //#Preview {
    134 //    TransactionDetailV()
    135 //}