chore: erweitere Datenmodelle um Nation und Bundesland, verbessere UI im Profil- und Veranstaltungs-Wizard

Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
2026-04-21 13:56:04 +02:00
parent 2662d4e82e
commit f13c2eb35b
8 changed files with 45 additions and 12 deletions
@@ -32,6 +32,8 @@ data class ZnsRemoteReiter(
val vorname: String, val vorname: String,
val lizenz: String?, val lizenz: String?,
val lizenzKlasse: String, val lizenzKlasse: String,
val nation: String? = "AUT",
val bundesland: String? = null,
) )
data class ZnsRemotePferd( data class ZnsRemotePferd(
@@ -48,6 +50,8 @@ data class ZnsRemoteFunktionaer(
val satzNummer: Int, val satzNummer: Int,
val name: String?, val name: String?,
val qualifikationen: List<String>, val qualifikationen: List<String>,
val nation: String? = "AUT",
val bundesland: String? = null,
) )
interface ZnsImportProvider { interface ZnsImportProvider {
@@ -97,5 +97,9 @@ data class ProfileDto(
val satznummer: String? = null, val satznummer: String? = null,
val bio: String? = null, val bio: String? = null,
val contactEmail: String? = null, val contactEmail: String? = null,
val logoUrl: String? = null val logoUrl: String? = null,
val vorname: String? = null,
val nachname: String? = null,
val nation: String? = "AUT",
val bundesland: String? = null
) )
@@ -131,6 +131,10 @@ private fun ConfirmStep(viewModel: ProfileOnboardingViewModel) {
Text("Satznummer: ${reiter.satznummer ?: "N/A"}") Text("Satznummer: ${reiter.satznummer ?: "N/A"}")
Text("Lizenz: ${reiter.lizenz ?: "Keine"}") Text("Lizenz: ${reiter.lizenz ?: "Keine"}")
Text("Klasse: ${reiter.lizenzKlasse}") Text("Klasse: ${reiter.lizenzKlasse}")
Text("Nation: ${reiter.nation ?: "AUT"}")
if (reiter.bundesland != null) {
Text("Bundesland: ${reiter.bundesland}")
}
} }
} }
@@ -4,10 +4,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Badge import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Link
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@@ -151,6 +148,20 @@ fun ProfileDetailsSection(
DetailItem(label = "Satznummer", value = profile.satznummer ?: "Nicht verknüpft", icon = Icons.Default.Badge) DetailItem(label = "Satznummer", value = profile.satznummer ?: "Nicht verknüpft", icon = Icons.Default.Badge)
if (profile.vorname != null || profile.nachname != null) {
Spacer(Modifier.height(12.dp))
DetailItem(
label = "Name",
value = "${profile.vorname ?: ""} ${profile.nachname ?: ""}".trim(),
icon = Icons.Default.Person
)
}
if (profile.nation != null) {
Spacer(Modifier.height(12.dp))
DetailItem(label = "Nation / Bundesland", value = "${profile.nation}${if (profile.bundesland != null) " (${profile.bundesland})" else ""}", icon = Icons.Default.Public)
}
Spacer(Modifier.height(12.dp)) Spacer(Modifier.height(12.dp))
if (isEditing) { if (isEditing) {
@@ -429,14 +429,14 @@ private fun TurnierAnlageStep(viewModel: VeranstaltungWizardViewModel) {
Text("Schritt 5: Turniere & Ausschreibung", style = MaterialTheme.typography.titleLarge) Text("Schritt 5: Turniere & Ausschreibung", style = MaterialTheme.typography.titleLarge)
if (showWizard) { if (showWizard) {
Card(modifier = Modifier.fillMaxWidth().height(500.dp)) { Card(modifier = Modifier.fillMaxWidth().height(600.dp)) {
TurnierWizard( TurnierWizard(
viewModel = turnierViewModel, viewModel = turnierViewModel,
veranstaltungId = 0, // In Echt wird hier die ID aus dem State genutzt veranstaltungId = 0, // Mock-Modus
onBack = { showWizard = false }, onBack = { showWizard = false },
onFinish = { onFinish = {
showWizard = false showWizard = false
viewModel.addTurnier(turnierViewModel.state.turnierNr, "") viewModel.addTurnier(turnierViewModel.state.turnierNr, "ZNS Ausschreibung")
} }
) )
} }
@@ -52,7 +52,7 @@ data class VeranstaltungWizardState(
val startDatum: LocalDate? = null, val startDatum: LocalDate? = null,
val endDatum: LocalDate? = null, val endDatum: LocalDate? = null,
val logoUrl: String? = null, val logoUrl: String? = null,
val turniere: List<TurnierEntry> = listOf(TurnierEntry()), val turniere: List<TurnierEntry> = emptyList(),
val isSaving: Boolean = false, val isSaving: Boolean = false,
val error: String? = null, val error: String? = null,
val createdVeranstaltungId: Uuid? = null, val createdVeranstaltungId: Uuid? = null,
@@ -188,7 +188,11 @@ class VeranstaltungWizardViewModel(
} }
fun addTurnier(nummer: String = "", pfad: String? = null) { fun addTurnier(nummer: String = "", pfad: String? = null) {
state = state.copy(turniere = state.turniere + TurnierEntry(nummer = nummer, ausschreibungPath = pfad)) val current = state.turniere.filter { it.nummer.isNotBlank() }
state = state.copy(turniere = current + TurnierEntry(nummer = nummer, ausschreibungPath = pfad))
// Reset child state for next tournament
turnierWizardViewModel.updateNr("")
turnierWizardViewModel.setNrConfirmed(false)
} }
fun removeTurnier(index: Int) { fun removeTurnier(index: Int) {
@@ -54,6 +54,7 @@ data class Reiter(
var vereinsNummer: String? = null, var vereinsNummer: String? = null,
var verein: String? = null, var verein: String? = null,
var nation: String = "AUT", var nation: String = "AUT",
var bundesland: String? = null,
var istGastreiter: Boolean = false, var istGastreiter: Boolean = false,
) )
@@ -68,6 +69,8 @@ data class Funktionaer(
var email: String? = null, var email: String? = null,
var telefon: String? = null, var telefon: String? = null,
var vereinsNummer: String? = null, var vereinsNummer: String? = null,
var nation: String = "AUT",
var bundesland: String? = null,
var istAktiv: Boolean = true, var istAktiv: Boolean = true,
) )
@@ -43,7 +43,8 @@ class DesktopMasterdataRepository : MasterdataRepository {
satznummer = remote.satznummer, satznummer = remote.satznummer,
oepsNummer = remote.satznummer, // Oft identisch oder Mapping nötig oepsNummer = remote.satznummer, // Oft identisch oder Mapping nötig
lizenzKlasse = remote.lizenzKlasse, lizenzKlasse = remote.lizenzKlasse,
nation = "AUT" // Default für ZNS-Import nation = remote.nation ?: "AUT",
bundesland = remote.bundesland
) )
if (existingIdx >= 0) { if (existingIdx >= 0) {
Store.reiter[existingIdx] = entry Store.reiter[existingIdx] = entry
@@ -83,7 +84,9 @@ class DesktopMasterdataRepository : MasterdataRepository {
id = id, id = id,
vorname = namen.firstOrNull() ?: "", vorname = namen.firstOrNull() ?: "",
nachname = namen.drop(1).joinToString(" "), nachname = namen.drop(1).joinToString(" "),
rollen = remote.qualifikationen rollen = remote.qualifikationen,
nation = remote.nation ?: "AUT",
bundesland = remote.bundesland
) )
if (existingIdx >= 0) { if (existingIdx >= 0) {
Store.funktionaere[existingIdx] = entry Store.funktionaere[existingIdx] = entry