Skip to content

Commit

Permalink
[Woo POS][Cash & Receipts] Render cash button and navigate to cash vi…
Browse files Browse the repository at this point in the history
…ew (#14724)
  • Loading branch information
iamgabrielma authored Jan 6, 2025
2 parents 2171556 + 4e5a727 commit 7f796e4
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 1 deletion.
138 changes: 138 additions & 0 deletions WooCommerce/Classes/POS/Presentation/PointOfSaleCollectCashView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import SwiftUI

struct PointOfSaleCollectCashView: View {
@Environment(\.dismiss) private var dismiss
@EnvironmentObject private var posModel: PointOfSaleAggregateModel

@State private var textFieldAmountInput: String = ""
@State private var isLoading: Bool = false
@State private var errorMessage: String?

let orderTotal: String

private var formattedOrderTotal: String {
String.localizedStringWithFormat(Localization.backNavigationSubtitle, orderTotal)
}

var body: some View {
VStack(alignment: .center, spacing: 20) {
HStack {
Button(action: {
dismiss()
}, label: {
VStack {
HStack {
Image(systemName: "chevron.left")
Text(Localization.backNavigationTitle)
}
.font(.posTitleRegular)
.bold()
.foregroundColor(.primary)

Text(formattedOrderTotal)
.font(.posBodyRegular)
.foregroundColor(.primary)
}
})
Spacer()
}
.padding()

TextField("$0.00", text: $textFieldAmountInput)
.keyboardType(.numbersAndPunctuation)
.textInputAutocapitalization(.none)
.autocorrectionDisabled()
.multilineTextAlignment(.center)
.font(POSFontStyle.posTitleRegular)
.focused()
.padding()
.onSubmit {
Task { @MainActor in
await markComplete()
}
}

if let errorMessage = errorMessage {
Text(errorMessage)
.font(POSFontStyle.posBodyRegular)
.foregroundColor(.red)
}

Button(action: {
Task { @MainActor in
await markComplete()
}
}, label: {
HStack(spacing: Constants.buttonSpacing) {
if isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
.tint(Color.posPrimaryTextInverted)
} else {
Text(Localization.markPaymentCompletedButtonTitle)
.font(Constants.buttonFont)
}
}
.frame(maxWidth: .infinity)
})
.padding(Constants.buttonPadding)
.frame(maxWidth: .infinity)
.foregroundColor(Color.posPrimaryTextInverted)
.background(Color.posOverlayFillInverted)
.cornerRadius(Constants.buttonCornerRadius)
.contentShape(Rectangle())
.disabled(isLoading)

Spacer()
}
.padding()
.animation(.easeInOut, value: errorMessage)
.onChange(of: textFieldAmountInput) { amount in
errorMessage = nil
}
}

private func markComplete() async {
// TODO:
// https://github.com/woocommerce/woocommerce-ios/issues/14602
}
}

private extension PointOfSaleCollectCashView {
enum Constants {
static let buttonSpacing: CGFloat = 12
static let buttonPadding: CGFloat = 32
static let buttonFont: POSFontStyle = .posBodyEmphasized
static let buttonCornerRadius: CGFloat = 8
}

enum Localization {
static let backNavigationTitle = NSLocalizedString(
"pointOfSale.cashview.back.navigation.title",
value: "Cash payment",
comment: "Title for the cash payment view navigation back button"
)
static let backNavigationSubtitle = NSLocalizedString(
"pointOfSale.cashview.back.navigation.subtitle",
value: "Total: %1$@",
comment: "Subtitle for the cash payment view navigation back button" +
"Reads as 'Total: $1.23'"
)
static let markPaymentCompletedButtonTitle = NSLocalizedString(
"pointOfSale.cashview.button.markpaymentcompleted.title",
value: "Mark payment as complete",
comment: "Button to mark a cash payment as completed"
)
}
}

