aboutsummaryrefslogtreecommitdiff
path: root/Map/Presentation/Preferences/StagesPreferencesView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Map/Presentation/Preferences/StagesPreferencesView.swift')
-rw-r--r--Map/Presentation/Preferences/StagesPreferencesView.swift165
1 files changed, 165 insertions, 0 deletions
diff --git a/Map/Presentation/Preferences/StagesPreferencesView.swift b/Map/Presentation/Preferences/StagesPreferencesView.swift
new file mode 100644
index 0000000..7131034
--- /dev/null
+++ b/Map/Presentation/Preferences/StagesPreferencesView.swift
@@ -0,0 +1,165 @@
+// Copyright (C) 2024 Rubén Beltrán del Río
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see https://map.tranquil.systems.
+
+import SwiftUI
+
+struct StagesPreferencesView: View {
+ @AppStorage("customStages") private var customStagesData: Data = Data()
+ @State private var customStages: [CustomStage] = []
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 16) {
+ Text("preferences.stages.title")
+ .font(.Theme.Title.emphasized)
+ .lineSpacing(Dimensions.FontSize.title - Dimensions.FontSize.title)
+ Text("preferences.stages.explanation")
+ .font(.Theme.Body.emphasized)
+ .lineSpacing(Dimensions.FontSize.body - Dimensions.FontSize.body)
+
+ HStack {
+ Spacer()
+ Button(action: addStage) {
+ Image(systemName: "plus")
+ }
+ .buttonStyle(.borderless)
+ }
+
+ Table(customStages) {
+ TableColumn("Name") { customStage in
+ TextField(
+ "Stage Name",
+ text: Binding(
+ get: { customStage.name },
+ set: { newValue in
+ updateStageName(customStage.id, newValue)
+ }
+ )
+ )
+ .textFieldStyle(.roundedBorder)
+ }
+ .width(120)
+
+ TableColumn("Stage I") { customStage in
+ TextField(
+ "Stage I",
+ text: Binding(
+ get: { customStage.stage.i },
+ set: { newValue in
+ updateStageValue(customStage.id, \.i, newValue)
+ }
+ )
+ )
+ .textFieldStyle(.roundedBorder)
+ }
+
+ TableColumn("Stage II") { customStage in
+ TextField(
+ "Stage II",
+ text: Binding(
+ get: { customStage.stage.ii },
+ set: { newValue in
+ updateStageValue(customStage.id, \.ii, newValue)
+ }
+ )
+ )
+ .textFieldStyle(.roundedBorder)
+ }
+
+ TableColumn("Stage III") { customStage in
+ TextField(
+ "Stage III",
+ text: Binding(
+ get: { customStage.stage.iii },
+ set: { newValue in
+ updateStageValue(customStage.id, \.iii, newValue)
+ }
+ )
+ )
+ .textFieldStyle(.roundedBorder)
+ }
+
+ TableColumn("Stage IV") { customStage in
+ TextField(
+ "Stage IV",
+ text: Binding(
+ get: { customStage.stage.iv },
+ set: { newValue in
+ updateStageValue(customStage.id, \.iv, newValue)
+ }
+ )
+ )
+ .textFieldStyle(.roundedBorder)
+ }
+
+ TableColumn("") { customStage in
+ Button(action: { removeStage(customStage.id) }) {
+ Image(systemName: "minus")
+ }
+ .buttonStyle(.borderless)
+ }
+ .width(30)
+ }
+ .tableStyle(.bordered(alternatesRowBackgrounds: true))
+
+ Spacer()
+ }
+ .padding()
+ .onAppear {
+ loadStages()
+ }
+ }
+
+ private func loadStages() {
+ if let decoded = try? JSONDecoder().decode([CustomStage].self, from: customStagesData) {
+ customStages = decoded
+ } else {
+ customStages = [CustomStage()]
+ }
+ }
+
+ private func saveStages() {
+ if let encoded = try? JSONEncoder().encode(customStages) {
+ customStagesData = encoded
+ }
+ }
+
+ private func addStage() {
+ customStages.append(CustomStage())
+ saveStages()
+ }
+
+ private func removeStage(_ id: UUID) {
+ customStages.removeAll { $0.id == id }
+ saveStages()
+ }
+
+ private func updateStageName(_ id: UUID, _ newName: String) {
+ if let index = customStages.firstIndex(where: { $0.id == id }) {
+ customStages[index].name = newName
+ saveStages()
+ }
+ }
+
+ private func updateStageValue(_ id: UUID, _ keyPath: WritableKeyPath<Stage, String>, _ value: String) {
+ if let index = customStages.firstIndex(where: { $0.id == id }) {
+ customStages[index].stage[keyPath: keyPath] = value
+ saveStages()
+ }
+ }
+}
+
+#Preview {
+ StagesPreferencesView()
+}