Untitled
unknown
swift
a day ago
6.2 kB
2
No Index
// // AddUserViewModel.swift // looploop admin // // Created by Florian Lammert on 08.07.25. // import Foundation import FirebaseFunctions import FirebaseAuth extension AddUserView { @Observable class ViewModel { var isLoading: Bool = false var errorMessage: String? = nil var successMessage: String? = nil // Account Information var email = "" var confirmEmail = "" var password = "" var username = "" var isPremium = false var isFormDisabled: Bool { email.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || confirmEmail.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || password.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isLoading } func createUser() { isLoading = true errorMessage = nil successMessage = nil // Validate inputs guard validateInputs() else { isLoading = false return } Task { do { // Create Firebase Auth user let functions = Functions.functions(region: "europe-west3") let callable = functions.httpsCallable("adminCreateAuthUser") let data: [String: Any] = [ "email": email.trimmingCharacters(in: .whitespacesAndNewlines), "password": password ] let result = try await callable.call(data) guard let resultData = result.data as? [String: Any], let success = resultData["success"] as? Bool, success == true, let userId = resultData["userId"] as? String, let userEmail = resultData["email"] as? String else { isLoading = false errorMessage = "Could not create user." return } // Create DBUser with additional information let newUser = DBUser( id: userId, email: userEmail, username: username.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? nil: username.trimmingCharacters(in: .whitespacesAndNewlines), photoUrl: nil, bio: nil, diet: nil, excludedIngredients: nil, allergies: nil, kitchenEquipment: nil, excludedCuisines: nil, savedRecipeIds: nil, isPremium: isPremium, createdAt: Date(), lastLoginAt: nil ) // Save to Firestore try await UserManager.shared.createUser(user: newUser) reset() isLoading = false successMessage = "User created successfully." DispatchQueue.main.asyncAfter(deadline: .now() + 3) { self.successMessage = nil } } catch { isLoading = false errorMessage = "Failed to create user: \(error.localizedDescription)" } } } private func validateInputs() -> Bool { // Check if emails match guard email.trimmingCharacters(in: .whitespacesAndNewlines) == confirmEmail.trimmingCharacters(in: .whitespacesAndNewlines) else { errorMessage = "Email addresses do not match." return false } // Validate email format guard isValidEmail(email.trimmingCharacters(in: .whitespacesAndNewlines)) else { errorMessage = "Please enter a valid email address." return false } // Validate password strength guard password.count >= 8 else { errorMessage = "Password must be at least 8 characters long." return false } // Validate username if provided if !username.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { let trimmedUsername = username.trimmingCharacters(in: .whitespacesAndNewlines) guard trimmedUsername.count >= 3 else { errorMessage = "Username must be at least 3 characters long." return false } guard trimmedUsername.count <= 20 else { errorMessage = "Username must be no longer than 20 characters." return false } // Check for valid username characters (alphanumeric and underscores) let usernameRegex = "^[a-zA-Z0-9_]+$" let usernamePredicate = NSPredicate(format: "SELF MATCHES %@", usernameRegex) guard usernamePredicate.evaluate(with: trimmedUsername) else { errorMessage = "Username can only contain letters, numbers, and underscores." return false } } return true } private func isValidEmail(_ email: String) -> Bool { let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex) return emailPredicate.evaluate(with: email) } func reset() { email = "" confirmEmail = "" password = "" username = "" isPremium = false } } }
Editor is loading...