### feat: verbessere Feedback- und Fehlerhandling im Nennformular
All checks were successful
All checks were successful
- **OnlineNennungFormular:** Ladeindikator und Fehleranzeige bei API-Fehlermeldungen hinzugefügt. - **WebMainScreen:** Navigation zum Erfolgsscreen erfolgt erst nach erfolgreicher API-Bestätigung. - **UI:** Aktualisiere Versionsmarker auf `v2026-04-23.11 - NETWORK STATUS FIX`.
This commit is contained in:
parent
76e6cebd90
commit
f7d11ccf97
|
|
@ -30,9 +30,9 @@ Die "Hallo Du!" Test-UI wurde durch produktive, fachlich korrekte Formulare erse
|
||||||
|
|
||||||
**Status:** Bereit für den Live-Einsatz am Wochenende. 🚀
|
**Status:** Bereit für den Live-Einsatz am Wochenende. 🚀
|
||||||
|
|
||||||
### 2026-04-23 08:30 - Version 10: HTTPS & CORS FIX
|
### 2026-04-23 09:10 - Version 11: Netzwerk-Status & Error-Handling Fix
|
||||||
- **Problem**: Mixed Content Fehler (HTTPS -> HTTP) und CORS-Blockade auf `app.mo-code.at`.
|
- **Problem**: Kein Feedback beim Absenden, Mixed Content trotz V10, sofortiger Navigations-Reset.
|
||||||
- **Lösung**:
|
- **Lösung**:
|
||||||
- `MailController.kt`: Whitelist für `https://app.mo-code.at` in `@CrossOrigin` hinzugefügt.
|
- `OnlineNennungFormular.kt`: Ladeindikator und dynamische Fehleranzeige implementiert.
|
||||||
- `dc-planb.yaml`: API-URLs auf `https://api.mo-code.at` umgestellt.
|
- `WebMainScreen.kt`: Navigation zum Erfolgsscreen erfolgt nun erst nach Bestätigung durch die API.
|
||||||
- UI-Marker auf `v2026-04-23.10 - HTTPS FIX` aktualisiert.
|
- UI-Marker auf `v2026-04-23.11 - NETWORK STATUS FIX` aktualisiert.
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ data class NennungPayload(
|
||||||
@Composable
|
@Composable
|
||||||
fun OnlineNennungFormular(
|
fun OnlineNennungFormular(
|
||||||
turnierNr: String,
|
turnierNr: String,
|
||||||
onNennenAbgeschickt: (NennungPayload) -> Unit,
|
onNennenAbgeschickt: (NennungPayload, (Boolean, String?) -> Unit) -> Unit,
|
||||||
onBack: () -> Unit
|
onBack: () -> Unit
|
||||||
) {
|
) {
|
||||||
var vorname by remember { mutableStateOf("") }
|
var vorname by remember { mutableStateOf("") }
|
||||||
|
|
@ -52,6 +52,9 @@ fun OnlineNennungFormular(
|
||||||
val ausgewaehlteBewerbe = remember { mutableStateListOf<Bewerb>() }
|
val ausgewaehlteBewerbe = remember { mutableStateListOf<Bewerb>() }
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
|
var isLoading by remember { mutableStateOf(false) }
|
||||||
|
var errorMessage by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
val bewerbeListe = remember(turnierNr) {
|
val bewerbeListe = remember(turnierNr) {
|
||||||
if (turnierNr == "26128") {
|
if (turnierNr == "26128") {
|
||||||
listOf(
|
listOf(
|
||||||
|
|
@ -381,7 +384,7 @@ fun OnlineNennungFormular(
|
||||||
shape = RoundedCornerShape(12.dp),
|
shape = RoundedCornerShape(12.dp),
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions(onDone = {
|
keyboardActions = KeyboardActions(onDone = {
|
||||||
if (canSubmit) {
|
if (canSubmit && !isLoading) {
|
||||||
val payload = NennungPayload(
|
val payload = NennungPayload(
|
||||||
vorname = vorname,
|
vorname = vorname,
|
||||||
nachname = nachname,
|
nachname = nachname,
|
||||||
|
|
@ -393,11 +396,33 @@ fun OnlineNennungFormular(
|
||||||
bewerbe = ausgewaehlteBewerbe.toList(),
|
bewerbe = ausgewaehlteBewerbe.toList(),
|
||||||
bemerkungen = bemerkungen
|
bemerkungen = bemerkungen
|
||||||
)
|
)
|
||||||
onNennenAbgeschickt(payload)
|
isLoading = true
|
||||||
|
errorMessage = null
|
||||||
|
onNennenAbgeschickt(payload) { success, error ->
|
||||||
|
isLoading = false
|
||||||
|
if (!success) {
|
||||||
|
errorMessage = error ?: "Ein unbekannter Fehler ist aufgetreten."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (errorMessage != null) {
|
||||||
|
Card(
|
||||||
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.errorContainer),
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = errorMessage!!,
|
||||||
|
color = MaterialTheme.colorScheme.onErrorContainer,
|
||||||
|
modifier = Modifier.padding(12.dp),
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(Modifier.height(24.dp))
|
Spacer(Modifier.height(24.dp))
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
|
|
@ -413,9 +438,16 @@ fun OnlineNennungFormular(
|
||||||
bewerbe = ausgewaehlteBewerbe.toList(),
|
bewerbe = ausgewaehlteBewerbe.toList(),
|
||||||
bemerkungen = bemerkungen
|
bemerkungen = bemerkungen
|
||||||
)
|
)
|
||||||
onNennenAbgeschickt(payload)
|
isLoading = true
|
||||||
|
errorMessage = null
|
||||||
|
onNennenAbgeschickt(payload) { success, error ->
|
||||||
|
isLoading = false
|
||||||
|
if (!success) {
|
||||||
|
errorMessage = error ?: "Ein unbekannter Fehler ist aufgetreten."
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
enabled = canSubmit,
|
enabled = canSubmit && !isLoading,
|
||||||
modifier = Modifier.fillMaxWidth().height(if (isMobile) 56.dp else 64.dp),
|
modifier = Modifier.fillMaxWidth().height(if (isMobile) 56.dp else 64.dp),
|
||||||
shape = RoundedCornerShape(12.dp),
|
shape = RoundedCornerShape(12.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
|
@ -424,11 +456,15 @@ fun OnlineNennungFormular(
|
||||||
),
|
),
|
||||||
elevation = ButtonDefaults.buttonElevation(defaultElevation = 4.dp, pressedElevation = 8.dp)
|
elevation = ButtonDefaults.buttonElevation(defaultElevation = 4.dp, pressedElevation = 8.dp)
|
||||||
) {
|
) {
|
||||||
|
if (isLoading) {
|
||||||
|
CircularProgressIndicator(modifier = Modifier.size(24.dp), color = Color.Black)
|
||||||
|
Spacer(Modifier.width(12.dp))
|
||||||
|
}
|
||||||
Text(
|
Text(
|
||||||
"Jetzt nennen",
|
text = if (isLoading) "Wird gesendet..." else "Jetzt nennen",
|
||||||
fontWeight = FontWeight.ExtraBold,
|
fontWeight = FontWeight.ExtraBold,
|
||||||
fontSize = if (isMobile) 18.sp else 20.sp,
|
fontSize = if (isMobile) 18.sp else 20.sp,
|
||||||
color = if (canSubmit) Color.Black else Color.DarkGray
|
color = if (canSubmit && !isLoading) Color.Black else Color.DarkGray
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,16 @@ fun MainAppContent() {
|
||||||
|
|
||||||
is WebScreen.Nennung -> OnlineNennungFormular(
|
is WebScreen.Nennung -> OnlineNennungFormular(
|
||||||
turnierNr = screen.turnierId.toString(),
|
turnierNr = screen.turnierId.toString(),
|
||||||
onNennenAbgeschickt = { payload ->
|
onNennenAbgeschickt = { payload, onResult ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val result = nennungRepository.sendeNennung(screen.turnierId.toString(), payload)
|
val result = nennungRepository.sendeNennung(screen.turnierId.toString(), payload)
|
||||||
if (result.isSuccess) {
|
if (result.isSuccess) {
|
||||||
|
onResult(true, null)
|
||||||
currentScreen = WebScreen.Erfolg(payload.email)
|
currentScreen = WebScreen.Erfolg(payload.email)
|
||||||
} else {
|
} else {
|
||||||
// Hier könnte man eine Fehlermeldung anzeigen
|
val error = result.exceptionOrNull()?.message
|
||||||
println("Fehler beim Senden der Nennung: ${result.exceptionOrNull()?.message}")
|
onResult(false, error)
|
||||||
|
println("Fehler beim Senden der Nennung: $error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -122,7 +124,7 @@ fun MainAppContent() {
|
||||||
// Dezentraler Versions-Marker in der unteren rechten Ecke
|
// Dezentraler Versions-Marker in der unteren rechten Ecke
|
||||||
Box(modifier = Modifier.fillMaxSize().padding(8.dp), contentAlignment = Alignment.BottomEnd) {
|
Box(modifier = Modifier.fillMaxSize().padding(8.dp), contentAlignment = Alignment.BottomEnd) {
|
||||||
Text(
|
Text(
|
||||||
text = "v2026-04-23.10 - HTTPS FIX",
|
text = "v2026-04-23.11 - NETWORK STATUS FIX",
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.labelSmall,
|
||||||
color = Color.LightGray.copy(alpha = 0.5f)
|
color = Color.LightGray.copy(alpha = 0.5f)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user