Skip to content

Commit f1267a9

Browse files
authored
[POS Settings] Add two-panel settings view (#16021)
2 parents 12e2fcf + 78b3836 commit f1267a9

File tree

7 files changed

+315
-23
lines changed

7 files changed

+315
-23
lines changed

Modules/Sources/Experiments/DefaultFeatureFlagService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
9595
case .pointOfSaleOrdersi2:
9696
return true
9797
case .pointOfSaleSettingsi1:
98-
return false
98+
return buildConfig == .localDeveloper || buildConfig == .alpha
9999
case .orderAddressMapSearch:
100100
return true
101101
case .pointOfSaleHistoricalOrdersi1:

WooCommerce/Classes/POS/Presentation/PointOfSaleSettingsView.swift

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import SwiftUI
2+
3+
struct PointOfSaleSettingsHardwareDetailView: View {
4+
@State private var navigationPath: [PointOfSaleSettingsView.HardwareDestination] = []
5+
6+
var body: some View {
7+
NavigationStack(path: $navigationPath) {
8+
List(PointOfSaleSettingsView.HardwareDestination.allCases) { destination in
9+
NavigationLink(value: destination) {
10+
HStack(alignment: .firstTextBaseline) {
11+
Image(systemName: destination.icon)
12+
.font(.posBodyLargeRegular())
13+
VStack(alignment: .leading, spacing: POSPadding.xSmall) {
14+
Text(destination.title)
15+
.font(.posBodyLargeRegular())
16+
Text(destination.subtitle)
17+
.font(.posBodyMediumRegular())
18+
.foregroundStyle(.secondary)
19+
}
20+
}
21+
}
22+
}
23+
.navigationDestination(for: PointOfSaleSettingsView.HardwareDestination.self) { destination in
24+
VStack(spacing: POSSpacing.medium) {
25+
Image(systemName: destination.icon).font(.largeTitle)
26+
.font(.posBodyLargeRegular())
27+
Text("\(destination.title) settings")
28+
.font(.posBodyMediumRegular())
29+
Text("Some placeholder")
30+
.font(.posBodyMediumRegular())
31+
.foregroundStyle(.secondary)
32+
}
33+
.padding()
34+
.navigationTitle(destination.title)
35+
}
36+
}
37+
}
38+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import SwiftUI
2+
3+
struct PointOfSaleSettingsHelpDetailView: View {
4+
var body: some View {
5+
NavigationStack {
6+
VStack(alignment: .leading) {
7+
Text("Help Settings")
8+
.font(.title2)
9+
Text("Help-related configuration")
10+
.font(.caption)
11+
.foregroundStyle(.secondary)
12+
}
13+
.padding()
14+
}
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import SwiftUI
2+
3+
struct PointOfSaleSettingsStoreDetailView: View {
4+
var body: some View {
5+
NavigationStack {
6+
VStack(alignment: .leading) {
7+
Text("Store Settings")
8+
.font(.title2)
9+
Text("Store-related configuration")
10+
.font(.caption)
11+
.foregroundStyle(.secondary)
12+
}
13+
.padding()
14+
}
15+
}
16+
}
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
import SwiftUI
2+
3+
struct PointOfSaleSettingsView: View {
4+
@Environment(\.dismiss) private var dismiss
5+
@State private var selection: SidebarNavigation? = .store
6+
7+
var body: some View {
8+
POSPageHeaderView(
9+
title: Localization.navigationTitle,
10+
trailingContent: {
11+
Button(action: { dismiss() }) {
12+
Text(Image(systemName: "xmark"))
13+
.font(.posButtonSymbolLarge)
14+
}
15+
.foregroundColor(.posOnSurface)
16+
})
17+
HStack(spacing: POSSpacing.none) {
18+
VStack(alignment: .leading, spacing: POSSpacing.none) {
19+
List(selection: $selection) {
20+
Section {
21+
ForEach([SidebarNavigation.store, SidebarNavigation.hardware], id: \.self) { item in
22+
HStack {
23+
Image(systemName: item.icon)
24+
.font(.posBodyLargeRegular())
25+
VStack(alignment: .leading) {
26+
Text(item.title)
27+
.font(.posBodyLargeRegular())
28+
Text(item.subtitle)
29+
.font(.posBodyMediumRegular())
30+
.foregroundStyle(.secondary)
31+
}
32+
}
33+
.tag(item)
34+
}
35+
}
36+
}
37+
.safeAreaInset(edge: .bottom) {
38+
Button {
39+
selection = .help
40+
} label: {
41+
HStack {
42+
Image(systemName: SidebarNavigation.help.icon)
43+
.font(.posBodyLargeRegular())
44+
.foregroundStyle(selection == .help ? .white : .primary)
45+
VStack(alignment: .leading) {
46+
Text(SidebarNavigation.help.title)
47+
.font(.posBodyLargeRegular())
48+
.foregroundStyle(selection == .help ? .white : .primary)
49+
Text(SidebarNavigation.help.subtitle)
50+
.font(.posBodyMediumRegular())
51+
.foregroundStyle(selection == .help ? .secondary : .secondary)
52+
}
53+
Spacer()
54+
}
55+
.padding(.vertical, POSPadding.small)
56+
.padding(.horizontal, POSPadding.medium)
57+
.contentShape(Rectangle())
58+
}
59+
.buttonStyle(.plain)
60+
.background(
61+
RoundedRectangle(cornerRadius: POSCornerRadiusStyle.large.value, style: .continuous)
62+
.fill(selection == .help ? Color.accentColor : Color.clear)
63+
)
64+
}
65+
}
66+
Group {
67+
switch selection {
68+
case .store:
69+
PointOfSaleSettingsStoreDetailView()
70+
case .hardware:
71+
PointOfSaleSettingsHardwareDetailView()
72+
case .help:
73+
PointOfSaleSettingsHelpDetailView()
74+
default:
75+
EmptyView()
76+
}
77+
}
78+
.frame(maxWidth: .infinity, maxHeight: .infinity)
79+
}
80+
}
81+
}
82+
83+
extension PointOfSaleSettingsView {
84+
enum HardwareDestination: Identifiable, CaseIterable {
85+
case cardReaders
86+
case scanners
87+
88+
var id: Self { self }
89+
90+
var title: String {
91+
switch self {
92+
case .cardReaders:
93+
return Localization.hardwareNavigationCardReaderTitle
94+
case .scanners:
95+
return Localization.hardwareNavigationBarcodeTitle
96+
}
97+
}
98+
99+
var subtitle: String {
100+
switch self {
101+
case .cardReaders:
102+
return Localization.hardwareNavigationCardReaderSubtitle
103+
case .scanners:
104+
return Localization.hardwareNavigationBarcodeSubtitle
105+
}
106+
}
107+
108+
var icon: String {
109+
switch self {
110+
case .cardReaders:
111+
return "creditcard"
112+
case .scanners:
113+
return "qrcode.viewfinder"
114+
}
115+
}
116+
}
117+
}
118+
119+
private extension PointOfSaleSettingsView {
120+
enum SidebarNavigation: String, CaseIterable, Identifiable {
121+
case store
122+
case hardware
123+
case help
124+
125+
var id: Self { self }
126+
127+
var title: String {
128+
switch self {
129+
case .store: return Localization.sidebarNavigationStoreTitle
130+
case .hardware: return Localization.sidebarNavigationHardwareTitle
131+
case .help: return Localization.sidebarNavigationHelpTitle
132+
}
133+
}
134+
135+
var subtitle: String {
136+
switch self {
137+
case .store: return Localization.sidebarNavigationStoreSubtitle
138+
case .hardware: return Localization.sidebarNavigationHardwareSubtitle
139+
case .help: return Localization.sidebarNavigationHelpSubtitle
140+
}
141+
}
142+
143+
var icon: String {
144+
switch self {
145+
case .store: return "bag"
146+
case .hardware: return "wrench.and.screwdriver"
147+
case .help: return "questionmark.circle"
148+
}
149+
}
150+
}
151+
152+
enum Localization {
153+
static let navigationTitle = NSLocalizedString(
154+
"pointOfSaleSettingsView.navigationTitle",
155+
value: "Settings",
156+
comment: "Title of the Point of Sale settings view."
157+
)
158+
159+
static let sidebarNavigationStoreTitle = NSLocalizedString(
160+
"pointOfSaleSettingsView.sidebarNavigationStoreTitle",
161+
value: "Store",
162+
comment: "Title of the Store section within Point of Sale settings."
163+
)
164+
165+
static let sidebarNavigationHardwareTitle = NSLocalizedString(
166+
"pointOfSaleSettingsView.sidebarNavigationHardwareTitle",
167+
value: "Hardware",
168+
comment: "Title of the Hardware section within Point of Sale settings."
169+
)
170+
171+
static let sidebarNavigationHelpTitle = NSLocalizedString(
172+
"pointOfSaleSettingsView.sidebarNavigationHelpTitle",
173+
value: "Help",
174+
comment: "Title of the Help section within Point of Sale settings."
175+
)
176+
177+
static let sidebarNavigationStoreSubtitle = NSLocalizedString(
178+
"pointOfSaleSettingsView.sidebarNavigationStoreSubtitle",
179+
value: "Store configuration and settings",
180+
comment: "Description of the settings to be found within the Store section."
181+
)
182+
183+
static let sidebarNavigationHardwareSubtitle = NSLocalizedString(
184+
"pointOfSaleSettingsView.sidebarNavigationHardwareSubtitle",
185+
value: "Manage hardware connections",
186+
comment: "Description of the settings to be found within the Hardware section."
187+
)
188+
189+
static let sidebarNavigationHelpSubtitle = NSLocalizedString(
190+
"pointOfSaleSettingsView.sidebarNavigationHelpSubtitle",
191+
value: "Get help and support",
192+
comment: "Description of the Help section in Point of Sale settings."
193+
)
194+
195+
static let hardwareNavigationBarcodeTitle = NSLocalizedString(
196+
"pointOfSaleSettingsView.hardwareNavigationBarcodeTitle",
197+
value: "Barcode scanners",
198+
comment: "Navigation title of Barcode scanner settings."
199+
)
200+
201+
static let hardwareNavigationCardReaderTitle = NSLocalizedString(
202+
"pointOfSaleSettingsView.hardwareNavigationCardReaderTitle",
203+
value: "Card readers",
204+
comment: "Navigation title of Card reader settings."
205+
)
206+
207+
static let hardwareNavigationCardReaderSubtitle = NSLocalizedString(
208+
"pointOfSaleSettingsView.hardwareNavigationCardReaderSubtitle",
209+
value: "Manage card reader connections",
210+
comment: "Description of Card reader settings for connections."
211+
)
212+
213+
static let hardwareNavigationBarcodeSubtitle = NSLocalizedString(
214+
"pointOfSaleSettingsView.hardwareNavigationBarcodeSubtitle",
215+
value: "Configure barcode scanner settings",
216+
comment: "Description of Barcode scanner settings configuration."
217+
)
218+
}
219+
}
220+
221+
#Preview {
222+
PointOfSaleSettingsView()
223+
}

0 commit comments

Comments
 (0)