block-employee-directory/EmployeeDirectory/ViewModels/EmployeesViewModel.swift
Matt Bruce 7e0c2fd310 added paging
Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
2025-01-21 11:49:09 -06:00

73 lines
2.3 KiB
Swift

//
// EmployeesViewModel.swift
// EmployeeDirectory
//
// Created by Matt Bruce on 1/20/25.
//
import Foundation
/// ViewModel that will be bound to an Employees model and used
/// specifically with the EmployeesViewController.
@MainActor
public class EmployeesViewModel: ObservableObject {
private var serviceMode: EmployeeServiceMode = .production
@Published public private(set) var employees: [Employee] = []
@Published public private(set) var errorMessage: String? = nil
@Published public private(set) var isLoading: Bool = false
@Published public private(set) var hasMorePages: Bool = true
private var currentPage = 1
private let perPage = 10
private var totalEmployees = 0
public init() {}
/// Fetch employees for the given page
public func fetchEmployees(page: Int = 1) {
// Prevent duplicate calls
guard !isLoading else { return }
isLoading = true
Task {
do {
// Fetch employees using the paginated API
let wrapper = try await MockEmployeeService.shared.getEmployees(.empty ,page: page, perPage: perPage)
// Update published properties
if page == 1 {
employees = wrapper.employees // Replace list for the first page
} else {
employees.append(contentsOf: wrapper.employees) // Append for subsequent pages
}
totalEmployees = wrapper.total
currentPage = page
hasMorePages = employees.count < totalEmployees
isLoading = false
} catch {
// Handle errors
isLoading = false
errorMessage = "An unexpected error occurred, please try to refresh."
}
}
}
/// Load the next page of employees
public func loadNextPage() {
guard hasMorePages else { return }
fetchEmployees(page: currentPage + 1)
}
/// Change the service mode (e.g., production, malformed, empty)
public func changeMode(to mode: EmployeeServiceMode) {
serviceMode = mode
currentPage = 1
employees = []
hasMorePages = true
fetchEmployees(page: 1)
}
}