1.5.0 Initial run as iOS in a monorepo
This commit is contained in:
114
ios/OpenClimb/ContentView.swift
Normal file
114
ios/OpenClimb/ContentView.swift
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// OpenClimb
|
||||
//
|
||||
// Created by OpenClimb on 2025-01-17.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
@StateObject private var dataManager = ClimbingDataManager()
|
||||
@State private var selectedTab = 0
|
||||
|
||||
var body: some View {
|
||||
TabView(selection: $selectedTab) {
|
||||
SessionsView()
|
||||
.tabItem {
|
||||
Image(systemName: "play.fill")
|
||||
Text("Sessions")
|
||||
}
|
||||
.tag(0)
|
||||
|
||||
ProblemsView()
|
||||
.tabItem {
|
||||
Image(systemName: "star.fill")
|
||||
Text("Problems")
|
||||
}
|
||||
.tag(1)
|
||||
|
||||
AnalyticsView()
|
||||
.tabItem {
|
||||
Image(systemName: "chart.bar.fill")
|
||||
Text("Analytics")
|
||||
}
|
||||
.tag(2)
|
||||
|
||||
GymsView()
|
||||
.tabItem {
|
||||
Image(systemName: "location.fill")
|
||||
Text("Gyms")
|
||||
}
|
||||
.tag(3)
|
||||
|
||||
SettingsView()
|
||||
.tabItem {
|
||||
Image(systemName: "gear")
|
||||
Text("Settings")
|
||||
}
|
||||
.tag(4)
|
||||
}
|
||||
.environmentObject(dataManager)
|
||||
.overlay(alignment: .top) {
|
||||
if let message = dataManager.successMessage {
|
||||
SuccessMessageView(message: message)
|
||||
.transition(.move(edge: .top).combined(with: .opacity))
|
||||
.animation(.easeInOut, value: dataManager.successMessage)
|
||||
}
|
||||
|
||||
if let error = dataManager.errorMessage {
|
||||
ErrorMessageView(message: error)
|
||||
.transition(.move(edge: .top).combined(with: .opacity))
|
||||
.animation(.easeInOut, value: dataManager.errorMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SuccessMessageView: View {
|
||||
let message: String
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Image(systemName: "checkmark.circle.fill")
|
||||
.foregroundColor(.green)
|
||||
Text(message)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(.regularMaterial)
|
||||
.shadow(radius: 4)
|
||||
)
|
||||
.padding(.horizontal)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}
|
||||
|
||||
struct ErrorMessageView: View {
|
||||
let message: String
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Image(systemName: "exclamationmark.triangle.fill")
|
||||
.foregroundColor(.red)
|
||||
Text(message)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(.regularMaterial)
|
||||
.shadow(radius: 4)
|
||||
)
|
||||
.padding(.horizontal)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ContentView()
|
||||
}
|
||||
Reference in New Issue
Block a user