Untitled

 avatar
unknown
swift
21 hours 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...