diff options
Diffstat (limited to 'Map/Presentation/Preferences/StagesPreferencesView.swift')
| -rw-r--r-- | Map/Presentation/Preferences/StagesPreferencesView.swift | 165 |
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() +} |