Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ struct StoreCreationCountryButton_Previews: PreviewProvider {
static var previews: some View {
VStack {
StoreCreationCountryButton(countryCode: .US,
viewModel: .init(storeName: "", onContinue: { _ in }))
viewModel: .init(storeName: "",
onContinue: { _ in },
onSupport: {}))
StoreCreationCountryButton(countryCode: .UM,
viewModel: .init(storeName: "", onContinue: { _ in }))
viewModel: .init(storeName: "",
onContinue: { _ in },
onSupport: {}))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ struct StoreCreationCountryQuestionView_Previews: PreviewProvider {
NavigationView {
StoreCreationCountryQuestionView(viewModel: .init(storeName: "only in 2023",
currentLocale: Locale.init(identifier: "en_US"),
onContinue: { _ in }))
onContinue: { _ in },
onSupport: {}))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ final class StoreCreationCountryQuestionViewModel: StoreCreationProfilerQuestion
@Published private var isContinueButtonEnabledValue: Bool = false

private let onContinue: (CountryCode) -> Void
private let onSupport: () -> Void

init(storeName: String,
currentLocale: Locale = .current,
onContinue: @escaping (CountryCode) -> Void) {
onContinue: @escaping (CountryCode) -> Void,
onSupport: @escaping () -> Void) {
self.topHeader = storeName
self.onContinue = onContinue
self.onSupport = onSupport

currentCountryCode = currentLocale.regionCode.map { CountryCode(rawValue: $0) } ?? nil
selectedCountryCode = currentCountryCode
Expand Down Expand Up @@ -65,6 +68,10 @@ extension StoreCreationCountryQuestionViewModel: RequiredStoreCreationProfilerQu
}
onContinue(selectedCountryCode)
}

func supportButtonTapped() {
onSupport()
}
}

extension StoreCreationCountryQuestionViewModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ struct StoreCreationCountrySectionView: View {

struct StoreCreationCountrySectionView_Previews: PreviewProvider {
static var previews: some View {
StoreCreationCountrySectionView(header: "EXAMPLES", countryCodes: [.FJ, .UM, .US], viewModel: .init(storeName: "", onContinue: { _ in }))
StoreCreationCountrySectionView(header: "EXAMPLES", countryCodes: [.FJ, .UM, .US], viewModel: .init(storeName: "", onContinue: { _ in }, onSupport: {}))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ protocol RequiredStoreCreationProfilerQuestionViewModel {
/// Called when the continue button is tapped.
func continueButtonTapped() async

/// Called when the Help & Support button is tapped.
func supportButtonTapped()

/// Whether the continue button is enabled for the user to continue.
var isContinueButtonEnabled: AnyPublisher<Bool, Never> { get }
}
Expand Down Expand Up @@ -46,6 +49,13 @@ struct RequiredStoreCreationProfilerQuestionView<QuestionContent: View>: View {
}
.background(Color(.systemBackground))
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
SupportButton {
viewModel.supportButtonTapped()
}
}
}
// Disables large title to avoid a large gap below the navigation bar.
.navigationBarTitleDisplayMode(.inline)
.onReceive(viewModel.isContinueButtonEnabled) { isContinueButtonEnabled in
Expand Down Expand Up @@ -75,6 +85,7 @@ private final class StoreCreationQuestionPreviewViewModel: StoreCreationProfiler
$isContinueButtonEnabledValue.eraseToAnyPublisher()
}
func continueButtonTapped() async {}
func supportButtonTapped() {}
}

struct RequiredStoreCreationProfilerQuestionView_Previews: PreviewProvider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,12 @@ import SwiftUI

