feat(mail-service): initialize Mail-Service and integrate online nomination workflow

- Created `MailServiceApplication` with Spring Boot setup.
- Added `MailPollingService` for IMAP polling, `TurnierNr` extraction, and auto-reply functionality.
- Implemented structured email sending for online nominations via `OnlineNennungFormular`.
- Updated frontend with `Erfolgsscreen` for nomination confirmation and fallback handling.
- Added build configurations for Mail-Service and frontend nomination module.
- Documented phase-based roadmap for Online-Nennung and Mail-Service rollout.
This commit is contained in:
2026-04-14 14:59:11 +02:00
parent 5f87eed86a
commit adfa97978e
9 changed files with 497 additions and 5 deletions
@@ -15,6 +15,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import at.mocode.frontend.core.designsystem.theme.AppColors
import at.mocode.frontend.features.billing.presentation.BillingViewModel
import at.mocode.frontend.features.nennung.presentation.web.NennungPayload
import at.mocode.frontend.features.nennung.presentation.web.OnlineNennungFormular
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -44,10 +46,17 @@ fun WebMainScreen() {
currentScreen = WebScreen.Nennung(vId, tId)
}
)
is WebScreen.Nennung -> NennungWebFormular(
veranstaltungId = screen.veranstaltungId,
turnierId = screen.turnierId,
billingViewModel = billingViewModel,
is WebScreen.Nennung -> OnlineNennungFormular(
turnierNr = screen.turnierId.toString(),
onNennenAbgeschickt = { payload ->
// Hier wird später der Mail-Versand oder API-Call integriert
println("Nennung abgeschickt: $payload")
currentScreen = WebScreen.Erfolg(payload.email)
},
onBack = { currentScreen = WebScreen.Landing }
)
is WebScreen.Erfolg -> Erfolgsscreen(
email = screen.email,
onBack = { currentScreen = WebScreen.Landing }
)
}
@@ -58,6 +67,27 @@ fun WebMainScreen() {
sealed class WebScreen {
data object Landing : WebScreen()
data class Nennung(val veranstaltungId: Long, val turnierId: Long) : WebScreen()
data class Erfolg(val email: String) : WebScreen()
}
@Composable
fun Erfolgsscreen(email: String, onBack: () -> Unit) {
Box(modifier = Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
Card(
colors = CardDefaults.cardColors(containerColor = AppColors.PrimaryContainer),
modifier = Modifier.fillMaxWidth().padding(16.dp)
) {
Column(modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally) {
Text("Nennung erfolgreich eingegangen!", style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
Spacer(Modifier.height(16.dp))
Text("Eine Bestätigungsmail wurde an $email gesendet.", style = MaterialTheme.typography.bodyLarge)
Spacer(Modifier.height(24.dp))
Button(onClick = onBack) {
Text("Zurück zur Startseite")
}
}
}
}
}
@Composable