diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddPackageView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddPackageView.swift new file mode 100644 index 00000000000..3ce11c2304f --- /dev/null +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddPackageView.swift @@ -0,0 +1,259 @@ +import SwiftUI + +struct WooShippingAddPackageView: View { + enum PackageProviderType: CaseIterable { + case custom, carrier, saved + var name: String { + switch self { + case .custom: + return Localization.custom + case .carrier: + return Localization.carrier + case .saved: + return Localization.saved + } + } + } + enum Constants { + static let defaultVerticalSpacing: CGFloat = 16.0 + } + + @Environment(\.presentationMode) var presentationMode + + @State var selectedPackageType = PackageProviderType.custom + var addPackageButtonDisabled: Bool { + for (_, value) in fieldValues { + if value.isEmpty { + return true + } + } + return fieldValues.count != WooShippingAddPackageDimensionView.DimensionType.allCases.count + } + + var body: some View { + NavigationView { + VStack { + Picker("", selection: $selectedPackageType) { + ForEach(PackageProviderType.allCases, id: \.self) { + Text($0.name) + } + } + .pickerStyle(.segmented) + .padding() + selectedPackageTypeView + Spacer() + Button(Localization.addPackage) { + // add package + } + .buttonStyle(PrimaryButtonStyle()) + .disabled(addPackageButtonDisabled) + .padding() + } + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button(action: { + presentationMode.wrappedValue.dismiss() + }, label: { + Text(Localization.cancel) + }) + } + } + .navigationTitle(Localization.addPackage) + .navigationBarTitleDisplayMode(.inline) + } + .navigationViewStyle(.stack) + } + + @ViewBuilder + private var selectedPackageTypeView: some View { + ScrollView { + switch selectedPackageType { + case .custom: + customPackageView + case .carrier: + carrierPackageView + case .saved: + savedPackageView + } + } + } + + enum PackageType: CaseIterable { + case box, envelope + var name: String { + switch self { + case .box: + return Localization.box + case .envelope: + return Localization.envelope + } + } + } + + @State var packageType: PackageType = .box + @State var showSaveTemplate: Bool = false + @State var fieldValues: [WooShippingAddPackageDimensionView.DimensionType: String] = [:] + + private var customPackageView: some View { + VStack(alignment: .leading, spacing: Constants.defaultVerticalSpacing) { + HStack { + Text(Localization.packageType) + .font(.subheadline) + Spacer() + } + // type selection + Menu { + // show selection + ForEach(PackageType.allCases, id: \.self) { option in + Button { + packageType = option + } label: { + Text(option.name) + .bodyStyle() + if packageType == option { + Image(uiImage: .checkmarkStyledImage) + } + } + } + } label: { + HStack { + // text + Text(packageType.name) + .bodyStyle() + // arrows + Spacer() + Image(systemName: "chevron.up.chevron.down") + } + .padding() + } + .roundedBorder(cornerRadius: 8, lineColor: Color(.separator), lineWidth: 1) + AdaptiveStack(spacing: 8) { + ForEach(WooShippingAddPackageDimensionView.DimensionType.allCases, id: \.self) { dimensionType in + WooShippingAddPackageDimensionView(dimensionType: dimensionType, fieldValue: Binding(get: { + return self.fieldValues[dimensionType] ?? "" + }, set: { value in + self.fieldValues[dimensionType] = value + })) + } + } + Toggle(isOn: $showSaveTemplate) { + Text(Localization.saveNewPackageTemplate) + .font(.subheadline) + } + if showSaveTemplate { + Button(Localization.savePackageTemplate) { + // save template + } + .buttonStyle(SecondaryButtonStyle()) + } + } + .padding(.horizontal) + } + + private var carrierPackageView: some View { + // TODO: just a placeholder + Text("carrier") + } + + private var savedPackageView: some View { + // TODO: just a placeholder + Text("saved") + } +} + +struct WooShippingAddPackageDimensionView: View { + enum DimensionType: CaseIterable { + case length, width, height + var name: String { + switch self { + case .length: + return Localization.length + case .width: + return Localization.width + case .height: + return Localization.height + } + } + } + + let dimensionType: DimensionType + @Binding var fieldValue: String + @FocusState var fieldFocused: Bool + + var body: some View { + VStack { + HStack { + Text(dimensionType.name) + .font(.subheadline) + Spacer() + } + HStack { + TextField("", text: $fieldValue) + .keyboardType(.decimalPad) + .bodyStyle() + .focused($fieldFocused) + Text("cm") + .font(.subheadline) + .foregroundStyle(.secondary) + } + .padding() + .roundedBorder(cornerRadius: 8, + lineColor: fieldFocused ? Color(UIColor.wooCommercePurple(.shade60)) : Color(.separator), + lineWidth: fieldFocused ? 2 : 1) + } + .frame(minHeight: 48) + } +} + +#Preview { + WooShippingAddPackageView() +} + +extension WooShippingAddPackageView { + enum Localization { + static let addPackage = NSLocalizedString("wooShipping.createLabel.addPackage.title", + value: "Add Package", + comment: "Title for the Add Package screen") + static let packageType = NSLocalizedString("wooShipping.createLabel.addPackage.packageType", + value: "Package type", + comment: "Info label for selecting package type") + static let cancel = NSLocalizedString("wooShipping.createLabel.addPackage.cancel", + value: "Cancel", + comment: "Cancel button in navigation bar to dismiss the screen") + static let custom = NSLocalizedString("wooShipping.createLabel.addPackage.custom", + value: "Custom", + comment: "Info label for custom package option") + static let carrier = NSLocalizedString("wooShipping.createLabel.addPackage.carrier", + value: "Carrier", + comment: "Info label for carrier package option") + static let saved = NSLocalizedString("wooShipping.createLabel.addPackage.saved", + value: "Saved", + comment: "Info label for saved package option") + static let box = NSLocalizedString("wooShipping.createLabel.addPackage.box", + value: "Box", + comment: "Info label for selected box as a package type") + static let envelope = NSLocalizedString("wooShipping.createLabel.addPackage.envelope", + value: "Envelope", + comment: "Info label for selected envelope as a package type") + static let saveNewPackageTemplate = NSLocalizedString("wooShipping.createLabel.addPackage.saveNewPackageTemplate", + value: "Save this as a new package template", + comment: "Info label for saving package as a new template toggle") + static let savePackageTemplate = NSLocalizedString("wooShipping.createLabel.addPackage.savePackageTemplate", + value: "Save package template", + comment: "Button for saving package as a new template") + } +} + +extension WooShippingAddPackageDimensionView { + enum Localization { + static let length = NSLocalizedString("wooShipping.createLabel.addPackage.length", + value: "Length", + comment: "Info label for length input field") + static let width = NSLocalizedString("wooShipping.createLabel.addPackage.width", + value: "Width", + comment: "Info label for width input field") + static let height = NSLocalizedString("wooShipping.createLabel.addPackage.height", + value: "Height", + comment: "Info label for height input field") + } +} diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift index 9882c9b4b29..da659bc5437 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift @@ -1,10 +1,11 @@ import SwiftUI struct WooShippingPackageAndRatePlaceholder: View { + @State private var showAddPackage: Bool = false var body: some View { VStack(spacing: .zero) { Button { - // TODO-13551: Open package selection UI + showAddPackage.toggle() } label: { Text(Localization.addPackage) } @@ -22,6 +23,9 @@ struct WooShippingPackageAndRatePlaceholder: View { .multilineTextAlignment(.center) .padding(Layout.padding) .roundedBorder(cornerRadius: Layout.borderCornerRadius, lineColor: Color(.border), lineWidth: Layout.borderLineWidth, dashed: true) + .sheet(isPresented: $showAddPackage) { + WooShippingAddPackageView() + } } } diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 5234372e734..dc510633ecb 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -2448,6 +2448,7 @@ DA81B4332C8EE5D6000F3466 /* MarkOrderAsReadUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA25ADDC2C86145E00AE81FE /* MarkOrderAsReadUseCase.swift */; }; DA81B4342C8EE5D6000F3466 /* MarkOrderAsReadUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA25ADDC2C86145E00AE81FE /* MarkOrderAsReadUseCase.swift */; }; DA81B4362C8F2BB8000F3466 /* MarkOrderAsReadUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA25ADDC2C86145E00AE81FE /* MarkOrderAsReadUseCase.swift */; }; + DAB4099F2CA5A329008EE1F2 /* WooShippingAddPackageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB4099E2CA5A329008EE1F2 /* WooShippingAddPackageView.swift */; }; DABF35272C11B426006AF826 /* PointOfSaleDashboardViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABF35262C11B426006AF826 /* PointOfSaleDashboardViewModelTests.swift */; }; DAD988C62C4A9CF9009DE9E3 /* CartItem+Order.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAD988C52C4A9CF9009DE9E3 /* CartItem+Order.swift */; }; DAD988C92C4A9D6C009DE9E3 /* CartItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAD988C82C4A9D6C009DE9E3 /* CartItemTests.swift */; }; @@ -5494,6 +5495,7 @@ DA25ADDE2C87403900AE81FE /* PushNotificationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationTests.swift; sourceTree = ""; }; DA3F99B92C92F6D30034BDA5 /* MarkOrderAsReadUseCaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkOrderAsReadUseCaseTests.swift; sourceTree = ""; }; DA4104392C247B6900E8456A /* POSOrderPreviewService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSOrderPreviewService.swift; sourceTree = ""; }; + DAB4099E2CA5A329008EE1F2 /* WooShippingAddPackageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingAddPackageView.swift; sourceTree = ""; }; DABF35262C11B426006AF826 /* PointOfSaleDashboardViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleDashboardViewModelTests.swift; sourceTree = ""; }; DAD988C52C4A9CF9009DE9E3 /* CartItem+Order.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CartItem+Order.swift"; sourceTree = ""; }; DAD988C82C4A9D6C009DE9E3 /* CartItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CartItemTests.swift; sourceTree = ""; }; @@ -11893,6 +11895,7 @@ isa = PBXGroup; children = ( CECEFA6C2CA2CEB50071C7DB /* WooShippingPackageAndRatePlaceholder.swift */, + DAB4099E2CA5A329008EE1F2 /* WooShippingAddPackageView.swift */, ); path = "WooShipping Package and Rate Selection"; sourceTree = ""; @@ -14746,6 +14749,7 @@ 0218B4EC242E06F00083A847 /* MediaType+WPMediaType.swift in Sources */, D85A3C5026C153A500C0E026 /* InPersonPaymentsPluginNotActivatedView.swift in Sources */, D8815AE726383FD600EDAD62 /* CardPresentPaymentsModalViewModel.swift in Sources */, + DAB4099F2CA5A329008EE1F2 /* WooShippingAddPackageView.swift in Sources */, 02B21C5729C9EEF900C5623B /* WooAnalyticsEvent+StoreOnboarding.swift in Sources */, 0216271E2375044D000208D2 /* AztecFormatBar+Update.swift in Sources */, CC254F3626C437AB005F3C82 /* ShippingLabelCustomPackageForm.swift in Sources */,