Add residence deletion functionality for iOS and Android

- Add delete residence button to iOS ResidenceDetailView (primary owners only)
- Add delete confirmation alert for iOS with destructive action
- Implement deleteResidence API call in iOS with navigation on success
- Add delete residence button to Android ResidenceDetailScreen (primary owners only)
- Add delete confirmation dialog for Android with error-colored button
- Add deleteResidenceState to ResidenceViewModel with StateFlow
- Implement deleteResidence() and resetDeleteResidenceState() in ViewModel
- Add LaunchedEffect to handle delete success (navigates back) and errors
- Display delete button with red/error styling on both platforms
- Restrict delete functionality to primary owners only

🤖 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-10 10:42:37 -06:00
parent 872a7df86f
commit 29b4c99f08
3 changed files with 121 additions and 0 deletions

View File

@@ -54,6 +54,8 @@ fun ResidenceDetailScreen(
var showManageUsersDialog by remember { mutableStateOf(false) }
var showReportSnackbar by remember { mutableStateOf(false) }
var reportMessage by remember { mutableStateOf("") }
var showDeleteConfirmation by remember { mutableStateOf(false) }
val deleteState by residenceViewModel.deleteResidenceState.collectAsState()
LaunchedEffect(residenceId) {
residenceViewModel.getResidence(residenceId) { result ->
@@ -126,6 +128,22 @@ fun ResidenceDetailScreen(
}
}
// Handle delete residence state
LaunchedEffect(deleteState) {
when (deleteState) {
is ApiResult.Success -> {
residenceViewModel.resetDeleteResidenceState()
onNavigateBack()
}
is ApiResult.Error -> {
reportMessage = (deleteState as ApiResult.Error).message
showReportSnackbar = true
residenceViewModel.resetDeleteResidenceState()
}
else -> {}
}
}
if (showCompleteDialog && selectedTask != null) {
CompleteTaskDialog(
taskId = selectedTask!!.id,
@@ -176,6 +194,33 @@ fun ResidenceDetailScreen(
)
}
if (showDeleteConfirmation && residenceState is ApiResult.Success) {
val residence = (residenceState as ApiResult.Success<Residence>).data
AlertDialog(
onDismissRequest = { showDeleteConfirmation = false },
title = { Text("Delete Residence") },
text = { Text("Are you sure you want to delete ${residence.name}? This action cannot be undone.") },
confirmButton = {
Button(
onClick = {
showDeleteConfirmation = false
residenceViewModel.deleteResidence(residenceId)
},
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.error
)
) {
Text("Delete")
}
},
dismissButton = {
TextButton(onClick = { showDeleteConfirmation = false }) {
Text("Cancel")
}
}
)
}
val snackbarHostState = remember { SnackbarHostState() }
LaunchedEffect(showReportSnackbar) {
@@ -231,6 +276,19 @@ fun ResidenceDetailScreen(
}) {
Icon(Icons.Default.Edit, contentDescription = "Edit Residence")
}
// Delete button - only show for primary owners
if (residence.isPrimaryOwner) {
IconButton(onClick = {
showDeleteConfirmation = true
}) {
Icon(
Icons.Default.Delete,
contentDescription = "Delete Residence",
tint = MaterialTheme.colorScheme.error
)
}
}
}
},
colors = TopAppBarDefaults.topAppBarColors(

View File

@@ -49,6 +49,9 @@ class ResidenceViewModel : ViewModel() {
private val _generateReportState = MutableStateFlow<ApiResult<com.mycrib.shared.network.GenerateReportResponse>>(ApiResult.Idle)
val generateReportState: StateFlow<ApiResult<com.mycrib.shared.network.GenerateReportResponse>> = _generateReportState
private val _deleteResidenceState = MutableStateFlow<ApiResult<Unit>>(ApiResult.Idle)
val deleteResidenceState: StateFlow<ApiResult<Unit>> = _deleteResidenceState
fun loadResidences() {
viewModelScope.launch {
_residencesState.value = ApiResult.Loading
@@ -208,4 +211,20 @@ class ResidenceViewModel : ViewModel() {
fun resetGenerateReportState() {
_generateReportState.value = ApiResult.Idle
}
fun deleteResidence(residenceId: Int) {
viewModelScope.launch {
_deleteResidenceState.value = ApiResult.Loading
val token = TokenStorage.getToken()
if (token != null) {
_deleteResidenceState.value = residenceApi.deleteResidence(token, residenceId)
} else {
_deleteResidenceState.value = ApiResult.Error("Not authenticated", 401)
}
}
}
fun resetDeleteResidenceState() {
_deleteResidenceState.value = ApiResult.Idle
}
}