Implement online registration (Nennung) workflow: add API integration, ViewModel logic, UI updates, backend endpoint, and roadmap adjustments.

This commit is contained in:
2026-04-14 19:41:32 +02:00
parent a6fcb81594
commit 26ac3007b9
6 changed files with 223 additions and 13 deletions
@@ -44,6 +44,10 @@ kotlin {
implementation(projects.frontend.core.network)
implementation(libs.kotlinx.datetime)
// Network & Serialization
implementation(libs.bundles.ktor.client.common)
implementation(libs.kotlinx.serialization.json)
implementation(compose.foundation)
implementation(compose.runtime)
implementation(compose.material3)
@@ -0,0 +1,79 @@
package at.mocode.frontend.features.nennung.presentation.web
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
@Serializable
data class NennungDto(
val id: String? = null,
val turnierNr: String,
val status: String = "NEU",
val vorname: String,
val nachname: String,
val lizenz: String,
val pferdName: String,
val pferdAlter: String,
val email: String,
val telefon: String?,
val bewerbe: String, // Als JSON-String oder Komma-separiert
val bemerkungen: String?
)
data class OnlineNennungUiState(
val isLoading: Boolean = false,
val error: String? = null,
val isSuccess: Boolean = false
)
class OnlineNennungViewModel(
private val httpClient: HttpClient
) : ViewModel() {
private val _uiState = MutableStateFlow(OnlineNennungUiState())
val uiState: StateFlow<OnlineNennungUiState> = _uiState.asStateFlow()
fun sendeNennung(turnierNr: String, payload: NennungPayload) {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true, error = null) }
try {
val dto = NennungDto(
turnierNr = turnierNr,
vorname = payload.vorname,
nachname = payload.nachname,
lizenz = payload.lizenz,
pferdName = payload.pferdName,
pferdAlter = payload.pferdAlter,
email = payload.email,
telefon = payload.telefon,
bewerbe = payload.bewerbe.joinToString(",") { it.nr.toString() },
bemerkungen = payload.bemerkungen
)
// Wir nutzen den httpClient, der via Koin injiziert wird.
// Da im Web-Frontend evtl. kein API-Gateway davor ist (oder ein anderes),
// konfigurieren wir den Pfad hier explizit.
httpClient.post("/api/mail/nennungen") {
contentType(ContentType.Application.Json)
setBody(dto)
}
_uiState.update { it.copy(isLoading = false, isSuccess = true) }
} catch (e: Exception) {
_uiState.update { it.copy(isLoading = false, error = "Fehler beim Senden: ${e.message}") }
}
}
}
fun resetState() {
_uiState.update { OnlineNennungUiState() }
}
}