#if DEBUG
#Preview {
let posModel = PointOfSaleAggregateModel(
itemsController: PointOfSalePreviewItemsController(),
cardPresentPaymentService: CardPresentPaymentPreviewService(),
orderController: PointOfSalePreviewOrderController())
PointOfSaleCollectCashView(orderTotal: "$1.23")
.environmentObject(posModel)
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct POSSendReceiptView: View {
isShowingSendReceiptView = false
}, label: {
HStack {
Image(systemName: "arrow.backward")
Image(systemName: "chevron.left")
Text(Localization.emailReceiptNavigationText)
}
.font(.title)
Expand Down
33 changes: 33 additions & 0 deletions WooCommerce/Classes/POS/Presentation/TotalsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,17 @@ struct TotalsView: View {
viewHelper.shouldShowTotalsFields(for: posModel.paymentState)
}

private var shouldShowCollectCashPaymentButton: Bool {
ServiceLocator.featureFlagService.isFeatureFlagEnabled(.acceptCashForPointOfSale) &&
posModel.orderState != .syncing &&
(posModel.paymentState == .idle || posModel.paymentState == .acceptingCard)
}

@Environment(\.dynamicTypeSize) var dynamicTypeSize
@Environment(\.colorScheme) var colorScheme

@State private var shouldShowCollectCashPayment: Bool = false

var body: some View {
HStack {
switch posModel.orderState {
Expand Down Expand Up @@ -52,6 +60,17 @@ struct TotalsView: View {
.opacity(viewHelper.shouldShowTotalsFields(for: posModel.paymentState) ? 1 : 0)
.layoutPriority(2)
}
Button(action: {
shouldShowCollectCashPayment = true
}, label: {
Text(Localization.cashPaymentButtonTitle)
.font(POSFontStyle.posBodyEmphasized)
.foregroundColor(.posPrimaryText)
.frame(height: Constants.buttonHeight)
})
.buttonStyle(SecondaryButtonStyle())
.padding(.horizontal, Constants.buttonHorizontalPadding)
.renderedIf(shouldShowCollectCashPaymentButton)
}
.animation(.default, value: posModel.cardPresentPaymentInlineMessage)
Spacer()
Expand All @@ -69,6 +88,13 @@ struct TotalsView: View {
isShowingTotalsFields = shouldShowTotalsFields
}
.onChange(of: shouldShowTotalsFields, perform: hideTotalsFieldsWithDelay)
.fullScreenCover(isPresented: $shouldShowCollectCashPayment) {
if case .loaded(let total) = posModel.orderState {
PointOfSaleCollectCashView(orderTotal: total.orderTotal)
.matchedGeometryEffect(id: Constants.matchedGeometryCashId,
in: totalsFieldAnimation)
}
}
.geometryGroupIfSupported()
}

Expand Down Expand Up @@ -291,6 +317,8 @@ private extension TotalsView {
enum Constants {
static let pricesIdealWidth: CGFloat = 382
static let verticalSpacing: CGFloat = 56
static let buttonHeight: CGFloat = 56
static let buttonHorizontalPadding: CGFloat = 48

static let totalsLineViewPadding: EdgeInsets = .init(top: 20, leading: 24, bottom: 20, trailing: 24)
static let subtotalsVerticalSpacing: CGFloat = 8
Expand All @@ -311,6 +339,7 @@ private extension TotalsView {
static let matchedGeometrySubtotalId: String = "pos_totals_view_subtotal_matched_geometry_id"
static let matchedGeometryTaxId: String = "pos_totals_view_tax_matched_geometry_id"
static let matchedGeometryTotalId: String = "pos_totals_view_total_matched_geometry_id"
static let matchedGeometryCashId: String = "pos_totals_view_cash_matched_geometry_id"

static let totalsFieldsHideAnimationDelay: CGFloat = 0.3
}
Expand All @@ -328,6 +357,10 @@ private extension TotalsView {
"pos.totalsView.taxes",
value: "Taxes",
comment: "Title for taxes amount field")
static let cashPaymentButtonTitle = NSLocalizedString(
"pos.totalsView.cash.button.title",
value: "Cash payment",
comment: "Title for the cash payment button title")
}
}

Expand Down
4 changes: 4 additions & 0 deletions WooCommerce/WooCommerce.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,7 @@
68D8FBD12BFEF9C700477C42 /* TotalsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D8FBD02BFEF9C700477C42 /* TotalsView.swift */; };
68DF5A8D2CB38EEA000154C9 /* EditableOrderCouponLineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68DF5A8C2CB38EEA000154C9 /* EditableOrderCouponLineViewModel.swift */; };
68DF5A8F2CB38F20000154C9 /* OrderCouponSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68DF5A8E2CB38F20000154C9 /* OrderCouponSectionView.swift */; };
68E141DB2D13107400A70D5B /* PointOfSaleCollectCashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E141DA2D13107200A70D5B /* PointOfSaleCollectCashView.swift */; };
68E4E8B52C0EF39D00CFA0C3 /* PreviewHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E4E8B42C0EF39D00CFA0C3 /* PreviewHelpers.swift */; };
68E6749F2A4DA01C0034BA1E /* WooWPComPlan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E6749E2A4DA01C0034BA1E /* WooWPComPlan.swift */; };
68E674A12A4DA0B30034BA1E /* InAppPurchasesError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E674A02A4DA0B30034BA1E /* InAppPurchasesError.swift */; };
Expand Down Expand Up @@ -4686,6 +4687,7 @@
68D8FBD02BFEF9C700477C42 /* TotalsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalsView.swift; sourceTree = "<group>"; };
68DF5A8C2CB38EEA000154C9 /* EditableOrderCouponLineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditableOrderCouponLineViewModel.swift; sourceTree = "<group>"; };
68DF5A8E2CB38F20000154C9 /* OrderCouponSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderCouponSectionView.swift; sourceTree = "<group>"; };
68E141DA2D13107200A70D5B /* PointOfSaleCollectCashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleCollectCashView.swift; sourceTree = "<group>"; };
68E4E8B42C0EF39D00CFA0C3 /* PreviewHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewHelpers.swift; sourceTree = "<group>"; };
68E6749E2A4DA01C0034BA1E /* WooWPComPlan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooWPComPlan.swift; sourceTree = "<group>"; };
68E674A02A4DA0B30034BA1E /* InAppPurchasesError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppPurchasesError.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -6989,6 +6991,7 @@
026826A72BF59DF70036F959 /* PointOfSaleEntryPointView.swift */,
68A345632D029E09002EE324 /* PaymentButtons.swift */,
026826A52BF59DF60036F959 /* PointOfSaleDashboardView.swift */,
68E141DA2D13107200A70D5B /* PointOfSaleCollectCashView.swift */,
DA013F502C65125100D9A391 /* PointOfSaleExitPosAlertView.swift */,
DA0DBE2E2C4FC61D00DF14C0 /* POSFloatingControlView.swift */,
20D3D42A2C64D7CC004CE6E3 /* SimpleProductsOnlyInformation.swift */,
Expand Down Expand Up @@ -15820,6 +15823,7 @@
EE19058C2B5F744300617C53 /* BlazeAddPaymentMethodWebView.swift in Sources */,
D83F5933225B2EB900626E75 /* ManualTrackingViewController.swift in Sources */,
3142663F2645E2AB00500598 /* PaymentSettingsFlowViewModelPresenter.swift in Sources */,
68E141DB2D13107400A70D5B /* PointOfSaleCollectCashView.swift in Sources */,
DEDB886B26E8531E00981595 /* ShippingLabelPackageAttributes.swift in Sources */,
AEC95D412774C5AE001571F5 /* AddressFormViewModelProtocol.swift in Sources */,
B6E851F5276330200041D1BA /* RefundCustomAmountsDetailsTableViewCell.swift in Sources */,
Expand Down

0 comments on commit 7f796e4

Please sign in to comment.