This commit is contained in:
Trey t
2025-11-05 10:38:46 -06:00
parent 025fcf677a
commit 2be3a5a3a8
23 changed files with 2837 additions and 124 deletions

View File

@@ -0,0 +1,171 @@
import SwiftUI
struct RegisterView: View {
@StateObject private var viewModel = RegisterViewModel()
@Environment(\.dismiss) var dismiss
@FocusState private var focusedField: Field?
enum Field {
case username, email, password, confirmPassword
}
var body: some View {
NavigationView {
ZStack {
Color(.systemGroupedBackground)
.ignoresSafeArea()
ScrollView {
VStack(spacing: 24) {
// Icon and Title
VStack(spacing: 12) {
Image(systemName: "person.badge.plus")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 64, height: 64)
.foregroundColor(.blue)
Text("Join MyCrib")
.font(.largeTitle)
.fontWeight(.bold)
Text("Start managing your properties today")
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.top, 40)
.padding(.bottom, 20)
// Registration Form
VStack(spacing: 16) {
// Username Field
VStack(alignment: .leading, spacing: 8) {
Text("Username")
.font(.subheadline)
.foregroundColor(.secondary)
TextField("Enter your username", text: $viewModel.username)
.textFieldStyle(.roundedBorder)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.focused($focusedField, equals: .username)
.submitLabel(.next)
.onSubmit {
focusedField = .email
}
}
// Email Field
VStack(alignment: .leading, spacing: 8) {
Text("Email")
.font(.subheadline)
.foregroundColor(.secondary)
TextField("Enter your email", text: $viewModel.email)
.textFieldStyle(.roundedBorder)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.keyboardType(.emailAddress)
.focused($focusedField, equals: .email)
.submitLabel(.next)
.onSubmit {
focusedField = .password
}
}
// Password Field
VStack(alignment: .leading, spacing: 8) {
Text("Password")
.font(.subheadline)
.foregroundColor(.secondary)
SecureField("Enter your password", text: $viewModel.password)
.textFieldStyle(.roundedBorder)
.focused($focusedField, equals: .password)
.submitLabel(.next)
.onSubmit {
focusedField = .confirmPassword
}
}
// Confirm Password Field
VStack(alignment: .leading, spacing: 8) {
Text("Confirm Password")
.font(.subheadline)
.foregroundColor(.secondary)
SecureField("Confirm your password", text: $viewModel.confirmPassword)
.textFieldStyle(.roundedBorder)
.focused($focusedField, equals: .confirmPassword)
.submitLabel(.go)
.onSubmit {
viewModel.register()
}
}
// Error Message
if let errorMessage = viewModel.errorMessage {
HStack {
Image(systemName: "exclamationmark.triangle.fill")
.foregroundColor(.red)
Text(errorMessage)
.font(.caption)
.foregroundColor(.red)
Spacer()
Button(action: viewModel.clearError) {
Image(systemName: "xmark.circle.fill")
.foregroundColor(.red)
}
}
.padding()
.background(Color.red.opacity(0.1))
.cornerRadius(8)
}
// Register Button
Button(action: viewModel.register) {
HStack {
if viewModel.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
} else {
Text("Create Account")
.fontWeight(.semibold)
}
}
.frame(maxWidth: .infinity)
.padding()
.background(viewModel.isLoading ? Color.gray : Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.disabled(viewModel.isLoading)
}
.padding(.horizontal, 24)
Spacer()
}
}
}
.navigationTitle("Create Account")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") {
dismiss()
}
}
}
.fullScreenCover(isPresented: $viewModel.isRegistered) {
MainTabView()
}
}
}
}
#Preview {
RegisterView()
}