feat(online-nennung): integrate online nomination workflow via REST and mail service
- Enabled web-to-backend nominations with `MailController` and REST endpoint (`/api/mail/nennung`). - Added `NennungRemoteRepository` for frontend API integration using Ktor. - Linked `WebMainScreen` to backend API for nomination handling and confirmation display. - Implemented automated confirmation emails for received nominations. - Updated `MASTER_ROADMAP` to reflect progress on Phase 13 milestones. - Improved Nennung UI, backend persistence, and QA tracking for Neumarkt tournament.
This commit is contained in:
@@ -10,6 +10,7 @@ plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
}
|
||||
|
||||
group = "at.mocode.clients"
|
||||
@@ -54,6 +55,8 @@ kotlin {
|
||||
implementation(libs.koin.core)
|
||||
implementation(libs.koin.compose)
|
||||
implementation(libs.koin.compose.viewmodel)
|
||||
|
||||
implementation(libs.bundles.ktor.client.common)
|
||||
}
|
||||
|
||||
jvmMain.dependencies {
|
||||
|
||||
+3
@@ -1,9 +1,12 @@
|
||||
package at.mocode.frontend.features.nennung.di
|
||||
|
||||
import at.mocode.frontend.features.nennung.domain.NennungRemoteRepository
|
||||
import at.mocode.frontend.features.nennung.presentation.NennungViewModel
|
||||
import io.ktor.client.HttpClient
|
||||
import org.koin.core.module.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val nennungFeatureModule = module {
|
||||
single<NennungRemoteRepository> { NennungRemoteRepository(get<HttpClient>()) }
|
||||
viewModel { NennungViewModel() }
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package at.mocode.frontend.features.nennung.domain
|
||||
|
||||
import at.mocode.frontend.features.nennung.presentation.web.NennungPayload
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.client.request.setBody
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.contentType
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class NennungApiRequest(
|
||||
val turnierNr: String,
|
||||
val vorname: String,
|
||||
val nachname: String,
|
||||
val lizenz: String,
|
||||
val pferdName: String,
|
||||
val pferdAlter: String,
|
||||
val email: String,
|
||||
val telefon: String?,
|
||||
val bewerbe: String,
|
||||
val bemerkungen: String?
|
||||
)
|
||||
|
||||
class NennungRemoteRepository(private val client: HttpClient) {
|
||||
suspend fun sendeNennung(turnierNr: String, payload: NennungPayload): Result<Unit> {
|
||||
return try {
|
||||
val request = NennungApiRequest(
|
||||
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 senden direkt an den mail-service (Port 8085)
|
||||
// In einer Prod-Umgebung würde dies über das Gateway laufen.
|
||||
client.post("http://localhost:8085/api/mail/nennung") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(request)
|
||||
}
|
||||
Result.success(Unit)
|
||||
} catch (e: Exception) {
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -761,7 +761,8 @@ private fun VerkaufTabInhalt(artikel: List<VerkaufArtikel>, onMengeChanged: (Ver
|
||||
IconButton(onClick = { onMengeChanged(art, -1) }, modifier = Modifier.size(20.dp)) {
|
||||
Icon(Icons.Default.Remove, contentDescription = "–", modifier = Modifier.size(12.dp))
|
||||
}
|
||||
Text(art.buchungstext,
|
||||
Text(
|
||||
art.buchungstext,
|
||||
fontSize = 10.sp,
|
||||
modifier = Modifier.weight(1f),
|
||||
maxLines = 1,
|
||||
|
||||
Reference in New Issue
Block a user