Skip to content

Commit 1e411df

Browse files
authored
[Local Catalog] POS Settings: add local catalog sync settings UI (#16125)
2 parents 42063c4 + 6568ace commit 1e411df

File tree

3 files changed

+225
-0
lines changed

3 files changed

+225
-0
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import SwiftUI
2+
3+
struct POSSettingsLocalCatalogDetailView: View {
4+
// TODO: WOOMOB-1335 - implement full sync cellular data setting functionality
5+
@State private var allowFullSyncOnCellular: Bool = true
6+
7+
var body: some View {
8+
NavigationStack {
9+
VStack(spacing: POSSpacing.none) {
10+
POSPageHeaderView(title: Localization.localCatalogTitle)
11+
.foregroundColor(.posSurface)
12+
.accessibilityAddTraits(.isHeader)
13+
14+
ScrollView {
15+
VStack(spacing: POSSpacing.medium) {
16+
catalogStatus
17+
managingDataUsage
18+
manualCatalogUpdate
19+
}
20+
}
21+
.background(Style.backgroundColor)
22+
}
23+
}
24+
}
25+
}
26+
27+
private extension POSSettingsLocalCatalogDetailView {
28+
@ViewBuilder
29+
var catalogStatus: some View {
30+
VStack(spacing: POSSpacing.none) {
31+
sectionHeaderView(title: Localization.catalogStatus)
32+
33+
VStack(spacing: POSSpacing.medium) {
34+
// TODO: WOOMOB-1100 - replace with catalog data
35+
fieldRowView(label: Localization.catalogSize, value: "1,250 products, 3,420 variations")
36+
fieldRowView(label: Localization.lastIncrementalUpdate, value: "5 minutes ago")
37+
fieldRowView(label: Localization.lastFullSync, value: "Today at 2:34 PM")
38+
}
39+
.padding(.bottom, POSPadding.medium)
40+
}
41+
}
42+
43+
@ViewBuilder
44+
var managingDataUsage: some View {
45+
VStack(spacing: POSSpacing.none) {
46+
sectionHeaderView(title: Localization.managingDataUsage)
47+
48+
VStack(spacing: POSSpacing.medium) {
49+
toggleRowView(label: Localization.allowFullSyncOnCellular, isOn: $allowFullSyncOnCellular)
50+
}
51+
.padding(.bottom, POSPadding.medium)
52+
}
53+
}
54+
55+
@ViewBuilder
56+
var manualCatalogUpdate: some View {
57+
VStack(spacing: POSSpacing.none) {
58+
sectionHeaderView(title: Localization.manualCatalogUpdate)
59+
60+
VStack(spacing: POSSpacing.medium) {
61+
Text(Localization.manualUpdateInfo)
62+
.font(.posCaptionRegular)
63+
.foregroundStyle(.secondary)
64+
.frame(maxWidth: .infinity, alignment: .leading)
65+
66+
Button(action: {
67+
// Handle refresh catalog action
68+
}) {
69+
Text(Localization.refreshCatalog)
70+
}
71+
.buttonStyle(POSFilledButtonStyle(size: .normal))
72+
}
73+
.padding(.horizontal, POSPadding.medium)
74+
.padding(.bottom, POSPadding.medium)
75+
}
76+
}
77+
78+
@ViewBuilder
79+
func sectionHeaderView(title: String) -> some View {
80+
ZStack {
81+
Style.backgroundColor
82+
Text(title)
83+
.font(.posBodyLargeBold)
84+
.foregroundColor(.posOnSurface)
85+
.frame(maxWidth: .infinity, alignment: .leading)
86+
.padding(.horizontal, POSPadding.medium)
87+
.padding(.vertical, POSPadding.small)
88+
}
89+
}
90+
91+
@ViewBuilder
92+
func fieldRowView(label: String, value: String) -> some View {
93+
VStack(alignment: .leading, spacing: POSPadding.small) {
94+
Text(label)
95+
.font(.posBodyMediumRegular())
96+
Text(value)
97+
.font(.posBodyMediumRegular())
98+
.foregroundStyle(.secondary)
99+
}
100+
.frame(maxWidth: .infinity, alignment: .leading)
101+
.padding(.horizontal, POSPadding.medium)
102+
}
103+
104+
@ViewBuilder
105+
func toggleRowView(label: String, isOn: Binding<Bool>) -> some View {
106+
HStack {
107+
Text(label)
108+
.font(.posBodyMediumRegular())
109+
Spacer()
110+
Toggle("", isOn: isOn)
111+
.toggleStyle(SwitchToggleStyle())
112+
}
113+
.frame(maxWidth: .infinity, alignment: .leading)
114+
.padding(.horizontal, POSPadding.medium)
115+
}
116+
}
117+
118+
private extension POSSettingsLocalCatalogDetailView {
119+
enum Style {
120+
static let backgroundColor = Color.posOnSecondaryContainer
121+
}
122+
123+
enum Localization {
124+
static let localCatalogTitle = NSLocalizedString(
125+
"posSettingsLocalCatalogDetailView.title",
126+
value: "Catalog Settings",
127+
comment: "Navigation title for the local catalog details in POS settings."
128+
)
129+
130+
static let catalogStatus = NSLocalizedString(
131+
"posSettingsLocalCatalogDetailView.catalogStatus",
132+
value: "Catalog Status",
133+
comment: "Section title for catalog status in Point of Sale settings."
134+
)
135+
136+
static let managingDataUsage = NSLocalizedString(
137+
"posSettingsLocalCatalogDetailView.managingDataUsage",
138+
value: "Managing data usage",
139+
comment: "Section title for managing data usage in Point of Sale settings."
140+
)
141+
142+
static let lastIncrementalUpdate = NSLocalizedString(
143+
"posSettingsLocalCatalogDetailView.lastIncrementalUpdate",
144+
value: "Last incremental update",
145+
comment: "Label for last incremental update field in Point of Sale settings."
146+
)
147+
148+
static let lastFullSync = NSLocalizedString(
149+
"posSettingsLocalCatalogDetailView.lastFullSync",
150+
value: "Last full sync",
151+
comment: "Label for last full sync field in Point of Sale settings."
152+
)
153+
154+
static let catalogSize = NSLocalizedString(
155+
"posSettingsLocalCatalogDetailView.catalogSize",
156+
value: "Catalog size",
157+
comment: "Label for catalog size field in Point of Sale settings."
158+
)
159+
160+
161+
static let allowFullSyncOnCellular = NSLocalizedString(
162+
"posSettingsLocalCatalogDetailView.allowFullSyncOnCellular",
163+
value: "Allow full sync on cellular data",
164+
comment: "Label for allow full sync on cellular data toggle in Point of Sale settings."
165+
)
166+
167+
168+
static let manualCatalogUpdate = NSLocalizedString(
169+
"posSettingsLocalCatalogDetailView.manualCatalogUpdate",
170+
value: "Manual Catalog Update",
171+
comment: "Section title for manual catalog update in Point of Sale settings."
172+
)
173+
174+
static let manualUpdateInfo = NSLocalizedString(
175+
"posSettingsLocalCatalogDetailView.manualUpdateInfo",
176+
value: "Use this refresh only when something seems off - POS keeps data current automatically.",
177+
comment: "Info text explaining when to use manual catalog update."
178+
)
179+
180+
static let refreshCatalog = NSLocalizedString(
181+
"posSettingsLocalCatalogDetailView.refreshCatalog",
182+
value: "Refresh catalog",
183+
comment: "Button text for refreshing the catalog manually."
184+
)
185+
}
186+
}
187+
188+
#if DEBUG
189+
#Preview {
190+
POSSettingsLocalCatalogDetailView()
191+
}
192+
#endif

