import SwiftUI struct ProfileView: View { @StateObject private var viewModel = ProfileViewModel() @Environment(\.dismiss) var dismiss @FocusState private var focusedField: Field? enum Field { case firstName, lastName, email } var body: some View { NavigationView { if viewModel.isLoadingUser { VStack { ProgressView() Text("Loading profile...") .font(.subheadline) .foregroundColor(Color.appTextSecondary) .padding(.top, 8) } } else { Form { Section { VStack(spacing: 16) { Image(systemName: "person.circle.fill") .font(.system(size: 60)) .foregroundStyle(Color.appPrimary.gradient) Text("Profile Settings") .font(.title2) .fontWeight(.bold) .foregroundColor(Color.appTextPrimary) } .frame(maxWidth: .infinity) .padding(.vertical) } .listRowBackground(Color.clear) Section { TextField("First Name", text: $viewModel.firstName) .textInputAutocapitalization(.words) .autocorrectionDisabled() .focused($focusedField, equals: .firstName) .submitLabel(.next) .onSubmit { focusedField = .lastName } TextField("Last Name", text: $viewModel.lastName) .textInputAutocapitalization(.words) .autocorrectionDisabled() .focused($focusedField, equals: .lastName) .submitLabel(.next) .onSubmit { focusedField = .email } } header: { Text("Personal Information") } .listRowBackground(Color.appBackgroundSecondary) Section { TextField("Email", text: $viewModel.email) .textInputAutocapitalization(.never) .autocorrectionDisabled() .keyboardType(.emailAddress) .focused($focusedField, equals: .email) .submitLabel(.done) .onSubmit { viewModel.updateProfile() } } header: { Text("Contact") } footer: { Text("Email is required and must be unique") } .listRowBackground(Color.appBackgroundSecondary) if let errorMessage = viewModel.errorMessage { Section { HStack { Image(systemName: "exclamationmark.triangle.fill") .foregroundColor(Color.appError) Text(errorMessage) .foregroundColor(Color.appError) .font(.subheadline) } } .listRowBackground(Color.appBackgroundSecondary) } if let successMessage = viewModel.successMessage { Section { HStack { Image(systemName: "checkmark.circle.fill") .foregroundColor(Color.appPrimary) Text(successMessage) .foregroundColor(Color.appPrimary) .font(.subheadline) } } .listRowBackground(Color.appBackgroundSecondary) } Section { Button(action: viewModel.updateProfile) { HStack { Spacer() if viewModel.isLoading { ProgressView() } else { Text("Save Changes") .fontWeight(.semibold) } Spacer() } } .disabled(viewModel.isLoading || viewModel.email.isEmpty) } .listRowBackground(Color.appBackgroundSecondary) } .listStyle(.plain) .scrollContentBackground(.hidden) .background(Color.appBackgroundPrimary) .navigationTitle("Profile") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Cancel") { dismiss() } } } .onChange(of: viewModel.firstName) { _, _ in viewModel.clearMessages() } .onChange(of: viewModel.lastName) { _, _ in viewModel.clearMessages() } .onChange(of: viewModel.email) { _, _ in viewModel.clearMessages() } .handleErrors( error: viewModel.errorMessage, onRetry: { viewModel.updateProfile() } ) } } } } #Preview { ProfileView() }