Files
pulse-mobile/PulseHealth/Views/LoginView.swift

56 lines
2.5 KiB
Swift

import SwiftUI
struct LoginView: View {
@EnvironmentObject var authManager: AuthManager
@State private var email = ""
@State private var password = ""
@State private var isLoading = false
@State private var errorMessage = ""
var body: some View {
ZStack {
LinearGradient(colors: [Color(hex: "1a1a2e"), Color(hex: "16213e")], startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
VStack(spacing: 32) {
VStack(spacing: 8) {
Text("🫀").font(.system(size: 60))
Text("Pulse Health").font(.largeTitle.bold()).foregroundColor(.white)
Text("Персональный дашборд здоровья").font(.subheadline).foregroundColor(.white.opacity(0.6))
}.padding(.top, 60)
VStack(spacing: 16) {
TextField("Email", text: $email)
.keyboardType(.emailAddress).autocapitalization(.none)
.padding().background(Color.white.opacity(0.1)).cornerRadius(12).foregroundColor(.white)
SecureField("Пароль", text: $password)
.padding().background(Color.white.opacity(0.1)).cornerRadius(12).foregroundColor(.white)
if !errorMessage.isEmpty {
Text(errorMessage).foregroundColor(.red).font(.caption)
}
Button(action: login) {
if isLoading { ProgressView().tint(.white) }
else { Text("Войти").font(.headline).foregroundColor(.black) }
}
.frame(maxWidth: .infinity).padding()
.background(Color(hex: "00d4aa")).cornerRadius(12).disabled(isLoading)
}.padding(.horizontal, 24)
Spacer()
}
}
}
func login() {
isLoading = true; errorMessage = ""
Task {
do {
let response = try await APIService.shared.login(email: email, password: password)
let profile = try await APIService.shared.getProfile(token: response.token)
await MainActor.run {
authManager.login(token: response.token, name: response.user.name, apiKey: profile.apiKey ?? "")
}
} catch {
await MainActor.run { errorMessage = error.localizedDescription; isLoading = false }
}
}
}
}