Add confirmation dialogs for destructive task actions

iOS:
- Add archive task confirmation to TaskActionButtons.swift
- Add archive task confirmation to AllTasksView.swift
- Add cancel and archive task confirmations to ResidenceDetailView.swift
- Fix generatePropertyReport call to use new method signature

Android:
- Add cancel task confirmation to ResidenceDetailScreen.kt
- Add archive task confirmation to ResidenceDetailScreen.kt

All destructive task actions (cancel, archive/delete) now require user confirmation with clear warning messages before proceeding.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-11-13 23:44:41 -06:00
parent a2de0f3454
commit 6ffd5ff626
4 changed files with 468 additions and 225 deletions

View File

@@ -12,6 +12,12 @@ struct AllTasksView: View {
@State private var selectedTaskForEdit: TaskDetail?
@State private var selectedTaskForComplete: TaskDetail?
@State private var selectedTaskForArchive: TaskDetail?
@State private var showArchiveConfirmation = false
@State private var selectedTaskForCancel: TaskDetail?
@State private var showCancelConfirmation = false
private var hasNoTasks: Bool {
guard let response = tasksResponse else { return true }
return response.columns.allSatisfy { $0.tasks.isEmpty }
@@ -20,8 +26,78 @@ struct AllTasksView: View {
private var hasTasks: Bool {
!hasNoTasks
}
var body: some View {
mainContent
.sheet(isPresented: $showAddTask) {
AddTaskWithResidenceView(
isPresented: $showAddTask,
residences: residenceViewModel.myResidences?.residences.toResidences() ?? []
)
}
.sheet(isPresented: $showEditTask) {
if let task = selectedTaskForEdit {
EditTaskView(task: task, isPresented: $showEditTask)
}
}
.sheet(item: $selectedTaskForComplete) { task in
CompleteTaskView(task: task) {
selectedTaskForComplete = nil
loadAllTasks()
}
}
.alert("Archive Task", isPresented: $showArchiveConfirmation) {
Button("Cancel", role: .cancel) {
selectedTaskForArchive = nil
}
Button("Archive", role: .destructive) {
if let task = selectedTaskForArchive {
taskViewModel.archiveTask(id: task.id) { _ in
loadAllTasks()
}
selectedTaskForArchive = nil
}
}
} message: {
if let task = selectedTaskForArchive {
Text("Are you sure you want to archive \"\(task.title)\"? You can unarchive it later from archived tasks.")
}
}
.alert("Delete Task", isPresented: $showCancelConfirmation) {
Button("Cancel", role: .cancel) {
selectedTaskForCancel = nil
}
Button("Archive", role: .destructive) {
if let task = selectedTaskForCancel {
taskViewModel.cancelTask(id: task.id) { _ in
loadAllTasks()
}
selectedTaskForCancel = nil
}
}
} message: {
if let task = selectedTaskForCancel {
Text("Are you sure you want to archive \"\(task.title)\"? You can unarchive it later from archived tasks.")
}
}
.onChange(of: showAddTask) { isShowing in
if !isShowing {
loadAllTasks()
}
}
.onChange(of: showEditTask) { isShowing in
if !isShowing {
loadAllTasks()
}
}
.onAppear {
loadAllTasks()
residenceViewModel.loadMyResidences()
}
}
@ViewBuilder
private var mainContent: some View {
ZStack {
Color(.systemGroupedBackground)
.ignoresSafeArea()
@@ -90,8 +166,10 @@ struct AllTasksView: View {
showEditTask = true
},
onCancelTask: { taskId in
taskViewModel.cancelTask(id: taskId) { _ in
loadAllTasks()
let allTasks = tasksResponse.columns.flatMap { $0.tasks }
if let task = allTasks.first(where: { $0.id == taskId }) {
selectedTaskForCancel = task
showCancelConfirmation = true
}
},
onUncancelTask: { taskId in
@@ -110,8 +188,10 @@ struct AllTasksView: View {
selectedTaskForComplete = task
},
onArchiveTask: { taskId in
taskViewModel.archiveTask(id: taskId) { _ in
loadAllTasks()
let allTasks = tasksResponse.columns.flatMap { $0.tasks }
if let task = allTasks.first(where: { $0.id == taskId }) {
selectedTaskForArchive = task
showArchiveConfirmation = true
}
},
onUnarchiveTask: { taskId in
@@ -158,42 +238,11 @@ struct AllTasksView: View {
.disabled(residenceViewModel.myResidences?.residences.isEmpty ?? true || isLoadingTasks)
}
}
.sheet(isPresented: $showAddTask) {
AddTaskWithResidenceView(
isPresented: $showAddTask,
residences: residenceViewModel.myResidences?.residences.toResidences() ?? [],
)
}
.sheet(isPresented: $showEditTask) {
if let task = selectedTaskForEdit {
EditTaskView(task: task, isPresented: $showEditTask)
}
}
.sheet(item: $selectedTaskForComplete) { task in
CompleteTaskView(task: task) {
selectedTaskForComplete = nil
loadAllTasks()
}
}
.onChange(of: showAddTask) { isShowing in
if !isShowing {
loadAllTasks()
}
}
.onChange(of: showEditTask) { isShowing in
if !isShowing {
loadAllTasks()
}
}
.onChange(of: taskViewModel.isLoading) { isLoading in
if !isLoading {
loadAllTasks()
}
}
.onAppear {
loadAllTasks()
residenceViewModel.loadMyResidences()
}
}
private func loadAllTasks(forceRefresh: Bool = false) {