### feat: verbessere Wizard-Validierung und UI-Feedback
- Integriere Fortschrittsanzeige während der Veranstalter-Suche (`isCheckingStats`). - Zeige Fehlermeldungen bei Suchfehlern im `EventWizardScreen`. - Füge `hasSelectedVeranstalter`-Guard und zugehörige Tests hinzu. - Präzisiere `DemoEventFlow` mit expliziter Guard-Logik. - Aktualisiere Unit-Tests zur Abdeckung neuer Guard-Szenarien.
This commit is contained in:
+25
-12
@@ -317,18 +317,31 @@ private fun VeranstalterSelectionStep(
|
||||
Text("Schritt 2: Veranstalter auswählen", style = MaterialTheme.typography.titleLarge)
|
||||
Text("Suchen Sie nach dem Verein (Name oder OEPS-Nummer).")
|
||||
|
||||
MsTextField(
|
||||
value = searchQuery,
|
||||
onValueChange = {
|
||||
searchQuery = it
|
||||
if (it.length >= 3) {
|
||||
viewModel.searchVeranstalterByOepsNr(it)
|
||||
}
|
||||
},
|
||||
label = "Verein suchen (z.B. 6-009)",
|
||||
placeholder = "OEPS-Nummer eingeben...",
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
MsTextField(
|
||||
value = searchQuery,
|
||||
onValueChange = {
|
||||
searchQuery = it
|
||||
if (it.length >= 3) {
|
||||
viewModel.searchVeranstalterByOepsNr(it)
|
||||
}
|
||||
},
|
||||
label = "Verein suchen (z.B. 6-009)",
|
||||
placeholder = "OEPS-Nummer eingeben...",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !viewModel.state.isCheckingStats
|
||||
)
|
||||
if (viewModel.state.isCheckingStats) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.align(Alignment.CenterEnd).padding(end = 12.dp).size(24.dp),
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (viewModel.state.error != null) {
|
||||
Text(viewModel.state.error!!, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall)
|
||||
}
|
||||
|
||||
if (viewModel.state.veranstalterId != null) {
|
||||
Card(
|
||||
|
||||
+9
-3
@@ -19,6 +19,7 @@ import at.mocode.frontend.core.wizard.runtime.WizardContext
|
||||
import at.mocode.frontend.core.wizard.runtime.WizardState
|
||||
import at.mocode.frontend.core.wizard.samples.DemoEventAcc
|
||||
import at.mocode.frontend.core.wizard.samples.DemoEventFlow
|
||||
import at.mocode.frontend.core.wizard.samples.DemoEventFlowNextManual
|
||||
import at.mocode.frontend.core.wizard.samples.DemoEventStep
|
||||
import at.mocode.frontend.features.turnier.presentation.TurnierWizardViewModel
|
||||
import at.mocode.frontend.features.veranstalter.domain.VeranstalterRepository
|
||||
@@ -163,8 +164,10 @@ class EventWizardViewModel(
|
||||
}
|
||||
|
||||
fun searchVeranstalterByOepsNr(oepsNr: String) {
|
||||
if (oepsNr.isBlank()) return
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
state = state.copy(isCheckingStats = true)
|
||||
val verein = vereinRepository.findByOepsNr(oepsNr)
|
||||
if (verein != null) {
|
||||
// Robustes Parsing für Mock-Daten (z. B. "v1")
|
||||
@@ -182,13 +185,16 @@ class EventWizardViewModel(
|
||||
standardOrt = "${verein.plz ?: ""} ${verein.ort ?: ""}".trim(),
|
||||
logo = null
|
||||
)
|
||||
state = state.copy(isCheckingStats = false, znsSearchResults = emptyList())
|
||||
} else if (oepsNr.length >= 3) {
|
||||
// Suche in den ZNS-Stammdaten als Fallback
|
||||
znsImportProvider.searchRemote(oepsNr)
|
||||
state = state.copy(znsSearchResults = znsImportProvider.state.remoteResults)
|
||||
state = state.copy(isCheckingStats = false, znsSearchResults = znsImportProvider.state.remoteResults)
|
||||
} else {
|
||||
state = state.copy(isCheckingStats = false)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
state = state.copy(error = "Fehler bei der Veranstalter-Suche: ${e.message}")
|
||||
state = state.copy(isCheckingStats = false, error = "Fehler bei der Veranstalter-Suche: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,7 +213,7 @@ class EventWizardViewModel(
|
||||
if (WizardFeatureFlags.WizardRuntimeEnabled && isHandledByRuntime(state.currentStep)) {
|
||||
val ctx = buildWizardContext()
|
||||
val currentRuntimeState = ensureWizardStateInitialized()
|
||||
val next = DemoEventFlow.next(ctx, currentRuntimeState)
|
||||
val next = DemoEventFlowNextManual(ctx, currentRuntimeState)
|
||||
wizardState = next
|
||||
val mapped = mapToWizardStep(next.current)
|
||||
if (mapped != null) {
|
||||
|
||||
Reference in New Issue
Block a user