feat(desktop): add NennungsEingang screen and integrate into navigation
- Introduced `NennungsEingangScreen` for managing online nomination entries. - Added `NennungsEingang` to `AppScreen` with corresponding route configuration. - Updated `DesktopMainLayout` to include navigation and UI components for `NennungsEingang`. - Adjusted `PreviewMain` for screen integration and testing.
This commit is contained in:
+2
@@ -65,6 +65,7 @@ sealed class AppScreen(val route: String) {
|
|||||||
data object Meisterschaften : AppScreen("/meisterschaften")
|
data object Meisterschaften : AppScreen("/meisterschaften")
|
||||||
data object Cups : AppScreen("/cups")
|
data object Cups : AppScreen("/cups")
|
||||||
data object StammdatenImport : AppScreen("/stammdaten/import")
|
data object StammdatenImport : AppScreen("/stammdaten/import")
|
||||||
|
data object NennungsEingang : AppScreen("/nennungs-eingang")
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val VERANSTALTUNG_DETAIL = Regex("/veranstaltung/(\\d+)$")
|
private val VERANSTALTUNG_DETAIL = Regex("/veranstaltung/(\\d+)$")
|
||||||
@@ -106,6 +107,7 @@ sealed class AppScreen(val route: String) {
|
|||||||
"/meisterschaften" -> Meisterschaften
|
"/meisterschaften" -> Meisterschaften
|
||||||
"/cups" -> Cups
|
"/cups" -> Cups
|
||||||
"/stammdaten/import" -> StammdatenImport
|
"/stammdaten/import" -> StammdatenImport
|
||||||
|
"/nennungs-eingang" -> NennungsEingang
|
||||||
else -> {
|
else -> {
|
||||||
BILLING.matchEntire(route)?.destructured?.let { (vId, tId) ->
|
BILLING.matchEntire(route)?.destructured?.let { (vId, tId) ->
|
||||||
return Billing(vId.toLong(), tId.toLong())
|
return Billing(vId.toLong(), tId.toLong())
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ fun DesktopApp() {
|
|||||||
&& currentScreen !is AppScreen.PferdVerwaltung
|
&& currentScreen !is AppScreen.PferdVerwaltung
|
||||||
&& currentScreen !is AppScreen.VereinVerwaltung
|
&& currentScreen !is AppScreen.VereinVerwaltung
|
||||||
&& currentScreen !is AppScreen.StammdatenImport
|
&& currentScreen !is AppScreen.StammdatenImport
|
||||||
|
&& currentScreen !is AppScreen.NennungsEingang
|
||||||
) {
|
) {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
// Standard: Start im Onboarding
|
// Standard: Start im Onboarding
|
||||||
|
|||||||
+4
@@ -5,6 +5,8 @@ import androidx.compose.material3.Surface
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.window.singleWindowApplication
|
import androidx.compose.ui.window.singleWindowApplication
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import at.mocode.desktop.v2.NennungsEingangScreen
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hot-Reload Preview Entry Point
|
* Hot-Reload Preview Entry Point
|
||||||
@@ -35,6 +37,8 @@ private fun PreviewContent() {
|
|||||||
// --- VEREIN ---
|
// --- VEREIN ---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ── Hier den gewünschten Screen eintragen ──────────────────────
|
// ── Hier den gewünschten Screen eintragen ──────────────────────
|
||||||
// VeranstalterAuswahlScreen(onVeranstalterSelected = {}, onNeuerVeranstalter = {})
|
// VeranstalterAuswahlScreen(onVeranstalterSelected = {}, onNeuerVeranstalter = {})
|
||||||
// VeranstalterNeuScreen(onBack = {}, onSave = {})
|
// VeranstalterNeuScreen(onBack = {}, onSave = {})
|
||||||
|
|||||||
+13
@@ -143,6 +143,13 @@ private fun DesktopNavRail(
|
|||||||
onClick = { onNavigate(AppScreen.VereinVerwaltung) }
|
onClick = { onNavigate(AppScreen.VereinVerwaltung) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NavRailItem(
|
||||||
|
icon = Icons.Default.Email,
|
||||||
|
label = "Mails",
|
||||||
|
selected = currentScreen is AppScreen.NennungsEingang,
|
||||||
|
onClick = { onNavigate(AppScreen.NennungsEingang) }
|
||||||
|
)
|
||||||
|
|
||||||
NavRailItem(
|
NavRailItem(
|
||||||
icon = Icons.Default.Settings,
|
icon = Icons.Default.Settings,
|
||||||
label = "Tools",
|
label = "Tools",
|
||||||
@@ -795,6 +802,12 @@ private fun DesktopContentArea(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is AppScreen.NennungsEingang -> {
|
||||||
|
at.mocode.desktop.v2.NennungsEingangScreen(
|
||||||
|
onBack = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback → Root
|
// Fallback → Root
|
||||||
else -> AdminUebersichtScreen(
|
else -> AdminUebersichtScreen(
|
||||||
onVeranstalterAuswahl = { onNavigate(AppScreen.VeranstalterAuswahl) },
|
onVeranstalterAuswahl = { onNavigate(AppScreen.VeranstalterAuswahl) },
|
||||||
|
|||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
package at.mocode.desktop.v2
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Check
|
||||||
|
import androidx.compose.material.icons.filled.Email
|
||||||
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
data class OnlineNennungMail(
|
||||||
|
val id: String,
|
||||||
|
val sender: String,
|
||||||
|
val empfaenger: String,
|
||||||
|
val datum: String,
|
||||||
|
val turnierNr: String,
|
||||||
|
val reiter: String,
|
||||||
|
val pferd: String,
|
||||||
|
val bewerbe: String,
|
||||||
|
val status: String = "Neu"
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun NennungsEingangScreen(onBack: () -> Unit) {
|
||||||
|
DesktopThemeV2 {
|
||||||
|
var mails by remember { mutableStateOf(getMockMails()) }
|
||||||
|
var isRefreshing by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Column(Modifier.fillMaxSize().padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
|
// Header
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||||
|
IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, null) }
|
||||||
|
Icon(Icons.Default.Email, null, modifier = Modifier.size(32.dp), tint = MaterialTheme.colorScheme.primary)
|
||||||
|
Text("Nennungs-Eingang (Online-Nennen)", style = MaterialTheme.typography.headlineMedium)
|
||||||
|
Spacer(Modifier.weight(1f))
|
||||||
|
Button(
|
||||||
|
onClick = { /* Refresh Logik */ },
|
||||||
|
enabled = !isRefreshing
|
||||||
|
) {
|
||||||
|
Icon(Icons.Default.Refresh, null)
|
||||||
|
Spacer(Modifier.width(8.dp))
|
||||||
|
Text("Aktualisieren")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
"Hier werden alle eingegangenen Online-Nennungen angezeigt, die über das Web-Formular an meldestelle-[Nr]@mo-code.at gesendet wurden.",
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
color = Color.Gray
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tabelle
|
||||||
|
Card(modifier = Modifier.fillMaxWidth().weight(1f)) {
|
||||||
|
Column {
|
||||||
|
// Header Zeile
|
||||||
|
Row(
|
||||||
|
Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.surfaceVariant).padding(12.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text("Datum", Modifier.width(150.dp), fontWeight = FontWeight.Bold, fontSize = 13.sp)
|
||||||
|
Text("Turnier", Modifier.width(100.dp), fontWeight = FontWeight.Bold, fontSize = 13.sp)
|
||||||
|
Text("Reiter", Modifier.width(200.dp), fontWeight = FontWeight.Bold, fontSize = 13.sp)
|
||||||
|
Text("Pferd", Modifier.width(200.dp), fontWeight = FontWeight.Bold, fontSize = 13.sp)
|
||||||
|
Text("Bewerbe", Modifier.weight(1f), fontWeight = FontWeight.Bold, fontSize = 13.sp)
|
||||||
|
Text("Aktion", Modifier.width(150.dp), fontWeight = FontWeight.Bold, fontSize = 13.sp)
|
||||||
|
}
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
|
if (mails.isEmpty()) {
|
||||||
|
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
Text("Keine neuen Nennungen vorhanden.", color = Color.Gray)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LazyColumn(Modifier.fillMaxSize()) {
|
||||||
|
items(mails) { mail ->
|
||||||
|
Row(
|
||||||
|
Modifier.fillMaxWidth().padding(horizontal = 12.dp, vertical = 8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(mail.datum, Modifier.width(150.dp), fontSize = 13.sp)
|
||||||
|
Text(mail.turnierNr, Modifier.width(100.dp), fontSize = 13.sp, fontWeight = FontWeight.SemiBold)
|
||||||
|
Text(mail.reiter, Modifier.width(200.dp), fontSize = 13.sp)
|
||||||
|
Text(mail.pferd, Modifier.width(200.dp), fontSize = 13.sp)
|
||||||
|
Text(mail.bewerbe, Modifier.weight(1f), fontSize = 13.sp)
|
||||||
|
|
||||||
|
Row(Modifier.width(150.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = { /* Übernahme Logik */ },
|
||||||
|
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 4.dp),
|
||||||
|
modifier = Modifier.height(32.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.secondary)
|
||||||
|
) {
|
||||||
|
Icon(Icons.Default.Check, null, modifier = Modifier.size(14.dp))
|
||||||
|
Spacer(Modifier.width(4.dp))
|
||||||
|
Text("Übernehmen", fontSize = 11.sp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HorizontalDivider(Modifier.padding(horizontal = 8.dp), thickness = 0.5.dp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMockMails() = listOf(
|
||||||
|
OnlineNennungMail("1", "max.mustermann@web.de", "meldestelle-26128@mo-code.at", "14.04.2026 14:30", "26128", "Max Mustermann", "Spirit", "1, 2, 5"),
|
||||||
|
OnlineNennungMail("2", "susi.sorglos@gmx.at", "meldestelle-26128@mo-code.at", "14.04.2026 15:12", "26128", "Susi Sorglos", "Flocke", "10, 11"),
|
||||||
|
OnlineNennungMail("3", "info@reitstall-hofer.at", "meldestelle-26129@mo-code.at", "14.04.2026 16:05", "26129", "Georg Hofer", "Black Beauty", "3, 4, 8")
|
||||||
|
)
|
||||||
@@ -22,12 +22,12 @@ kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wasmJs {
|
wasmJs {
|
||||||
binaries.library()
|
|
||||||
browser {
|
browser {
|
||||||
testTask {
|
testTask {
|
||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binaries.executable()
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import at.mocode.frontend.core.designsystem.theme.AppColors
|
import at.mocode.frontend.core.designsystem.theme.AppColors
|
||||||
import at.mocode.frontend.features.billing.presentation.BillingViewModel
|
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 at.mocode.frontend.features.nennung.presentation.web.OnlineNennungFormular
|
||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user