/// Hosting controller that wraps the `StoreNameForm`.
final class StoreNameFormHostingController: UIHostingController<StoreNameForm> {
private let onContinue: (String) -> Void
private let onClose: () -> Void

init(onContinue: @escaping (String) -> Void,
onClose: @escaping () -> Void) {
self.onContinue = onContinue
self.onClose = onClose
super.init(rootView: StoreNameForm())

rootView.onContinue = { [weak self] storeName in
self?.onContinue(storeName)
}
onClose: @escaping () -> Void,
onSupport: @escaping () -> Void) {
super.init(rootView: StoreNameForm(onContinue: onContinue,
onClose: onClose,
onSupport: onSupport))
}

@available(*, unavailable)
Expand All @@ -24,38 +18,15 @@ final class StoreNameFormHostingController: UIHostingController<StoreNameForm> {
override func viewDidLoad() {
super.viewDidLoad()

configureNavigationBarAppearance()
}

/// Shows a transparent navigation bar without a bottom border and with a close button to dismiss.
func configureNavigationBarAppearance() {
addCloseNavigationBarButton(title: Localization.cancelButtonTitle,
target: self,
action: #selector(closeButtonTapped))
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = .systemBackground

navigationItem.standardAppearance = appearance
navigationItem.scrollEdgeAppearance = appearance
navigationItem.compactAppearance = appearance
}

@objc private func closeButtonTapped() {
onClose()
}
}

private extension StoreNameFormHostingController {
enum Localization {
static let cancelButtonTitle = NSLocalizedString("Cancel", comment: "Navigation bar button on the store name form to leave the store creation flow.")
configureTransparentNavigationBar()
}
}

/// Allows the user to enter a store name during the store creation flow.
struct StoreNameForm: View {
/// Set in the hosting controller.
var onContinue: (String) -> Void = { _ in }
let onContinue: (String) -> Void
let onClose: () -> Void
let onSupport: () -> Void

@State private var name: String = ""

Expand Down Expand Up @@ -104,6 +75,19 @@ struct StoreNameForm: View {
.buttonStyle(PrimaryButtonStyle())
.disabled(name.isEmpty)
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(Localization.cancelButtonTitle) {
onClose()
}
.buttonStyle(TextButtonStyle())
}
ToolbarItem(placement: .navigationBarTrailing) {
SupportButton {
onSupport()
}
}
}
// Disables large title to avoid a large gap below the navigation bar.
.navigationBarTitleDisplayMode(.inline)
// Hides the back button and shows a close button in the hosting controller instead.
Expand Down Expand Up @@ -148,11 +132,19 @@ private extension StoreNameForm {
"Continue",
comment: "Title of the button on the store creation store name form to continue."
)
static let cancelButtonTitle = NSLocalizedString(
"Cancel",
comment: "Navigation bar button on the store name form to leave the store creation flow."
)
}
}

struct StoreNameForm_Previews: PreviewProvider {
static var previews: some View {
StoreNameForm()
NavigationView {
StoreNameForm(onContinue: { _ in },
onClose: {},
onSupport: {})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ private extension StoreCreationCoordinator {
}
} onClose: { [weak self] in
self?.showDiscardChangesAlert(flow: .native)
} onSupport: { [weak self] in
self?.showSupport(from: navigationController)
}
navigationController.pushViewController(storeNameForm, animated: true)
analytics.track(event: .StoreCreation.siteCreationStep(step: .storeName))
Expand Down Expand Up @@ -297,6 +299,10 @@ private extension StoreCreationCoordinator {
// Presents the alert with the presented webview.
navigationController.presentedViewController?.present(alert, animated: true)
}

func showSupport(from navigationController: UINavigationController) {
ZendeskProvider.shared.showNewRequestIfPossible(from: navigationController, with: "origin:store-creation")
}
}

// MARK: - Store creation M2
Expand Down Expand Up @@ -349,13 +355,15 @@ private extension StoreCreationCoordinator {
planToPurchase: WPComPlanProduct) {
let questionController = StoreCreationCountryQuestionHostingController(viewModel:
.init(storeName: storeName) { [weak self] countryCode in
guard let self else { return }
self.showDomainSelector(from: navigationController,
storeName: storeName,
categoryName: categoryName,
countryCode: countryCode,
planToPurchase: planToPurchase)
})
guard let self else { return }
self.showDomainSelector(from: navigationController,
storeName: storeName,
categoryName: categoryName,
countryCode: countryCode,
planToPurchase: planToPurchase)
} onSupport: { [weak self] in
self?.showSupport(from: navigationController)
})
navigationController.pushViewController(questionController, animated: true)
// TODO: analytics
}
Expand All @@ -375,6 +383,8 @@ private extension StoreCreationCoordinator {
countryCode: countryCode,
domain: domain,
planToPurchase: planToPurchase)
}, onSupport: { [weak self] in
self?.showSupport(from: navigationController)
})
navigationController.pushViewController(domainSelector, animated: true)
analytics.track(event: .StoreCreation.siteCreationStep(step: .domainPicker))
Expand Down Expand Up @@ -426,6 +436,8 @@ private extension StoreCreationCoordinator {
planToPurchase: planToPurchase,
siteID: result.siteID,
siteSlug: result.siteSlug)
} onSupport: { [weak self] in
self?.showSupport(from: navigationController)
}
navigationController.pushViewController(storeSummary, animated: true)
analytics.track(event: .StoreCreation.siteCreationStep(step: .storeSummary))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import SwiftUI

