173 lines
6.3 KiB
Swift
173 lines
6.3 KiB
Swift
import SwiftUI
|
|
|
|
struct LoginView: View {
|
|
@StateObject private var viewModel = LoginViewModel()
|
|
@FocusState private var focusedField: Field?
|
|
@State private var showingRegister = false
|
|
@State private var showMainTab = false
|
|
@State private var showVerification = false
|
|
@State private var isPasswordVisible = false
|
|
|
|
enum Field {
|
|
case username, password
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationView {
|
|
Form {
|
|
Section {
|
|
VStack(spacing: 16) {
|
|
Image(systemName: "house.fill")
|
|
.font(.system(size: 60))
|
|
.foregroundStyle(.blue.gradient)
|
|
|
|
Text("MyCrib")
|
|
.font(.largeTitle)
|
|
.fontWeight(.bold)
|
|
|
|
Text("Manage your properties with ease")
|
|
.font(.subheadline)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical)
|
|
}
|
|
.listRowBackground(Color.clear)
|
|
|
|
Section {
|
|
TextField("Username", text: $viewModel.username)
|
|
.textInputAutocapitalization(.never)
|
|
.autocorrectionDisabled()
|
|
.focused($focusedField, equals: .username)
|
|
.submitLabel(.next)
|
|
.onSubmit {
|
|
focusedField = .password
|
|
}
|
|
.onChange(of: viewModel.username) { _, _ in
|
|
viewModel.clearError()
|
|
}
|
|
|
|
HStack {
|
|
if isPasswordVisible {
|
|
TextField("Password", text: $viewModel.password)
|
|
.textInputAutocapitalization(.never)
|
|
.autocorrectionDisabled()
|
|
.focused($focusedField, equals: .password)
|
|
.submitLabel(.go)
|
|
.onSubmit {
|
|
viewModel.login()
|
|
}
|
|
} else {
|
|
SecureField("Password", text: $viewModel.password)
|
|
.focused($focusedField, equals: .password)
|
|
.submitLabel(.go)
|
|
.onSubmit {
|
|
viewModel.login()
|
|
}
|
|
}
|
|
|
|
Button(action: {
|
|
isPasswordVisible.toggle()
|
|
}) {
|
|
Image(systemName: isPasswordVisible ? "eye.slash.fill" : "eye.fill")
|
|
.foregroundColor(.secondary)
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
.onChange(of: viewModel.password) { _, _ in
|
|
viewModel.clearError()
|
|
}
|
|
} header: {
|
|
Text("Account Information")
|
|
}
|
|
|
|
if let errorMessage = viewModel.errorMessage {
|
|
Section {
|
|
HStack {
|
|
Image(systemName: "exclamationmark.triangle.fill")
|
|
.foregroundColor(.red)
|
|
Text(errorMessage)
|
|
.foregroundColor(.red)
|
|
.font(.subheadline)
|
|
}
|
|
}
|
|
}
|
|
|
|
Section {
|
|
Button(action: viewModel.login) {
|
|
HStack {
|
|
Spacer()
|
|
if viewModel.isLoading {
|
|
ProgressView()
|
|
} else {
|
|
Text("Login")
|
|
.fontWeight(.semibold)
|
|
}
|
|
Spacer()
|
|
}
|
|
}
|
|
.disabled(viewModel.isLoading)
|
|
}
|
|
|
|
Section {
|
|
HStack {
|
|
Spacer()
|
|
Text("Don't have an account?")
|
|
.font(.subheadline)
|
|
.foregroundColor(.secondary)
|
|
Button("Sign Up") {
|
|
showingRegister = true
|
|
}
|
|
.font(.subheadline)
|
|
.fontWeight(.semibold)
|
|
Spacer()
|
|
}
|
|
}
|
|
.listRowBackground(Color.clear)
|
|
}
|
|
.onChange(of: viewModel.isAuthenticated) { _, isAuth in
|
|
if isAuth {
|
|
print("isAuthenticated changed to true, isVerified = \(viewModel.isVerified)")
|
|
if viewModel.isVerified {
|
|
showMainTab = true
|
|
} else {
|
|
showVerification = true
|
|
}
|
|
}
|
|
}
|
|
.onChange(of: viewModel.isVerified) { _, isVerified in
|
|
print("isVerified changed to \(isVerified)")
|
|
if isVerified && viewModel.isAuthenticated {
|
|
showVerification = false
|
|
showMainTab = true
|
|
}
|
|
}
|
|
.fullScreenCover(isPresented: $showMainTab) {
|
|
MainTabView()
|
|
}
|
|
.fullScreenCover(isPresented: $showVerification) {
|
|
VerifyEmailView(
|
|
onVerifySuccess: {
|
|
// After verification, show main tab view
|
|
viewModel.isVerified = true
|
|
},
|
|
onLogout: {
|
|
// Logout and dismiss verification screen
|
|
viewModel.logout()
|
|
showVerification = false
|
|
showMainTab = false
|
|
}
|
|
)
|
|
}
|
|
.sheet(isPresented: $showingRegister) {
|
|
RegisterView()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Preview
|
|
#Preview {
|
|
LoginView()
|
|
}
|