Import/export fixes, icon, and graphing

This commit is contained in:
2025-09-13 00:42:15 -06:00
parent 7da1893748
commit 61384623bd
11 changed files with 388 additions and 230 deletions

View File

@@ -8,31 +8,53 @@
import SwiftUI
import UniformTypeIdentifiers
enum SheetType {
case export(Data)
case importData
}
struct SettingsView: View {
@EnvironmentObject var dataManager: ClimbingDataManager
@State private var showingResetAlert = false
@State private var showingExportSheet = false
@State private var showingImportSheet = false
@State private var exportData: Data?
@State private var activeSheet: SheetType?
var body: some View {
NavigationView {
List {
DataManagementSection()
List {
DataManagementSection(
activeSheet: $activeSheet
)
AppInfoSection()
AppInfoSection()
}
.navigationTitle("Settings")
.sheet(
item: Binding<SheetType?>(
get: { activeSheet },
set: { activeSheet = $0 }
)
) { sheetType in
switch sheetType {
case .export(let data):
ExportDataView(data: data)
case .importData:
ImportDataView()
}
.navigationTitle("Settings")
}
}
}
extension SheetType: Identifiable {
var id: String {
switch self {
case .export: return "export"
case .importData: return "import"
}
}
}
struct DataManagementSection: View {
@EnvironmentObject var dataManager: ClimbingDataManager
@Binding var activeSheet: SheetType?
@State private var showingResetAlert = false
@State private var showingExportSheet = false
@State private var showingImportSheet = false
@State private var exportData: Data?
@State private var isExporting = false
var body: some View {
@@ -60,7 +82,7 @@ struct DataManagementSection: View {
// Import Data
Button(action: {
showingImportSheet = true
activeSheet = .importData
}) {
HStack {
Image(systemName: "square.and.arrow.down")
@@ -94,38 +116,15 @@ struct DataManagementSection: View {
"Are you sure you want to reset all data? This will permanently delete:\n\n• All gyms and their information\n• All problems and their images\n• All climbing sessions\n• All attempts and progress data\n\nThis action cannot be undone. Consider exporting your data first."
)
}
.sheet(isPresented: $showingExportSheet) {
if let data = exportData {
ExportDataView(data: data)
} else {
Text("No export data available")
}
}
.sheet(isPresented: $showingImportSheet) {
ImportDataView()
}
}
private func exportDataAsync() {
isExporting = true
Task {
let data = await withCheckedContinuation { continuation in
DispatchQueue.global(qos: .userInitiated).async {
let result = dataManager.exportData()
continuation.resume(returning: result)
}
}
await MainActor.run {
isExporting = false
if let data = data {
exportData = data
showingExportSheet = true
} else {
// Error message should already be set by dataManager
exportData = nil
}
let data = await MainActor.run { dataManager.exportData() }
isExporting = false
if let data = data {
activeSheet = .export(data)
}
}
}
@@ -143,8 +142,9 @@ struct AppInfoSection: View {
var body: some View {
Section("App Information") {
HStack {
Image(systemName: "mountain.2.fill")
.foregroundColor(.blue)
Image("MountainsIcon")
.resizable()
.frame(width: 24, height: 24)
VStack(alignment: .leading) {
Text("OpenClimb")
.font(.headline)
@@ -163,15 +163,6 @@ struct AppInfoSection: View {
Text("\(appVersion) (\(buildNumber))")
.foregroundColor(.secondary)
}
HStack {
Image(systemName: "person.fill")
.foregroundColor(.blue)
Text("Developer")
Spacer()
Text("OpenClimb Team")
.foregroundColor(.secondary)
}
}
}
}
@@ -203,7 +194,7 @@ struct ExportDataView: View {
item: fileURL,
preview: SharePreview(
"OpenClimb Data Export",
image: Image(systemName: "mountain.2.fill"))
image: Image("MountainsIcon"))
) {
Label("Share Data", systemImage: "square.and.arrow.up")
.font(.headline)
@@ -324,13 +315,6 @@ struct ImportDataView: View {
Text("Import climbing data from a previously exported ZIP file.")
.multilineTextAlignment(.center)
Text(
"Fully compatible with Android exports - identical ZIP format with images."
)
.font(.subheadline)
.foregroundColor(.blue)
.multilineTextAlignment(.center)
Text("⚠️ Warning: This will replace all current data!")
.font(.subheadline)
.foregroundColor(.red)
@@ -423,7 +407,10 @@ struct ImportDataView: View {
await MainActor.run {
isImporting = false
dismiss()
// Auto-close after successful import
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
dismiss()
}
}
} catch {
await MainActor.run {