From 0e138544a74d5347ba65ae6d54d2411b82efbb6a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 15 Mar 2025 14:07:32 -0500 Subject: [PATCH] Signed-off-by: Matt Bruce --- EmployeeDirectory-Observed/ContentView.swift | 47 +++++++++++++++----- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/EmployeeDirectory-Observed/ContentView.swift b/EmployeeDirectory-Observed/ContentView.swift index bdfe556..3755d11 100644 --- a/EmployeeDirectory-Observed/ContentView.swift +++ b/EmployeeDirectory-Observed/ContentView.swift @@ -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() + @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 { - path.append(employee) + 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") } @@ -74,7 +78,7 @@ public struct EmployeeDirectoryList: View { } .onMove(perform: moveEmployee) .onDelete(perform: deleteEmployees) - + if viewModel.hasNextPage { ProgressView() .frame(maxWidth: .infinity, alignment: .center) @@ -84,7 +88,9 @@ public struct EmployeeDirectoryList: View { } } .refreshable { - await viewModel.refresh() + if editMode != .active { + await viewModel.refresh() + } } .navigationTitle("Employee Directory") .navigationDestination(for: Employee.self) { employee in @@ -98,7 +104,24 @@ 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) } } @@ -226,6 +249,10 @@ public class EmployeesViewModel { public func delete(employee: Employee) { employees.removeAll { $0.id == employee.id } } + + public func delete(selectedEmployees: Set) { + employees.removeAll { selectedEmployees.contains($0.id) } + } } public struct EmployeeViewModel {