WooCommerce/Classes/POS/Presentation/Settings/PointOfSaleSettingsView.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ extension PointOfSaleSettingsView {
5353
}
5454
)
5555

56+
// TODO: WOOMOB-1287 - integrate with local catalog feature eligibility
57+
if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.pointOfSaleLocalCatalogi1) {
58+
PointOfSaleSettingsCard(
59+
item: .localCatalog,
60+
isSelected: selection == .localCatalog,
61+
onTap: {
62+
selection = .localCatalog
63+
}
64+
)
65+
}
66+
5667
Spacer()
5768

5869
PointOfSaleSettingsCard(
@@ -76,6 +87,8 @@ extension PointOfSaleSettingsView {
7687
PointOfSaleSettingsStoreDetailView(viewModel: settingsController.storeViewModel)
7788
case .hardware:
7889
PointOfSaleSettingsHardwareDetailView(settingsController: settingsController)
90+
case .localCatalog:
91+
POSSettingsLocalCatalogDetailView()
7992
case .help:
8093
PointOfSaleSettingsHelpDetailView()
8194
default:
@@ -141,6 +154,7 @@ extension PointOfSaleSettingsView {
141154
enum SidebarNavigation: String, CaseIterable, Identifiable {
142155
case store
143156
case hardware
157+
case localCatalog
144158
case help
145159

146160
var id: Self { self }
@@ -149,6 +163,7 @@ extension PointOfSaleSettingsView {
149163
switch self {
150164
case .store: return Localization.sidebarNavigationStoreTitle
151165
case .hardware: return Localization.sidebarNavigationHardwareTitle
166+
case .localCatalog: return Localization.sidebarNavigationLocalCatalogTitle
152167
case .help: return Localization.sidebarNavigationHelpTitle
153168
}
154169
}
@@ -157,6 +172,7 @@ extension PointOfSaleSettingsView {
157172
switch self {
158173
case .store: return Localization.sidebarNavigationStoreSubtitle
159174
case .hardware: return Localization.sidebarNavigationHardwareSubtitle
175+
case .localCatalog: return Localization.sidebarNavigationLocalCatalogSubtitle
160176
case .help: return Localization.sidebarNavigationHelpSubtitle
161177
}
162178
}
@@ -165,6 +181,7 @@ extension PointOfSaleSettingsView {
165181
switch self {
166182
case .store: return "bag"
167183
case .hardware: return "wrench.and.screwdriver"
184+
case .localCatalog: return "internaldrive"
168185
case .help: return "questionmark.circle"
169186
}
170187
}
@@ -207,6 +224,18 @@ extension PointOfSaleSettingsView {
207224
comment: "Description of the settings to be found within the Hardware section."
208225
)
209226

227+
static let sidebarNavigationLocalCatalogTitle = NSLocalizedString(
228+
"pointOfSaleSettingsView.sidebarNavigationLocalCatalogTitle",
229+
value: "Catalog",
230+
comment: "Title of the Local catalog section within Point of Sale settings."
231+
)
232+
233+
static let sidebarNavigationLocalCatalogSubtitle = NSLocalizedString(
234+
"pointOfSaleSettingsView.sidebarNavigationLocalCatalogSubtitle",
235+
value: "Manage catalog settings",
236+
comment: "Description of the settings to be found within the Local catalog section."
237+
)
238+
210239
static let sidebarNavigationHelpSubtitle = NSLocalizedString(
211240
"pointOfSaleSettingsView.sidebarNavigationHelpSubtitle",
212241
value: "Get help and support",

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@
269269
023D69442588C6BD00F7DA72 /* ShippingLabelPaperSizeListSelectorCommandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023D69432588C6BD00F7DA72 /* ShippingLabelPaperSizeListSelectorCommandTests.swift */; };
270270
023D69BC2589BF5900F7DA72 /* PrintShippingLabelCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023D69BB2589BF5900F7DA72 /* PrintShippingLabelCoordinator.swift */; };
271271
023D877925EC8BCB00625963 /* UIScrollView+LargeTitleWorkaround.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023D877825EC8BCB00625963 /* UIScrollView+LargeTitleWorkaround.swift */; };
272+
023DE6262E73FE4600FF6562 /* POSSettingsLocalCatalogDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023DE6252E73FE4600FF6562 /* POSSettingsLocalCatalogDetailView.swift */; };
272273
023EC2E024DA87460021DA91 /* ProductInventorySettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023EC2DF24DA87460021DA91 /* ProductInventorySettingsViewModelTests.swift */; };
273274
023EC2E224DA8BAB0021DA91 /* MockProductSKUValidationStoresManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023EC2E124DA8BAB0021DA91 /* MockProductSKUValidationStoresManager.swift */; };
274275
023EC2E424DA95DB0021DA91 /* ProductInventorySettingsViewModel+VariationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023EC2E324DA95DB0021DA91 /* ProductInventorySettingsViewModel+VariationTests.swift */; };
@@ -3495,6 +3496,7 @@
34953496
023D69432588C6BD00F7DA72 /* ShippingLabelPaperSizeListSelectorCommandTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingLabelPaperSizeListSelectorCommandTests.swift; sourceTree = "<group>"; };
34963497
023D69BB2589BF5900F7DA72 /* PrintShippingLabelCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrintShippingLabelCoordinator.swift; sourceTree = "<group>"; };
34973498
023D877825EC8BCB00625963 /* UIScrollView+LargeTitleWorkaround.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+LargeTitleWorkaround.swift"; sourceTree = "<group>"; };
3499+
023DE6252E73FE4600FF6562 /* POSSettingsLocalCatalogDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSSettingsLocalCatalogDetailView.swift; sourceTree = "<group>"; };
34983500
023EC2DF24DA87460021DA91 /* ProductInventorySettingsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductInventorySettingsViewModelTests.swift; sourceTree = "<group>"; };
34993501
023EC2E124DA8BAB0021DA91 /* MockProductSKUValidationStoresManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockProductSKUValidationStoresManager.swift; sourceTree = "<group>"; };
35003502
023EC2E324DA95DB0021DA91 /* ProductInventorySettingsViewModel+VariationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProductInventorySettingsViewModel+VariationTests.swift"; sourceTree = "<group>"; };
@@ -10023,6 +10025,7 @@
1002310025
68707A152E570E7D00500CD8 /* Settings */ = {
1002410026
isa = PBXGroup;
1002510027
children = (
10028+
023DE6252E73FE4600FF6562 /* POSSettingsLocalCatalogDetailView.swift */,
1002610029
683D41172E4D9B570024CFE4 /* PointOfSaleSettingsView.swift */,
1002710030
68707A1A2E570F2200500CD8 /* PointOfSaleSettingsStoreDetailView.swift */,
1002810031
685A30602E60908B001E667B /* POSSettingsStoreViewModel.swift */,
@@ -15731,6 +15734,7 @@
1573115734
D89CFFDD25B44468000E4683 /* ULAccountMismatchViewController.swift in Sources */,
1573215735
03E471C6293A2E95001A58AD /* CardPresentModalTapToPayReaderCheckingDeviceSupport.swift in Sources */,
1573315736
B687940C27699D420092BCA0 /* RefundFeesCalculationUseCase.swift in Sources */,
15737+
023DE6262E73FE4600FF6562 /* POSSettingsLocalCatalogDetailView.swift in Sources */,
1573415738
02EA6BF82435E80600FFF90A /* ImageDownloader.swift in Sources */,
1573515739
CECC758623D21AC200486676 /* AggregateOrderItem.swift in Sources */,
1573615740
453326FA2C3C38ED000E4862 /* ProductCreationAIBarProgressStyle.swift in Sources */,

0 commit comments

Comments
 (0)