/// Hosting controller that wraps the `StoreCreationSummaryView`.
final class StoreCreationSummaryHostingController: UIHostingController<StoreCreationSummaryView> {
private let onContinueToPayment: () -> Void

init(viewModel: StoreCreationSummaryViewModel,
onContinueToPayment: @escaping () -> Void) {
self.onContinueToPayment = onContinueToPayment
super.init(rootView: StoreCreationSummaryView(viewModel: viewModel))

rootView.onContinueToPayment = { [weak self] in
self?.onContinueToPayment()
}
onContinueToPayment: @escaping () -> Void,
onSupport: @escaping () -> Void) {
super.init(rootView: StoreCreationSummaryView(viewModel: viewModel,
onContinueToPayment: onContinueToPayment,
onSupport: onSupport))
}

@available(*, unavailable)
Expand Down Expand Up @@ -52,13 +48,17 @@ struct StoreCreationSummaryViewModel {

/// Displays a summary of the store creation flow with the store information (e.g. store name, store slug).
struct StoreCreationSummaryView: View {
/// Set in the hosting controller.
var onContinueToPayment: (() -> Void) = {}
private let onContinueToPayment: () -> Void
private let onSupport: () -> Void

private let viewModel: StoreCreationSummaryViewModel

init(viewModel: StoreCreationSummaryViewModel) {
init(viewModel: StoreCreationSummaryViewModel,
onContinueToPayment: @escaping () -> Void,
onSupport: @escaping () -> Void) {
self.viewModel = viewModel
self.onContinueToPayment = onContinueToPayment
self.onSupport = onSupport
}

var body: some View {
Expand Down Expand Up @@ -126,6 +126,13 @@ struct StoreCreationSummaryView: View {
.padding(Layout.defaultButtonPadding)
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
SupportButton {
onSupport()
}
}
}
.navigationTitle(Localization.title)
.navigationBarTitleDisplayMode(.large)
}
Expand Down Expand Up @@ -168,12 +175,16 @@ struct StoreCreationSummaryView_Previews: PreviewProvider {
.init(storeName: "Fruity shop",
storeSlug: "fruityshop.com",
categoryName: "Arts and Crafts",
countryCode: .UG))
countryCode: .UG),
onContinueToPayment: {},
onSupport: {})
StoreCreationSummaryView(viewModel:
.init(storeName: "Fruity shop",
storeSlug: "fruityshop.com",
categoryName: "Arts and Crafts",
countryCode: nil))
countryCode: nil),
onContinueToPayment: {},
onSupport: {})
.preferredColorScheme(.dark)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import SwiftUI

/// A support button with a help icon that is currently shown in the navigation bar.
struct SupportButton: View {
let onTapped: () -> Void

var body: some View {
Button {
onTapped()
} label: {
Image(uiImage: .helpOutlineImage)
.renderingMode(.template)
.linkStyle()
}
.accessibilityLabel(Localization.accessibilityLabel)
}
}

private extension SupportButton {
enum Localization {
static let accessibilityLabel = NSLocalizedString(
"Help & Support",
comment: "Accessibility label for the Help & Support image navigation bar button in the store creation flow."
)
}
}

struct SupportButton_Previews: PreviewProvider {
static var previews: some View {
SupportButton(onTapped: {})
}
}
6 changes: 6 additions & 0 deletions WooCommerce/Classes/Extensions/UIImage+Woo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,12 @@ extension UIImage {
return UIImage.gridicon(.heartOutline)
}

/// Help Outline
///
static var helpOutlineImage: UIImage {
return UIImage.gridicon(.helpOutline)
}

/// House Image
///
static var houseImage: UIImage {
Expand Down
Loading