feat: Implement account deletion feature with UI and API integration
Some checks failed
Deploy tt-tagebuch / deploy (push) Has been cancelled
Some checks failed
Deploy tt-tagebuch / deploy (push) Has been cancelled
This commit is contained in:
Binary file not shown.
@@ -5972,8 +5972,10 @@ private fun SettingsScreen(
|
||||
}
|
||||
val authState by dependencies.authManager.state.collectAsState()
|
||||
val clubState by dependencies.clubManager.state.collectAsState()
|
||||
val androidContext = LocalContext.current
|
||||
var sessionStatus by rememberSaveable { mutableStateOf<String?>(null) }
|
||||
var isLoading by rememberSaveable { mutableStateOf(false) }
|
||||
var showDeleteAccountDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val sessionValidMessage = tr("mobile.sessionValid", "Session gültig")
|
||||
val sessionInvalidMessage = tr("mobile.sessionInvalid", "Session ungültig")
|
||||
val sessionCheckFailedMessage = tr("mobile.sessionCheckFailed", "Session check fehlgeschlagen")
|
||||
@@ -6084,11 +6086,22 @@ private fun SettingsScreen(
|
||||
) { Text(tr("billing.title", "Abrechnung")) }
|
||||
}
|
||||
SectionTitle(tr("mobile.legal", "Rechtliches"))
|
||||
Text(
|
||||
tr("mobile.legalInAppTodo", "Impressum/Datenschutz: in-App-Ansicht folgt (kein Browser-Aufruf)."),
|
||||
style = MaterialTheme.typography.caption,
|
||||
modifier = Modifier.padding(bottom = 4.dp),
|
||||
)
|
||||
TextButton(
|
||||
onClick = {
|
||||
androidContext.startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse("${dependencies.apiConfig.baseUrl}/datenschutz")),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) { Text("Datenschutzerklärung") }
|
||||
TextButton(
|
||||
onClick = {
|
||||
androidContext.startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse("${dependencies.apiConfig.baseUrl}/impressum")),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) { Text("Impressum") }
|
||||
Button(
|
||||
onClick = {
|
||||
isLoading = true
|
||||
@@ -6134,6 +6147,17 @@ private fun SettingsScreen(
|
||||
Text(tr("auth.logout", "Abmelden"))
|
||||
}
|
||||
|
||||
SectionTitle("Konto und Daten")
|
||||
OutlinedButton(
|
||||
onClick = { showDeleteAccountDialog = true },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
.heightIn(min = TouchMinHeight),
|
||||
) {
|
||||
Text("Eigenes Konto löschen", color = MaterialTheme.colors.error)
|
||||
}
|
||||
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
dependencies.applicationScope.launch {
|
||||
@@ -6149,6 +6173,73 @@ private fun SettingsScreen(
|
||||
Text(tr("club.change", "Verein wechseln"))
|
||||
}
|
||||
}
|
||||
|
||||
if (showDeleteAccountDialog) {
|
||||
DeleteAccountDialog(
|
||||
onDismiss = { showDeleteAccountDialog = false },
|
||||
onConfirm = { password, onError ->
|
||||
dependencies.applicationScope.launch {
|
||||
runCatching {
|
||||
dependencies.authManager.deleteAccount(password)
|
||||
dependencies.clubManager.clearSelection()
|
||||
dependencies.diaryManager.clear()
|
||||
dependencies.membersManager.clear()
|
||||
dependencies.trainingStatsManager.clear()
|
||||
dependencies.scheduleManager.clear()
|
||||
dependencies.pendingApprovalsManager.clear()
|
||||
dependencies.permissionsAdminManager.clear()
|
||||
dependencies.apiLogsManager.clear()
|
||||
dependencies.clubInternalTournamentsManager.clear()
|
||||
dependencies.officialTournamentsReadManager.clear()
|
||||
}.onSuccess {
|
||||
showDeleteAccountDialog = false
|
||||
}.onFailure {
|
||||
onError(it.message ?: "Konto konnte nicht gelöscht werden.")
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DeleteAccountDialog(
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: (password: String, onError: (String) -> Unit) -> Unit,
|
||||
) {
|
||||
var password by rememberSaveable { mutableStateOf("") }
|
||||
var error by rememberSaveable { mutableStateOf<String?>(null) }
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text("Eigenes Konto löschen") },
|
||||
text = {
|
||||
Column {
|
||||
Text("Diese Aktion löscht dein Benutzerkonto, deine Login-Sessions, Vereinszuordnungen und personenbezogene Integrationsdaten. Geteilte Vereinsdaten bleiben erhalten.")
|
||||
error?.let { Text(it, color = MaterialTheme.colors.error, modifier = Modifier.padding(top = 8.dp)) }
|
||||
OutlinedTextField(
|
||||
value = password,
|
||||
onValueChange = { password = it },
|
||||
label = { Text("Passwort zur Bestätigung") },
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
|
||||
singleLine = true,
|
||||
)
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (password.isBlank()) {
|
||||
error = "Bitte Passwort eingeben."
|
||||
} else {
|
||||
onConfirm(password) { error = it }
|
||||
}
|
||||
},
|
||||
) { Text("Endgültig löschen", color = MaterialTheme.colors.error) }
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) { Text("Abbrechen") }
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
Reference in New Issue
Block a user