Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-03-15 14:07:32 -05:00
parent cb69829d26
commit 0e138544a7

View File

@ -9,8 +9,13 @@ import SwiftUI
struct ContentView: View {
let service: EmployeeDirectoryService
@Environment(\.editMode) private var editMode
var body: some View {
EmployeeDirectoryList(viewModel: .init(service: service))
.onChange(of: editMode?.wrappedValue) { oldValue, newValue in
print("Edit mode changed from \(String(describing: oldValue)) to \(String(describing: newValue))")
}
}
}
@ -22,6 +27,8 @@ struct ContentView: View {
public struct EmployeeDirectoryList: View {
@State public var viewModel: EmployeesViewModel
@State public var path = NavigationPath()
@State private var selectedEmployees = Set<Employee.ID>()
@State private var editMode: EditMode = .inactive
init(viewModel: EmployeesViewModel? = nil) {
_viewModel = .init(wrappedValue: viewModel ?? .init(service: EmployeeService()))
@ -29,26 +36,23 @@ public struct EmployeeDirectoryList: View {
public var body: some View {
NavigationStack(path: $path) {
List {
List(selection: $selectedEmployees) {
ForEach(viewModel.employees, id: \.id) { employee in
let employeeViewModel = EmployeeViewModel(employee: employee)
HStack (spacing: 10) {
HStack(spacing: 10) {
ProfileImageView(urlString: employeeViewModel.smallPhoto, size: 51)
VStack(alignment: .leading, spacing: 5) {
Text(employeeViewModel.fullName)
.font(.headline)
if let bio = employeeViewModel.biography {
Text(bio)
.font(.footnote)
.foregroundColor(.gray)
.lineLimit(2)
}
Label("Email: \(employeeViewModel.emailAddress)", systemImage: "envelope.fill")
.foregroundColor(.gray)
.font(.caption)
if let phoneNumber = employeeViewModel.phoneNumber {
Label("Call: \(phoneNumber)", systemImage: "phone.fill")
.foregroundColor(.gray)
@ -57,15 +61,15 @@ public struct EmployeeDirectoryList: View {
}
}
.onTapGesture {
if editMode != .active {
path.append(employee)
}
}
.swipeActions(edge: .leading) {
Button("Pin") {
print("\(employee.firstName) pinned")
}
.tint(.orange)
}
.swipeActions(edge: .leading) {
Button("Flagged") {
print("\(employee.firstName) flagged")
}
@ -84,8 +88,10 @@ public struct EmployeeDirectoryList: View {
}
}
.refreshable {
if editMode != .active {
await viewModel.refresh()
}
}
.navigationTitle("Employee Directory")
.navigationDestination(for: Employee.self) { employee in
EmployeeDetailView(viewModel: .init(employee: employee))
@ -98,8 +104,25 @@ public struct EmployeeDirectoryList: View {
}
.toolbar {
EditButton()
.onTapGesture {
editMode = editMode == .active ? .inactive : .active
}
}
.toolbar {
if !selectedEmployees.isEmpty {
ToolbarItemGroup(placement: .bottomBar) {
Button("Delete") {
withAnimation {
viewModel.delete(selectedEmployees: selectedEmployees)
selectedEmployees.removeAll()
}
}
Spacer()
}
}
}
.environment(\.editMode, $editMode)
}
}
private func moveEmployee(from source: IndexSet, to destination: Int) {
@ -226,6 +249,10 @@ public class EmployeesViewModel {
public func delete(employee: Employee) {
employees.removeAll { $0.id == employee.id }
}
public func delete(selectedEmployees: Set<Employee.ID>) {
employees.removeAll { selectedEmployees.contains($0.id) }
}
}
public struct EmployeeViewModel {