Skip to content

Commit 89f1add

Browse files
authored
[Woo POS][Local Catalog] Catalog settings (#16368)
2 parents 57f25e1 + 2f73a6d commit 89f1add

File tree

6 files changed

+130
-116
lines changed

6 files changed

+130
-116
lines changed

Modules/Sources/PointOfSale/Presentation/Settings/POSInformationCard.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,44 @@ struct POSInformationCardFieldRow: View {
2222
case primary
2323
}
2424

25+
enum LabelStyle {
26+
case regular
27+
case bold
28+
}
29+
2530
let label: String
2631
let value: String
2732
let showSeparator: Bool
33+
let labelStyle: LabelStyle
2834
let buttonTitle: String?
2935
let buttonAction: (() -> Void)?
3036
let buttonStyle: ButtonStyle
37+
let isLoading: Bool
3138

3239
init(label: String,
3340
value: String,
3441
showSeparator: Bool = true,
42+
labelStyle: LabelStyle = .regular,
3543
buttonTitle: String? = nil,
3644
buttonAction: (() -> Void)? = nil,
37-
buttonStyle: ButtonStyle = .default) {
45+
buttonStyle: ButtonStyle = .default,
46+
isLoading: Bool = false) {
3847
self.label = label
3948
self.value = value
4049
self.showSeparator = showSeparator
50+
self.labelStyle = labelStyle
4151
self.buttonTitle = buttonTitle
4252
self.buttonAction = buttonAction
4353
self.buttonStyle = buttonStyle
54+
self.isLoading = isLoading
4455
}
4556

4657
var body: some View {
4758
VStack(alignment: .leading, spacing: POSPadding.small) {
4859
HStack(alignment: .center, spacing: POSSpacing.medium) {
4960
VStack(alignment: .leading, spacing: POSPadding.small) {
5061
Text(label)
51-
.font(.posBodyMediumRegular())
62+
.font(labelStyle == .bold ? .posBodyMediumBold : .posBodyMediumRegular())
5263
Text(value)
5364
.font(.posBodyMediumRegular())
5465
.foregroundStyle(.secondary)
@@ -60,7 +71,8 @@ struct POSInformationCardFieldRow: View {
6071
Button(buttonTitle, action: buttonAction)
6172
.buttonStyle(POSInfoCardButtonStyle(
6273
size: .compact,
63-
variant: buttonStyle == .primary ? .primary : .default
74+
variant: buttonStyle == .primary ? .primary : .default,
75+
isLoading: isLoading
6476
))
6577
}
6678
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import SwiftUI
2+
3+
struct POSInformationCardFieldRowWithToggle: View {
4+
let label: String
5+
let value: String
6+
let showSeparator: Bool
7+
@Binding var isOn: Bool
8+
9+
init(label: String,
10+
value: String,
11+
showSeparator: Bool = true,
12+
isOn: Binding<Bool>) {
13+
self.label = label
14+
self.value = value
15+
self.showSeparator = showSeparator
16+
self._isOn = isOn
17+
}
18+
19+
var body: some View {
20+
VStack(alignment: .leading, spacing: POSPadding.small) {
21+
HStack(alignment: .center, spacing: POSSpacing.medium) {
22+
VStack(alignment: .leading, spacing: POSPadding.small) {
23+
Text(label)
24+
.font(.posBodyMediumBold)
25+
Text(value)
26+
.font(.posBodyMediumRegular())
27+
.foregroundStyle(.secondary)
28+
}
29+
30+
Spacer()
31+
32+
Toggle("", isOn: $isOn)
33+
.toggleStyle(SwitchToggleStyle())
34+
.tint(Color.posPrimaryContainer)
35+
}
36+
37+
if showSeparator {
38+
Divider()
39+
.padding(.top, POSPadding.small)
40+
}
41+
}
42+
.frame(maxWidth: .infinity, alignment: .leading)
43+
}
44+
}

Modules/Sources/PointOfSale/Presentation/Settings/POSSettingsLocalCatalogDetailView.swift

Lines changed: 64 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import SwiftUI
22

33
struct POSSettingsLocalCatalogDetailView: View {
4-
// TODO: WOOMOB-1335 - implement full sync cellular data setting functionality
54
private let viewModel: POSSettingsLocalCatalogViewModel
65

76
init(viewModel: POSSettingsLocalCatalogViewModel) {
@@ -35,96 +34,63 @@ struct POSSettingsLocalCatalogDetailView: View {
3534
private extension POSSettingsLocalCatalogDetailView {
3635
@ViewBuilder
3736
var catalogStatus: some View {
38-
VStack(spacing: POSSpacing.none) {
39-
sectionHeaderView(title: Localization.catalogStatus)
40-
41-
VStack(spacing: POSSpacing.medium) {
42-
fieldRowView(label: Localization.catalogSize, value: viewModel.catalogSize)
43-
fieldRowView(label: Localization.lastIncrementalUpdate, value: viewModel.lastIncrementalSyncDate)
44-
fieldRowView(label: Localization.lastFullSync, value: viewModel.lastFullSyncDate)
37+
POSInformationCard {
38+
VStack(spacing: POSSpacing.small) {
39+
POSInformationCardFieldRow(
40+
label: Localization.catalogSize,
41+
value: viewModel.catalogSize
42+
)
43+
POSInformationCardFieldRow(
44+
label: Localization.lastIncrementalSync,
45+
value: viewModel.lastIncrementalSyncDate
46+
)
47+
POSInformationCardFieldRow(
48+
label: Localization.lastFullSync,
49+
value: viewModel.lastFullSyncDate,
50+
showSeparator: false
51+
)
4552
}
46-
.padding(.bottom, POSPadding.medium)
47-
.redacted(reason: viewModel.isLoading ? .placeholder : [])
48-
.shimmering(active: viewModel.isLoading)
4953
}
54+
.redacted(reason: viewModel.isLoading ? .placeholder : [])
55+
.shimmering(active: viewModel.isLoading)
5056
}
5157

5258
@ViewBuilder
5359
var managingDataUsage: some View {
5460
@Bindable var viewModel = viewModel
5561
VStack(spacing: POSSpacing.none) {
56-
sectionHeaderView(title: Localization.managingDataUsage)
57-
58-
VStack(spacing: POSSpacing.medium) {
59-
toggleRowView(label: Localization.allowFullSyncOnCellular, isOn: $viewModel.allowFullSyncOnCellular)
62+
POSInformationCard {
63+
POSInformationCardFieldRowWithToggle(
64+
label: Localization.managingDataUsage,
65+
value: Localization.allowSyncOnCellular,
66+
showSeparator: false,
67+
isOn: $viewModel.allowFullSyncOnCellular
68+
)
6069
}
61-
.padding(.bottom, POSPadding.medium)
6270
}
6371
}
6472

6573
@ViewBuilder
6674
var manualCatalogUpdate: some View {
6775
VStack(spacing: POSSpacing.none) {
68-
sectionHeaderView(title: Localization.manualCatalogUpdate)
69-
70-
VStack(spacing: POSSpacing.medium) {
71-
Text(Localization.manualUpdateInfo)
72-
.font(.posCaptionRegular)
73-
.foregroundStyle(.secondary)
74-
.frame(maxWidth: .infinity, alignment: .leading)
75-
76-
Button(action: {
77-
Task {
78-
await viewModel.refreshCatalog()
79-
}
80-
}) {
81-
Text(Localization.refreshCatalog)
82-
}
83-
.buttonStyle(POSFilledButtonStyle(size: .normal, isLoading: viewModel.isRefreshingCatalog))
76+
POSInformationCard {
77+
POSInformationCardFieldRow(
78+
label: Localization.manualCatalogUpdate,
79+
value: Localization.manualUpdateInfo,
80+
showSeparator: false,
81+
labelStyle: .bold,
82+
buttonTitle: Localization.updateCatalog,
83+
buttonAction: {
84+
Task {
85+
await viewModel.refreshCatalog()
86+
}
87+
},
88+
buttonStyle: .primary,
89+
isLoading: viewModel.isRefreshingCatalog
90+
)
8491
}
85-
.padding(.horizontal, POSPadding.medium)
86-
.padding(.bottom, POSPadding.medium)
87-
}
88-
}
89-
90-
@ViewBuilder
91-
func sectionHeaderView(title: String) -> some View {
92-
ZStack {
93-
Style.backgroundColor
94-
Text(title)
95-
.font(.posBodyLargeBold)
96-
.foregroundColor(.posOnSurface)
97-
.frame(maxWidth: .infinity, alignment: .leading)
98-
.padding(.horizontal, POSPadding.medium)
99-
.padding(.vertical, POSPadding.small)
10092
}
10193
}
102-
103-
@ViewBuilder
104-
func fieldRowView(label: String, value: String) -> some View {
105-
VStack(alignment: .leading, spacing: POSPadding.small) {
106-
Text(label)
107-
.font(.posBodyMediumRegular())
108-
Text(value)
109-
.font(.posBodyMediumRegular())
110-
.foregroundStyle(.secondary)
111-
}
112-
.frame(maxWidth: .infinity, alignment: .leading)
113-
.padding(.horizontal, POSPadding.medium)
114-
}
115-
116-
@ViewBuilder
117-
func toggleRowView(label: String, isOn: Binding<Bool>) -> some View {
118-
HStack {
119-
Text(label)
120-
.font(.posBodyMediumRegular())
121-
Spacer()
122-
Toggle("", isOn: isOn)
123-
.toggleStyle(SwitchToggleStyle())
124-
}
125-
.frame(maxWidth: .infinity, alignment: .leading)
126-
.padding(.horizontal, POSPadding.medium)
127-
}
12894
}
12995

13096
private extension POSSettingsLocalCatalogDetailView {
@@ -134,65 +100,57 @@ private extension POSSettingsLocalCatalogDetailView {
134100

135101
enum Localization {
136102
static let localCatalogTitle = NSLocalizedString(
137-
"posSettingsLocalCatalogDetailView.title",
138-
value: "Catalog Settings",
103+
"posSettingsLocalCatalogDetailView.title.1",
104+
value: "Product catalog",
139105
comment: "Navigation title for the local catalog details in POS settings."
140106
)
141107

142-
static let catalogStatus = NSLocalizedString(
143-
"posSettingsLocalCatalogDetailView.catalogStatus",
144-
value: "Catalog Status",
145-
comment: "Section title for catalog status in Point of Sale settings."
146-
)
147-
148108
static let managingDataUsage = NSLocalizedString(
149-
"posSettingsLocalCatalogDetailView.managingDataUsage.1",
150-
value: "Managing Data Usage",
109+
"posSettingsLocalCatalogDetailView.managingDataUsage.2",
110+
value: "Cellular data",
151111
comment: "Section title for managing data usage in Point of Sale settings."
152112
)
153113

154-
static let lastIncrementalUpdate = NSLocalizedString(
155-
"posSettingsLocalCatalogDetailView.lastIncrementalSync",
156-
value: "Last update",
157-
comment: "Label for last incremental update field in Point of Sale settings."
114+
static let lastIncrementalSync = NSLocalizedString(
115+
"posSettingsLocalCatalogDetailView.lastIncrementalSync.1",
116+
value: "Last incremental sync",
117+
comment: "Label for last incremental sync field in Point of Sale settings."
158118
)
159119

160120
static let lastFullSync = NSLocalizedString(
161-
"posSettingsLocalCatalogDetailView.lastFullSync.1",
162-
value: "Last full update",
121+
"posSettingsLocalCatalogDetailView.lastFullSync.2",
122+
value: "Last full sync",
163123
comment: "Label for last full sync field in Point of Sale settings."
164124
)
165125

166126
static let catalogSize = NSLocalizedString(
167-
"posSettingsLocalCatalogDetailView.catalogSize",
168-
value: "Catalog size",
127+
"posSettingsLocalCatalogDetailView.catalogSize.1",
128+
value: "Size",
169129
comment: "Label for catalog size field in Point of Sale settings."
170130
)
171131

172-
173-
static let allowFullSyncOnCellular = NSLocalizedString(
174-
"posSettingsLocalCatalogDetailView.allowFullSyncOnCellular.1",
175-
value: "Allow full update on cellular data",
176-
comment: "Label for allow full sync on cellular data toggle in Point of Sale settings."
132+
static let allowSyncOnCellular = NSLocalizedString(
133+
"posSettingsLocalCatalogDetailView.allowSyncOnCellular.2",
134+
value: "Allow sync using cellular data",
135+
comment: "Label for allow sync on cellular data toggle in Point of Sale settings."
177136
)
178137

179-
180138
static let manualCatalogUpdate = NSLocalizedString(
181-
"posSettingsLocalCatalogDetailView.manualCatalogUpdate",
182-
value: "Manual Catalog Update",
139+
"posSettingsLocalCatalogDetailView.manualCatalogUpdate.1",
140+
value: "Catalog update",
183141
comment: "Section title for manual catalog update in Point of Sale settings."
184142
)
185143

186144
static let manualUpdateInfo = NSLocalizedString(
187-
"posSettingsLocalCatalogDetailView.manualUpdateInfo",
188-
value: "Use this refresh only when something seems off - POS keeps data current automatically.",
189-
comment: "Info text explaining when to use manual catalog update."
145+
"posSettingsLocalCatalogDetailView.manualUpdateInfo.1",
146+
value: "Update the catalog manually",
147+
comment: "Info text explaining the usage of the manual catalog update button."
190148
)
191149

192-
static let refreshCatalog = NSLocalizedString(
193-
"posSettingsLocalCatalogDetailView.refreshCatalog",
194-
value: "Refresh catalog",
195-
comment: "Button text for refreshing the catalog manually."
150+
static let updateCatalog = NSLocalizedString(
151+
"posSettingsLocalCatalogDetailView.updateCatalog",
152+
value: "Update catalog",
153+
comment: "Button text for updating the catalog manually."
196154
)
197155
}
198156
}

Modules/Sources/PointOfSale/Presentation/Settings/POSSettingsLocalCatalogViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ private extension POSSettingsLocalCatalogViewModel {
150150
enum Localization {
151151
static let catalogSizeFormat = NSLocalizedString(
152152
"posSettingsLocalCatalogViewModel.catalogSizeFormat",
153-
value: "%1$d products, %2$ld variations",
153+
value: "%1$d products and %2$ld variations",
154154
comment: "Format string for catalog size showing product count and variation count. " +
155155
"%1$d will be replaced by the product count, and %2$ld will be replaced by the variation count."
156156
)

Modules/Sources/PointOfSale/Presentation/Settings/POSSettingsView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ extension POSSettingsView {
195195
)
196196

197197
static let sidebarNavigationLocalCatalogTitle = NSLocalizedString(
198-
"pointOfSaleSettingsView.sidebarNavigationLocalCatalogTitle",
199-
value: "Catalog",
198+
"pointOfSaleSettingsView.sidebarNavigationLocalCatalogTitle.2",
199+
value: "Product catalog",
200200
comment: "Title of the Local catalog section within Point of Sale settings."
201201
)
202202

Modules/Tests/PointOfSaleTests/Presentation/Settings/POSSettingsLocalCatalogViewModelTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct POSSettingsLocalCatalogViewModelTests {
4949
await sut.loadCatalogData()
5050

5151
// Then
52-
#expect(sut.catalogSize == "150 products, 75 variations")
52+
#expect(sut.catalogSize == "150 products and 75 variations")
5353
#expect(sut.lastFullSyncDate.contains("ago"))
5454
#expect(sut.lastIncrementalSyncDate.contains("ago"))
5555
#expect(sut.isLoading == false)
@@ -81,7 +81,7 @@ struct POSSettingsLocalCatalogViewModelTests {
8181
await sut.loadCatalogData()
8282

8383
// Then
84-
#expect(sut.catalogSize == "100 products, 50 variations")
84+
#expect(sut.catalogSize == "100 products and 50 variations")
8585
#expect(sut.lastFullSyncDate == "Not updated")
8686
#expect(sut.lastIncrementalSyncDate == "Not updated")
8787
}
@@ -128,7 +128,7 @@ struct POSSettingsLocalCatalogViewModelTests {
128128
// Then
129129
#expect(catalogSyncCoordinator.performFullSyncInvocationCount == 1)
130130
#expect(catalogSyncCoordinator.performFullSyncSiteID == sampleSiteID)
131-
#expect(sut.catalogSize == "200 products, 100 variations")
131+
#expect(sut.catalogSize == "200 products and 100 variations")
132132
#expect(sut.isRefreshingCatalog == false)
133133
}
134134

@@ -198,7 +198,7 @@ struct POSSettingsLocalCatalogViewModelTests {
198198
await refreshTask.value
199199

200200
// Then
201-
#expect(sut.catalogSize == "100 products, 50 variations")
201+
#expect(sut.catalogSize == "100 products and 50 variations")
202202
#expect(sut.isLoading == false)
203203
#expect(sut.isRefreshingCatalog == false)
204204
#expect(catalogSyncCoordinator.performFullSyncInvocationCount == 1)

0 commit comments

Comments
 (0)