refactored tel/email

Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
Matt Bruce 2025-03-15 11:15:12 -05:00
parent 73f53d8ef0
commit f72c31b0d3

View File

@ -22,6 +22,7 @@ struct ContentView: View {
public struct EmployeeDirectoryList: View { public struct EmployeeDirectoryList: View {
@State public var viewModel: EmployeesViewModel @State public var viewModel: EmployeesViewModel
@State public var path = NavigationPath() @State public var path = NavigationPath()
init(viewModel: EmployeesViewModel? = nil) { init(viewModel: EmployeesViewModel? = nil) {
_viewModel = .init(wrappedValue: viewModel ?? .init(service: EmployeeService())) _viewModel = .init(wrappedValue: viewModel ?? .init(service: EmployeeService()))
} }
@ -33,7 +34,7 @@ public struct EmployeeDirectoryList: View {
let employeeViewModel = EmployeeViewModel(employee: employee) let employeeViewModel = EmployeeViewModel(employee: employee)
HStack (spacing: 10) { HStack (spacing: 10) {
ProfileImageView(urlString: employeeViewModel.smallPhoto, size: 51) ProfileImageView(urlString: employeeViewModel.smallPhoto, size: 51)
VStack(alignment: .leading) { VStack(alignment: .leading, spacing: 5) {
Text(employeeViewModel.fullName) Text(employeeViewModel.fullName)
.font(.headline) .font(.headline)
@ -54,10 +55,33 @@ public struct EmployeeDirectoryList: View {
.font(.caption) .font(.caption)
} }
} }
}.onTapGesture { }
.onTapGesture {
path.append(employee) path.append(employee)
} }
.swipeActions(edge: .leading) {
Button("Pin") {
print("\(employee.firstName) pinned")
}
.tint(.orange)
}
.swipeActions(edge: .leading) {
Button("Flagged") {
print("\(employee.firstName) flagged")
}
.tint(.yellow)
}
.swipeActions {
Button(role: .destructive) {
print("\(employee.firstName) deleted")
} label: {
Label("Delete", systemImage: "trash")
}
}
} }
.onMove(perform: moveEmployee)
.onDelete(perform: deleteEmployees)
if viewModel.hasNextPage { if viewModel.hasNextPage {
ProgressView() ProgressView()
.frame(maxWidth: .infinity, alignment: .center) .frame(maxWidth: .infinity, alignment: .center)
@ -76,8 +100,26 @@ public struct EmployeeDirectoryList: View {
await viewModel.loadNextPage() await viewModel.loadNextPage()
} }
} }
.toolbar {
EditButton()
}
} }
} }
// Move Function (Reordering Rows)
private func moveEmployee(from source: IndexSet, to destination: Int) {
viewModel.employees.move(fromOffsets: source, toOffset: destination)
}
// Delete Function (Swipe to Delete)
private func deleteEmployees(at offsets: IndexSet) {
viewModel.employees.remove(atOffsets: offsets)
}
// Single Delete Function (For Swipe Actions)
private func deleteEmployee(_ employee: Employee) {
viewModel.employees.removeAll { $0.id == employee.id }
}
} }
public struct EmployeeDetailView: View { public struct EmployeeDetailView: View {
@ -99,13 +141,23 @@ public struct EmployeeDetailView: View {
} }
Label("Email: \(viewModel.emailAddress)", systemImage: "envelope.fill") Label("Email: \(viewModel.emailAddress)", systemImage: "envelope.fill")
.foregroundColor(.gray) .foregroundColor(viewModel.emailAddressURL != nil ? .blue : .gray)
.font(.caption) .font(.caption)
.onTapGesture {
if let url = viewModel.emailAddressURL {
UIApplication.shared.open(url)
}
}
if let phoneNumber = viewModel.phoneNumber { if let phoneNumber = viewModel.phoneNumber {
Label("Call: \(phoneNumber)", systemImage: "phone.fill") Label("Call: \(phoneNumber)", systemImage: "phone.fill")
.foregroundColor(.gray) .foregroundColor(viewModel.phoneNumberURL != nil ? .blue : .gray)
.font(.caption) .font(.caption)
.onTapGesture {
if let url = viewModel.phoneNumberURL {
UIApplication.shared.open(url)
}
}
} }
Spacer() Spacer()
@ -180,6 +232,8 @@ public class EmployeeViewModel {
public private(set) var biography: String? public private(set) var biography: String?
public private(set) var smallPhoto: String? public private(set) var smallPhoto: String?
public private(set) var largePhoto: String? public private(set) var largePhoto: String?
public private(set) var emailAddressURL: URL?
public private(set) var phoneNumberURL: URL?
// MARK: - Initializer // MARK: - Initializer
public init(employee: Employee) { public init(employee: Employee) {
@ -191,6 +245,14 @@ public class EmployeeViewModel {
biography = employee.biography biography = employee.biography
smallPhoto = employee.photoURLSmall smallPhoto = employee.photoURLSmall
largePhoto = employee.photoURLLarge largePhoto = employee.photoURLLarge
if let url = URL(string: "mailto:\(emailAddress)"), UIApplication.shared.canOpenURL(url) {
emailAddressURL = url
}
if let phoneNumber, let url = URL(string: "tel:\(phoneNumber)"), UIApplication.shared.canOpenURL(url) {
phoneNumberURL = url
}
} }
} }